From 2b9f3835607b5459615b8656455d4b2b3ab24309 Mon Sep 17 00:00:00 2001 From: hitzhangjie Date: Wed, 22 Feb 2023 15:23:43 +0800 Subject: [PATCH] feat: generates trailing comments of message field close #764 --- protoc-gen-gogo/descriptor/descriptor.pb.go | 3 +- protoc-gen-gogo/generator/generator.go | 68 ++++++++++++++------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/protoc-gen-gogo/descriptor/descriptor.pb.go b/protoc-gen-gogo/descriptor/descriptor.pb.go index 18b2a3318a..c7fba9d9f7 100644 --- a/protoc-gen-gogo/descriptor/descriptor.pb.go +++ b/protoc-gen-gogo/descriptor/descriptor.pb.go @@ -5,8 +5,9 @@ package descriptor import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" math "math" + + proto "github.com/gogo/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/protoc-gen-gogo/generator/generator.go b/protoc-gen-gogo/generator/generator.go index 879939ea48..ecedace450 100644 --- a/protoc-gen-gogo/generator/generator.go +++ b/protoc-gen-gogo/generator/generator.go @@ -35,9 +35,9 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* - The code generator for the plugin for the Google protocol buffer compiler. - It generates Go code from the protocol buffer description files read by the - main routine. +The code generator for the plugin for the Google protocol buffer compiler. +It generates Go code from the protocol buffer description files read by the +main routine. */ package generator @@ -1321,15 +1321,15 @@ func (g *Generator) PrintComments(path string) bool { if !g.writeOutput { return false } - if c, ok := g.makeComments(path); ok { + if c, ok := g.makeLeadingComments(path); ok { g.P(c) return true } return false } -// makeComments generates the comment string for the field, no "\n" at the end -func (g *Generator) makeComments(path string) (string, bool) { +// makeLeadingComments generates the comment string for the field, no "\n" at the end +func (g *Generator) makeLeadingComments(path string) (string, bool) { loc, ok := g.file.comments[path] if !ok { return "", false @@ -1343,6 +1343,21 @@ func (g *Generator) makeComments(path string) (string, bool) { return w.String(), true } +// makeTrailingComments generates the trailing comment string for the field, no "\n" at the end +func (g *Generator) makeTrailingComments(path string) (string, bool) { + loc, ok := g.file.comments[path] + if !ok { + return "", false + } + w := new(bytes.Buffer) + nl := "" + for _, line := range strings.Split(strings.TrimSuffix(loc.GetTrailingComments(), "\n"), "\n") { + fmt.Fprintf(w, "%s//%s", nl, line) + nl = "\n" + } + return w.String(), true +} + // Comments returns any comments from the source .proto file and empty string if comments not found. // The path is a comma-separated list of intergers. // See descriptor.proto for its format. @@ -1605,6 +1620,7 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) { // The tag is a string like "varint,2,opt,name=fieldname,def=7" that // identifies details of the field for the protocol buffer marshaling and unmarshaling // code. The fields are: +// // wire encoding // protocol tag number // opt,req,rep for optional, required, or repeated @@ -1613,6 +1629,7 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) { // enum= the name of the enum type if it is an enum-typed field. // proto3 if this field is in a proto3 message // def= string representation of the default value, if any. +// // The default value must be in a representation that can be used at run-time // to generate the default value. Thus bools become 0 and 1, for instance. func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string { @@ -2179,17 +2196,18 @@ func (f *fieldCommon) getGoType() string { // simpleField is not weak, not a oneof, not an extension. Can be required, optional or repeated. type simpleField struct { fieldCommon - protoTypeName string // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration" - protoType descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 - deprecated string // Deprecation comment, if any, e.g. "// Deprecated: Do not use." - getterDef string // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName" - protoDef string // Default value as defined in the proto file, e.g "yoshi" or "5" - comment string // The full comment for the field, e.g. "// Useful information" + protoTypeName string // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration" + protoType descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 + deprecated string // Deprecation comment, if any, e.g. "// Deprecated: Do not use." + getterDef string // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName" + protoDef string // Default value as defined in the proto file, e.g "yoshi" or "5" + comment string // The full comment for the field, e.g. "// Useful information" + trailingComment string // The trailing comment for the field, e.g. "fieldName fieldType // Useful information" } // decl prints the declaration of the field in the struct (if any). func (f *simpleField) decl(g *Generator, mc *msgCtx) { - g.P(f.comment, Annotate(mc.message.file, f.fullPath, f.goName), "\t", f.goType, "\t`", f.tags, "`", f.deprecated) + g.P(f.comment, f.deprecated, Annotate(mc.message.file, f.fullPath, f.goName), "\t", f.goType, "\t`", f.tags, "`", f.trailingComment) } // getter prints the getter for the field. @@ -2870,7 +2888,7 @@ func (g *Generator) generateMessage(message *Descriptor) { // This is the first field of a oneof we haven't seen before. // Generate the union field. oneofFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex) - c, ok := g.makeComments(oneofFullPath) + c, ok := g.makeLeadingComments(oneofFullPath) if ok { c += "\n//\n" } @@ -2909,7 +2927,7 @@ func (g *Generator) generateMessage(message *Descriptor) { goTyp, _ := g.GoType(message, field) fieldDeprecated := "" if field.GetOptions().GetDeprecated() { - fieldDeprecated = deprecationComment + fieldDeprecated = deprecationComment + "\n" } dvalue := g.getterDefault(field, goTypeName, GoTypeToName(goTyp)) if oneof { @@ -2965,10 +2983,15 @@ func (g *Generator) generateMessage(message *Descriptor) { } fieldFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i) - c, ok := g.makeComments(fieldFullPath) + c, ok := g.makeLeadingComments(fieldFullPath) if ok { c += "\n" } + tc, ok := g.makeTrailingComments(fieldFullPath) + if ok { + tc += "\n" + } + rf := simpleField{ fieldCommon: fieldCommon{ goName: fieldName, @@ -2979,12 +3002,13 @@ func (g *Generator) generateMessage(message *Descriptor) { fullPath: fieldFullPath, protoField: field, }, - protoTypeName: field.GetTypeName(), - protoType: *field.Type, - deprecated: fieldDeprecated, - getterDef: dvalue, - protoDef: field.GetDefaultValue(), - comment: c, + protoTypeName: field.GetTypeName(), + protoType: *field.Type, + deprecated: fieldDeprecated, + getterDef: dvalue, + protoDef: field.GetDefaultValue(), + comment: c, + trailingComment: tc, } var pf topLevelField = &rf