Denis Kulagin
Denis Kulagin

Reputation: 8917

Google Protocol Buffers: find out what message is encoded in byte[]

Is there a way to find out what type of message is encoded in byte[]? I mean, is it possible to develop things like:

byte [] buf;

if (typeOfMessage(buf) == "AProto") {
  AProto.parseFrom(buf);
} else if (typeOfMessage(buf) == "BProto") {
  BProto.parseFrom(buf);
}

...

Upvotes: 1

Views: 1086

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1501586

No, it isn't. Several different messages could all have the same byte[] representation. A message doesn't carry around with it any type information. The wire format indicates for each tag value what the encoding of the value is out of the various encodings, but that's as far as it goes.

If you want this functionality, however, it's relatively easy to wrap it up into your own message:

message MessageWithType {
  required string type_name = 1;
  required bytes data = 2;
}

Basically that just wraps each real message with the name of its type. This only works if you control the whole process, of course... if you don't get to change the data, you can't add that information.

As Kenton noted, with a fixed (and ideally small) set of types that you're interested in, you can declare a message with a field of each type (as per ursa's answer), using a oneof if you're using Protobuf 2.6.0+.

Upvotes: 1

ursa
ursa

Reputation: 4601

It does not work in the way you suggest. But there is a trick:

message DTO {
    // NOTE! The only and only message have to set.
    optional AProto aPhoto = 1;
    optional BPhoto bPhoto = 2;
    ...
    optional RenderRequest renderRequest = 20;
}

It adds some tech information into message, so you always know what you are working with. Also it allows to track versioning, when incompatible changes happens:

message DTO {
    ...
    //optional BPhoto bPhoto = 2; // Compatibility broken in release 2014-10-09 by ursa
    optional BPhoto bPhoto = 21;
    ...
}

Upvotes: 1

Related Questions