Optional fields

As of Google Protobuf version 3.15 optional fields have been reintroduced in proto3. Embedded Proto supports optional fields as of version 2.3.0.

This feature allows you to track if a field has been set. Even if the field is set to it’s default value. Marking a fields as optional will also serialize default values when a field is set. This in contrast to a regular field which will not be serialized when it’s value equals to the default.

Lets take a look at a simple example:

message Foo 
{
  optional int32 count = 1;
};

Here we marked an integer as optional. This will add tracking of the fields presence. To check if a field has been set, even to it’s default value, you can use the has_xxx() function:

Foo msg;
msg.set_count(2);
if(msg.has_count()) 
{
 // Do someting with the count field. 
}

// Set to default value
msg.set_count(0);
// Still true even thow count equals zero.
bool count_is_set = msg.has_count();

Even when you set the field to zero, the default for an integer, it is still marked as present. This will result in the field being serialized into the byte stream. This would not happen with regular fields not marked as optional.

// Set to default value
msg.set_count(0);
// Still true even thow count equals zero.
bool count_is_set = msg.has_count(); 

// Count will show up in the serialized data.
msg.serialize(buffer);

To clear the presence of a field, you call the clear_xxx() function of that field. This will reset the value of the field to it’s default.

msg.clear_count();
// Returns false
bool count_is_set = msg.has_count(); 

The table below states an overview of the effect the optional keyword has on different types of fields.

Variable TypeMarked OptionalPresence Tracked
Singular integer or floating pointNoNo
Singular integer or floating pointYesYes
Singular enumNoNo
Singular enumYesYes
Singular string or bytesNoNo
Singular string or bytesYesYes
Singular messageNo§No
Singular messageYesYes
RepeatedN/A
OneofsN/AYes†
MapsN/A

§ The google implementation tracks the presence of nested message fields when memory is allocated for that field. In Embedded Proto no memory is dynamically allocated and the presence of nested message fields is not tracked unless the fields is marked as optional.

† The presence of an oneof field can be tracked using the which_xxx() function.