Only way I found is to serialize/deserialize the message body as byte array. Then you will get needed level of abstraction:
message header {
required string src = 1;
required string dest = 2;
required string type = 3;
}
message foo {
required string a = 2;
}
message bar {
required uint32 num = 2;
}
message request {
required header h;
required bytes data; // serialize foo or bar here
}
Then your code will be like that (this is a pseudo-code):
request req = request.ParseFromString(buffer);
if (req.h().type() == "foo") {
foo msg = foo.ParseFromString(req.data);
// process foo msg
}
else if (req.h().type() == "bar") {
bar msg = bar.ParseFromString(req.data);
// process bar msg
}