Skip to content

Commit 2fbf142

Browse files
committed
Provide base methods for Abstract stub
Default implementation returns status UNIMPLEMENTED. This allows adding new methods to services without breaking existing code.
1 parent b053d89 commit 2fbf142

14 files changed

Lines changed: 440 additions & 123 deletions

File tree

benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/BenchmarkServiceGrpc.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
1313
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
1414
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
15+
import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
16+
import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
1517

1618
@javax.annotation.Generated(
1719
value = "by gRPC proto compiler",
@@ -65,6 +67,25 @@ public io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Messages.SimpleReque
6567
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Messages.SimpleResponse> responseObserver);
6668
}
6769

70+
public static abstract class AbstractBenchmarkService implements BenchmarkService, io.grpc.BindableService {
71+
72+
@java.lang.Override
73+
public void unaryCall(io.grpc.benchmarks.proto.Messages.SimpleRequest request,
74+
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Messages.SimpleResponse> responseObserver) {
75+
asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
76+
}
77+
78+
@java.lang.Override
79+
public io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Messages.SimpleRequest> streamingCall(
80+
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Messages.SimpleResponse> responseObserver) {
81+
return asyncUnimplementedStreamingCall(METHOD_STREAMING_CALL, responseObserver);
82+
}
83+
84+
@java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
85+
return BenchmarkServiceGrpc.bindService(this);
86+
}
87+
}
88+
6889
public static interface BenchmarkServiceBlockingClient {
6990

7091
public io.grpc.benchmarks.proto.Messages.SimpleResponse unaryCall(io.grpc.benchmarks.proto.Messages.SimpleRequest request);
@@ -157,12 +178,6 @@ public com.google.common.util.concurrent.ListenableFuture<io.grpc.benchmarks.pro
157178
}
158179
}
159180

160-
public static abstract class AbstractBenchmarkService implements BenchmarkService, io.grpc.BindableService {
161-
@Override public io.grpc.ServerServiceDefinition bindService() {
162-
return BenchmarkServiceGrpc.bindService(this);
163-
}
164-
}
165-
166181
private static final int METHODID_UNARY_CALL = 0;
167182
private static final int METHODID_STREAMING_CALL = 1;
168183

benchmarks/src/generated/main/grpc/io/grpc/benchmarks/proto/WorkerServiceGrpc.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
1313
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
1414
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
15+
import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
16+
import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
1517

1618
@javax.annotation.Generated(
1719
value = "by gRPC proto compiler",
@@ -89,6 +91,37 @@ public void quitWorker(io.grpc.benchmarks.proto.Control.Void request,
8991
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.Void> responseObserver);
9092
}
9193

94+
public static abstract class AbstractWorkerService implements WorkerService, io.grpc.BindableService {
95+
96+
@java.lang.Override
97+
public io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.ServerArgs> runServer(
98+
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.ServerStatus> responseObserver) {
99+
return asyncUnimplementedStreamingCall(METHOD_RUN_SERVER, responseObserver);
100+
}
101+
102+
@java.lang.Override
103+
public io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.ClientArgs> runClient(
104+
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.ClientStatus> responseObserver) {
105+
return asyncUnimplementedStreamingCall(METHOD_RUN_CLIENT, responseObserver);
106+
}
107+
108+
@java.lang.Override
109+
public void coreCount(io.grpc.benchmarks.proto.Control.CoreRequest request,
110+
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.CoreResponse> responseObserver) {
111+
asyncUnimplementedUnaryCall(METHOD_CORE_COUNT, responseObserver);
112+
}
113+
114+
@java.lang.Override
115+
public void quitWorker(io.grpc.benchmarks.proto.Control.Void request,
116+
io.grpc.stub.StreamObserver<io.grpc.benchmarks.proto.Control.Void> responseObserver) {
117+
asyncUnimplementedUnaryCall(METHOD_QUIT_WORKER, responseObserver);
118+
}
119+
120+
@java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
121+
return WorkerServiceGrpc.bindService(this);
122+
}
123+
}
124+
92125
public static interface WorkerServiceBlockingClient {
93126

94127
public io.grpc.benchmarks.proto.Control.CoreResponse coreCount(io.grpc.benchmarks.proto.Control.CoreRequest request);
@@ -213,12 +246,6 @@ public com.google.common.util.concurrent.ListenableFuture<io.grpc.benchmarks.pro
213246
}
214247
}
215248

216-
public static abstract class AbstractWorkerService implements WorkerService, io.grpc.BindableService {
217-
@Override public io.grpc.ServerServiceDefinition bindService() {
218-
return WorkerServiceGrpc.bindService(this);
219-
}
220-
}
221-
222249
private static final int METHODID_CORE_COUNT = 0;
223250
private static final int METHODID_QUIT_WORKER = 1;
224251
private static final int METHODID_RUN_SERVER = 2;

