@@ -52,8 +52,10 @@ const generatedCodeVersion = 4
52
52
// Paths for packages used by code generated in this file,
53
53
// relative to the import_prefix of the generator.Generator.
54
54
const (
55
+ errorPkgPath = "google.golang.org/grpc/status"
55
56
contextPkgPath = "context"
56
57
grpcPkgPath = "google.golang.org/grpc"
58
+ codePkgPath = "google.golang.org/grpc/codes"
57
59
)
58
60
59
61
func init () {
@@ -77,6 +79,8 @@ func (g *grpc) Name() string {
77
79
var (
78
80
contextPkg string
79
81
grpcPkg string
82
+ errorPkg string
83
+ codePkg string
80
84
)
81
85
82
86
// Init initializes the plugin.
@@ -105,13 +109,19 @@ func (g *grpc) Generate(file *generator.FileDescriptor) {
105
109
return
106
110
}
107
111
112
+ errorPkg = string (g .gen .AddImport (errorPkgPath ))
113
+ codePkg = string (g .gen .AddImport (codePkgPath ))
108
114
contextPkg = string (g .gen .AddImport (contextPkgPath ))
109
115
grpcPkg = string (g .gen .AddImport (grpcPkgPath ))
110
116
111
117
g .P ("// Reference imports to suppress errors if they are not otherwise used." )
112
118
g .P ("var _ " , contextPkg , ".Context" )
113
119
g .P ("var _ " , grpcPkg , ".ClientConn" )
114
120
g .P ()
121
+ g .P ("func errUnimplemented(methodName string) error {" )
122
+ g .P ("\t return " , errorPkg , ".Errorf(codes.Unimplemented, \" method %s not implemented\" , methodName)" )
123
+ g .P ("}" )
124
+ g .P ()
115
125
116
126
// Assert version compatibility.
117
127
g .P ("// This is a compile-time assertion to ensure that this generated file" )
@@ -216,6 +226,12 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
216
226
g .P ("}" )
217
227
g .P ()
218
228
229
+ // Server Unimplemented struct for forward compatability.
230
+ if deprecated {
231
+ g .P (deprecationComment )
232
+ }
233
+ g .generateUnimplementedServer (servName , service )
234
+
219
235
// Server registration.
220
236
if deprecated {
221
237
g .P (deprecationComment )
@@ -269,6 +285,34 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
269
285
g .P ()
270
286
}
271
287
288
+ // generateUnimplementedServer creates the unimplemented server struct
289
+ func (g * grpc ) generateUnimplementedServer (servName string , service * pb.ServiceDescriptorProto ) {
290
+ serverType := servName + "Server"
291
+ g .P ("// Unimplemented" , serverType , " can be embedded to have forward compatible implementations." )
292
+ g .P ("type Unimplemented" , serverType , " struct {" )
293
+ g .P ("}" )
294
+ g .P ()
295
+ // Unimplemented<service_name>Server's concrete methods
296
+ for _ , method := range service .Method {
297
+ g .P (g .generateServerMethodConcrete (servName , method ))
298
+ }
299
+ g .P ()
300
+ }
301
+
302
+ // generateServerMethodConcrete returns unimplemented methods which ensure forward compatibility
303
+ func (g * grpc ) generateServerMethodConcrete (servName string , method * pb.MethodDescriptorProto ) string {
304
+ header := g .generateServerSignatureWithParamNames (servName , method )
305
+ implementation := fmt .Sprintf ("func (*Unimplemented%sServer) %s {\n " , servName , header )
306
+ implementation += fmt .Sprintf ("\t return " )
307
+ if ! method .GetServerStreaming () && ! method .GetClientStreaming () {
308
+ implementation += "nil, "
309
+ }
310
+ origMethName := method .GetName ()
311
+ methName := generator .CamelCase (origMethName )
312
+ implementation += fmt .Sprintf ("errUnimplemented(%q)\n }" , methName )
313
+ return implementation
314
+ }
315
+
272
316
// generateClientSignature returns the client-side signature for a method.
273
317
func (g * grpc ) generateClientSignature (servName string , method * pb.MethodDescriptorProto ) string {
274
318
origMethName := method .GetName ()
@@ -368,6 +412,30 @@ func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar strin
368
412
}
369
413
}
370
414
415
+ // generateServerSignatureWithParamNames returns the server-side signature for a method with parameter names.
416
+ func (g * grpc ) generateServerSignatureWithParamNames (servName string , method * pb.MethodDescriptorProto ) string {
417
+ origMethName := method .GetName ()
418
+ methName := generator .CamelCase (origMethName )
419
+ if reservedClientName [methName ] {
420
+ methName += "_"
421
+ }
422
+
423
+ var reqArgs []string
424
+ ret := "error"
425
+ if ! method .GetServerStreaming () && ! method .GetClientStreaming () {
426
+ reqArgs = append (reqArgs , "ctx " + contextPkg + ".Context" )
427
+ ret = "(*" + g .typeName (method .GetOutputType ()) + ", error)"
428
+ }
429
+ if ! method .GetClientStreaming () {
430
+ reqArgs = append (reqArgs , "req *" + g .typeName (method .GetInputType ()))
431
+ }
432
+ if method .GetServerStreaming () || method .GetClientStreaming () {
433
+ reqArgs = append (reqArgs , "srv " + servName + "_" + generator .CamelCase (origMethName )+ "Server" )
434
+ }
435
+
436
+ return methName + "(" + strings .Join (reqArgs , ", " ) + ") " + ret
437
+ }
438
+
371
439
// generateServerSignature returns the server-side signature for a method.
372
440
func (g * grpc ) generateServerSignature (servName string , method * pb.MethodDescriptorProto ) string {
373
441
origMethName := method .GetName ()
0 commit comments