我正在尝试减少由 Google proto-buf 生成的方法的数量,其中一种替代方法是使用 proto-buf nano。但是我没有找到关于如何使用它的文档。除了 package link ,我找不到任何关于如何使用 nano 从 proto 文件生成 java 文件的信息。
所以问题很简单:如何使用 google proto nano 从 proto 文件生成 java 类以及如何在项目中使用它们?
最佳答案
查看主要的 protobuf 编译器源代码:
#include <google/protobuf/compiler/javanano/javanano_generator.h>
....
int main(int argc, char* argv[]) {
google::protobuf::compiler::CommandLineInterface cli;
cli.AllowPlugins("protoc-");
...
// Proto2 JavaNano
google::protobuf::compiler::javanano::JavaNanoGenerator javanano_generator;
cli.RegisterGenerator("--javanano_out", &javanano_generator,
"Generate Java source file nano runtime.");
return cli.Run(argc, argv);
}
Nano Generator options
java_package -> <file-name>|<package-name>
java_outer_classname -> <file-name>|<package-name>
java_multiple_files -> true or false
java_nano_generate_has -> true or false [DEPRECATED]
optional_field_style -> default or accessors
enum_style -> c or java
在 Android 存储库之外使用 nano protobufs:
- Link with the generated jar file
<protobuf-root>java/target/protobuf-java-2.3.0-nano.jar.
- Invoke with
--javanano_out
, e.g.:
./protoc '--javanano_out=java_package=src/proto/simple-data.proto|my_package,java_outer_classname=src/proto/simple-data.proto|OuterName:.' src/proto/simple-data.proto
在 Android 存储库中使用 nano protobufs:
- Set '
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
' in your local .mk file. When building a Java library or an app (package) target, the build
system will add the Java nano runtime library to the
LOCAL_STATIC_JAVA_LIBRARIES
variable, so you don't need to.- Set '
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := ...
' in your local .mk file for any command-line options you need. Use commas to join multiple
options. In the nano flavor only, whitespace surrounding the option
names and values are ignored, so you can use backslash-newline or
'+=' to structure your make files nicely.- The options will be applied to all proto files in
LOCAL_SRC_FILES
when you build a Java library or package. In case different options
are needed for different proto files, build separate Java libraries
and reference them in your main target. Note: you should make sure
that, for each separate target, all proto files imported from any
proto file inLOCAL_SRC_FILES
are included inLOCAL_SRC_FILES
. This
is because the generator has to assume that the imported files are
built using the same options, and will generate code that reference
the fields and enums from the imported files using the same code
style.- Hint: '
include $(CLEAR_VARS)
' resets allLOCAL_
variables, including the two above.
来自 https://android.googlesource.com/platform/external/protobuf/+/master/src/google/protobuf/ 的简单 nano 示例。
unittest_simple_nano.proto
package protobuf_unittest_import;
option java_package = "com.google.protobuf.nano";
// Explicit outer classname to suppress legacy info.
option java_outer_classname = "UnittestSimpleNano";
message SimpleMessageNano {
message NestedMessage {
optional int32 bb = 1;
}
enum NestedEnum {
FOO = 1;
BAR = 2;
BAZ = 3;
}
optional int32 d = 1 [default = 123];
optional NestedMessage nested_msg = 2;
optional NestedEnum default_nested_enum = 3 [default = BAZ];
}
命令行
./protoc '--javanano_out=java_package=google/protobuf/unittest_simple_nano.proto|com.google.protobuf.nano,java_outer_classname=google/protobuf/unittest_simple_nano.proto|UnittestSimpleNano:target/generated-test-sources' google/protobuf/unittest_simple_nano.proto
从NanoTest.java中提取的测试
public void testSimpleMessageNano() throws Exception {
SimpleMessageNano msg = new SimpleMessageNano();
assertEquals(123, msg.d);
assertEquals(null, msg.nestedMsg);
assertEquals(SimpleMessageNano.BAZ, msg.defaultNestedEnum);
msg.d = 456;
assertEquals(456, msg.d);
SimpleMessageNano.NestedMessage nestedMsg = new SimpleMessageNano.NestedMessage();
nestedMsg.bb = 2;
assertEquals(2, nestedMsg.bb);
msg.nestedMsg = nestedMsg;
assertEquals(2, msg.nestedMsg.bb);
msg.defaultNestedEnum = SimpleMessageNano.BAR;
assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
byte [] result = MessageNano.toByteArray(msg);
int msgSerializedSize = msg.getSerializedSize();
//System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
assertTrue(msgSerializedSize == 9);
assertEquals(result.length, msgSerializedSize);
SimpleMessageNano newMsg = SimpleMessageNano.parseFrom(result);
assertEquals(456, newMsg.d);
assertEquals(2, msg.nestedMsg.bb);
assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
}
同一个类中有很多测试用例,查看项目pom可以找到一个maven-antrun-plugin
配置来生成那个测试资源类
<!-- java nano -->
<exec executable="../src/protoc">
<arg value="--javanano_out=java_package=google/protobuf/unittest_import_nano.proto|com.google.protobuf.nano,java_outer_classname=google/protobuf/unittest_import_nano.proto|UnittestImportNano:target/generated-test-sources" />
<arg value="--proto_path=../src" />
<arg value="--proto_path=src/test/java" />
<arg value="../src/google/protobuf/unittest_nano.proto" />
<arg value="../src/google/protobuf/unittest_simple_nano.proto" />
<arg value="../src/google/protobuf/unittest_stringutf8_nano.proto" />
<arg value="../src/google/protobuf/unittest_recursive_nano.proto" />
<arg value="../src/google/protobuf/unittest_import_nano.proto" />
<arg value="../src/google/protobuf/unittest_enum_multiplejava_nano.proto" />
<arg value="../src/google/protobuf/unittest_multiple_nano.proto" />
</exec>
希望这对您有所帮助。
关于java - Android protobuf nano 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22247951/