Skip to content

Commit

Permalink
customize json tag
Browse files Browse the repository at this point in the history
  • Loading branch information
liov authored and liov committed Sep 14, 2020
1 parent c2bd0c6 commit e0fe946
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 74 deletions.
4 changes: 4 additions & 0 deletions patch/go.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ message Options {
// The stringer_name option renames a generated String() method (if any)
// so a custom String() method can be implemented in its place.
optional string stringer_name = 30; // TODO: implement for messages

// The json_tag option Rewrite the json tag
// This option may be specified on a message field or a oneof field.
optional string json_tag = 40;
}

extend google.protobuf.MessageOptions {
Expand Down
160 changes: 86 additions & 74 deletions patch/gopb/go.pb.go

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

42 changes: 42 additions & 0 deletions patch/patcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type Patcher struct {
objectRenames map[types.Object]string
tags map[protogen.GoIdent]string
fieldTags map[types.Object]string
jsonTag map[protogen.GoIdent]string
objectJSONTag map[types.Object]string
}

// NewPatcher returns an initialized Patcher for gen.
Expand All @@ -61,6 +63,8 @@ func NewPatcher(gen *protogen.Plugin) (*Patcher, error) {
objectRenames: make(map[types.Object]string),
tags: make(map[protogen.GoIdent]string),
fieldTags: make(map[types.Object]string),
jsonTag: make(map[protogen.GoIdent]string),
objectJSONTag: make(map[types.Object]string),
}
return p, p.scan()
}
Expand Down Expand Up @@ -195,6 +199,14 @@ func (p *Patcher) scanField(f *protogen.Field) {
p.Tag(ident.WithChild(m.GoIdent, f.GoName), tags) // Field tags
}
}
jsonTag := opts.GetJsonTag()
if jsonTag != "" {
if o != nil {
p.JSONTag(ident.WithChild(f.GoIdent, f.GoName), jsonTag) // Oneof wrapper field tags
} else {
p.JSONTag(ident.WithChild(m.GoIdent, f.GoName), jsonTag) // Field tags
}
}
}

func (p *Patcher) scanExtension(f *protogen.Field) {
Expand Down Expand Up @@ -269,6 +281,11 @@ func (p *Patcher) Tag(id protogen.GoIdent, tags string) {
log.Printf("Tags:\t%s.%s `%s`", id.GoImportPath, id.GoName, tags)
}

func (p *Patcher) JSONTag(id protogen.GoIdent, jsonTag string) {
p.jsonTag[id] = jsonTag
log.Printf("jsonTag:\t%s.%s `%s`", id.GoImportPath, id.GoName, jsonTag)
}

// Patch applies the patch(es) in p the Go files in res.
// Clone res before calling Patch if you want to retain an unmodified copy.
// The behavior of calling Patch multiple times is currently undefined.
Expand Down Expand Up @@ -373,6 +390,13 @@ func (p *Patcher) checkGoFiles() error {
p.fieldTags[obj] = tags
}

for id, tag := range p.jsonTag {
obj, _ := p.find(id)
if obj == nil {
continue
}
p.objectJSONTag[obj] = tag
}
return nil
}

Expand Down Expand Up @@ -521,6 +545,24 @@ func (p *Patcher) patchIdent(id *ast.Ident, obj types.Object) {
id.Name = name
}

jsonTag := p.objectJSONTag[obj]

if jsonTag != "" && id.Obj != nil {
v, ok := id.Obj.Decl.(*ast.Field)
if !ok {
log.Printf("Warning: struct tags declared for non-field object: %v `%s`", obj, jsonTag)
} else {
if v.Tag == nil {
v.Tag = &ast.BasicLit{}
}
tags := strings.Split(strings.TrimSpace(strings.Trim(v.Tag.Value, "` ")), " ")
tags = append(tags[:len(tags)-1], `json:"`+jsonTag+`"`)
tag := strings.Join(tags, " ")
v.Tag.Value = "`" + tag + "`"
log.Printf("Add tags:\t%q.%s %s", obj.Pkg().Path(), id.Name, v.Tag.Value)
}
}

// Struct tags
tags := p.fieldTags[obj]
if tags != "" && id.Obj != nil {
Expand Down

0 comments on commit e0fe946

Please sign in to comment.