Protobuf getAllFields() not working as expected

2019-09-07 03:23发布

问题:

I need to parse protobuf messages sent by third party and process those. A part where I am facing an issue in accessing fields looks like following:

ext {\n  is_foo: NO\n  is_bar: false\n  
12: \"fgyhcbho-4594-34545-gbvj\"\n  13: 0\n } 

I am mainly interested in accessing the value of the field name "12". However, getAllFields().entrySet() returns only 2 entries - is_foo and is_bar . So I am unable to get the value "fgyhcbho-4594-34545-gbvj" of the field "12".

Following is a part of my .proto file which I compiled using protobuf(v2.6) compiler to generate .java file:

message Ext {
    optional bool is_foor = 1;      
    optional bool is_bar = 2;  
    optional string uid = 12;  
    optional int32 did = 13;  
 }

My .java file contains method hasUid() and getUid(). But the protobuf message I receive contains field "12" and not "uid". So when I try to deserialize to Java, it just does not contain that field and no unknown fields either.

Below is the code snippet I am using:

if (this.protoReq.getExt() != null) {
        for (Map.Entry<FieldDescriptor, Object> entry : this.protoReq.getExt().getAllFields().entrySet()) {
            FieldDescriptor field = entry.getKey();
            if (field.getName().equals("12")) {
                Object value = entry.getValue();
                if (value != null) {
                   //do something
                }
                break;
            }
        }
    }

Am I missing something? Is there any other way to access it ? Any help is appreciated. Thank you.

回答1:

When you see fields with numeric labels, it means that the field is an unknown field -- the number seen on the wire doesn't match any field name defined in the .proto file.

getAllFields() only returns known fields, because it returns a descriptor->value map, and descriptors only exist for known fields.

To read unknown fields, you need to call message.getUnknownFields(), which returns an UnknownFieldSet. That object maps unknown field numbers to values.