-
Notifications
You must be signed in to change notification settings - Fork 282
/
parse.go
124 lines (113 loc) · 3.88 KB
/
parse.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
package main
import (
"fmt"
_struct "github.com/golang/protobuf/ptypes/struct"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/hashicorp/boundary/internal/gen/controller/protooptions"
"github.com/hashicorp/boundary/sdk/strutil"
"github.com/iancoleman/strcase"
)
func printDebug(desc protoreflect.MessageDescriptor) {
fmt.Printf("Evaluating: %q\n", desc.FullName())
fmt.Printf("Name: %q\n", strcase.ToCamel(string(desc.Name())))
fmt.Printf("ProtoName: %q\n", desc.Name())
fmt.Printf("Double Parent: %q\n", desc.FullName().Parent().Parent().Name())
fmt.Printf("Field Descriptors:\n")
for i := 0; i < desc.Fields().Len(); i++ {
fieldDesc := desc.Fields().Get(i)
fmt.Printf(" field %d: %#v\n", i, fieldDesc)
fieldDesc.Options()
}
fmt.Println()
}
func parsePBs() {
for _, in := range inputStructs {
msg := in.inProto.ProtoReflect()
desc := msg.Descriptor()
// printDebug(desc)
// Evaluate above, populate below.
in.generatedStructure.pkg = packageFromFullName(desc.FullName())
in.generatedStructure.name = string(desc.Name())
for i := 0; i < desc.Fields().Len(); i++ {
fd := desc.Fields().Get(i)
if strutil.StrListContains(in.fieldFilter, string(fd.Name())) {
continue
}
fi := fieldInfo{
Name: strcase.ToCamel(string(fd.Name())),
ProtoName: string(fd.Name()),
}
// Adjust for slices
sliceText := ""
if fd.Cardinality() == protoreflect.Repeated {
sliceText = "[]"
}
// Add generate option info
opts := fd.Options().(*descriptorpb.FieldOptions)
if proto.GetExtension(opts, protooptions.E_GenerateSdkOption).(bool) {
fi.GenerateSdkOption = true
}
switch k := fd.Kind(); k {
case protoreflect.MessageKind:
ptr, pkg, name := messageKind(fd)
if pkg != "" && pkg != in.generatedStructure.pkg {
name = fmt.Sprintf("%s.%s", pkg, name)
}
switch name {
case "v1.AuthorizedCollectionActionsEntry":
fi.FieldType = "map[string][]string"
default:
fi.FieldType = sliceText + ptr + name
}
case protoreflect.BytesKind:
fi.FieldType = "[]byte"
default:
fi.FieldType = sliceText + k.String()
}
in.generatedStructure.fields = append(in.generatedStructure.fields, fi)
}
// fmt.Printf("Parsed: %#v\n", in.generatedStructure)
}
}
func packageFromFullName(fullName protoreflect.FullName) string {
// Example full name: controller.api.resources.groups.v1.Group
// Crawling up the parent twice jumps back past v1.Group placing us at "groups".
pkgName := fullName.Parent().Parent().Name()
if pkgName.IsValid() {
return string(pkgName)
}
return ""
}
var (
stringValueName = (&wrapperspb.StringValue{}).ProtoReflect().Descriptor().FullName()
boolValueName = (&wrapperspb.BoolValue{}).ProtoReflect().Descriptor().FullName()
uInt32ValueName = (&wrapperspb.UInt32Value{}).ProtoReflect().Descriptor().FullName()
int32ValueName = (&wrapperspb.Int32Value{}).ProtoReflect().Descriptor().FullName()
structValueName = (&_struct.Struct{}).ProtoReflect().Descriptor().FullName()
timestampName = (×tamppb.Timestamp{}).ProtoReflect().Descriptor().FullName()
valueName = (&_struct.Value{}).ProtoReflect().Descriptor().FullName()
)
func messageKind(fd protoreflect.FieldDescriptor) (ptr, pkg, name string) {
switch fd.Message().FullName() {
case stringValueName:
return "", "", "string"
case boolValueName:
return "", "", "bool"
case uInt32ValueName:
return "", "", "uint32"
case int32ValueName:
return "", "", "int32"
case structValueName:
return "", "", "map[string]interface{}"
case valueName:
return "", "", "interface{}"
case timestampName:
return "", "time", "Time"
default:
return "*", packageFromFullName(fd.Message().FullName()), string(fd.Message().Name())
}
}