Alcott
Alcott

Reputation: 18585

Iterate over all the fields and get their values in protobuf message

I have a dynamic protobuf message, and I don't know what fields this message contains.

What I want to do is, put all the values of all the fields into one string, for example, the message contains 2 fields, string name = "Jack"; and int age = 12;, the final result I want is "name:Jack, age:12".

Here is my idea, since I don't know what fields contained in this message, so I need to traverse the message to get all the fields' name, type (which can be accessed by Descriptor), and then get the value of each field, this is the most annoying part, because I need to write a long

switch (type) {
case TYPE_UINT32:
    //call get_uint32
    break;
case TYPE_UINT64:
    //call get_uint64
    break;
......
}

I wonder is there any other better idea to do this?

Upvotes: 5

Views: 7919

Answers (2)

wangyu
wangyu

Reputation: 150

Message* message = &your_proto;
const google::protobuf::Descriptor* desc = message->GetDescriptor();
const google::protobuf::Reflection* ref = message->GetReflection();
for (int i = 0; i < desc->field_count(); ++i) {
  const google::protobuf::FieldDescriptor* field_desc = desc->field(i); 
  switch (field_desc->cpp_type()) {
    case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
      // call get_int32
      break;
    case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
      // call get_int64
      break;
    ...
  }
}

Upvotes: 1

Kenton Varda
Kenton Varda

Reputation: 45171

This is basically what Protobuf's own TextFormat class does:

https://github.com/google/protobuf/blob/master/src/google/protobuf/text_format.cc#L1473

You can use that code as an example when writing your own. It is indeed rather tedious, but there's really no better way to do it.

Upvotes: 1

Related Questions