Why are there no custom default values in proto3?

Protocol BuffersProto3

Protocol Buffers Problem Overview


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.

Protocol Buffers Solutions


Solution 1 - Protocol Buffers

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.)

Solution 2 - Protocol Buffers

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 ) );

Solution 3 - Protocol Buffers

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?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDaniel PauliView Question on Stackoverflow
Solution 1 - Protocol BuffersKenton VardaView Answer on Stackoverflow
Solution 2 - Protocol BuffersEvanView Answer on Stackoverflow
Solution 3 - Protocol BuffersIlyanView Answer on Stackoverflow