Как написать собственный Protobuf CodeGenerator на Java
Я пытаюсь написать собственный генератор кода для собственного проприетарного языка программирования. Я подумал, что смогу написать генератор на Java, используя руководство по плагину protoc. Мой main() делает что-то вроде этого:
public static void main(String[] args) throws IOException {
CodeGenerator gen = new CodeGenerator();
PluginProtos.CodeGeneratorRequest codeGeneratorRequest = PluginProtos.CodeGeneratorRequest.parseFrom(args[0].getBytes());
codeGeneratorRequest.getProtoFileList().forEach(gen::handleFile);
// get the response and do something with it
//PluginProtos.CodeGeneratorResponse response = PluginProtos.CodeGeneratorResponse.newBuilder().build();
//response.writeTo(System.out);
}
(Очевидно, я только начал; хотел сначала получить что-нибудь короткое, прежде чем писать логику генерации)
Проблема заключается в следующем: как мне вызвать protoc с аргументом --plugin для генерации кода на моем собственном языке, используя мой плагин? Я попытался написать сценарий оболочки, чтобы сделать это так:
#!/bin/bash
java -cp ./codegen.jar CodeGeneratorMain "$@"
И я попытался вызвать protoc так: protoc --plugin=protoc-gen-code --code_out=./build hello.proto
однако, когда я запускаю это, я получаю эту ошибку:
Исключение в потоке "main" java.lang.ArrayIndexOutOfBoundsException: 0 в CodeGeneratorMain.main(CodeGeneratorMain.java:12) --code_out: protoc-gen-code: Ошибка плагина с кодом состояния 1.
Как будто он не передает CodeGeneratorRequest на стандартный ввод. Как мне это проверить? Я делаю что-то явно неправильно?
1 ответ
Поэтому, прочитав и перечитав документы, я понял свою очень глупую ошибку: protoc передает проанализированный ввод через stdin, а не через argv. Это означает, что если я изменю это: PluginProtos.CodeGeneratorRequest codeGeneratorRequest = PluginProtos.CodeGeneratorRequest.parseFrom(args[0].getBytes());
к этому: PluginProtos.CodeGeneratorRequest codeGeneratorRequest = PluginProtos.CodeGeneratorRequest.parseFrom(System.in);
оно работает.