Skip to content

Commit

Permalink
Merge pull request #506 from paranoiacblack/deprecated-fields
Browse files Browse the repository at this point in the history
protoc-gen-go: indicate deprecated fields in documentation
  • Loading branch information
Chris Manghane authored Feb 3, 2018
2 parents 42d4f47 + da3e237 commit cb908bf
Show file tree
Hide file tree
Showing 6 changed files with 555 additions and 6 deletions.
47 changes: 42 additions & 5 deletions protoc-gen-go/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -1330,7 +1330,11 @@ func (g *Generator) generate(file *FileDescriptor) {
// 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()
Expand Down Expand Up @@ -1374,6 +1378,10 @@ func (g *Generator) generateHeader() {
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.
Expand Down Expand Up @@ -1488,17 +1496,26 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) {
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()
for i, e := range enum.Value {
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()
Expand Down Expand Up @@ -1839,7 +1856,18 @@ func (g *Generator) generateMessage(message *Descriptor) {
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()

Expand Down Expand Up @@ -1965,9 +1993,14 @@ func (g *Generator) generateMessage(message *Descriptor) {
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
Expand Down Expand Up @@ -2252,6 +2285,10 @@ func (g *Generator) generateMessage(message *Descriptor) {
})
}

if field.GetOptions().GetDeprecated() {
g.P(deprecationComment)
}

g.P("func (m *", ccTypeName, ") ", Annotate(message.file, fieldFullPath, mname), "() "+typename+" {")
g.In()
def, hasDef := defNames[field]
Expand Down
22 changes: 21 additions & 1 deletion protoc-gen-go/grpc/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,15 @@ func (g *grpc) GenerateImports(file *generator.FileDescriptor) {

// 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.
Expand All @@ -153,12 +157,16 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
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.
Expand All @@ -174,6 +182,9 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
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("}")
Expand All @@ -200,6 +211,9 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P()

// Server interface.
if deprecated {
g.P(deprecationComment)
}
serverType := servName + "Server"
g.P("type ", serverType, " interface {")
for i, method := range service.Method {
Expand All @@ -210,6 +224,9 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
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("}")
Expand Down Expand Up @@ -283,6 +300,9 @@ func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar strin
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, ")")
Expand Down
11 changes: 11 additions & 0 deletions protoc-gen-go/testdata/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ golden:
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
Expand Down
207 changes: 207 additions & 0 deletions protoc-gen-go/testdata/deprecated/deprecated.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit cb908bf

Please sign in to comment.