protoc-gen-go: indicate deprecated fields in documentation
Tools in the Go ecosystem treat code documented with "Deprecated:"
as special for purposes of warning users not to use them. When a file,
message, field, enum, enum value, service, or method is marked as
deprecated, the generator will emit "// Deprecated: Do not use."
comments on all relevant exported Go package information related to
the deprecated element.
This is an outline of how deprecation of each element effects the generated proto:
* file - a comment is added to the top of the generated proto.
* message - a comment is added above its type definition.
* field, enum, or enum value - a comment is added inline with the defintion.
* field - an additional comment is added above the field Getter.
* service - a comment is added above generated Client interface and New method.
* service - a comment is added above generated Server interface and Registration method.
* method - a comment is added above the generated method definition.
Fixes #396.
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go
index a49189b..c5e9314 100644
--- a/protoc-gen-go/generator/generator.go
+++ b/protoc-gen-go/generator/generator.go
@@ -1330,7 +1330,11 @@
// Generate the header, including package definition
func (g *Generator) generateHeader() {
g.P("// Code generated by protoc-gen-go. DO NOT EDIT.")
- g.P("// source: ", g.file.Name)
+ if g.file.GetOptions().GetDeprecated() {
+ g.P("// ", g.file.Name, " is a deprecated file.")
+ } else {
+ g.P("// source: ", g.file.Name)
+ }
g.P()
name := g.file.PackageName()
@@ -1374,6 +1378,10 @@
g.P()
}
+// deprecationComment is the standard comment added to deprecated
+// messages, fields, enums, and enum values.
+var deprecationComment = "// Deprecated: Do not use."
+
// PrintComments prints any comments from the source .proto file.
// The path is a comma-separated list of integers.
// It returns an indication of whether any comments were printed.
@@ -1488,8 +1496,12 @@
ccTypeName := CamelCaseSlice(typeName)
ccPrefix := enum.prefix()
+ deprecatedEnum := ""
+ if enum.GetOptions().GetDeprecated() {
+ deprecatedEnum = deprecationComment
+ }
g.PrintComments(enum.path)
- g.P("type ", Annotate(enum.file, enum.path, ccTypeName), " int32")
+ g.P("type ", Annotate(enum.file, enum.path, ccTypeName), " int32", deprecatedEnum)
g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()})
g.P("const (")
g.In()
@@ -1497,8 +1509,13 @@
etorPath := fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i)
g.PrintComments(etorPath)
+ deprecatedValue := ""
+ if e.GetOptions().GetDeprecated() {
+ deprecatedValue = deprecationComment
+ }
+
name := ccPrefix + *e.Name
- g.P(Annotate(enum.file, etorPath, name), " ", ccTypeName, " = ", e.Number)
+ g.P(Annotate(enum.file, etorPath, name), " ", ccTypeName, " = ", e.Number, " ", deprecatedValue)
g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName})
}
g.Out()
@@ -1839,7 +1856,18 @@
oneofTypeName := make(map[*descriptor.FieldDescriptorProto]string) // without star
oneofInsertPoints := make(map[int32]int) // oneof_index => offset of g.Buffer
- g.PrintComments(message.path)
+ comments := g.PrintComments(message.path)
+
+ // Guarantee deprecation comments appear after user-provided comments.
+ if message.GetOptions().GetDeprecated() {
+ if comments {
+ // Convention: Separate deprecation comments from original
+ // comments with an empty line.
+ g.P("//")
+ }
+ g.P(deprecationComment)
+ }
+
g.P("type ", Annotate(message.file, message.path, ccTypeName), " struct {")
g.In()
@@ -1965,9 +1993,14 @@
continue
}
+ fieldDeprecated := ""
+ if field.GetOptions().GetDeprecated() {
+ fieldDeprecated = deprecationComment
+ }
+
fieldFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i)
g.PrintComments(fieldFullPath)
- g.P(Annotate(message.file, fieldFullPath, fieldName), "\t", typename, "\t`", tag, "`")
+ g.P(Annotate(message.file, fieldFullPath, fieldName), "\t", typename, "\t`", tag, "`", fieldDeprecated)
g.RecordTypeUse(field.GetTypeName())
}
g.P("XXX_NoUnkeyedLiteral\tstruct{} `json:\"-\"`") // prevent unkeyed struct literals
@@ -2252,6 +2285,10 @@
})
}
+ if field.GetOptions().GetDeprecated() {
+ g.P(deprecationComment)
+ }
+
g.P("func (m *", ccTypeName, ") ", Annotate(message.file, fieldFullPath, mname), "() "+typename+" {")
g.In()
def, hasDef := defNames[field]
diff --git a/protoc-gen-go/grpc/grpc.go b/protoc-gen-go/grpc/grpc.go
index 2660e47..f11aa1b 100644
--- a/protoc-gen-go/grpc/grpc.go
+++ b/protoc-gen-go/grpc/grpc.go
@@ -138,11 +138,15 @@
// reservedClientName records whether a client name is reserved on the client side.
var reservedClientName = map[string]bool{
-// TODO: do we need any in gRPC?
+ // TODO: do we need any in gRPC?
}
func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] }
+// deprecationComment is the standard comment added to deprecated
+// messages, fields, enums, and enum values.
+var deprecationComment = "// Deprecated: Do not use."
+
// generateService generates all the code for the named service.
func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) {
path := fmt.Sprintf("6,%d", index) // 6 means service.
@@ -153,12 +157,16 @@
fullServName = pkg + "." + fullServName
}
servName := generator.CamelCase(origServName)
+ deprecated := service.GetOptions().GetDeprecated()
g.P()
g.P("// Client API for ", servName, " service")
g.P()
// Client interface.
+ if deprecated {
+ g.P(deprecationComment)
+ }
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.
@@ -174,6 +182,9 @@
g.P()
// NewClient factory.
+ if deprecated {
+ g.P(deprecationComment)
+ }
g.P("func New", servName, "Client (cc *", grpcPkg, ".ClientConn) ", servName, "Client {")
g.P("return &", unexport(servName), "Client{cc}")
g.P("}")
@@ -200,6 +211,9 @@
g.P()
// Server interface.
+ if deprecated {
+ g.P(deprecationComment)
+ }
serverType := servName + "Server"
g.P("type ", serverType, " interface {")
for i, method := range service.Method {
@@ -210,6 +224,9 @@
g.P()
// Server registration.
+ if deprecated {
+ g.P(deprecationComment)
+ }
g.P("func Register", servName, "Server(s *", grpcPkg, ".Server, srv ", serverType, ") {")
g.P("s.RegisterService(&", serviceDescVar, `, srv)`)
g.P("}")
@@ -283,6 +300,9 @@
inType := g.typeName(method.GetInputType())
outType := g.typeName(method.GetOutputType())
+ if method.GetOptions().GetDeprecated() {
+ g.P(deprecationComment)
+ }
g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{")
if !method.GetServerStreaming() && !method.GetClientStreaming() {
g.P("out := new(", outType, ")")
diff --git a/protoc-gen-go/testdata/Makefile b/protoc-gen-go/testdata/Makefile
index a0bf9fe..945e7d0 100644
--- a/protoc-gen-go/testdata/Makefile
+++ b/protoc-gen-go/testdata/Makefile
@@ -51,6 +51,17 @@
gofmt -w my_test/test.pb.go
diff -w my_test/test.pb.go my_test/test.pb.go.golden
+ make -B deprecated/deprecated.pb.go
+ sed -i -e '/return.*fileDescriptor/d' deprecated/deprecated.pb.go
+ sed -i -e '/^var fileDescriptor/,/^}/d' deprecated/deprecated.pb.go
+ sed -i -e '/proto.RegisterFile.*fileDescriptor/d' deprecated/deprecated.pb.go
+ gofmt -w deprecated/deprecated.pb.go
+ diff -w deprecated/deprecated.pb.go deprecated/deprecated.pb.go.golden
+
+
+deprecated/deprecated.pb.go: deprecated/deprecated.proto
+ protoc --go_out=plugins=grpc,import_path=Mdeprecated/deprecated.proto=github.com/golang/protobuf/protoc-gen-go/testdata/deprecated:. $<
+
nuke: clean
testbuild: regenerate
diff --git a/protoc-gen-go/testdata/deprecated/deprecated.pb.go b/protoc-gen-go/testdata/deprecated/deprecated.pb.go
new file mode 100644
index 0000000..1cdbe42
--- /dev/null
+++ b/protoc-gen-go/testdata/deprecated/deprecated.pb.go
@@ -0,0 +1,207 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// deprecated/deprecated.proto is a deprecated file.
+
+/*
+Package deprecated is a generated protocol buffer package.
+
+package deprecated contains only deprecated messages and services.
+
+It is generated from these files:
+ deprecated/deprecated.proto
+
+It has these top-level messages:
+ DeprecatedRequest
+ DeprecatedResponse
+*/
+package deprecated
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// 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
+
+// DeprecatedEnum contains deprecated values.
+type DeprecatedEnum int32 // Deprecated: Do not use.
+const (
+ // DEPRECATED is the iota value of this enum.
+ DeprecatedEnum_DEPRECATED DeprecatedEnum = 0 // Deprecated: Do not use.
+)
+
+var DeprecatedEnum_name = map[int32]string{
+ 0: "DEPRECATED",
+}
+var DeprecatedEnum_value = map[string]int32{
+ "DEPRECATED": 0,
+}
+
+func (x DeprecatedEnum) String() string {
+ return proto.EnumName(DeprecatedEnum_name, int32(x))
+}
+
+// DeprecatedRequest is a request to DeprecatedCall.
+//
+// Deprecated: Do not use.
+type DeprecatedRequest struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeprecatedRequest) Reset() { *m = DeprecatedRequest{} }
+func (m *DeprecatedRequest) String() string { return proto.CompactTextString(m) }
+func (*DeprecatedRequest) ProtoMessage() {}
+func (m *DeprecatedRequest) Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeprecatedRequest.Unmarshal(m, b)
+}
+func (m *DeprecatedRequest) Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeprecatedRequest.Marshal(b, m, deterministic)
+}
+func (dst *DeprecatedRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeprecatedRequest.Merge(dst, src)
+}
+func (m *DeprecatedRequest) XXX_Size() int {
+ return xxx_messageInfo_DeprecatedRequest.Size(m)
+}
+func (m *DeprecatedRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeprecatedRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeprecatedRequest proto.InternalMessageInfo
+
+// Deprecated: Do not use.
+type DeprecatedResponse struct {
+ // DeprecatedField contains a DeprecatedEnum.
+ DeprecatedField DeprecatedEnum `protobuf:"varint,1,opt,name=deprecated_field,json=deprecatedField,enum=deprecated.DeprecatedEnum" json:"deprecated_field,omitempty"` // Deprecated: Do not use.
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeprecatedResponse) Reset() { *m = DeprecatedResponse{} }
+func (m *DeprecatedResponse) String() string { return proto.CompactTextString(m) }
+func (*DeprecatedResponse) ProtoMessage() {}
+func (m *DeprecatedResponse) Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeprecatedResponse.Unmarshal(m, b)
+}
+func (m *DeprecatedResponse) Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeprecatedResponse.Marshal(b, m, deterministic)
+}
+func (dst *DeprecatedResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeprecatedResponse.Merge(dst, src)
+}
+func (m *DeprecatedResponse) XXX_Size() int {
+ return xxx_messageInfo_DeprecatedResponse.Size(m)
+}
+func (m *DeprecatedResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeprecatedResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeprecatedResponse proto.InternalMessageInfo
+
+// Deprecated: Do not use.
+func (m *DeprecatedResponse) GetDeprecatedField() DeprecatedEnum {
+ if m != nil {
+ return m.DeprecatedField
+ }
+ return DeprecatedEnum_DEPRECATED
+}
+
+func init() {
+ proto.RegisterType((*DeprecatedRequest)(nil), "deprecated.DeprecatedRequest")
+ proto.RegisterType((*DeprecatedResponse)(nil), "deprecated.DeprecatedResponse")
+ proto.RegisterEnum("deprecated.DeprecatedEnum", DeprecatedEnum_name, DeprecatedEnum_value)
+}
+
+// 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
+
+// Client API for DeprecatedService service
+
+// Deprecated: Do not use.
+type DeprecatedServiceClient interface {
+ // DeprecatedCall takes a DeprecatedRequest and returns a DeprecatedResponse.
+ DeprecatedCall(ctx context.Context, in *DeprecatedRequest, opts ...grpc.CallOption) (*DeprecatedResponse, 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 *DeprecatedRequest, opts ...grpc.CallOption) (*DeprecatedResponse, error) {
+ out := new(DeprecatedResponse)
+ err := grpc.Invoke(ctx, "/deprecated.DeprecatedService/DeprecatedCall", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// Server API for DeprecatedService service
+
+// Deprecated: Do not use.
+type DeprecatedServiceServer interface {
+ // DeprecatedCall takes a DeprecatedRequest and returns a DeprecatedResponse.
+ DeprecatedCall(context.Context, *DeprecatedRequest) (*DeprecatedResponse, 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(DeprecatedRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(DeprecatedServiceServer).DeprecatedCall(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/deprecated.DeprecatedService/DeprecatedCall",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(DeprecatedServiceServer).DeprecatedCall(ctx, req.(*DeprecatedRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _DeprecatedService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "deprecated.DeprecatedService",
+ HandlerType: (*DeprecatedServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "DeprecatedCall",
+ Handler: _DeprecatedService_DeprecatedCall_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "deprecated/deprecated.proto",
+}
diff --git a/protoc-gen-go/testdata/deprecated/deprecated.pb.go.golden b/protoc-gen-go/testdata/deprecated/deprecated.pb.go.golden
new file mode 100644
index 0000000..1cdbe42
--- /dev/null
+++ b/protoc-gen-go/testdata/deprecated/deprecated.pb.go.golden
@@ -0,0 +1,207 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// deprecated/deprecated.proto is a deprecated file.
+
+/*
+Package deprecated is a generated protocol buffer package.
+
+package deprecated contains only deprecated messages and services.
+
+It is generated from these files:
+ deprecated/deprecated.proto
+
+It has these top-level messages:
+ DeprecatedRequest
+ DeprecatedResponse
+*/
+package deprecated
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// 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
+
+// DeprecatedEnum contains deprecated values.
+type DeprecatedEnum int32 // Deprecated: Do not use.
+const (
+ // DEPRECATED is the iota value of this enum.
+ DeprecatedEnum_DEPRECATED DeprecatedEnum = 0 // Deprecated: Do not use.
+)
+
+var DeprecatedEnum_name = map[int32]string{
+ 0: "DEPRECATED",
+}
+var DeprecatedEnum_value = map[string]int32{
+ "DEPRECATED": 0,
+}
+
+func (x DeprecatedEnum) String() string {
+ return proto.EnumName(DeprecatedEnum_name, int32(x))
+}
+
+// DeprecatedRequest is a request to DeprecatedCall.
+//
+// Deprecated: Do not use.
+type DeprecatedRequest struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeprecatedRequest) Reset() { *m = DeprecatedRequest{} }
+func (m *DeprecatedRequest) String() string { return proto.CompactTextString(m) }
+func (*DeprecatedRequest) ProtoMessage() {}
+func (m *DeprecatedRequest) Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeprecatedRequest.Unmarshal(m, b)
+}
+func (m *DeprecatedRequest) Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeprecatedRequest.Marshal(b, m, deterministic)
+}
+func (dst *DeprecatedRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeprecatedRequest.Merge(dst, src)
+}
+func (m *DeprecatedRequest) XXX_Size() int {
+ return xxx_messageInfo_DeprecatedRequest.Size(m)
+}
+func (m *DeprecatedRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeprecatedRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeprecatedRequest proto.InternalMessageInfo
+
+// Deprecated: Do not use.
+type DeprecatedResponse struct {
+ // DeprecatedField contains a DeprecatedEnum.
+ DeprecatedField DeprecatedEnum `protobuf:"varint,1,opt,name=deprecated_field,json=deprecatedField,enum=deprecated.DeprecatedEnum" json:"deprecated_field,omitempty"` // Deprecated: Do not use.
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeprecatedResponse) Reset() { *m = DeprecatedResponse{} }
+func (m *DeprecatedResponse) String() string { return proto.CompactTextString(m) }
+func (*DeprecatedResponse) ProtoMessage() {}
+func (m *DeprecatedResponse) Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeprecatedResponse.Unmarshal(m, b)
+}
+func (m *DeprecatedResponse) Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeprecatedResponse.Marshal(b, m, deterministic)
+}
+func (dst *DeprecatedResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeprecatedResponse.Merge(dst, src)
+}
+func (m *DeprecatedResponse) XXX_Size() int {
+ return xxx_messageInfo_DeprecatedResponse.Size(m)
+}
+func (m *DeprecatedResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeprecatedResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeprecatedResponse proto.InternalMessageInfo
+
+// Deprecated: Do not use.
+func (m *DeprecatedResponse) GetDeprecatedField() DeprecatedEnum {
+ if m != nil {
+ return m.DeprecatedField
+ }
+ return DeprecatedEnum_DEPRECATED
+}
+
+func init() {
+ proto.RegisterType((*DeprecatedRequest)(nil), "deprecated.DeprecatedRequest")
+ proto.RegisterType((*DeprecatedResponse)(nil), "deprecated.DeprecatedResponse")
+ proto.RegisterEnum("deprecated.DeprecatedEnum", DeprecatedEnum_name, DeprecatedEnum_value)
+}
+
+// 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
+
+// Client API for DeprecatedService service
+
+// Deprecated: Do not use.
+type DeprecatedServiceClient interface {
+ // DeprecatedCall takes a DeprecatedRequest and returns a DeprecatedResponse.
+ DeprecatedCall(ctx context.Context, in *DeprecatedRequest, opts ...grpc.CallOption) (*DeprecatedResponse, 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 *DeprecatedRequest, opts ...grpc.CallOption) (*DeprecatedResponse, error) {
+ out := new(DeprecatedResponse)
+ err := grpc.Invoke(ctx, "/deprecated.DeprecatedService/DeprecatedCall", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// Server API for DeprecatedService service
+
+// Deprecated: Do not use.
+type DeprecatedServiceServer interface {
+ // DeprecatedCall takes a DeprecatedRequest and returns a DeprecatedResponse.
+ DeprecatedCall(context.Context, *DeprecatedRequest) (*DeprecatedResponse, 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(DeprecatedRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(DeprecatedServiceServer).DeprecatedCall(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/deprecated.DeprecatedService/DeprecatedCall",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(DeprecatedServiceServer).DeprecatedCall(ctx, req.(*DeprecatedRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _DeprecatedService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "deprecated.DeprecatedService",
+ HandlerType: (*DeprecatedServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "DeprecatedCall",
+ Handler: _DeprecatedService_DeprecatedCall_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "deprecated/deprecated.proto",
+}
diff --git a/protoc-gen-go/testdata/deprecated/deprecated.proto b/protoc-gen-go/testdata/deprecated/deprecated.proto
new file mode 100644
index 0000000..5ee932a
--- /dev/null
+++ b/protoc-gen-go/testdata/deprecated/deprecated.proto
@@ -0,0 +1,67 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2018 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+// package deprecated contains only deprecated messages and services.
+package deprecated;
+
+option deprecated = true; // file-level deprecation
+
+// DeprecatedRequest is a request to DeprecatedCall.
+message DeprecatedRequest {
+ option deprecated = true;
+}
+
+message DeprecatedResponse {
+ // comment for DeprecatedResponse is omitted to guarantee deprecation
+ // message doesn't append unnecessary comments.
+ option deprecated = true;
+ // DeprecatedField contains a DeprecatedEnum.
+ DeprecatedEnum deprecated_field = 1 [deprecated=true];
+}
+
+// DeprecatedEnum contains deprecated values.
+enum DeprecatedEnum {
+ option deprecated = true;
+ // DEPRECATED is the iota value of this enum.
+ DEPRECATED = 0 [deprecated=true];
+}
+
+// DeprecatedService is for making DeprecatedCalls
+service DeprecatedService {
+ option deprecated = true;
+
+ // DeprecatedCall takes a DeprecatedRequest and returns a DeprecatedResponse.
+ rpc DeprecatedCall(DeprecatedRequest) returns (DeprecatedResponse) {
+ option deprecated = true;
+ }
+}
\ No newline at end of file