It is possible to get universal message functionality, but when adding new types, you will need to rebuild the proto classes.
You use shell class
message Wrapper { extensions 1000 to max; required uint32 type = 1; }
Then add some types
message Foo { extend Wrapper { optional Foo item = 1000; } optional int attr1_of_foo = 1; optional int attr2_of_foo = 2; optional int attr3_of_foo = 3; } message Bar { extend Wrapper { optional Bar item = 1001; } optional int attr1_of_bar = 1; optional int attr2_of_bar = 2; optional int attr3_of_bar = 3; }
See how we extend the Wrapper class in the classes that we want to keep the Wrapper class using the extension.
Now, an example of creating a Foo wrapped object. I use Python as this is the most concise form. Other languages ββcan do the same.
wrapper = Wrapper() wrapper.type = Foo.ITEM_FIELD_NUMBER foo = wrapper.Extensions[Foo.item] foo.attr1_of_foo = 1 foo.attr2_of_foo = 2 foo.attr3_of_foo = 3 data = wrapper.SerializeToString()
And an example of deserialization
wrapper = Wrapper() wrapper.ParseFromString(data) if wrapper.type == Foo.ITEM_FIELD_NUMBER: foo = wrapper.Extensions[Foo.item] elif wrapper.type == Bar.ITEM_FIELD_NUMBER: bar = wrapper.Extensions[Bar.item] else: raise Exception('Unrecognized wrapped type: %s' % wrapper.type)
Now, since you need a common collection, make Wrapper a repeating field for another message and voilΓ .
Of course, this is not a complete solution, a little more packaging is required to create this architecture. For more information, read about Protobuf extensions, especially nested ( https://developers.google.com/protocol-buffers/docs/proto#nested ) or google about sorting items.
source share