2015-02-07 4 views
1

Я могу создать схему (Descriptors.Descriptor) во время выполнения динамически, используя FileDescriptorProto, также я могу сериализовать и десериализовать сообщения с помощью DynamicMessage.Как скомпилировать схему буферов протокола во время выполнения?

Однако производительность DynamicMessage не достаточно хороша из-за того, как она создает сообщения. Интересно, можно ли компилировать схему во время выполнения и использовать ее при де-сериализации сообщений для повышения производительности.

Если протокол буфера не обеспечивают способ компилировать схемы во время выполнения, то, если это возможно, чтобы преобразовать Descriptors.Descriptor временный файл .proto, то я могу попытаться создать классы, вызвав protoc команды из моей программы и загрузок их в программу, используя API Class.forName.

ответ

2

Буферы протокола не включают в себя встроенную компиляцию «JIT».

Если вы хотите сгенерировать код и скомпилировать его с помощью javac во время выполнения, и вы начинаете с FileDescriptorProto, то, вероятно, вам нужно просто вызвать генератор кода Java (без преобразования определения прото в текст).

Вы можете выполнить это, написав небольшую программу на C++, которая создает google::protobuf::compiler::java::JavaGenerator и передает ее в google::protobuf::compiler::PluginMain(). Теперь у вас есть программа, которая считывает CodeGeneratorRequest со стандартного ввода и записывает CodeGeneratorResponse в стандартный вывод. Таким образом, вы можете выполнить эту программу для генерации кода Java непосредственно с FileDescirptorProto s. Вам решать передать этот код компилятору Java. Это должно быть намного проще и чище, чем пытаться подготовить текст для перехода на protoc.

+0

К сожалению, у меня недостаточно опыта работы с C++, поэтому я считаю, что мне будет сложно поддерживать и распространять этот плагин в узлах кластера. Компилятор javac фактически не компилирует код «на лету», поэтому, даже если я прочитал исходный код непосредственно со стандартного ввода, мне все равно нужно записать его в файл, чтобы использовать javac. Я подумал, может быть, protobuf может обеспечить способ сериализации FileDescriptorProto обратно в .proto, поскольку он уже использует это определение для создания FileDescriptorProto, но если это не так, я пойду своим путем. – Boyolame

+0

FWIW, необходимый код на C++ содержит около четырех строк для всей программы - это просто создание «JavaGenerator» и передача его в «PluginMain». ;; Я несколько смущен вашим возражением против 'javac' - даже если вы преобразовали FileDescriptorProto обратно в текст и затем загрузили его в' protoc', выход по-прежнему является кодом Java, поэтому вам все равно нужно 'javac' или что-то вроде Это. –

+0

Я предположил, что вы предложили мне написать небольшой плагин, это проблема переносимости, потому что программа позволит мне напрямую записывать/читать данные в программу без использования файловой системы. Однако, хотя я прочитал исходный код java из этой программы, мне все равно нужно записать его в файловую систему, чтобы запустить javac-компилятор, поэтому единственное преимущество этого плагина для меня - преобразование экземпляра FileDescriptorProto в определение protoc больше не требуется. Кроме того, protoc легко устанавливается через менеджеров пакетов в Linux, но если я пишу плагин, я также должен сам его распространять на узлы. – Boyolame