Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design for a future additional enum value in protocol buffers?

One of the attractive features of protocol buffers is that it allows you extend the message definitions without breaking code that uses the older definition. In the case of an enum according to the documentation:

a field with an enum type can only have one of a specified set of constants as its value (if you try to provide a different value, the parser will treat it like an unknown field)

therefore if you extend the enum and use the new value then a field with that type in old code will be undefined or have its default value, if there is one.

What is a good strategy to deal with this, knowing that in future the enum may have additional values added?

One way that comes to mind is to define an "undefined" member of the enum and make that the default, then old code will know it has been sent something that it can't interpret. Is that sensible, are there better ways to deal with this situation?

like image 209
glennr Avatar asked May 01 '12 02:05

glennr


People also ask

How does Protobuf define enum?

enum is one of the composite datatypes of Protobuf. It translates to an enum in the languages that we use, for example, Java. Now our message class contains an Enum for payment. Each of them also has a position which is what Protobuf uses while serialization and deserialization.

How do you define an optional field in Protobuf 3?

The Best Answer is In proto3, all fields are "optional" (in that it is not an error if the sender fails to set them). But, fields are no longer "nullable", in that there's no way to tell the difference between a field being explicitly set to its default value vs. not having been set at all.

How do I set default value in Protobuf?

For bool s, the default value is false. For numeric types, the default value is zero. For enums , the default value is the first value listed in the enum's type definition. This means care must be taken when adding a value to the beginning of an enum value list.

What is the difference between proto2 and Proto3?

Proto3 is the latest version of Protocol Buffers and includes the following changes from proto2: Field presence, also known as hasField , is removed by default for primitive fields. An unset primitive field has a language-defined default value.


2 Answers

Yes, the best approach is to make the first value in the enum something like UNKNOWN = 0. Then old programs reading a protobuf with an enum value they don't recognize will see it as UNKNOWN and hopefully they can handle that reasonably, eg by skipping that element.

If you want to do this you'll also want to make the enum be optional not required.

required, generally, means "I'd rather the program just abort than handle something it doesn't understand."

Note that it must be the first value declared in the proto source - just being the zero value doesn't make it the default.

like image 148
poolie Avatar answered Oct 13 '22 06:10

poolie


At least in the java implementation of proto3, it creates a default value. The value will start with "UNKNOWN_ENUM_VALUE_"

Code references:

  • https://github.com/protocolbuffers/protobuf/blob/0707f2e7f556c8396d6027d0533ec3a56d1061db/java/core/src/main/java/com/google/protobuf/Descriptors.java#L640-L642
  • https://github.com/protocolbuffers/protobuf/blob/0707f2e7f556c8396d6027d0533ec3a56d1061db/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java#L2750-L2751
  • https://github.com/protocolbuffers/protobuf/blob/0707f2e7f556c8396d6027d0533ec3a56d1061db/java/core/src/main/java/com/google/protobuf/Descriptors.java#L1832
  • https://github.com/protocolbuffers/protobuf/blob/0707f2e7f556c8396d6027d0533ec3a56d1061db/java/core/src/main/java/com/google/protobuf/Descriptors.java#L2034-L2045
like image 37
Chris Avatar answered Oct 13 '22 06:10

Chris