-
Notifications
You must be signed in to change notification settings - Fork 194
Description
References for proto3 optional
syntax:
- https://github.com/protocolbuffers/protobuf/blob/main/docs/implementing_proto3_presence.md
- https://github.com/protocolbuffers/protobuf/blob/main/docs/field_presence.md
Quoting the second reference above:
The no presence serialization discipline results in visible differences from the explicit presence tracking discipline, when the default value is set. For a singular field with numeric, enum, or string type:
- No presence discipline:
...
The default value may mean:
- the field was explicitly set to its default value, which is valid in the application-specific domain of values;
- the field was notionally "cleared" by setting its default; or
- the field was never set.
In addition, it says
Without the optional label, proto3 APIs do not track presence for basic types (numeric, string, bytes, and enums), either
So in proto3, without optional
, a field with default value cannot be distinguished from the non-presence of the same field. In all cases the value of the field is the default one, and presence of the field is not tracked.
With all this information, as a user, I would expect a message with default int32
value, and a message with the field non-present to be equal, and generate the same hash code, as the difference should not be observed. This currently does not hold:
// field tag is 9
var m1 = Msg1()..mergeFromBuffer([72, 0]);
var m2 = Msg1()..mergeFromBuffer([]);
print('hash codes equal = ${m1.hashCode == m2.hashCode}');
print('values equal = ${m1 == m2}');
Output:
hash codes equal = false
values equal = false
We also generate a hazzer for this field, and it works as if the field was optional
. That's also a bug, but I think an separate one. For example, we could be generating hazzers and track presence, but without using the hazzer the messages could be identical (i.e. equal, with same hash code, all other API methods returning the same values).
b/134058565