Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Protocol Buffer field options

How does one get the options associated with a protocol buffer field?

E.g., suppose I have a field with a custom options:

message Foo {
  optional string title = 1 [(indexed) = true];
}

I can get a list of fields:

for f in foo.ListFields():
  print f

How do I access the "indexed" state? (I can see there is a list of f "_options", but that seems "internal"? Is there a proper way to access option extensions by name)?

like image 562
rsb Avatar asked Dec 14 '22 11:12

rsb


1 Answers

I'll use as an example the nanopb custom options, as defined here. However the answer itself is not in any way nanopb-specific, nanopb uses the standard protobuf style for custom options:

message NanoPBOptions {
   optional int32 max_size = 1;
   ...
}
extend google.protobuf.FieldOptions {
   optional NanoPBOptions nanopb = 1010;
}

and an option defined like this:

message Person {
   optional string email = 3 [(nanopb).max_size = 40];
}

The API used to get the option value varies between languages. However the basic flow is the same:

  1. Get the message descriptor from the object.
  2. Get the field descriptor from the message descriptor.
  3. Get the options from the field descriptor.
  4. Get the extension field from the options, and the value you want from that.

In Python:

desc = person_pb2.Person.DESCRIPTOR
field_desc = desc.fields_by_name['email']
options = field_desc.GetOptions()
value = options.Extensions[nanopb_pb2.nanopb].max_size

In Java:

desc = PersonProto.Person.getDescriptor();
field_desc = desc.findFieldByName("email");
options = field_desc.getOptions();
value = options.getExtension(Nanopb.nanopb).getMaxSize();

In C++:

desc = Person::descriptor()
field_desc = desc->FindFieldByName("email");
options = field_desc->options();
value = options.GetExtension(nanopb).max_size());
like image 96
jpa Avatar answered Jan 04 '23 05:01

jpa