-
Notifications
You must be signed in to change notification settings - Fork 15
/
generator.go
108 lines (90 loc) · 2.27 KB
/
generator.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
package main
import (
"fmt"
"regexp"
"sort"
"strings"
"google.golang.org/protobuf/compiler/protogen"
"google.golang.org/protobuf/reflect/protoreflect"
)
var toCamelCaseRe = regexp.MustCompile(`(^[A-Za-z])|(_|\.)([A-Za-z])`)
func toCamelCase(str string) string {
return toCamelCaseRe.ReplaceAllStringFunc(str, func(s string) string {
return strings.ToUpper(strings.Replace(s, "_", "", -1))
})
}
type pathParam struct {
Index int
Name string
GoName string
}
func (t *pathParam) GetSplitedGoNames() []string {
names := make([]string, 0)
ps := strings.Split(t.GoName, ".")
for i := range ps {
if i == 0 {
continue
}
names = append(names, strings.Join(ps[0:i], "."))
}
return names
}
func parsePathParam(pattern string) ([]*pathParam, error) {
if !strings.HasPrefix(pattern, "/") {
return nil, fmt.Errorf("no leading /")
}
tokens, _ := tokenize(pattern[1:])
p := parser{tokens: tokens}
segs, err := p.topLevelSegments()
if err != nil {
return nil, err
}
params := make([]*pathParam, 0)
for i, seg := range segs {
if v, ok := seg.(variable); ok {
params = append(params, &pathParam{
Index: i + 1,
Name: v.path,
GoName: toCamelCase(v.path),
})
}
}
sort.Slice(params, func(i, j int) bool {
a := params[i]
b := params[j]
if len(strings.Split(a.Name, ".")) < len(strings.Split(b.Name, ".")) {
return true
}
return params[i].Name < params[j].Name
})
return params, nil
}
type queryParam struct {
*protogen.Field
GoName string
Name string
}
func createQueryParams(method *protogen.Method) []*queryParam {
queryParams := make([]*queryParam, 0)
var f func(parent *queryParam, fields []*protogen.Field)
f = func(parent *queryParam, fields []*protogen.Field) {
for _, field := range fields {
if field.Desc.Kind() == protoreflect.MessageKind {
q := &queryParam{
Field: field,
GoName: fmt.Sprintf("%s.", field.GoName),
Name: fmt.Sprintf("%s.", field.Desc.Name()),
}
f(q, field.Message.Fields)
continue
}
queryParams = append(queryParams, &queryParam{
Field: field,
GoName: fmt.Sprintf("%s%s", parent.GoName, field.GoName),
Name: fmt.Sprintf("%s%s", parent.Name, field.Desc.Name()),
})
}
}
f(&queryParam{GoName: "", Name: ""}, method.Input.Fields)
return queryParams
}