Przeglądaj źródła

cmd/protoc-gen-go-grpc: add deprecation comments

Change-Id: I7cf579acb11eeb4e56ec3dd4baec08758b8dc7e1
Reviewed-on: https://go-review.googlesource.com/138376
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Damien Neil 7 lat temu
rodzic
commit
183aa3a3e6

+ 18 - 12
cmd/protoc-gen-go-grpc/internal_gengogrpc/grpc.go

@@ -70,7 +70,10 @@ func genService(gen *protogen.Plugin, file *fileInfo, g *protogen.GeneratedFile,
 	g.P("// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.")
 
 	// Client interface.
-	// TODO deprecation
+	if serviceOptions(gen, service).GetDeprecated() {
+		g.P("//")
+		g.P(deprecationComment)
+	}
 	g.P("type ", clientName, " interface {")
 	for _, method := range service.Methods {
 		genComment(g, file, method.Path)
@@ -86,7 +89,9 @@ func genService(gen *protogen.Plugin, file *fileInfo, g *protogen.GeneratedFile,
 	g.P()
 
 	// NewClient factory.
-	// TODO deprecation
+	if serviceOptions(gen, service).GetDeprecated() {
+		g.P(deprecationComment)
+	}
 	g.P("func New", clientName, " (cc *", ident("grpc.ClientConn"), ") ", clientName, " {")
 	g.P("return &", unexport(clientName), "{cc}")
 	g.P("}")
@@ -109,7 +114,10 @@ func genService(gen *protogen.Plugin, file *fileInfo, g *protogen.GeneratedFile,
 	// Server interface.
 	serverType := service.GoName + "Server"
 	g.P("// ", serverType, " is the server API for ", service.GoName, " service.")
-	// TODO deprecation
+	if serviceOptions(gen, service).GetDeprecated() {
+		g.P("//")
+		g.P(deprecationComment)
+	}
 	g.P("type ", serverType, " interface {")
 	for _, method := range service.Methods {
 		genComment(g, file, method.Path)
@@ -119,7 +127,9 @@ func genService(gen *protogen.Plugin, file *fileInfo, g *protogen.GeneratedFile,
 	g.P()
 
 	// Server registration.
-	// TODO deprecation
+	if serviceOptions(gen, service).GetDeprecated() {
+		g.P(deprecationComment)
+	}
 	serviceDescVar := "_" + service.GoName + "_serviceDesc"
 	g.P("func Register", service.GoName, "Server(s *", ident("grpc.Server"), ", srv ", serverType, ") {")
 	g.P("s.RegisterService(&", serviceDescVar, `, srv)`)
@@ -189,7 +199,9 @@ func genClientMethod(gen *protogen.Plugin, file *fileInfo, g *protogen.Generated
 	service := method.ParentService
 	sname := fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.Desc.Name())
 
-	// TODO deprecation
+	if methodOptions(gen, method).GetDeprecated() {
+		g.P(deprecationComment)
+	}
 	g.P("func (c *", unexport(service.GoName), "Client) ", clientSignature(g, method), "{")
 	if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() {
 		g.P("out := new(", method.OutputType.GoIdent, ")")
@@ -386,13 +398,7 @@ func genComment(g *protogen.GeneratedFile, file *fileInfo, path []int32) (hasCom
 	return hasComment
 }
 
-// deprecationComment returns a standard deprecation comment if deprecated is true.
-func deprecationComment(deprecated bool) string {
-	if !deprecated {
-		return ""
-	}
-	return "// Deprecated: Do not use."
-}
+const deprecationComment = "// Deprecated: Do not use."
 
 // pathKey converts a location path to a string suitable for use as a map key.
 func pathKey(path []int32) string {

+ 116 - 0
cmd/protoc-gen-go-grpc/internal_gengogrpc/options.go

@@ -0,0 +1,116 @@
+// Copyright 2018 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.
+
+// This file contains functions for fetching the options for a protoreflect descriptor.
+//
+// TODO: Replace this with the appropriate protoreflect API, once it exists.
+
+package internal_gengogrpc
+
+import (
+	"github.com/golang/protobuf/proto"
+	descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+	"github.com/golang/protobuf/v2/protogen"
+	"github.com/golang/protobuf/v2/reflect/protoreflect"
+)
+
+// serviceOptions returns the options for a service.
+func serviceOptions(gen *protogen.Plugin, service *protogen.Service) *descpb.ServiceOptions {
+	d := getDescriptorProto(gen, service.Desc, service.Path)
+	if d == nil {
+		return nil
+	}
+	return d.(*descpb.ServiceDescriptorProto).GetOptions()
+}
+
+// methodOptions returns the options for a method.
+func methodOptions(gen *protogen.Plugin, method *protogen.Method) *descpb.MethodOptions {
+	d := getDescriptorProto(gen, method.Desc, method.Path)
+	if d == nil {
+		return nil
+	}
+	return d.(*descpb.MethodDescriptorProto).GetOptions()
+}
+
+func getDescriptorProto(gen *protogen.Plugin, desc protoreflect.Descriptor, path []int32) proto.Message {
+	var p proto.Message
+	// Look up the FileDescriptorProto.
+	for {
+		if fdesc, ok := desc.(protoreflect.FileDescriptor); ok {
+			file, ok := gen.FileByName(fdesc.Path())
+			if !ok {
+				return nil
+			}
+			p = file.Proto
+			break
+		}
+		var ok bool
+		desc, ok = desc.Parent()
+		if !ok {
+			return nil
+		}
+	}
+	const (
+		// field numbers in FileDescriptorProto
+		filePackageField   = 2 // package
+		fileMessageField   = 4 // message_type
+		fileEnumField      = 5 // enum_type
+		fileServiceField   = 6 // service
+		fileExtensionField = 7 // extension
+		// field numbers in DescriptorProto
+		messageFieldField     = 2 // field
+		messageMessageField   = 3 // nested_type
+		messageEnumField      = 4 // enum_type
+		messageExtensionField = 6 // extension
+		messageOneofField     = 8 // oneof_decl
+		// field numbers in EnumDescriptorProto
+		enumValueField = 2 // value
+		// field numbers in ServiceDescriptorProto
+		serviceMethodField = 2 // method
+	)
+	for len(path) > 1 {
+		switch d := p.(type) {
+		case *descpb.FileDescriptorProto:
+			switch path[0] {
+			case fileMessageField:
+				p = d.MessageType[path[1]]
+			case fileEnumField:
+				p = d.EnumType[path[1]]
+			case fileServiceField:
+				p = d.Service[path[1]]
+			default:
+				return nil
+			}
+		case *descpb.DescriptorProto:
+			switch path[0] {
+			case messageFieldField:
+				p = d.Field[path[1]]
+			case messageMessageField:
+				p = d.NestedType[path[1]]
+			case messageEnumField:
+				p = d.EnumType[path[1]]
+			default:
+				return nil
+			}
+		case *descpb.EnumDescriptorProto:
+			switch path[0] {
+			case enumValueField:
+				p = d.Value[path[1]]
+			default:
+				return nil
+			}
+		case *descpb.ServiceDescriptorProto:
+			switch path[0] {
+			case serviceMethodField:
+				p = d.Method[path[1]]
+			default:
+				return nil
+			}
+		default:
+			return nil
+		}
+		path = path[2:]
+	}
+	return p
+}

+ 39 - 0
cmd/protoc-gen-go-grpc/testdata/grpc/deprecation.pb.go

@@ -0,0 +1,39 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: grpc/deprecation.proto
+
+package grpc
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+func init() { proto.RegisterFile("grpc/deprecation.proto", fileDescriptor_1e7146702b7fe8c5) }
+
+var fileDescriptor_1e7146702b7fe8c5 = []byte{
+	// 184 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4b, 0x2f, 0x2a, 0x48,
+	0xd6, 0x4f, 0x49, 0x2d, 0x28, 0x4a, 0x4d, 0x4e, 0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x2b, 0x28, 0xca,
+	0x2f, 0xc9, 0x17, 0x12, 0x4e, 0xcf, 0x07, 0x33, 0x20, 0xdc, 0x64, 0x3d, 0x90, 0x32, 0x29, 0x7e,
+	0xb0, 0x62, 0x10, 0x01, 0x11, 0x36, 0xca, 0xe1, 0x12, 0x74, 0x81, 0x6a, 0x4d, 0x4d, 0x09, 0x4e,
+	0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0x15, 0x0a, 0xe2, 0xe2, 0x43, 0x08, 0x3a, 0x27, 0xe6, 0xe4, 0x08,
+	0xc9, 0xe8, 0x61, 0x31, 0x4d, 0x2f, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x4a, 0x16, 0x87,
+	0x6c, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x12, 0x73, 0x07, 0x13, 0xa3, 0x14, 0x88, 0x70, 0xb2,
+	0x8f, 0xb2, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf,
+	0x49, 0xcc, 0x4b, 0xd7, 0x07, 0xeb, 0x49, 0x2a, 0x4d, 0xd3, 0x2f, 0x33, 0xd2, 0x4f, 0xce, 0x4d,
+	0x81, 0xf0, 0x93, 0x75, 0xd3, 0x53, 0xf3, 0x74, 0xd3, 0xf3, 0xf5, 0x4b, 0x52, 0x8b, 0x4b, 0x52,
+	0x12, 0x4b, 0x12, 0xc1, 0x8e, 0x4e, 0x62, 0x03, 0x4b, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff,
+	0x8d, 0xbe, 0xc2, 0x16, 0xf5, 0x00, 0x00, 0x00,
+}

+ 19 - 0
cmd/protoc-gen-go-grpc/testdata/grpc/deprecation.proto

@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+syntax = "proto3";
+
+package goproto.protoc.grpc;
+
+import "grpc/grpc.proto";
+
+option go_package = "github.com/golang/protobuf/v2/cmd/protoc-gen-go/testdata/grpc";
+
+service DeprecatedService {
+  option deprecated = true;
+
+  rpc DeprecatedCall(Request) returns (Response) {
+    option deprecated = true;
+  }
+}

+ 87 - 0
cmd/protoc-gen-go-grpc/testdata/grpc/deprecation_grpc.pb.go

@@ -0,0 +1,87 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package grpc
+
+import (
+	context "golang.org/x/net/context"
+	grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// DeprecatedServiceClient is the client API for DeprecatedService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+//
+// Deprecated: Do not use.
+type DeprecatedServiceClient interface {
+	DeprecatedCall(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
+}
+
+type deprecatedServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+// Deprecated: Do not use.
+func NewDeprecatedServiceClient(cc *grpc.ClientConn) DeprecatedServiceClient {
+	return &deprecatedServiceClient{cc}
+}
+
+// Deprecated: Do not use.
+func (c *deprecatedServiceClient) DeprecatedCall(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/goproto.protoc.grpc.DeprecatedService/DeprecatedCall", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// DeprecatedServiceServer is the server API for DeprecatedService service.
+//
+// Deprecated: Do not use.
+type DeprecatedServiceServer interface {
+	DeprecatedCall(context.Context, *Request) (*Response, error)
+}
+
+// Deprecated: Do not use.
+func RegisterDeprecatedServiceServer(s *grpc.Server, srv DeprecatedServiceServer) {
+	s.RegisterService(&_DeprecatedService_serviceDesc, srv)
+}
+
+func _DeprecatedService_DeprecatedCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Request)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(DeprecatedServiceServer).DeprecatedCall(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/goproto.protoc.grpc.DeprecatedService/DeprecatedCall",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(DeprecatedServiceServer).DeprecatedCall(ctx, req.(*Request))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _DeprecatedService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "goproto.protoc.grpc.DeprecatedService",
+	HandlerType: (*DeprecatedServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "DeprecatedCall",
+			Handler:    _DeprecatedService_DeprecatedCall_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "grpc/deprecation.proto",
+}