本文介绍了如何从原型文件向JAVA生成的类添加我自己的代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用protobuf,并且正在从以下proto文件中生成JAVA类.

I'm using protobuf and I'm generating JAVA classes from the following proto file.

syntax = "proto3";
enum Greeting {
    NONE = 0;
    MR = 1;
    MRS = 2;
    MISS = 3;
}

message Hello {
    Greeting greeting = 1;
    string name = 2;
}

message Bye {
    string name = 1;
}

option java_multiple_files = true;

现在,我需要向生成的文件中添加一些代码,我发现可以使用自定义插件( https://developers.google.com/protocol-buffers/docs/reference/java-generated#plugins ).我正在尝试用Java生成该插件,就像这样.

Now I need to add some code to the generated files and I found that is possible using a custom plugin (https://developers.google.com/protocol-buffers/docs/reference/java-generated#plugins). I'm trying to generate that plugin in Java, something like this.

public class Test {
   PluginProtos.CodeGeneratorResponse.getDefaultInstance();
   /* Code to get generated files from java_out and use the insertion points */
   codeGeneratorResponse.writeTo(System.out);
}

然后我运行

protoc --java_out=./classes --plugin=protoc-gen-demo=my-plugin --demo_out=. example.proto

问题在于,在我的Test.java主方法上,我不知道如何访问由选项--java_out创建的文件,因此我无法使用它们的插入点.当前,默认实例的CodeGeneratorResponse为空(没有文件).

The problem is that on my Test.java main method I don't know how to get access to the files created by the option --java_out so that I can use their insertion points. Currently the CodeGeneratorResponse for the default instance is empty (no files).

有人知道如何从--java_out获取CodeGeneratorResponse,以便可以向生成的类中添加更多代码吗?

Does anybody know how can I get the CodeGeneratorResponse from the --java_out so that I can add more code to the generated classes?

谢谢.

推荐答案

我最近也为此苦苦挣扎,无法找到一个好的答案.盯着 CodeGeneratorResponse 消息一段时间.

I recently struggled with this as well and wasn't able to find a good answer. I finally figured it out after staring at the comments within the CodeGeneratorResponse message for a while.

最初让我失望的是,我将插件视为一条管道,其中来自一个插件的输出将馈送给另一个插件.但是,每个插件都获得完全相同的输入(通过CodeGeneratorRequest消息表示的已解析的.proto文件),并且所有从插件生成的代码(包括内置代码)都组合到了输出文件.但是,插件可能会修改以前的插件的输出,这就是设计插入点的目的.

What threw me off at first was that I was thinking of plugins as a pipeline, where the output from one feeds into the next. However, each plugin gets the exact same input (the parsed .proto files expressed via CodeGeneratorRequest messages), and all the generated code from the plugins (including the built-in ones) gets combined into the output file. However, plugins may modify the output from the previous plugins, which is what insertion points are designed for.

针对您的问题,您将在响应中添加file,其中name字段设置为生成的Java文件的名称,insertion_point字段设置为插入点的名称,位于您要添加代码的位置,content字段设置为此时要插入的代码.

Specifically to your question, you would add a file to the response with the name field getting set to the name of the generated Java file, the insertion_point field getting set to the name of the insertion point at which you want to add code, and the content field getting set to the code you want inserted at that point.

我找到了这篇文章有助于创建简单的插件(在本例中为python).作为一个简单的测试,我修改了该文章中的generate_code函数,如下所示:

I found this article helpful in creating a simple plugin (in this case in python). As a simple test, I modified the generate_code function from that article to look like this:

def generate_code(request, response):
    for proto_file in request.proto_file:
        f = response.file.add()
        f.name = "Test.java"
        f.insertion_point = "outer_class_scope"
        f.content = "// Inserting a comment as a test"

然后我使用该插件运行了协议

Then I ran protoc with the plugin:

$ cat test.proto
syntax = "proto3";
message MyMsg {
    int32 num = 1;
}
$ protoc --plugin=protoc-gen-sample=sample_proto_gen.py --java_out=. --sample_out=. test.proto
$ tail -n3 Test.java
  // Inserting a comment as a test
  // @@protoc_insertion_point(outer_class_scope)
}

您的插件只需要是一些可执行文件,即可从stdin读取CodeGeneratorRequest消息并将一条CodeGeneratorResponse消息写入stdout,因此可以肯定地用Java编写.我只是选择了python,因为我通常更喜欢它,并找到了这个简单的示例.

Your plugin just needs to be some executable which reads a CodeGeneratorRequest message from stdin and writes a CodeGeneratorResponse message to stdout, so could certainly be written in Java instead. I just chose python as I'm generally more comfortable with it and found this simple example.

这篇关于如何从原型文件向JAVA生成的类添加我自己的代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 14:19