Skip to content Skip to sidebar Skip to footer

Android Protobuf Nano Documentation

I am trying to reduce the number of methods that are generated by Google proto-buf and one of the alternatives is to use proto-buf nano. However I found no documentation on how to

Solution 1:

Looking at the main protobuf compiler source code:

#include<google/protobuf/compiler/javanano/javanano_generator.h>
.... 

intmain(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);
}

looking at 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

To use nano protobufs outside of Android repo:

  • 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

To use nano protobufs within the Android repo:

  • 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.

Simple nano example from https://android.googlesource.com/platform/external/protobuf/+/master/src/google/protobuf/.

unittest_simple_nano.proto

package protobuf_unittest_import;

optionjava_package="com.google.protobuf.nano";
// Explicit outer classname to suppress legacy info.optionjava_outer_classname="UnittestSimpleNano";

message SimpleMessageNano {
  message NestedMessage {
    optional int32bb=1;
  }

  enumNestedEnum {
    FOO = 1;
    BAR = 2;
    BAZ = 3;
  }

  optional int32d=1 [default = 123];
  optional NestedMessagenested_msg=2;
  optional NestedEnumdefault_nested_enum=3 [default = BAZ];
}

Command line

./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

Test extracted from NanoTest.java

publicvoidtestSimpleMessageNano()throws Exception {
    SimpleMessageNanomsg=newSimpleMessageNano();
    assertEquals(123, msg.d);
    assertEquals(null, msg.nestedMsg);
    assertEquals(SimpleMessageNano.BAZ, msg.defaultNestedEnum);

    msg.d = 456;
    assertEquals(456, msg.d);

    SimpleMessageNano.NestedMessagenestedMsg=newSimpleMessageNano.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);
    intmsgSerializedSize= msg.getSerializedSize();
    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    assertTrue(msgSerializedSize == 9);
    assertEquals(result.length, msgSerializedSize);

    SimpleMessageNanonewMsg= SimpleMessageNano.parseFrom(result);
    assertEquals(456, newMsg.d);
    assertEquals(2, msg.nestedMsg.bb);
    assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
  }

There are a lot of test cases in the same class, and looking at the project pom you can find a maven-antrun-plugin configuration to generate that test resource classes

<!-- java nano --><execexecutable="../src/protoc"><argvalue="--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" /><argvalue="--proto_path=../src" /><argvalue="--proto_path=src/test/java" /><argvalue="../src/google/protobuf/unittest_nano.proto" /><argvalue="../src/google/protobuf/unittest_simple_nano.proto" /><argvalue="../src/google/protobuf/unittest_stringutf8_nano.proto" /><argvalue="../src/google/protobuf/unittest_recursive_nano.proto" /><argvalue="../src/google/protobuf/unittest_import_nano.proto" /><argvalue="../src/google/protobuf/unittest_enum_multiplejava_nano.proto" /><argvalue="../src/google/protobuf/unittest_multiple_nano.proto" /></exec>

Hope this helps.

Post a Comment for "Android Protobuf Nano Documentation"