В настоящее время я повторно посещаю проект с использованием протокольных буферов Google.
В своем проекте я хочу использовать функции Descriptors и Reflection буферов протокола.
В официальной документации указано, что комментарии к .proto
файлам можно читать:
- С помощью функции
DebugStringWithOptions()
, вызываемой сообщение или дескриптор. - С помощью функции _3 _, вызванный дескриптором.
Я не могу получить комментарии, поэтому думаю, что делаю что-то совершенно не так, или эта функция еще не полностью реализована в буферах протокола.
Вот несколько фрагментов кода:
google::protobuf::DebugStringOptions options;
options.include_comments = true;
std::cout << "google::protobuf::Descriptor::DebugStringWithOptions(): "
<< message.descriptor()->DebugStringWithOptions(options) << std::endl
<< std::endl;
const google::protobuf::FieldDescriptor* field_descriptor{
message.descriptor()->field(1)};
// TODO(wolters): Why doesn't this work?
google::protobuf::SourceLocation* source_location{
new google::protobuf::SourceLocation};
field_descriptor->GetSourceLocation(source_location);
// if (field_descriptor->GetSourceLocation(source_location)) {
std::cout << "start_line: " << source_location->leading_comments
<< std::endl;
std::cout << "end_line: " << source_location->leading_comments << std::endl;
std::cout << "start_column: " << source_location->start_column << std::endl;
std::cout << "end_column: " << source_location->end_column << std::endl;
std::cout << "leading_comments: " << source_location->leading_comments
<< std::endl;
std::cout << "trailing_comments: " << source_location->trailing_comments
<< std::endl;
// }
Я пробовал использовать следующие два синтаксиса для комментариев в файле .proto
, но ни один из них, похоже, не работает:
MessageHeader header = 1; // The header of this `Message`.
/**
* The header of this `Message`.
*/
MessageHeader header = 1;
Я использую GCC 4.7.1 (с включенной поддержкой C ++ 11) и последнюю версию Protocol Buffers версии 3.0.0-alpha-4.1.
Может ли кто-нибудь направить меня в правильном направлении и / или предоставить рабочий пример?
ИЗМЕНИТЬ 24 сентября 2015 г .:
После рассмотрения раздела Самоописывающиеся сообщения в официальной документации и тестировании много всего, мне кажется, я немного лучше разбираюсь в дескрипторах protobuf.
Поправьте меня, если одно или несколько из следующих утверждений неверны:
SelfDescribingMessage
proto только полезен, если другой конец не знает определений .proto.- Единственный способ получить доступ к комментариям к прототипу определения - создать файл .desc с помощью приложения
protoc
. - Чтобы получить комментарий, функцию-член GetSourceLocation можно использовать только в том случае, если «верхний» элемент имеет значение
FileDescriptorSet
,FileDescriptorProto
илиFileDesriptor
. Если это верно, то у буферов протокола плохой дизайн API, поскольку классgoogle::protobuf::Message
является божественным классом (предоставляющим доступ к полному API файлового дескриптора, но значения не предоставляются вообще). - Вызов
concrete_message.descriptor()->file()
не (и не может) содержать информацию об исходных комментариях, поскольку он не является частью скомпилированного кода.
Мне кажется, что единственный способ заставить это работать:
Вызвать протокол для файла Message.proto (который ссылается на все другие сообщения) с аргументами:
--include_imports --include_source_info and --descriptor_set_out=message.desc
Отправьте файл
message.desc
вместе с приложением / библиотекой, чтобы иметь возможность читать его во время выполнения (см. Ниже).- Создайте
google::protobuf::FileDescriptorSet
из этого файла. - Перебрать все
google::protobuf::FileDescriptorProto
изFileDescriptorSet
. - Преобразуйте каждый FileDescriptorProto в
google::protobuf::FileDescriptor
, используяgoogle::protobuf::DescriptorPool::BuildFile()
. - Найдите сообщение и / или поля с помощью одной из функций
Find…
, примененных к экземпляруFileDescriptor
. - Вызовите функцию
GetSourceLocation
для экземпляра дескриптора сообщения / поля. - Прочтите комментарии через
google::protobuf::SourceLocation::leading_comments
иgoogle::protobuf::SourceLocation::trailing_comments
.
Мне это кажется довольно сложным, поэтому у меня есть два дополнительных вопроса:
- Нет ли способа включить исходную информацию без использования FileDescriptorSet?
- Можно ли «связать» / установить
FileDescriptorSet
с конкретным классом / экземпляром сообщения, поскольку это резко упростит ситуацию?
РЕДАКТИРОВАТЬ 25 сентября 2015 г .: Под God Class я имею в виду, что класс Message
и / или классы дескрипторов предлагают общедоступные функции, которые более или менее бесполезны, поскольку они не предоставляют информация при использовании клиентом. Возьмем, к примеру, «нормальное» сообщение: сгенерированный код не содержит информацию об исходном комментарии, поэтому метод GetSourceLocation
во всех классах дескрипторов (например, Descriptor
и FieldDescriptor
) совершенно бесполезен. С логической точки зрения должны быть предоставлены отдельные экземпляры DescriptorLite
и FieldDescriptorLite
при работе с сообщениями и Descriptor
и FieldDescriptor
при работе с информацией из FileDescriptorSet
(источником которого обычно является файл .desc, сгенерированный из файла .proto). Тогда [...]Lite
класс будет родительским классом «нормального» класса. Аргумент о том, что protoc
, возможно, никогда не будет включать комментарии к источникам, подчеркивает мою точку зрения.
Под «соединением» я имею в виду функцию API, которая обновляет информацию дескриптора в сообщении с помощью информации дескриптора из файла .desc (который всегда является надмножеством дескрипторов, предоставленных сообщением, если я правильно понял).
protoc
? Я только что наткнулся наprotoc
аргументы-o
и--include_source_info
. Нужно ли мне создаватьFileDescriptorSet
, чтобы получать комментарии? - person Florian Wolters   schedule 23.09.2015