Разбор плагина пользовательского протокола не работает для пользовательских параметров

Я пытаюсь написать плагин protoc, который требует от меня использования пользовательских параметров. Я определил свой собственный параметр, как показано в примере (https://developers.google.com/protocol-buffers/docs/proto#customoptions):

import "google/protobuf/descriptor.proto";

extend google.protobuf.MessageOptions {
    string my_option = 51234;
}

Я использую его следующим образом:

message Hello {
    bool greeting = 1;
    string name = 2;
    int32 number = 3;

    option (my_option) = "telephone";
}

Однако, когда я читаю проанализированный запрос, поле параметров пусто для сообщения «Привет».

Я делаю следующее, чтобы прочитать

data = sys.stdin.read()

request = plugin.CodeGeneratorRequest()
request.ParseFromString(data)

Когда я печатаю «запрос», он просто дает мне это

message_type {
  name: "Hello"
  field {
    name: "greeting"
    number: 1
    label: LABEL_REQUIRED
    type: TYPE_BOOL
    json_name: "greeting"
  }
  field {
    name: "name"
    number: 2
    label: LABEL_REQUIRED
    type: TYPE_STRING
    json_name: "name"
  }
  field {
    name: "number"
    number: 3
    label: LABEL_OPTIONAL
    type: TYPE_INT32
    json_name: "number"
  }
  options {
  }
}

Как видно, поле параметров пусто, хотя я определил параметры в своем файле .proto. Является ли мой синтаксис неправильным для определения пользовательских параметров? Или это может быть проблема с моей версией protoc?


person staleMilk    schedule 05.07.2017    source источник
comment
Данные являются расширениями объекта параметров. Вы использовали API расширения? Вы должны использовать API расширений для чтения пользовательских параметров. Чтобы увидеть, есть ли он там, вы можете использовать descriptor-set-output и загрузить файл на protogen.marcgravell.com/decode. - он разделяет любой файл, чтобы показать все поля   -  person Marc Gravell    schedule 05.07.2017
comment
Спасибо за ответ, @MarcGravell! Я возился с API расширений, но не могу заставить его перечислить расширения, которые были сделаны для параметров. Это то, что у меня есть до сих пор. Не могли бы вы помочь мне получить доступ к элементам внутри этого объекта? d = msg.DESCRIPTOR.GetOptions().Extensions где msg — это сообщение в моем прото-файле   -  person staleMilk    schedule 05.07.2017
comment
Хорошо: какой язык/фреймворк вы используете? От этого зависит синтаксис доступа к расширениям. Здесь есть примеры для C++: developers.google.com/protocol-buffers/docs /прото#расширения   -  person Marc Gravell    schedule 05.07.2017
comment
Я использую python, но пример в приведенной вами ссылке, похоже, не работает. При попытке доступа к my_proto_file_pb2.my_option выдает ошибку AttributeError: 'FileDescriptorProto' object has no attribute 'my_option'. Нужно ли использовать файлы, сгенерированные протоколом, для доступа к расширениям? @МаркГравелл   -  person staleMilk    schedule 05.07.2017
comment
это будет зависеть от используемой вами структуры; К сожалению, по Python ничего не могу посоветовать.   -  person Marc Gravell    schedule 05.07.2017


Ответы (2)


Оказывается, вам нужно импортировать файл _pb2.py для файла .proto, в котором определена пользовательская опция. Например, если вы анализируете файл (используя ParseFromString) с именем example.proto, который использует пользовательскую опцию, определенную в option.proto, вы должны импортировать option_pb2.py в файл Python, который вызывает ParseFromString.

person staleMilk    schedule 07.07.2017

Я делаю свой плагин protobuf python. У меня также есть проблема, как у вас, и я нашел решение для этого.

  • Поместите свои пользовательские параметры в файл my_custom.proto
  • Используйте protoc для создания файла python из my_custom.proto => my_custom_pb2.py
  • В коде вашего плагина Python импортируйте my_custom_pb2.py import my_custom_pb2
person Hoai Nguyen    schedule 12.12.2019