Skip to content

Commit

Permalink
chore: In amino/pkg, add optional WithComments, use them in GenerateP…
Browse files Browse the repository at this point in the history
…roto3MessagePartial

Signed-off-by: Jeff Thompson <jeff@thefirst.org>
  • Loading branch information
jefft0 committed Oct 11, 2023
1 parent b34816b commit 45eede4
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 2 deletions.
61 changes: 61 additions & 0 deletions tm2/pkg/amino/genproto/comments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package genproto

import (
"path"
"testing"

"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/jaekwon/testify/assert"
)

// message comment
type TestMessageName struct {
// field comment 1
FieldName1 string
// field comment 2
FieldName2 []uint64
}

// message comment 2
type TestMessageName2 struct {
// another field comment
FieldName string
}

func TestComments(t *testing.T) {
pkg := amino.RegisterPackage(
amino.NewPackage(
"github.com/gnolang/gno/tm2/pkg/amino/genproto",
"amino_test",
amino.GetCallersDirname(),
).WithTypes(
&TestMessageName{},
&TestMessageName2{},
// Add comments from this same source file.
).WithComments(path.Join(amino.GetCallersDirname(), "comments_test.go")))

p3c := NewP3Context()
p3c.RegisterPackage(pkg)
p3c.ValidateBasic()
p3doc := p3c.GenerateProto3SchemaForTypes(pkg, pkg.ReflectTypes()...)
proto3Schema := p3doc.Print()
assert.Equal(t, proto3Schema, `syntax = "proto3";
package amino_test;
option go_package = "github.com/gnolang/gno/tm2/pkg/amino/genproto/pb";
// messages
// message comment
message TestMessageName {
// field comment 1
string FieldName1 = 1;
// field comment 2
repeated uint64 FieldName2 = 2;
}
// message comment 2
message TestMessageName2 {
// another field comment
string FieldName = 1;
}`)
}
10 changes: 10 additions & 0 deletions tm2/pkg/amino/genproto/genproto.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ func (p3c *P3Context) GenerateProto3MessagePartial(p3doc *P3Doc, rt reflect.Type

p3msg.Name = info.Name // not rinfo.

var fieldComments map[string]string
if pkgType, ok := rinfo.Package.GetType(rt); ok {
p3msg.Comment = pkgType.Comment
// We will check for optional field comments below.
fieldComments = pkgType.FieldComments
}

// Append to p3msg.Fields, fields of the struct.
for _, field := range rsfields { // rinfo.
fp3, fp3IsRepeated, implicit := typeToP3Type(info.Package, field.TypeInfo, field.FieldOptions)
Expand All @@ -209,6 +216,9 @@ func (p3c *P3Context) GenerateProto3MessagePartial(p3doc *P3Doc, rt reflect.Type
Name: field.Name,
Number: field.FieldOptions.BinFieldNum,
}
if fieldComments != nil {
p3Field.Comment = fieldComments[field.Name]
}
p3msg.Fields = append(p3msg.Fields, p3Field)
}

Expand Down
62 changes: 60 additions & 2 deletions tm2/pkg/amino/pkg/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package pkg

import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"path/filepath"
"reflect"
"regexp"
Expand All @@ -11,8 +14,10 @@ import (

type Type struct {
Type reflect.Type
Name string // proto3 name (override)
PointerPreferred bool // whether pointer is preferred for decoding interface.
Name string // proto3 name (override)
PointerPreferred bool // whether pointer is preferred for decoding interface.
Comment string // optional doc comment for the type
FieldComments map[string]string // If not nil, the optional doc comment for each field name
}

func (t *Type) FullName(pkg *Package) string {
Expand Down Expand Up @@ -196,6 +201,59 @@ func (pkg *Package) WithP3SchemaFile(file string) *Package {
return pkg
}

// Parse the Go code in filename and scan the AST looking for struct doc comments.
// Find the Type in pkg.Types and set its Comment and FieldComments, which are
// used by genproto.GenerateProto3MessagePartial to set the Comment in the P3Doc
// and related P3Field objects.
func (pkg *Package) WithComments(filename string) *Package {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
if err != nil {
panic(err)

Check warning on line 212 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L208-L212

Added lines #L208 - L212 were not covered by tests
}

ast.Inspect(f, func(node ast.Node) bool {
if genDecl, ok := node.(*ast.GenDecl); ok {
for _, spec := range genDecl.Specs {
if typeSpec, ok := spec.(*ast.TypeSpec); ok {
if pkgType := pkg.getTypeByName(typeSpec.Name.Name); pkgType != nil {
if genDecl.Doc != nil {
// Set the type comment.
pkgType.Comment = strings.TrimSpace(genDecl.Doc.Text())
}
if structType, ok := typeSpec.Type.(*ast.StructType); ok {
for _, field := range structType.Fields.List {
if field.Names != nil && len(field.Names) == 1 && field.Doc != nil {
// Set the field comment.
if pkgType.FieldComments == nil {
pkgType.FieldComments = make(map[string]string)
}

Check warning on line 230 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L215-L230

Added lines #L215 - L230 were not covered by tests

pkgType.FieldComments[field.Names[0].Name] = strings.TrimSpace(field.Doc.Text())

Check warning on line 232 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L232

Added line #L232 was not covered by tests
}
}
}
}
}
}
}
return true

Check warning on line 240 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L240

Added line #L240 was not covered by tests
})

return pkg

Check warning on line 243 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L243

Added line #L243 was not covered by tests
}

// Get the Type by name. If not found, return nil.
func (pkg *Package) getTypeByName(name string) *Type {
for _, t := range pkg.Types {
if t.Name == name {
return t
}

Check warning on line 251 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L247-L251

Added lines #L247 - L251 were not covered by tests
}

return nil

Check warning on line 254 in tm2/pkg/amino/pkg/pkg.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/amino/pkg/pkg.go#L254

Added line #L254 was not covered by tests
}

// Result cannot be modified.
func (pkg *Package) GetType(rt reflect.Type) (t Type, ok bool) {
if rt.Kind() == reflect.Ptr {
Expand Down

0 comments on commit 45eede4

Please sign in to comment.