Check if a field has been set in protocol buffer 3

user1798617 picture user1798617 · Aug 19, 2018 · Viewed 25.8k times · Source

I am migrating a java application from protocol buffers 2 to protocol buffer 3.

In proto 2 to check if a field is set you have hasfield() method for which an example Java code generated is:

public boolean hasText() {
  return ((bitField0_ & 0x00000004) == 0x00000004);
}

However in proto 3 there it has been removed. How do you check if a field has been set in proto 3?

Answer

P.W picture P.W · Aug 20, 2018

One of the suggested approaches is given here:

# NOTE: As of proto3, HasField() only works for message fields, not for
#       singular (non-message) fields. First try to use HasField and
#       if it fails (with a ValueError) we manually consult the fields.
try:
    return message_pb.HasField(property_name)
except ValueError:
    all_fields = set([field.name for field in message_pb._fields])
    return property_name in all_fields

Also, from the same page:

In proto3, field presence for scalar fields simply doesn't exist. Your mental model for proto3 should be that it's a C++ or Go struct. For integers and strings, there is no such thing as being set or not, it always has a value. For submessages, it's a pointer to the submessage instance which can be NULL, that's why you can test presence for it.