Skip to content

Commit dcff315

Browse files
committed
Add nano support to Java codegen. Now the user can specify a flag nano=true
to generate naon related code in grpc service interface Commandline example: protoc --plugin=protoc-gen-java_rpc=build/binaries/java_pluginExecutable/java_plugin \ --java_rpc_out=nano=true:"$OUTPUT_FILE" --javanano_out=ignore_services=true:"$OUTPUT_FILE" \ --proto_path="$DIR_OF_PROTO_FILE" "$PROTO_FILE
1 parent 46dd47f commit dcff315

6 files changed

Lines changed: 482 additions & 18 deletions

File tree

compiler/build.gradle

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,17 @@ binaries.all {
4040
protobufCodeGenPlugins = ["java_plugin:$buildDir/binaries/java_pluginExecutable/java_plugin"]
4141

4242
generateTestProto.dependsOn 'java_pluginExecutable'
43-
test.dependsOn 'testGolden'
43+
test.dependsOn('testGolden','testNanoGolden')
4444

4545
task testGolden(type: Exec, dependsOn: 'generateTestProto') {
4646
executable "diff"
4747
args "$buildDir/generated-sources/test/io/grpc/testing/integration/TestServiceGrpc.java",
4848
"$projectDir/src/test/golden/TestService.java.txt"
4949
}
50+
51+
task testNanoGolden(type: Exec, dependsOn: 'java_pluginExecutable') {
52+
environment 'TEST_TMP_DIR', temporaryDir
53+
commandLine './src/test/run_nano_test.sh'
54+
}
55+
56+

compiler/src/java_plugin/cpp/java_generator.cpp

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ static inline string MessageFullJavaName(const Descriptor* desc) {
6060
}
6161

6262
static void PrintMethodFields(
63-
const ServiceDescriptor* service, map<string, string>* vars, Printer* p) {
63+
const ServiceDescriptor* service, map<string, string>* vars, Printer* p,
64+
bool generate_nano) {
6465
for (int i = 0; i < service->method_count(); ++i) {
6566
const MethodDescriptor* method = service->method(i);
6667
(*vars)["method_name"] = method->name();
@@ -82,14 +83,43 @@ static void PrintMethodFields(
8283
(*vars)["method_type"] = "UNARY";
8384
}
8485
}
85-
p->Print(
86-
*vars,
87-
"private static final $Method$<$input_type$,\n"
88-
" $output_type$> $method_field_name$ =\n"
89-
" $Method$.create(\n"
90-
" $MethodType$.$method_type$, \"$method_name$\",\n"
91-
" $ProtoUtils$.marshaller($input_type$.PARSER),\n"
92-
" $ProtoUtils$.marshaller($output_type$.PARSER));\n");
86+
87+
if (generate_nano) {
88+
// TODO(zsurocking): we're creating two Parsers for each method right now.
89+
// We could instead create static Parsers and reuse them if some methods
90+
// share the same request or response messages.
91+
p->Print(
92+
*vars,
93+
"private static final $Method$<$input_type$,\n"
94+
" $output_type$> $method_field_name$ =\n"
95+
" $Method$.create(\n"
96+
" $MethodType$.$method_type$, \"$method_name$\",\n"
97+
" $NanoUtils$.<$input_type$>marshaller(\n"
98+
" new io.grpc.nano.Parser<$input_type$>() {\n"
99+
" @Override\n"
100+
" public $input_type$ parse("
101+
"$CodedInputByteBufferNano$ input) throws IOException {\n"
102+
" return $input_type$.parseFrom(input);\n"
103+
" }\n"
104+
" }),\n"
105+
" $NanoUtils$.<$output_type$>marshaller(\n"
106+
" new io.grpc.nano.Parser<$output_type$>() {\n"
107+
" @Override\n"
108+
" public $output_type$ parse("
109+
"$CodedInputByteBufferNano$ input) throws IOException {\n"
110+
" return $output_type$.parseFrom(input);\n"
111+
" }\n"
112+
" }));\n");
113+
} else {
114+
p->Print(
115+
*vars,
116+
"private static final $Method$<$input_type$,\n"
117+
" $output_type$> $method_field_name$ =\n"
118+
" $Method$.create(\n"
119+
" $MethodType$.$method_type$, \"$method_name$\",\n"
120+
" $ProtoUtils$.marshaller($input_type$.PARSER),\n"
121+
" $ProtoUtils$.marshaller($output_type$.PARSER));\n");
122+
}
93123
}
94124
p->Print("\n");
95125
}
@@ -526,7 +556,8 @@ static void PrintBindServiceMethod(const ServiceDescriptor* service,
526556

527557
static void PrintService(const ServiceDescriptor* service,
528558
map<string, string>* vars,
529-
Printer* p) {
559+
Printer* p,
560+
bool generate_nano) {
530561
(*vars)["service_name"] = service->name();
531562
(*vars)["service_class_name"] = ServiceClassName(service);
532563
p->Print(
@@ -535,7 +566,7 @@ static void PrintService(const ServiceDescriptor* service,
535566
"public class $service_class_name$ {\n\n");
536567
p->Indent();
537568

538-
PrintMethodFields(service, vars, p);
569+
PrintMethodFields(service, vars, p, generate_nano);
539570

540571
p->Print(
541572
*vars,
@@ -583,7 +614,7 @@ static void PrintService(const ServiceDescriptor* service,
583614
p->Print("}\n");
584615
}
585616

586-
void PrintImports(Printer* p) {
617+
void PrintImports(Printer* p, bool generate_nano) {
587618
p->Print(
588619
"import static "
589620
"io.grpc.stub.Calls.createMethodDescriptor;\n"
@@ -607,10 +638,14 @@ void PrintImports(Printer* p) {
607638
"io.grpc.stub.ServerCalls.asyncUnaryRequestCall;\n"
608639
"import static "
609640
"io.grpc.stub.ServerCalls.asyncStreamingRequestCall;\n\n");
641+
if (generate_nano) {
642+
p->Print("import java.io.IOException;\n\n");
643+
}
610644
}
611645

612646
void GenerateService(const ServiceDescriptor* service,
613-
google::protobuf::io::ZeroCopyOutputStream* out) {
647+
google::protobuf::io::ZeroCopyOutputStream* out,
648+
bool generate_nano) {
614649
// All non-generated classes must be referred by fully qualified names to
615650
// avoid collision with generated classes.
616651
map<string, string> vars;
@@ -627,6 +662,7 @@ void GenerateService(const ServiceDescriptor* service,
627662
vars["ImmutableList"] = "com.google.common.collect.ImmutableList";
628663
vars["MethodDescriptor"] = "io.grpc.MethodDescriptor";
629664
vars["ProtoUtils"] = "io.grpc.proto.ProtoUtils";
665+
vars["NanoUtils"] = "io.grpc.nano.NanoUtils";
630666
vars["StreamObserver"] = "io.grpc.stub.StreamObserver";
631667
vars["Iterator"] = "java.util.Iterator";
632668
vars["Map"] = "java.util.Map";
@@ -635,20 +671,22 @@ void GenerateService(const ServiceDescriptor* service,
635671
vars["Immutable"] = "javax.annotation.concurrent.Immutable";
636672
vars["ListenableFuture"] =
637673
"com.google.common.util.concurrent.ListenableFuture";
674+
vars["CodedInputByteBufferNano"] =
675+
"com.google.protobuf.nano.CodedInputByteBufferNano";
638676

639677
Printer printer(out, '$');
640678
string package_name = ServiceJavaPackage(service->file());
641679
printer.Print(
642680
"package $package_name$;\n\n",
643681
"package_name", package_name);
644-
PrintImports(&printer);
682+
PrintImports(&printer, generate_nano);
645683

646684
// Package string is used to fully qualify method names.
647685
vars["Package"] = service->file()->package();
648686
if (!vars["Package"].empty()) {
649687
vars["Package"].append(".");
650688
}
651-
PrintService(service, &vars, &printer);
689+
PrintService(service, &vars, &printer, generate_nano);
652690
}
653691

654692
string ServiceJavaPackage(const FileDescriptor* file) {

compiler/src/java_plugin/cpp/java_generator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ string ServiceClassName(const google::protobuf::ServiceDescriptor* service);
4747

4848
// Writes the generated service interface into the given ZeroCopyOutputStream
4949
void GenerateService(const google::protobuf::ServiceDescriptor* service,
50-
google::protobuf::io::ZeroCopyOutputStream* out);
50+
google::protobuf::io::ZeroCopyOutputStream* out,
51+
bool generate_nano);
5152

5253
} // namespace java_grpc_generator
5354

compiler/src/java_plugin/cpp/java_plugin.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ class JavaGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
3131
const string& parameter,
3232
google::protobuf::compiler::GeneratorContext* context,
3333
string* error) const {
34+
vector<pair<string, string> > options;
35+
google::protobuf::compiler::ParseGeneratorParameter(parameter, &options);
36+
37+
bool generate_nano = false;
38+
for (int i = 0; i < options.size(); i++) {
39+
if (options[i].first == "nano" && options[i].second == "true") {
40+
generate_nano = true;
41+
}
42+
}
43+
3444
string package_name = java_grpc_generator::ServiceJavaPackage(file);
3545
string package_filename = JavaPackageToDir(package_name);
3646
for (int i = 0; i < file->service_count(); ++i) {
@@ -39,7 +49,7 @@ class JavaGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
3949
+ java_grpc_generator::ServiceClassName(service) + ".java";
4050
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
4151
context->Open(filename));
42-
java_grpc_generator::GenerateService(service, output.get());
52+
java_grpc_generator::GenerateService(service, output.get(), generate_nano);
4353
}
4454
return true;
4555
}

0 commit comments

Comments
 (0)