Optional fields

As of Google Protobuf version 3.15, optional fields are 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 its default value. Marking a field 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 its value equals the default.

Let us take a look at a simple example:

message Foo 
{
  optional int32 count = 1;
};

Here we marked an integer as optional, enabling tracking of the presence of the field. To check if a field has been set, even to its 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 its 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 are marked as optional.

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