compiler/src/java_plugin/cpp/java_generator.cpp

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ static void PrintMethodFields(
155155

156156
if (flavor == ProtoFlavor::NANO) {
157157
p->Print(
158+
*vars,
158159
"private static final class NanoFactory<T extends com.google.protobuf.nano.MessageNano>\n"
159160
" implements io.grpc.protobuf.nano.MessageNanoFactory<T> {\n"
160161
" private final int id;\n"
@@ -163,7 +164,7 @@ static void PrintMethodFields(
163164
" this.id = id;\n"
164165
" }\n"
165166
"\n"
166-
" @Override\n"
167+
" @$Override$\n"
167168
" public T newInstance() {\n"
168169
" Object o;\n"
169170
" switch (id) {\n");
@@ -204,7 +205,8 @@ enum StubType {
204205
BLOCKING_SERVER_INTERFACE = 3,
205206
ASYNC_CLIENT_IMPL = 4,
206207
BLOCKING_CLIENT_IMPL = 5,
207-
FUTURE_CLIENT_IMPL = 6
208+
FUTURE_CLIENT_IMPL = 6,
209+
ABSTRACT = 7,
208210
};
209211

210212
enum CallType {
@@ -219,9 +221,14 @@ static void PrintStub(
219221
map<string, string>* vars,
220222
Printer* p, StubType type, bool generate_nano) {
221223
(*vars)["service_name"] = service->name();
224+
(*vars)["abstract_name"] = "Abstract" + service->name();
222225
string interface_name = service->name();
223226
string impl_name = service->name();
227+
bool abstract = false;
224228
switch (type) {
229+
case ABSTRACT:
230+
abstract = true;
231+
break;
225232
case ASYNC_INTERFACE:
226233
case ASYNC_CLIENT_IMPL:
227234
impl_name += "Stub";
@@ -242,9 +249,10 @@ static void PrintStub(
242249
default:
243250
GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type;
244251
}
245-
bool impl;
246252
CallType call_type;
253+
bool impl = false;
247254
switch (type) {
255+
case ABSTRACT:
248256
case ASYNC_INTERFACE:
249257
call_type = ASYNC_CALL;
250258
impl = false;
@@ -277,7 +285,12 @@ static void PrintStub(
277285
(*vars)["impl_name"] = impl_name;
278286

279287
// Class head
280-
if (!impl) {
288+
if (abstract) {
289+
p->Print(
290+
*vars,
291+
"public static abstract class $abstract_name$ implements $service_name$, "
292+
"$BindableService$ {\n");
293+
} else if (!impl) {
281294
p->Print(
282295
*vars,
283296
"public static interface $interface_name$ {\n");
@@ -343,7 +356,7 @@ static void PrintStub(
343356

344357
// Method signature
345358
p->Print("\n");
346-
if (impl) {
359+
if (impl || abstract) {
347360
p->Print(
348361
*vars,
349362
"@$Override$\n");
@@ -395,10 +408,34 @@ static void PrintStub(
395408
" $input_type$ request)");
396409
break;
397410
}
398-
if (impl) {
399-
// Method body for client impls
400-
p->Print(" {\n");
401-
p->Indent();
411+
412+
if (!(abstract || impl)) {
413+
// Interface method - there will be no body, close method.
414+
p->Print(";\n");
415+
continue;
416+
}
417+
418+
// Method body for abstract stub & client impls.
419+
p->Print(" {\n");
420+
p->Indent();
421+
422+
if (abstract) {
423+
switch (call_type) {
424+
// NB: Skipping validation of service methods. If something is wrong, we wouldn't get to
425+
// this point as compiler would return errors when generating service interface.
426+
case ASYNC_CALL:
427+
if (client_streaming) {
428+
p->Print(
429+
*vars,
430+
"return asyncUnimplementedStreamingCall($method_field_name$, responseObserver);\n");
431+
} else {
432+
p->Print(
433+
*vars,
434+
"asyncUnimplementedUnaryCall($method_field_name$, responseObserver);\n");
435+
}
436+
break;
437+
}
438+
} else if (impl) {
402439
switch (call_type) {
403440
case BLOCKING_CALL:
404441
GRPC_CODEGEN_CHECK(!client_streaming)
@@ -451,12 +488,24 @@ static void PrintStub(
451488
" getChannel().newCall($method_field_name$, getCallOptions()), request);\n");
452489
break;
453490
}
454-
p->Outdent();
455-
p->Print("}\n");
456-
} else {
457-
p->Print(";\n");
458491
}
492+
p->Outdent();
493+
p->Print("}\n");
459494
}
495+
496+
if (abstract) {
497+
p->Print("\n");
498+
p->Print(*vars,
499+
"@$Override$ public $ServerServiceDefinition$ bindService() {\n"
500+
);
501+
p->Indent();
502+
p->Print(*vars,
503+
"return $service_class_name$.bindService(this);\n"
504+
);
505+
p->Outdent();
506+
p->Print("}\n");
507+
}
508+
460509
p->Outdent();
461510
p->Print("}\n\n");
462511
}
@@ -642,27 +691,6 @@ static void PrintBindServiceMethod(const ServiceDescriptor* service,
642691
p->Print("}\n");
643692
}
644693

645-
static void PrintAbstractServiceClass(const ServiceDescriptor* service,
646-
map<string, string>* vars,
647-
Printer* p) {
648-
p->Print(
649-
*vars,
650-
"public static abstract class Abstract$service_name$"
651-
" implements $service_name$, $BindableService$ {\n");
652-
p->Indent();
653-
p->Print(*vars,
654-
"@Override public $ServerServiceDefinition$ bindService() {\n"
655-
);
656-
p->Indent();
657-
p->Print(*vars,
658-
"return $service_class_name$.bindService(this);\n"
659-
);
660-
p->Outdent();
661-
p->Print("}\n");
662-
p->Outdent();
663-
p->Print("}\n\n");
664-
}
665-
666694
static void PrintService(const ServiceDescriptor* service,
667695
map<string, string>* vars,
668696
Printer* p,
@@ -720,12 +748,12 @@ static void PrintService(const ServiceDescriptor* service,
720748

721749
bool generate_nano = flavor == ProtoFlavor::NANO;
722750
PrintStub(service, vars, p, ASYNC_INTERFACE, generate_nano);
751+
PrintStub(service, vars, p, ABSTRACT, generate_nano);
723752
PrintStub(service, vars, p, BLOCKING_CLIENT_INTERFACE, generate_nano);
724753
PrintStub(service, vars, p, FUTURE_CLIENT_INTERFACE, generate_nano);
725754
PrintStub(service, vars, p, ASYNC_CLIENT_IMPL, generate_nano);
726755
PrintStub(service, vars, p, BLOCKING_CLIENT_IMPL, generate_nano);
727756
PrintStub(service, vars, p, FUTURE_CLIENT_IMPL, generate_nano);
728-
PrintAbstractServiceClass(service, vars, p);
729757
PrintMethodHandlerClass(service, vars, p, generate_nano);
730758
PrintBindServiceMethod(service, vars, p, generate_nano);
731759
p->Outdent();
@@ -757,7 +785,11 @@ void PrintImports(Printer* p, bool generate_nano) {
757785
"import static "
758786
"io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n"
759787
"import static "
760-
"io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n\n");
788+
"io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n"
789+
"import static "
790+
"io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n"
791+
"import static "
792+
"io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n\n");
761793
if (generate_nano) {
762794
p->Print("import java.io.IOException;\n\n");
763795
}

compiler/src/test/golden/TestService.java.txt

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import static io.grpc.stub.ServerCalls.asyncUnaryCall;
1212
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
1313
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
1414
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
15+
import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
16+
import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
1517

1618
@javax.annotation.Generated(
1719
value = "by gRPC proto compiler",
@@ -101,6 +103,43 @@ public class TestServiceGrpc {
101103
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
102104
}
103105

106+
public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
107+
108+
@java.lang.Override
109+
public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
110+
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
111+
asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
112+
}
113+
114+
@java.lang.Override
115+
public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
116+
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
117+
asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
118+
}
119+
120+
@java.lang.Override
121+
public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
122+
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
123+
return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
124+
}
125+
126+
@java.lang.Override
127+
public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
128+
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
129+
return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
130+
}
131+
132+
@java.lang.Override
133+
public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
134+
io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
135+
return asyncUnimplementedStreamingCall(METHOD_HALF_BIDI_CALL, responseObserver);
136+
}
137+
138+
@java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
139+
return TestServiceGrpc.bindService(this);
140+
}
141+
}
142+
104143
public static interface TestServiceBlockingClient {
105144

106145
public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
@@ -224,12 +263,6 @@ public class TestServiceGrpc {
224263
}
225264
}
226265

227-
public static abstract class AbstractTestService implements TestService, io.grpc.BindableService {
228-
@Override public io.grpc.ServerServiceDefinition bindService() {
229-
return TestServiceGrpc.bindService(this);
230-
}
231-
}
232-
233266
private static final int METHODID_UNARY_CALL = 0;
234267
private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
235268
private static final int METHODID_STREAMING_INPUT_CALL = 2;

0 commit comments

Comments
 (0)