...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package pbinternal
16
17 import (
18 "strings"
19 "unicode"
20 "unicode/utf8"
21
22 "cuelang.org/go/cue"
23 )
24
25 type CompositeType int
26
27 const (
28 Normal CompositeType = iota
29 List
30 Map
31 )
32
33 type ValueType int
34
35 const (
36 Unknown ValueType = iota
37 Message
38 Int
39 Float
40 String
41 Bytes
42 Bool
43 )
44
45 type Info struct {
46 Name string
47 CUEName string
48 Attr cue.Attribute
49 Value cue.Value
50
51 CompositeType CompositeType
52 ValueType ValueType
53 Type string
54
55 IsEnum bool
56
57
58 KeyType ValueType
59 KeyTypeString string
60 }
61
62 func FromIter(i *cue.Iterator) (info Info, err error) {
63 return FromValue(i.Label(), i.Value())
64 }
65
66 func FromValue(name string, v cue.Value) (info Info, err error) {
67 a := v.Attribute("protobuf")
68
69 info.Name = name
70 info.CUEName = name
71
72 if a.Err() == nil {
73 info.Attr = a
74
75 s, ok, err := a.Lookup(1, "name")
76 if err != nil {
77 return info, err
78 }
79 if ok {
80 info.Name = strings.TrimSpace(s)
81 }
82
83 info.Type, err = a.String(1)
84 if err != nil {
85 return info, err
86 }
87 }
88
89 switch v.IncompleteKind() {
90 case cue.ListKind:
91 info.CompositeType = List
92 e, _ := v.Elem()
93 if e.Exists() {
94 v = e
95 } else {
96 for i, _ := v.List(); i.Next(); {
97 v = i.Value()
98 break
99 }
100 }
101
102 case cue.StructKind:
103 if strings.HasPrefix(info.Type, "map[") {
104 a := strings.SplitN(info.Type[len("map["):], "]", 2)
105 info.KeyTypeString = strings.TrimSpace(a[0])
106 switch info.KeyTypeString {
107 case "string":
108 info.KeyType = String
109 case "bytes":
110 info.KeyType = Bytes
111 case "double", "float":
112 info.KeyType = Float
113 case "bool":
114 info.KeyType = Bool
115 default:
116 info.KeyType = Int
117 }
118 info.CompositeType = Map
119 v, _ = v.Elem()
120 }
121 }
122
123 info.Value = v
124
125 switch v.IncompleteKind() {
126 case cue.StructKind:
127 info.ValueType = Message
128
129 case cue.StringKind:
130 info.ValueType = String
131
132 case cue.BytesKind:
133 info.ValueType = Bytes
134
135 case cue.BoolKind:
136 info.ValueType = Bool
137
138 case cue.IntKind:
139 info.ValueType = Int
140 r, _ := utf8.DecodeRuneInString(info.Type)
141 info.IsEnum = unicode.In(r, unicode.Upper)
142
143 case cue.FloatKind, cue.NumberKind:
144 info.ValueType = Float
145 }
146
147 return info, nil
148 }
149
View as plain text