1
16
17 package value
18
19 import (
20 "encoding/base64"
21 "fmt"
22 "reflect"
23 )
24
25
26
27
28
29
30 func NewValueReflect(value interface{}) (Value, error) {
31 if value == nil {
32 return NewValueInterface(nil), nil
33 }
34 v := reflect.ValueOf(value)
35 if v.Kind() != reflect.Ptr {
36
37 return nil, fmt.Errorf("value provided to NewValueReflect must be a pointer")
38 }
39 return wrapValueReflect(v, nil, nil)
40 }
41
42
43
44 func wrapValueReflect(value reflect.Value, parentMap, parentMapKey *reflect.Value) (Value, error) {
45 val := HeapAllocator.allocValueReflect()
46 return val.reuse(value, nil, parentMap, parentMapKey)
47 }
48
49
50
51 func mustWrapValueReflect(value reflect.Value, parentMap, parentMapKey *reflect.Value) Value {
52 v, err := wrapValueReflect(value, parentMap, parentMapKey)
53 if err != nil {
54 panic(err)
55 }
56 return v
57 }
58
59
60 var nilType = reflect.TypeOf(&struct{}{})
61
62
63
64 func (r *valueReflect) reuse(value reflect.Value, cacheEntry *TypeReflectCacheEntry, parentMap, parentMapKey *reflect.Value) (Value, error) {
65 if cacheEntry == nil {
66 cacheEntry = TypeReflectEntryOf(value.Type())
67 }
68 if cacheEntry.CanConvertToUnstructured() {
69 u, err := cacheEntry.ToUnstructured(value)
70 if err != nil {
71 return nil, err
72 }
73 if u == nil {
74 value = reflect.Zero(nilType)
75 } else {
76 value = reflect.ValueOf(u)
77 }
78 }
79 r.Value = dereference(value)
80 r.ParentMap = parentMap
81 r.ParentMapKey = parentMapKey
82 r.kind = kind(r.Value)
83 return r, nil
84 }
85
86
87
88 func (r *valueReflect) mustReuse(value reflect.Value, cacheEntry *TypeReflectCacheEntry, parentMap, parentMapKey *reflect.Value) Value {
89 v, err := r.reuse(value, cacheEntry, parentMap, parentMapKey)
90 if err != nil {
91 panic(err)
92 }
93 return v
94 }
95
96 func dereference(val reflect.Value) reflect.Value {
97 kind := val.Kind()
98 if (kind == reflect.Interface || kind == reflect.Ptr) && !safeIsNil(val) {
99 return val.Elem()
100 }
101 return val
102 }
103
104 type valueReflect struct {
105 ParentMap *reflect.Value
106 ParentMapKey *reflect.Value
107 Value reflect.Value
108 kind reflectType
109 }
110
111 func (r valueReflect) IsMap() bool {
112 return r.kind == mapType || r.kind == structMapType
113 }
114
115 func (r valueReflect) IsList() bool {
116 return r.kind == listType
117 }
118
119 func (r valueReflect) IsBool() bool {
120 return r.kind == boolType
121 }
122
123 func (r valueReflect) IsInt() bool {
124 return r.kind == intType || r.kind == uintType
125 }
126
127 func (r valueReflect) IsFloat() bool {
128 return r.kind == floatType
129 }
130
131 func (r valueReflect) IsString() bool {
132 return r.kind == stringType || r.kind == byteStringType
133 }
134
135 func (r valueReflect) IsNull() bool {
136 return r.kind == nullType
137 }
138
139 type reflectType = int
140
141 const (
142 mapType = iota
143 structMapType
144 listType
145 intType
146 uintType
147 floatType
148 stringType
149 byteStringType
150 boolType
151 nullType
152 )
153
154 func kind(v reflect.Value) reflectType {
155 typ := v.Type()
156 rk := typ.Kind()
157 switch rk {
158 case reflect.Map:
159 if v.IsNil() {
160 return nullType
161 }
162 return mapType
163 case reflect.Struct:
164 return structMapType
165 case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
166 return intType
167 case reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uint8:
168
169 return uintType
170 case reflect.Float64, reflect.Float32:
171 return floatType
172 case reflect.String:
173 return stringType
174 case reflect.Bool:
175 return boolType
176 case reflect.Slice:
177 if v.IsNil() {
178 return nullType
179 }
180 elemKind := typ.Elem().Kind()
181 if elemKind == reflect.Uint8 {
182 return byteStringType
183 }
184 return listType
185 case reflect.Chan, reflect.Func, reflect.Ptr, reflect.UnsafePointer, reflect.Interface:
186 if v.IsNil() {
187 return nullType
188 }
189 panic(fmt.Sprintf("unsupported type: %v", v.Type()))
190 default:
191 panic(fmt.Sprintf("unsupported type: %v", v.Type()))
192 }
193 }
194
195
196 func safeIsNil(v reflect.Value) bool {
197 k := v.Kind()
198 switch k {
199 case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
200 return v.IsNil()
201 }
202 return false
203 }
204
205 func (r valueReflect) AsMap() Map {
206 return r.AsMapUsing(HeapAllocator)
207 }
208
209 func (r valueReflect) AsMapUsing(a Allocator) Map {
210 switch r.kind {
211 case structMapType:
212 v := a.allocStructReflect()
213 v.valueReflect = r
214 return v
215 case mapType:
216 v := a.allocMapReflect()
217 v.valueReflect = r
218 return v
219 default:
220 panic("value is not a map or struct")
221 }
222 }
223
224 func (r valueReflect) AsList() List {
225 return r.AsListUsing(HeapAllocator)
226 }
227
228 func (r valueReflect) AsListUsing(a Allocator) List {
229 if r.IsList() {
230 v := a.allocListReflect()
231 v.Value = r.Value
232 return v
233 }
234 panic("value is not a list")
235 }
236
237 func (r valueReflect) AsBool() bool {
238 if r.IsBool() {
239 return r.Value.Bool()
240 }
241 panic("value is not a bool")
242 }
243
244 func (r valueReflect) AsInt() int64 {
245 if r.kind == intType {
246 return r.Value.Int()
247 }
248 if r.kind == uintType {
249 return int64(r.Value.Uint())
250 }
251
252 panic("value is not an int")
253 }
254
255 func (r valueReflect) AsFloat() float64 {
256 if r.IsFloat() {
257 return r.Value.Float()
258 }
259 panic("value is not a float")
260 }
261
262 func (r valueReflect) AsString() string {
263 switch r.kind {
264 case stringType:
265 return r.Value.String()
266 case byteStringType:
267 return base64.StdEncoding.EncodeToString(r.Value.Bytes())
268 }
269 panic("value is not a string")
270 }
271
272 func (r valueReflect) Unstructured() interface{} {
273 val := r.Value
274 switch {
275 case r.IsNull():
276 return nil
277 case val.Kind() == reflect.Struct:
278 return structReflect{r}.Unstructured()
279 case val.Kind() == reflect.Map:
280 return mapReflect{valueReflect: r}.Unstructured()
281 case r.IsList():
282 return listReflect{r.Value}.Unstructured()
283 case r.IsString():
284 return r.AsString()
285 case r.IsInt():
286 return r.AsInt()
287 case r.IsBool():
288 return r.AsBool()
289 case r.IsFloat():
290 return r.AsFloat()
291 default:
292 panic(fmt.Sprintf("value of type %s is not a supported by value reflector", val.Type()))
293 }
294 }
295
View as plain text