Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a field has been set in protocol buffer 3

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?

like image 478
user1798617 Avatar asked Aug 19 '18 14:08

user1798617


People also ask

What is oneof in protobuf?

Protocol Buffer (Protobuf) provides two simpler options for dealing with values that might be of more than one type. The Any type can represent any known Protobuf message type. And you can use the oneof keyword to specify that only one of a range of fields can be set in any message.

What is the difference between proto2 and proto3?

Proto3 is the latest version of Protocol Buffers and includes the following changes from proto2: Field presence, also known as hasField , is removed by default for primitive fields. An unset primitive field has a language-defined default value.

What is field number in protobuf?

Field numbers are an important part of Protobuf. They're used to identify fields in the binary encoded data, which means they can't change from version to version of your service. The advantage is that backward compatibility and forward compatibility are possible.


1 Answers

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.

like image 152
P.W Avatar answered Sep 28 '22 04:09

P.W