1- // Copyright 2015 The Go Authors. All rights reserved.
1+ // Copyright 2015 The Go Authors. All rights reserved.
22// Use of this source code is governed by a BSD-style
33// license that can be found in the LICENSE file.
44
@@ -23,13 +23,15 @@ import (
2323// It is incremented whenever an incompatibility between the generated code and
2424// the grpc package is introduced; the generated code references
2525// a constant, grpc.SupportPackageIsVersionN (where N is generatedCodeVersion).
26- const generatedCodeVersion = 4
26+ const generatedCodeVersion = 6
2727
2828// Paths for packages used by code generated in this file,
2929// relative to the import_prefix of the generator.Generator.
3030const (
3131 contextPkgPath = "context"
3232 grpcPkgPath = "google.golang.org/grpc"
33+ codePkgPath = "google.golang.org/grpc/codes"
34+ statusPkgPath = "google.golang.org/grpc/status"
3335)
3436
3537func init () {
@@ -86,7 +88,7 @@ func (g *grpc) Generate(file *generator.FileDescriptor) {
8688
8789 g .P ("// Reference imports to suppress errors if they are not otherwise used." )
8890 g .P ("var _ " , contextPkg , ".Context" )
89- g .P ("var _ " , grpcPkg , ".ClientConn " )
91+ g .P ("var _ " , grpcPkg , ".ClientConnInterface " )
9092 g .P ()
9193
9294 // Assert version compatibility.
@@ -140,22 +142,26 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
140142 g .P ("type " , servName , "Client interface {" )
141143 for i , method := range service .Method {
142144 g .gen .PrintComments (fmt .Sprintf ("%s,2,%d" , path , i )) // 2 means method in a service.
145+ if method .GetOptions ().GetDeprecated () {
146+ g .P ("//" )
147+ g .P (deprecationComment )
148+ }
143149 g .P (g .generateClientSignature (servName , method ))
144150 }
145151 g .P ("}" )
146152 g .P ()
147153
148154 // Client structure.
149155 g .P ("type " , unexport (servName ), "Client struct {" )
150- g .P ("cc * " , grpcPkg , ".ClientConn " )
156+ g .P ("cc " , grpcPkg , ".ClientConnInterface " )
151157 g .P ("}" )
152158 g .P ()
153159
154160 // NewClient factory.
155161 if deprecated {
156162 g .P (deprecationComment )
157163 }
158- g .P ("func New" , servName , "Client (cc * " , grpcPkg , ".ClientConn ) " , servName , "Client {" )
164+ g .P ("func New" , servName , "Client (cc " , grpcPkg , ".ClientConnInterface ) " , servName , "Client {" )
159165 g .P ("return &" , unexport (servName ), "Client{cc}" )
160166 g .P ("}" )
161167 g .P ()
@@ -187,11 +193,21 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
187193 g .P ("type " , serverType , " interface {" )
188194 for i , method := range service .Method {
189195 g .gen .PrintComments (fmt .Sprintf ("%s,2,%d" , path , i )) // 2 means method in a service.
196+ if method .GetOptions ().GetDeprecated () {
197+ g .P ("//" )
198+ g .P (deprecationComment )
199+ }
190200 g .P (g .generateServerSignature (servName , method ))
191201 }
192202 g .P ("}" )
193203 g .P ()
194204
205+ // Server Unimplemented struct for forward compatibility.
206+ if deprecated {
207+ g .P (deprecationComment )
208+ }
209+ g .generateUnimplementedServer (servName , service )
210+
195211 // Server registration.
196212 if deprecated {
197213 g .P (deprecationComment )
@@ -245,6 +261,35 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
245261 g .P ()
246262}
247263
264+ // generateUnimplementedServer creates the unimplemented server struct
265+ func (g * grpc ) generateUnimplementedServer (servName string , service * pb.ServiceDescriptorProto ) {
266+ serverType := servName + "Server"
267+ g .P ("// Unimplemented" , serverType , " can be embedded to have forward compatible implementations." )
268+ g .P ("type Unimplemented" , serverType , " struct {" )
269+ g .P ("}" )
270+ g .P ()
271+ // Unimplemented<service_name>Server's concrete methods
272+ for _ , method := range service .Method {
273+ g .generateServerMethodConcrete (servName , method )
274+ }
275+ g .P ()
276+ }
277+
278+ // generateServerMethodConcrete returns unimplemented methods which ensure forward compatibility
279+ func (g * grpc ) generateServerMethodConcrete (servName string , method * pb.MethodDescriptorProto ) {
280+ header := g .generateServerSignatureWithParamNames (servName , method )
281+ g .P ("func (*Unimplemented" , servName , "Server) " , header , " {" )
282+ var nilArg string
283+ if ! method .GetServerStreaming () && ! method .GetClientStreaming () {
284+ nilArg = "nil, "
285+ }
286+ methName := generator .CamelCase (method .GetName ())
287+ statusPkg := string (g .gen .AddImport (statusPkgPath ))
288+ codePkg := string (g .gen .AddImport (codePkgPath ))
289+ g .P ("return " , nilArg , statusPkg , `.Errorf(` , codePkg , `.Unimplemented, "method ` , methName , ` not implemented")` )
290+ g .P ("}" )
291+ }
292+
248293// generateClientSignature returns the client-side signature for a method.
249294func (g * grpc ) generateClientSignature (servName string , method * pb.MethodDescriptorProto ) string {
250295 origMethName := method .GetName ()
@@ -344,6 +389,30 @@ func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar strin
344389 }
345390}
346391
392+ // generateServerSignatureWithParamNames returns the server-side signature for a method with parameter names.
393+ func (g * grpc ) generateServerSignatureWithParamNames (servName string , method * pb.MethodDescriptorProto ) string {
394+ origMethName := method .GetName ()
395+ methName := generator .CamelCase (origMethName )
396+ if reservedClientName [methName ] {
397+ methName += "_"
398+ }
399+
400+ var reqArgs []string
401+ ret := "error"
402+ if ! method .GetServerStreaming () && ! method .GetClientStreaming () {
403+ reqArgs = append (reqArgs , "ctx " + contextPkg + ".Context" )
404+ ret = "(*" + g .typeName (method .GetOutputType ()) + ", error)"
405+ }
406+ if ! method .GetClientStreaming () {
407+ reqArgs = append (reqArgs , "req *" + g .typeName (method .GetInputType ()))
408+ }
409+ if method .GetServerStreaming () || method .GetClientStreaming () {
410+ reqArgs = append (reqArgs , "srv " + servName + "_" + generator .CamelCase (origMethName )+ "Server" )
411+ }
412+
413+ return methName + "(" + strings .Join (reqArgs , ", " ) + ") " + ret
414+ }
415+
347416// generateServerSignature returns the server-side signature for a method.
348417func (g * grpc ) generateServerSignature (servName string , method * pb.MethodDescriptorProto ) string {
349418 origMethName := method .GetName ()
0 commit comments