Если вы используете proto2 (а не proto3), это, похоже, хорошо подойдет для extensions . Каждое «внешнее» сообщение будет определять диапазон расширения, например (для цитирования из документа):
message Foo {
// ...
extensions 100 to 199;
}
Затем в вашей "внутренней" схеме вы можете объявить дополнительные поля для родительского сообщения - либо тривиальные поля, либо целые объекты:
message Bar { /*...*/ }
extend Foo {
optional Bar bar = 126;
}
Затем «внутренний» код использует любой API «расширений» для выбранной вами платформы; если вы используете реализацию Google, то это ряд методов, таких как HasExtension()
, ClearExtension()
, GetExtension()
, MutableExtension()
и AddExtension()
, но разные реализации могут иметь разные API.
При таком подходе «внешнее» сообщение никогда не имеет (или не нуждается) в знании внутренних данных; библиотека занимается всем этим.
Самое замечательное в этом подходе состоит в том, что он является побайтным идентичным использованию bytes
- поэтому ваши существующие данные должны быть полностью совместимы с тем, если вы использовали:
message Foo {
optional bytes bar = 126;
}
Обратите внимание, что proto3 не поддерживает расширения . Существует новая концепция Any
, которая предлагает в целом аналогичные результаты, но работает совсем по-другому. Он не совместим с байтами.