Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there no custom default values in proto3?

The proto2 version of Protocol Buffers allows to specify default values for message elements:

optional double scaling_factor = 3 [default = 1.0];

Why is this no longer possible in proto3? I consider this a neat feature to save additional bytes on the wire without the need of writing any wrapper code.

like image 628
Daniel Pauli Avatar asked Oct 19 '15 19:10

Daniel Pauli


People also ask

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.

Why was required removed from proto3?

We dropped required fields in proto3 because required fields are generally considered harmful and violating protobuf's compatibility semantics.

Are all fields optional in proto3?

proto3 basically makes all fields optional.

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.


3 Answers

My understanding is that proto3 no longer allows you to detect field presence and no longer supports non-zero default values because this makes it easier to implement protobufs in terms of "plain old structs" in various languages, without the need to generate accessor methods. This is perceived as making Protobuf easier to use in those languages.

(I personally think that languages which lack accessors and properties aren't very good languages and protobuf should not design down to them, but it's not my project anymore.)

like image 70
Kenton Varda Avatar answered Oct 16 '22 11:10

Kenton Varda


This is a work around instead of a direct answer to your question, but I've found myself using wrappers.proto optional values and then setting the default value myself programatically when I absolutely must know if this was a default value or a value that was explicitly set.

Not optimal that your code has to enforce the value instead of the generated code itself, but if you own both sides, at least it's a viable alternative versus having no idea if the value was the default or explicity set as such, especially when looking at a bool set to false.

I am unclear how this affects bytes on the wire. For the instances where I've used it, message length was not a design constraint.

Proto File

import "google/protobuf/wrappers.proto";

google.protobuf.BoolValue optional_bool = 1;

Java code

//load or receive message here
if( !message.hasOptionalBool() )
    message.setOptionalBool( BoolValue.newBuilder().setValue( true ) );
like image 5
Evan Avatar answered Oct 16 '22 11:10

Evan


In my autogenerated file .pb.cc I see few places like this:

if (this->myint() != 0) {

and few like this:

myint_ = 0;

So, why not to enable default value and generate

static ::google::protobuf::int32 myint_defaultvalue = 5;

...
if (this->myint() != myint_defaultvalue) {
...

...
myint_ = myint_defaultvalue;
...

instead?

like image 4
Ilyan Avatar answered Oct 16 '22 09:10

Ilyan