https://protobuf.dev/best-practices/dos-donts/#unspecified-e...
https://protobuf.dev/best-practices/dos-donts/#unspecified-e...
It’s more complicated:
https://protobuf.dev/programming-guides/enum/
>> What happens when a program parses binary data that contains field 1 with the value 2?
>- Open enums will parse the value 2 and store it directly in the field. Accessor will report the field as being set and will return something that represents 2.
>- Closed enums will parse the value 2 and store it in the message’s unknown field set. Accessors will report the field as being unset and will return the enum’s default value.
It used to be that we broadly had two sets of semantics (modulo additional customizations): proto2 and proto3. Proto editions was supposed to unify the two versions, but instead now we have the option to mix and match all of the quirks of each of the versions.
And, to make matters worse, you also have language-dependent implementations that don't conform to the spec (in fact, very few implementations are conformant). C++ and Java treat everything imported by a proto2 file as closed; C#, Golang, and JS treat everything as open.
I don't see a path forward for removing these custom deprecated field features, or else we'd have already begun that effort during the initial adoption of editions.
I've taken to coding my C enums with the first value being "Invalid", indicating it is never intended to be created. If one is encountered, it's a bug.
This doesn’t happen when you make the first value in the enum unknown/unspecified
So any future new flavor will be read back as ‘0’ in older versions.
I've used a few clients that completely lock me out for every tiniest minor version update. Very top-tier annoying imho.
I’ve seen engineers bring those unknowns or unspecified through to the business logic and that always made my face flush red with anger.
If you are consuming data from some other system you have no power over what to require from users. You will have data points with unknown properties.
Say you are tracking sign ups in some other system, and they collect the users’ browser in the process, and you want to see conversion rate per browser. If the browser could not be identified, you prefer it to say ”other” instead of ”unknown”?
I think I prefer the protobuf best practices way: you have a 0 ”unknown”/”unset” value, and you enumerate the rest with a unique name (and number). The enum can be expanded in the future so your code must be prepared for unknown enumerated values tagged with the new (future for your code) number. They are all unique, you just don’t yet know the name of some of the enum values.
You can choose to not consume them until your code is updated with a more recent schema. Or you can reconcile later, annotating with the name of you need it.
Now personally, I would not pick an enum for any set och things that is not closed when you are designing. But I’m starting to think that such sets hardly exist in the real world. Humans redefine everything over time.