java - Android protobuf nano 文档

标签 java android protocol-buffers

我正在尝试减少由 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);
}

看着 protobuf's Readme

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 in LOCAL_SRC_FILES are included in LOCAL_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 all LOCAL_ 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/

相关文章:

android - Facebook 登录 : It doesn't redirect to the Facebook app installed?

c++ - 使用 Protocol Buffers 更快反序列化的建议

java - 高效地将 Java 列表转换为 Matlab 矩阵

Java HSB颜色模型: colors changing with brightness?

java - 如何将原始数组的正值返回到新数组中

Android 词典安全问题

android - 使用 Firebase 向所有已注册设备发送推送通知的 JSON 数据

java - hibernate 中的连接代理错误

java 2D 和 swing

crash - 仅在 GDB 中调用的纯虚方法