0

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.

dhamu
  • 605
  • 1
  • 7
  • 17

1 Answers1

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.

Kenton Varda
  • 41,353
  • 8
  • 121
  • 105
  • Thanks @Kenton. That's good to know. But even if I use getUnknownFields() i.e. following code :- 'Field field = this.protoReq.getExt().getUnknownFields().getField(12); ' , returns empty collection. I am using protobuf 2.6, just FYI. – dhamu Dec 14 '16 at 16:02
  • @pooja AFAIK that should work. :/ Maybe if you provided more code I could spot the problem. – Kenton Varda Dec 15 '16 at 05:10
  • I have edited the question to include .proto part . Please let me know if that helps. I am stuck. Appreciate any pointer. Thanks. – dhamu Dec 19 '16 at 16:04
  • @pooja Please show the code where you parse the message and which produces the text output that you gave at the beginning of your question. (AFAICT the `Ext` type as you've declared it should never produce the text you gave.) – Kenton Varda Dec 21 '16 at 05:24
  • Actually the text I shared at the beginning is sent by the third party which I don't have control over and they use protobuf v2.1. The 'message Ext' is a part of .proto file they shared with us and I am using the same to generate my .java file which has not worked so far. Is there a possibility that they are using a different version of .proto file? – dhamu Dec 21 '16 at 15:58
  • I suspect so. The .proto file you provided shows fields 12 and 13 clearly defined. In that case the text should never contain "12:" or "13:" -- it should show the textual names, "uid:" and "did:". – Kenton Varda Dec 22 '16 at 05:01
  • Thanks @Kenton . Finally I figured out that our vendor had made that field optional and it was not in our .proto file which is why our parser was simply ignoring it. Updated our .proto file and it worked . – dhamu Jan 05 '17 at 16:06