cmd/protoc-gen-go-grpc: add Unimplemented...Server type
Also add deprecation comments on methods.
Forward port:
https://github.com/golang/protobuf/pull/785
https://github.com/golang/protobuf/pull/952
Fixes golang/protobuf#816
Change-Id: Id4d9f08b39fe16eaf57fb7a92fb8ada222b5cbf4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/205246
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go-grpc/internal_gengogrpc/grpc.go b/cmd/protoc-gen-go-grpc/internal_gengogrpc/grpc.go
index fd25cd0..a4523a6 100644
--- a/cmd/protoc-gen-go-grpc/internal_gengogrpc/grpc.go
+++ b/cmd/protoc-gen-go-grpc/internal_gengogrpc/grpc.go
@@ -18,6 +18,8 @@
const (
contextPackage = protogen.GoImportPath("context")
grpcPackage = protogen.GoImportPath("google.golang.org/grpc")
+ codesPackage = protogen.GoImportPath("google.golang.org/grpc/codes")
+ statusPackage = protogen.GoImportPath("google.golang.org/grpc/status")
)
// GenerateFile generates a _grpc.pb.go file containing gRPC service definitions.
@@ -72,6 +74,9 @@
g.P("type ", clientName, " interface {")
for _, method := range service.Methods {
g.Annotate(clientName+"."+method.GoName, method.Location)
+ if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() {
+ g.P(deprecationComment)
+ }
g.P(method.Comments.Leading,
clientSignature(g, method))
}
@@ -118,12 +123,31 @@
g.P("type ", serverType, " interface {")
for _, method := range service.Methods {
g.Annotate(serverType+"."+method.GoName, method.Location)
+ if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() {
+ g.P(deprecationComment)
+ }
g.P(method.Comments.Leading,
serverSignature(g, method))
}
g.P("}")
g.P()
+ // Server Unimplemented struct for forward compatibility.
+ g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.")
+ g.P("type Unimplemented", serverType, " struct {")
+ g.P("}")
+ g.P()
+ for _, method := range service.Methods {
+ nilArg := ""
+ if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
+ nilArg = "nil,"
+ }
+ g.P("func (*Unimplemented", serverType, ") ", serverSignature(g, method), "{")
+ g.P("return ", nilArg, statusPackage.Ident("Errorf"), "(", codesPackage.Ident("Unimplemented"), `, "method `, method.GoName, ` not implemented")`)
+ g.P("}")
+ }
+ g.P()
+
// Server registration.
if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
g.P(deprecationComment)
diff --git a/cmd/protoc-gen-go-grpc/testdata/grpc/deprecation_grpc.pb.go b/cmd/protoc-gen-go-grpc/testdata/grpc/deprecation_grpc.pb.go
index fd5cbc2..02124aa 100644
--- a/cmd/protoc-gen-go-grpc/testdata/grpc/deprecation_grpc.pb.go
+++ b/cmd/protoc-gen-go-grpc/testdata/grpc/deprecation_grpc.pb.go
@@ -5,6 +5,8 @@
import (
context "context"
grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
)
// Reference imports to suppress errors if they are not otherwise used.
@@ -21,6 +23,7 @@
//
// Deprecated: Do not use.
type DeprecatedServiceClient interface {
+ // Deprecated: Do not use.
DeprecatedCall(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
@@ -47,9 +50,18 @@
//
// Deprecated: Do not use.
type DeprecatedServiceServer interface {
+ // Deprecated: Do not use.
DeprecatedCall(context.Context, *Request) (*Response, error)
}
+// UnimplementedDeprecatedServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedDeprecatedServiceServer struct {
+}
+
+func (*UnimplementedDeprecatedServiceServer) DeprecatedCall(context.Context, *Request) (*Response, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DeprecatedCall not implemented")
+}
+
// Deprecated: Do not use.
func RegisterDeprecatedServiceServer(s *grpc.Server, srv DeprecatedServiceServer) {
s.RegisterService(&_DeprecatedService_serviceDesc, srv)
diff --git a/cmd/protoc-gen-go-grpc/testdata/grpc/grpc_grpc.pb.go b/cmd/protoc-gen-go-grpc/testdata/grpc/grpc_grpc.pb.go
index b638f8c..376ccdb 100644
--- a/cmd/protoc-gen-go-grpc/testdata/grpc/grpc_grpc.pb.go
+++ b/cmd/protoc-gen-go-grpc/testdata/grpc/grpc_grpc.pb.go
@@ -5,6 +5,8 @@
import (
context "context"
grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
)
// Reference imports to suppress errors if they are not otherwise used.
@@ -153,6 +155,23 @@
BidiCall(TestService_BidiCallServer) error
}
+// UnimplementedTestServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedTestServiceServer struct {
+}
+
+func (*UnimplementedTestServiceServer) UnaryCall(context.Context, *Request) (*Response, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented")
+}
+func (*UnimplementedTestServiceServer) DownstreamCall(*Request, TestService_DownstreamCallServer) error {
+ return status.Errorf(codes.Unimplemented, "method DownstreamCall not implemented")
+}
+func (*UnimplementedTestServiceServer) UpstreamCall(TestService_UpstreamCallServer) error {
+ return status.Errorf(codes.Unimplemented, "method UpstreamCall not implemented")
+}
+func (*UnimplementedTestServiceServer) BidiCall(TestService_BidiCallServer) error {
+ return status.Errorf(codes.Unimplemented, "method BidiCall not implemented")
+}
+
func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) {
s.RegisterService(&_TestService_serviceDesc, srv)
}