This repository has been archived by the owner on Jan 16, 2023. It is now read-only.
/
registry.go
147 lines (114 loc) · 2.99 KB
/
registry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package registry
import (
"log"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
)
const restmapimport = "github.com/doozer-de/restgen/pbmap"
// Messages is a map from the messages name ot the Message
type Messages []*Message
func (ms *Messages) Add(m *Message) {
for _, c := range *ms {
if c.String() == m.String() {
return
}
}
*ms = append(*ms, m)
}
func (ms *Messages) Get(key string) (*Message, bool) {
for _, c := range *ms {
if c.String() == key {
return c, true
}
}
return nil, false
}
// The Registry is the root for registering the Types found in the protobuf structures from the compiler
type Registry struct {
Files Files
Service *Service
RootFile *File
Messages Messages
Enums Enums
Package string
}
func (r *Registry) registerMessageProto(pkg string, d *descriptor.DescriptorProto) {
var fields Fields
m := &Message{
Package: pkg,
Type: d,
Registry: r,
}
for _, field := range d.GetField() {
fields = append(fields, NewField(field, m, r))
}
m.Fields = fields
r.Messages.Add(m)
}
func (r *Registry) registerEnumProto(d *descriptor.EnumDescriptorProto, f *File, index int) {
e := NewEnum(d, f, index)
r.Enums.Add(e)
}
func (r *Registry) registerServiceProto(file *File) {
svcs := file.Type.GetService()
if len(svcs) == 0 {
return
}
svc := svcs[0]
if r.Service != nil {
log.Fatal("Only one service in file supported")
}
gopkg := *file.Type.GetOptions().GoPackage
s := &Service{
Package: file.Package,
GoPackage: gopkg,
Name: svc.GetName(),
Type: svc,
Imports: []string{},
Methods: []*Method{},
Registry: r,
File: file,
}
r.Service = s
r.RootFile = s.File
ext, err := r.Service.getServiceMapExtension()
if err != nil {
return
}
r.Service.BaseURI = ext.BaseUri
r.Service.TargetPackage = ext.TargetPackage
r.Service.Version = ext.Version
for _, method := range svc.GetMethod() {
r.Service.RegisterMethod(method)
}
}
// New createsa new Registry that will read all the information neede from the given CodeGeneratorRequest
func New(r *plugin.CodeGeneratorRequest) *Registry {
reg := &Registry{
Files: []*File{},
Messages: []*Message{},
}
files := r.GetProtoFile()
// Register all Messages, Enums
for _, f := range files {
file := NewFile(f, reg)
reg.Files.Add(file)
pkg := f.GetPackage()
for _, m := range f.GetMessageType() {
reg.registerMessageProto(pkg, m)
}
for _, e := range f.GetEnumType() {
reg.registerEnumProto(e, file, 0) // TOOO(cs) find correct index
}
}
// The last file is the service file we want to generate code for (the imports come first)
rootFile := reg.Files[len(reg.Files)-1]
reg.RootFile = rootFile
reg.registerServiceProto(reg.RootFile)
return reg
}
// QueryStringParam is provides all the information nessesary for the code generation to map on query string parameter to a go field
type QueryStringParam struct {
Converter string
Field string // can also be more deep:
}