Finding protocol buffer message type from serialized data

c++, protocol-buffers, serialization

Solution

protobuf does not include any type information on the wire (unless you do that yourself external to protobuf). As such you cannot strictly validate that - which is actually a good thing, because it means that types are interchangeable and compatible. As long as `class abc` has a compatible contract to the other type, it will work. By "compatible" here, I mean: for any field-numbers that are common to both, they have compatible wire-types. If `abc` declares field 4 to be a string, and the other class declares field 4 to be a double-precision number, then it will fail at deserialize.

One other "signal" you could use is the omission of `required` fields: if `abc` always includes field 3, but you get data that omits field 3, then it probably isn't an `abc`. Note that protobuf is designed to be version tolerant, though: you can't assume that extra fields mean it isn't an `abc`, as it could be that the data is using a later version of the contract, or is using extension fields. Likewise, missing optional fields could be missing because either they simply chose not to provide a value, or that field is not declared on the version of the contract they are using.

Re testing for a successful parse: that will be implementation specific. I would imagine that the c++ implementation will have either a return-value to check, or a flag field to check. I don't use that api myself so I cannot say. On some other platforms I would expect an exception to be thrown (java, .net, etc) if there was a critical issue.

Problem

I have some binary data, which was obtained by serializing a google protocol buffer class. How do I find out, at runtime, the class for which the data was serialized. For example, suppose i have a class abc. I serialized this class abc into binary data. Is there any way of validating that this binary data was obtained by serializing class abc, and not some other class? Further, if i parse this binary data of class abc by the parse method of class xyz, how would I know if the parse was successful.

Original source