Skip to content

Commit

Permalink
protoc-gen-go/grpc: make grpc identical to v1.3.5 (#1113)
Browse files Browse the repository at this point in the history
Even through the grpc package is excluded from our compatibility agreement,
the v1.4.0 release accidentally reverted the package to an older revision.
Update this code to be identical to the v1.3.5 release (barring non-semantic
documentation changes).

Fixes #1111
  • Loading branch information
dsnet authored May 4, 2020
1 parent fa093f5 commit 8d9af28
Showing 1 changed file with 74 additions and 5 deletions.
79 changes: 74 additions & 5 deletions protoc-gen-go/grpc/grpc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Expand All @@ -23,13 +23,15 @@ import (
// It is incremented whenever an incompatibility between the generated code and
// the grpc package is introduced; the generated code references
// a constant, grpc.SupportPackageIsVersionN (where N is generatedCodeVersion).
const generatedCodeVersion = 4
const generatedCodeVersion = 6

// Paths for packages used by code generated in this file,
// relative to the import_prefix of the generator.Generator.
const (
contextPkgPath = "context"
grpcPkgPath = "google.golang.org/grpc"
codePkgPath = "google.golang.org/grpc/codes"
statusPkgPath = "google.golang.org/grpc/status"
)

func init() {
Expand Down Expand Up @@ -86,7 +88,7 @@ func (g *grpc) Generate(file *generator.FileDescriptor) {

g.P("// Reference imports to suppress errors if they are not otherwise used.")
g.P("var _ ", contextPkg, ".Context")
g.P("var _ ", grpcPkg, ".ClientConn")
g.P("var _ ", grpcPkg, ".ClientConnInterface")
g.P()

// Assert version compatibility.
Expand Down Expand Up @@ -140,22 +142,26 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P("type ", servName, "Client interface {")
for i, method := range service.Method {
g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service.
if method.GetOptions().GetDeprecated() {
g.P("//")
g.P(deprecationComment)
}
g.P(g.generateClientSignature(servName, method))
}
g.P("}")
g.P()

// Client structure.
g.P("type ", unexport(servName), "Client struct {")
g.P("cc *", grpcPkg, ".ClientConn")
g.P("cc ", grpcPkg, ".ClientConnInterface")
g.P("}")
g.P()

// NewClient factory.
if deprecated {
g.P(deprecationComment)
}
g.P("func New", servName, "Client (cc *", grpcPkg, ".ClientConn) ", servName, "Client {")
g.P("func New", servName, "Client (cc ", grpcPkg, ".ClientConnInterface) ", servName, "Client {")
g.P("return &", unexport(servName), "Client{cc}")
g.P("}")
g.P()
Expand Down Expand Up @@ -187,11 +193,21 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P("type ", serverType, " interface {")
for i, method := range service.Method {
g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service.
if method.GetOptions().GetDeprecated() {
g.P("//")
g.P(deprecationComment)
}
g.P(g.generateServerSignature(servName, method))
}
g.P("}")
g.P()

// Server Unimplemented struct for forward compatibility.
if deprecated {
g.P(deprecationComment)
}
g.generateUnimplementedServer(servName, service)

// Server registration.
if deprecated {
g.P(deprecationComment)
Expand Down Expand Up @@ -245,6 +261,35 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P()
}

// generateUnimplementedServer creates the unimplemented server struct
func (g *grpc) generateUnimplementedServer(servName string, service *pb.ServiceDescriptorProto) {
serverType := servName + "Server"
g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.")
g.P("type Unimplemented", serverType, " struct {")
g.P("}")
g.P()
// Unimplemented<service_name>Server's concrete methods
for _, method := range service.Method {
g.generateServerMethodConcrete(servName, method)
}
g.P()
}

// generateServerMethodConcrete returns unimplemented methods which ensure forward compatibility
func (g *grpc) generateServerMethodConcrete(servName string, method *pb.MethodDescriptorProto) {
header := g.generateServerSignatureWithParamNames(servName, method)
g.P("func (*Unimplemented", servName, "Server) ", header, " {")
var nilArg string
if !method.GetServerStreaming() && !method.GetClientStreaming() {
nilArg = "nil, "
}
methName := generator.CamelCase(method.GetName())
statusPkg := string(g.gen.AddImport(statusPkgPath))
codePkg := string(g.gen.AddImport(codePkgPath))
g.P("return ", nilArg, statusPkg, `.Errorf(`, codePkg, `.Unimplemented, "method `, methName, ` not implemented")`)
g.P("}")
}

// generateClientSignature returns the client-side signature for a method.
func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string {
origMethName := method.GetName()
Expand Down Expand Up @@ -344,6 +389,30 @@ func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar strin
}
}

// generateServerSignatureWithParamNames returns the server-side signature for a method with parameter names.
func (g *grpc) generateServerSignatureWithParamNames(servName string, method *pb.MethodDescriptorProto) string {
origMethName := method.GetName()
methName := generator.CamelCase(origMethName)
if reservedClientName[methName] {
methName += "_"
}

var reqArgs []string
ret := "error"
if !method.GetServerStreaming() && !method.GetClientStreaming() {
reqArgs = append(reqArgs, "ctx "+contextPkg+".Context")
ret = "(*" + g.typeName(method.GetOutputType()) + ", error)"
}
if !method.GetClientStreaming() {
reqArgs = append(reqArgs, "req *"+g.typeName(method.GetInputType()))
}
if method.GetServerStreaming() || method.GetClientStreaming() {
reqArgs = append(reqArgs, "srv "+servName+"_"+generator.CamelCase(origMethName)+"Server")
}

return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret
}

// generateServerSignature returns the server-side signature for a method.
func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string {
origMethName := method.GetName()
Expand Down

0 comments on commit 8d9af28

Please sign in to comment.