Provide base methods for Abstract stub
Default implementation returns status UNIMPLEMENTED. This allows adding
new methods to services without breaking existing code.
diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp
index 81e452d..0aadd18 100644
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ b/compiler/src/java_plugin/cpp/java_generator.cpp
@@ -155,6 +155,7 @@
if (flavor == ProtoFlavor::NANO) {
p->Print(
+ *vars,
"private static final class NanoFactory<T extends com.google.protobuf.nano.MessageNano>\n"
" implements io.grpc.protobuf.nano.MessageNanoFactory<T> {\n"
" private final int id;\n"
@@ -163,7 +164,7 @@
" this.id = id;\n"
" }\n"
"\n"
- " @Override\n"
+ " @$Override$\n"
" public T newInstance() {\n"
" Object o;\n"
" switch (id) {\n");
@@ -204,7 +205,8 @@
BLOCKING_SERVER_INTERFACE = 3,
ASYNC_CLIENT_IMPL = 4,
BLOCKING_CLIENT_IMPL = 5,
- FUTURE_CLIENT_IMPL = 6
+ FUTURE_CLIENT_IMPL = 6,
+ ABSTRACT = 7,
};
enum CallType {
@@ -219,9 +221,14 @@
map<string, string>* vars,
Printer* p, StubType type, bool generate_nano) {
(*vars)["service_name"] = service->name();
+ (*vars)["abstract_name"] = "Abstract" + service->name();
string interface_name = service->name();
string impl_name = service->name();
+ bool abstract = false;
switch (type) {
+ case ABSTRACT:
+ abstract = true;
+ break;
case ASYNC_INTERFACE:
case ASYNC_CLIENT_IMPL:
impl_name += "Stub";
@@ -242,9 +249,10 @@
default:
GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type;
}
- bool impl;
CallType call_type;
+ bool impl = false;
switch (type) {
+ case ABSTRACT:
case ASYNC_INTERFACE:
call_type = ASYNC_CALL;
impl = false;
@@ -277,7 +285,12 @@
(*vars)["impl_name"] = impl_name;
// Class head
- if (!impl) {
+ if (abstract) {
+ p->Print(
+ *vars,
+ "public static abstract class $abstract_name$ implements $service_name$, "
+ "$BindableService$ {\n");
+ } else if (!impl) {
p->Print(
*vars,
"public static interface $interface_name$ {\n");
@@ -343,7 +356,7 @@
// Method signature
p->Print("\n");
- if (impl) {
+ if (impl || abstract) {
p->Print(
*vars,
"@$Override$\n");
@@ -395,10 +408,34 @@
" $input_type$ request)");
break;
}
- if (impl) {
- // Method body for client impls
- p->Print(" {\n");
- p->Indent();
+
+ if (!(abstract || impl)) {
+ // Interface method - there will be no body, close method.
+ p->Print(";\n");
+ continue;
+ }
+
+ // Method body for abstract stub & client impls.
+ p->Print(" {\n");
+ p->Indent();
+
+ if (abstract) {
+ switch (call_type) {
+ // NB: Skipping validation of service methods. If something is wrong, we wouldn't get to
+ // this point as compiler would return errors when generating service interface.
+ case ASYNC_CALL:
+ if (client_streaming) {
+ p->Print(
+ *vars,
+ "return asyncUnimplementedStreamingCall($method_field_name$, responseObserver);\n");
+ } else {
+ p->Print(
+ *vars,
+ "asyncUnimplementedUnaryCall($method_field_name$, responseObserver);\n");
+ }
+ break;
+ }
+ } else if (impl) {
switch (call_type) {
case BLOCKING_CALL:
GRPC_CODEGEN_CHECK(!client_streaming)
@@ -451,12 +488,24 @@
" getChannel().newCall($method_field_name$, getCallOptions()), request);\n");
break;
}
- p->Outdent();
- p->Print("}\n");
- } else {
- p->Print(";\n");
}
+ p->Outdent();
+ p->Print("}\n");
}
+
+ if (abstract) {
+ p->Print("\n");
+ p->Print(*vars,
+ "@$Override$ public $ServerServiceDefinition$ bindService() {\n"
+ );
+ p->Indent();
+ p->Print(*vars,
+ "return $service_class_name$.bindService(this);\n"
+ );
+ p->Outdent();
+ p->Print("}\n");
+ }
+
p->Outdent();
p->Print("}\n\n");
}
@@ -642,27 +691,6 @@
p->Print("}\n");
}
-static void PrintAbstractServiceClass(const ServiceDescriptor* service,
- map<string, string>* vars,
- Printer* p) {
- p->Print(
- *vars,
- "public static abstract class Abstract$service_name$"
- " implements $service_name$, $BindableService$ {\n");
- p->Indent();
- p->Print(*vars,
- "@Override public $ServerServiceDefinition$ bindService() {\n"
- );
- p->Indent();
- p->Print(*vars,
- "return $service_class_name$.bindService(this);\n"
- );
- p->Outdent();
- p->Print("}\n");
- p->Outdent();
- p->Print("}\n\n");
-}
-
static void PrintService(const ServiceDescriptor* service,
map<string, string>* vars,
Printer* p,
@@ -720,12 +748,12 @@
bool generate_nano = flavor == ProtoFlavor::NANO;
PrintStub(service, vars, p, ASYNC_INTERFACE, generate_nano);
+ PrintStub(service, vars, p, ABSTRACT, generate_nano);
PrintStub(service, vars, p, BLOCKING_CLIENT_INTERFACE, generate_nano);
PrintStub(service, vars, p, FUTURE_CLIENT_INTERFACE, generate_nano);
PrintStub(service, vars, p, ASYNC_CLIENT_IMPL, generate_nano);
PrintStub(service, vars, p, BLOCKING_CLIENT_IMPL, generate_nano);
PrintStub(service, vars, p, FUTURE_CLIENT_IMPL, generate_nano);
- PrintAbstractServiceClass(service, vars, p);
PrintMethodHandlerClass(service, vars, p, generate_nano);
PrintBindServiceMethod(service, vars, p, generate_nano);
p->Outdent();
@@ -757,7 +785,11 @@
"import static "
"io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n"
"import static "
- "io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n\n");
+ "io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n"
+ "import static "
+ "io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n"
+ "import static "
+ "io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n\n");
if (generate_nano) {
p->Print("import java.io.IOException;\n\n");
}
diff --git a/compiler/src/test/golden/TestService.java.txt b/compiler/src/test/golden/TestService.java.txt
index b029819..cd82a81 100644
--- a/compiler/src/test/golden/TestService.java.txt
+++ b/compiler/src/test/golden/TestService.java.txt
@@ -12,6 +12,8 @@
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
@javax.annotation.Generated(
value = "by gRPC proto compiler",
@@ -101,6 +103,43 @@
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
}
+ public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
+
+ @java.lang.Override
+ public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_HALF_BIDI_CALL, responseObserver);
+ }
+
+ @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
+ return TestServiceGrpc.bindService(this);
+ }
+ }
+
public static interface TestServiceBlockingClient {
public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
@@ -224,12 +263,6 @@
}
}
- public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
- @Override public io.grpc.ServerServiceDefinition bindService() {
- return TestServiceGrpc.bindService(this);
- }
- }
-
private static final int METHODID_UNARY_CALL = 0;
private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
private static final int METHODID_STREAMING_INPUT_CALL = 2;
diff --git a/compiler/src/testLite/golden/TestService.java.txt b/compiler/src/testLite/golden/TestService.java.txt
index 726bf70..1270fc7 100644
--- a/compiler/src/testLite/golden/TestService.java.txt
+++ b/compiler/src/testLite/golden/TestService.java.txt
@@ -12,6 +12,8 @@
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
@javax.annotation.Generated(
value = "by gRPC proto compiler",
@@ -101,6 +103,43 @@
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
}
+ public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
+
+ @java.lang.Override
+ public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_HALF_BIDI_CALL, responseObserver);
+ }
+
+ @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
+ return TestServiceGrpc.bindService(this);
+ }
+ }
+
public static interface TestServiceBlockingClient {
public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
@@ -224,12 +263,6 @@
}
}
- public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
- @Override public io.grpc.ServerServiceDefinition bindService() {
- return TestServiceGrpc.bindService(this);
- }
- }
-
private static final int METHODID_UNARY_CALL = 0;
private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
private static final int METHODID_STREAMING_INPUT_CALL = 2;
diff --git a/compiler/src/testNano/golden/TestService.java.txt b/compiler/src/testNano/golden/TestService.java.txt
index 0be68b1..88dc9cd 100644
--- a/compiler/src/testNano/golden/TestService.java.txt
+++ b/compiler/src/testNano/golden/TestService.java.txt
@@ -12,6 +12,8 @@
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
import java.io.IOException;
@@ -104,7 +106,7 @@
this.id = id;
}
- @Override
+ @java.lang.Override
public T newInstance() {
Object o;
switch (id) {
@@ -179,6 +181,43 @@
io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
}
+ public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
+
+ @java.lang.Override
+ public void unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request,
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.SimpleResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public void streamingOutputCall(io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request,
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallRequest> streamingInputCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> fullBidiCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
+ }
+
+ @java.lang.Override
+ public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> halfBidiCall(
+ io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
+ return asyncUnimplementedStreamingCall(METHOD_HALF_BIDI_CALL, responseObserver);
+ }
+
+ @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
+ return TestServiceGrpc.bindService(this);
+ }
+ }
+
public static interface TestServiceBlockingClient {
public io.grpc.testing.integration.nano.Test.SimpleResponse unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request);
@@ -302,12 +341,6 @@
}
}
- public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
- @Override public io.grpc.ServerServiceDefinition bindService() {
- return TestServiceGrpc.bindService(this);
- }
- }
-
private static final int METHODID_UNARY_CALL = 0;
private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
private static final int METHODID_STREAMING_INPUT_CALL = 2;