'proto3 check if parameter is set

since in proto3 all parameters are optional when parameter is not set and message is deserialized then unset parameter holds default value. I can not find a way to check if the parameter has been set or not. Is there any way to find if parameter has been set similary as in proto2? I see that there is a method has_<param_name>() but it is private.



Solution 1:[1]

I don't think the distinction exists anymore in proto3. You are encouraged to have meaningful defaults.

But if you must, you can use a singular embedded message containing the value.

Solution 2:[2]

It seems after Protobuf 3.15.0 you could use hasField in C++ again:

According to the CHANGELOG:

Now Proto3 Oneof fields have "has" methods for checking their presence in C++.

Solution 3:[3]

Building upon ramsay's answers, one thing that you can do if you have a real need for Null kind of value, is this:

import "google/protobuf/struct.proto";

message Test {
  oneof value_or_null {
    string value = 1;
    google.protobuf.NullValue null = 2;
  };
}

with the one of you will get the has_<param_name>() function back and you will be able to check if you have null or a value. Also this is a safer approach because you cannot set the two fields, the oneof implementation will make sure that potential previous field value get cleared and set the new one.

Do note however, that evolving oneof fields is trickier than evolving normal fields (you can see the potential problems here)

My recommendations

  • I would first make sure that there is a real need for Null and thus a real need for oneof.
  • I would try to make the default value of each field an invalid value in my business logic (eg: uint32 id with 0 value is invalid and I return an error)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thomas
Solution 2 ramsay
Solution 3 Clément Jean