Как написать собственный 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);

оно работает.

Другие вопросы по тегам