Skip to content

Commit 25deb65

Browse files
committed
Add support to read gopb tags from proto request
1 parent d71e9a8 commit 25deb65

File tree

1 file changed

+149
-34
lines changed

1 file changed

+149
-34
lines changed

patch/patcher.go

Lines changed: 149 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ import (
1818
"golang.org/x/tools/go/ast/astutil"
1919
"google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo"
2020
"google.golang.org/protobuf/compiler/protogen"
21+
"google.golang.org/protobuf/types/descriptorpb"
2122
"google.golang.org/protobuf/types/pluginpb"
2223

24+
"github.com/golang/protobuf/proto"
25+
2326
"github.com/alta/protopatch/lint"
27+
"github.com/alta/protopatch/patch/gopb"
2428
"github.com/alta/protopatch/patch/ident"
2529
)
2630

@@ -33,56 +37,166 @@ import (
3337
// - (go.enum).name overrides the name of an enum type.
3438
// - (go.value).name overrides the name of an enum value.
3539
type Patcher struct {
36-
gen *protogen.Plugin
37-
fset *token.FileSet
38-
filesByName map[string]*ast.File
39-
info *types.Info
40-
packages []*Package
41-
packagesByPath map[string]*Package
42-
packagesByName map[string]*Package
43-
renames map[protogen.GoIdent]string
44-
typeRenames map[protogen.GoIdent]string
45-
valueRenames map[protogen.GoIdent]string
46-
fieldRenames map[protogen.GoIdent]string
47-
methodRenames map[protogen.GoIdent]string
48-
objectRenames map[types.Object]string
49-
tags map[protogen.GoIdent]string
50-
fieldTags map[types.Object]string
51-
embeds map[protogen.GoIdent]string
52-
fieldEmbeds map[types.Object]string
53-
types map[protogen.GoIdent]string
54-
fieldTypes map[types.Object]string
40+
gen *protogen.Plugin
41+
fset *token.FileSet
42+
filesByName map[string]*ast.File
43+
info *types.Info
44+
packages []*Package
45+
packagesByPath map[string]*Package
46+
packagesByName map[string]*Package
47+
renames map[protogen.GoIdent]string
48+
typeRenames map[protogen.GoIdent]string
49+
valueRenames map[protogen.GoIdent]string
50+
fieldRenames map[protogen.GoIdent]string
51+
methodRenames map[protogen.GoIdent]string
52+
objectRenames map[types.Object]string
53+
tags map[protogen.GoIdent]string
54+
fieldTags map[types.Object]string
55+
embeds map[protogen.GoIdent]string
56+
fieldEmbeds map[types.Object]string
57+
types map[protogen.GoIdent]string
58+
fieldTypes map[types.Object]string
59+
processedMessages map[protogen.GoIdent]bool
5560
}
5661

5762
// NewPatcher returns an initialized Patcher for gen.
5863
func NewPatcher(gen *protogen.Plugin) (*Patcher, error) {
5964
p := &Patcher{
60-
gen: gen,
61-
packagesByPath: make(map[string]*Package),
62-
packagesByName: make(map[string]*Package),
63-
renames: make(map[protogen.GoIdent]string),
64-
typeRenames: make(map[protogen.GoIdent]string),
65-
valueRenames: make(map[protogen.GoIdent]string),
66-
fieldRenames: make(map[protogen.GoIdent]string),
67-
methodRenames: make(map[protogen.GoIdent]string),
68-
objectRenames: make(map[types.Object]string),
69-
tags: make(map[protogen.GoIdent]string),
70-
fieldTags: make(map[types.Object]string),
71-
embeds: make(map[protogen.GoIdent]string),
72-
fieldEmbeds: make(map[types.Object]string),
73-
types: make(map[protogen.GoIdent]string),
74-
fieldTypes: make(map[types.Object]string),
65+
gen: gen,
66+
packagesByPath: make(map[string]*Package),
67+
packagesByName: make(map[string]*Package),
68+
renames: make(map[protogen.GoIdent]string),
69+
typeRenames: make(map[protogen.GoIdent]string),
70+
valueRenames: make(map[protogen.GoIdent]string),
71+
fieldRenames: make(map[protogen.GoIdent]string),
72+
methodRenames: make(map[protogen.GoIdent]string),
73+
objectRenames: make(map[types.Object]string),
74+
tags: make(map[protogen.GoIdent]string),
75+
fieldTags: make(map[types.Object]string),
76+
embeds: make(map[protogen.GoIdent]string),
77+
fieldEmbeds: make(map[types.Object]string),
78+
types: make(map[protogen.GoIdent]string),
79+
fieldTypes: make(map[types.Object]string),
80+
processedMessages: make(map[protogen.GoIdent]bool),
7581
}
7682
return p, p.scan()
7783
}
7884

85+
func getExtensionDesc(pb proto.Message, extname string) (*proto.ExtensionDesc, error) {
86+
desc := proto.RegisteredExtensions(pb)
87+
for _, d := range desc {
88+
if d.Name == extname {
89+
return d, nil
90+
}
91+
}
92+
return nil, fmt.Errorf("ExtensionDesc not found")
93+
}
94+
95+
func getExtension(pb proto.Message, extname string) (interface{}, error) {
96+
d, err := getExtensionDesc(pb, extname)
97+
if err != nil {
98+
return nil, err
99+
}
100+
e, err := proto.GetExtension(pb, d)
101+
if err != nil {
102+
return nil, err
103+
}
104+
return e, err
105+
}
106+
79107
func (p *Patcher) scan() error {
80108
for _, f := range p.gen.Files {
81109
p.scanFile(f)
82110
}
111+
for _, f := range p.gen.Request.ProtoFile {
112+
found := false
113+
mident := protogen.GoIdent{GoName: "", GoImportPath: ""}
114+
fident := protogen.GoIdent{GoName: "", GoImportPath: ""}
115+
for _, genFile := range p.gen.Files {
116+
if *f.Name == genFile.Desc.Path() {
117+
found = true
118+
mident = protogen.GoIdent{GoName: "", GoImportPath: genFile.GoImportPath}
119+
fident = protogen.GoIdent{GoName: "", GoImportPath: genFile.GoImportPath}
120+
break
121+
}
122+
}
123+
if !found {
124+
panic("Not found")
125+
}
126+
for _, m := range f.MessageType {
127+
mident.GoName = *m.Name
128+
if _, ok := p.processedMessages[mident]; ok {
129+
continue
130+
}
131+
nmident := protogen.GoIdent{GoName: "", GoImportPath: mident.GoImportPath}
132+
nfident := protogen.GoIdent{GoName: "", GoImportPath: mident.GoImportPath}
133+
for _, nestedMsgType := range m.NestedType {
134+
nmident.GoName = mident.GoName + "_" + *nestedMsgType.Name
135+
for _, msgfield := range nestedMsgType.Field {
136+
nfident.GoName = *msgfield.Name
137+
p.scanProtoField(nmident, nfident, msgfield)
138+
}
139+
}
140+
141+
for _, msgfield := range m.Field {
142+
fident.GoName = *msgfield.Name
143+
p.scanProtoField(mident, fident, msgfield)
144+
}
145+
}
146+
}
147+
83148
return nil
84149
}
85150

151+
func (p *Patcher) scanProtoField(mident protogen.GoIdent, fident protogen.GoIdent, f *descriptorpb.FieldDescriptorProto) {
152+
//m := f.Parent
153+
//o := f.Oneof
154+
155+
if f.TypeName == nil {
156+
log.Printf("Typename not set")
157+
return
158+
}
159+
fi, err := getExtension(f.GetOptions(), "go.field")
160+
if err != nil {
161+
log.Printf("go.field extension not found", err)
162+
return
163+
}
164+
opts := fi.(*gopb.Options)
165+
166+
log.Printf("Parent Message %v (%v), opts %v", *f.Name, *f.TypeName, opts)
167+
// Embed field ?
168+
embed := false
169+
newName := ""
170+
if opts.GetEmbed() {
171+
switch {
172+
default:
173+
embed = true
174+
log.Printf("Embed Set %v ", *f.Name, *f.TypeName)
175+
splitStrings := strings.Split((*f.TypeName)[1:], ".")
176+
newName = splitStrings[len(splitStrings)-1]
177+
}
178+
}
179+
if newName != "" {
180+
if false {
181+
p.RenameType(fident, p.nameFor(mident)+"_"+newName) // Oneof wrapper struct
182+
p.RenameField(ident.WithChild(fident, fident.GoName), newName, false) // Oneof wrapper field (not embeddable)
183+
} else {
184+
p.RenameField(ident.WithChild(mident, fident.GoName), newName, embed) // Field
185+
childID := ident.WithChild(mident, fident.GoName)
186+
log.Printf("child %v parent %v", childID, mident.GoName)
187+
}
188+
p.RenameMethod(ident.WithChild(mident, "Get"+fident.GoName), "Get"+newName) // Getter
189+
} else {
190+
p.RenameField(ident.WithChild(mident, fident.GoName), newName, embed) // Field
191+
}
192+
193+
tags := opts.GetTags()
194+
if tags != "" {
195+
log.Printf("Tags Set identifier %v %v %v", ident.WithChild(mident, fident.GoName), *f.Name, *f.TypeName, tags)
196+
p.Tag(ident.WithChild(mident, fident.GoName), tags) // Field tags
197+
}
198+
}
199+
86200
func (p *Patcher) scanFile(f *protogen.File) {
87201
log.Printf("\nScan proto:\t%s", f.Desc.Path())
88202

@@ -190,6 +304,7 @@ func (p *Patcher) scanMessage(m *protogen.Message, parent *protogen.Message) {
190304
opts := messageOptions(m)
191305
lints := fileLintOptions(m.Desc)
192306

307+
p.processedMessages[m.GoIdent] = true
193308
// Rename message?
194309
newName := opts.GetName()
195310
if newName == "" && parent != nil && p.isRenamed(parent.GoIdent) {

0 commit comments

Comments
 (0)