diff options
Diffstat (limited to 'vendor/github.com/json-iterator/go/reflect.go')
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect.go | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go new file mode 100644 index 0000000..39acb32 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect.go | |||
@@ -0,0 +1,337 @@ | |||
1 | package jsoniter | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "reflect" | ||
6 | "unsafe" | ||
7 | |||
8 | "github.com/modern-go/reflect2" | ||
9 | ) | ||
10 | |||
11 | // ValDecoder is an internal type registered to cache as needed. | ||
12 | // Don't confuse jsoniter.ValDecoder with json.Decoder. | ||
13 | // For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). | ||
14 | // | ||
15 | // Reflection on type to create decoders, which is then cached | ||
16 | // Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions | ||
17 | // 1. create instance of new value, for example *int will need a int to be allocated | ||
18 | // 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New | ||
19 | // 3. assignment to map, both key and value will be reflect.Value | ||
20 | // For a simple struct binding, it will be reflect.Value free and allocation free | ||
21 | type ValDecoder interface { | ||
22 | Decode(ptr unsafe.Pointer, iter *Iterator) | ||
23 | } | ||
24 | |||
25 | // ValEncoder is an internal type registered to cache as needed. | ||
26 | // Don't confuse jsoniter.ValEncoder with json.Encoder. | ||
27 | // For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). | ||
28 | type ValEncoder interface { | ||
29 | IsEmpty(ptr unsafe.Pointer) bool | ||
30 | Encode(ptr unsafe.Pointer, stream *Stream) | ||
31 | } | ||
32 | |||
33 | type checkIsEmpty interface { | ||
34 | IsEmpty(ptr unsafe.Pointer) bool | ||
35 | } | ||
36 | |||
37 | type ctx struct { | ||
38 | *frozenConfig | ||
39 | prefix string | ||
40 | encoders map[reflect2.Type]ValEncoder | ||
41 | decoders map[reflect2.Type]ValDecoder | ||
42 | } | ||
43 | |||
44 | func (b *ctx) caseSensitive() bool { | ||
45 | if b.frozenConfig == nil { | ||
46 | // default is case-insensitive | ||
47 | return false | ||
48 | } | ||
49 | return b.frozenConfig.caseSensitive | ||
50 | } | ||
51 | |||
52 | func (b *ctx) append(prefix string) *ctx { | ||
53 | return &ctx{ | ||
54 | frozenConfig: b.frozenConfig, | ||
55 | prefix: b.prefix + " " + prefix, | ||
56 | encoders: b.encoders, | ||
57 | decoders: b.decoders, | ||
58 | } | ||
59 | } | ||
60 | |||
61 | // ReadVal copy the underlying JSON into go interface, same as json.Unmarshal | ||
62 | func (iter *Iterator) ReadVal(obj interface{}) { | ||
63 | depth := iter.depth | ||
64 | cacheKey := reflect2.RTypeOf(obj) | ||
65 | decoder := iter.cfg.getDecoderFromCache(cacheKey) | ||
66 | if decoder == nil { | ||
67 | typ := reflect2.TypeOf(obj) | ||
68 | if typ == nil || typ.Kind() != reflect.Ptr { | ||
69 | iter.ReportError("ReadVal", "can only unmarshal into pointer") | ||
70 | return | ||
71 | } | ||
72 | decoder = iter.cfg.DecoderOf(typ) | ||
73 | } | ||
74 | ptr := reflect2.PtrOf(obj) | ||
75 | if ptr == nil { | ||
76 | iter.ReportError("ReadVal", "can not read into nil pointer") | ||
77 | return | ||
78 | } | ||
79 | decoder.Decode(ptr, iter) | ||
80 | if iter.depth != depth { | ||
81 | iter.ReportError("ReadVal", "unexpected mismatched nesting") | ||
82 | return | ||
83 | } | ||
84 | } | ||
85 | |||
86 | // WriteVal copy the go interface into underlying JSON, same as json.Marshal | ||
87 | func (stream *Stream) WriteVal(val interface{}) { | ||
88 | if nil == val { | ||
89 | stream.WriteNil() | ||
90 | return | ||
91 | } | ||
92 | cacheKey := reflect2.RTypeOf(val) | ||
93 | encoder := stream.cfg.getEncoderFromCache(cacheKey) | ||
94 | if encoder == nil { | ||
95 | typ := reflect2.TypeOf(val) | ||
96 | encoder = stream.cfg.EncoderOf(typ) | ||
97 | } | ||
98 | encoder.Encode(reflect2.PtrOf(val), stream) | ||
99 | } | ||
100 | |||
101 | func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { | ||
102 | cacheKey := typ.RType() | ||
103 | decoder := cfg.getDecoderFromCache(cacheKey) | ||
104 | if decoder != nil { | ||
105 | return decoder | ||
106 | } | ||
107 | ctx := &ctx{ | ||
108 | frozenConfig: cfg, | ||
109 | prefix: "", | ||
110 | decoders: map[reflect2.Type]ValDecoder{}, | ||
111 | encoders: map[reflect2.Type]ValEncoder{}, | ||
112 | } | ||
113 | ptrType := typ.(*reflect2.UnsafePtrType) | ||
114 | decoder = decoderOfType(ctx, ptrType.Elem()) | ||
115 | cfg.addDecoderToCache(cacheKey, decoder) | ||
116 | return decoder | ||
117 | } | ||
118 | |||
119 | func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { | ||
120 | decoder := getTypeDecoderFromExtension(ctx, typ) | ||
121 | if decoder != nil { | ||
122 | return decoder | ||
123 | } | ||
124 | decoder = createDecoderOfType(ctx, typ) | ||
125 | for _, extension := range extensions { | ||
126 | decoder = extension.DecorateDecoder(typ, decoder) | ||
127 | } | ||
128 | decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) | ||
129 | for _, extension := range ctx.extraExtensions { | ||
130 | decoder = extension.DecorateDecoder(typ, decoder) | ||
131 | } | ||
132 | return decoder | ||
133 | } | ||
134 | |||
135 | func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { | ||
136 | decoder := ctx.decoders[typ] | ||
137 | if decoder != nil { | ||
138 | return decoder | ||
139 | } | ||
140 | placeholder := &placeholderDecoder{} | ||
141 | ctx.decoders[typ] = placeholder | ||
142 | decoder = _createDecoderOfType(ctx, typ) | ||
143 | placeholder.decoder = decoder | ||
144 | return decoder | ||
145 | } | ||
146 | |||
147 | func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { | ||
148 | decoder := createDecoderOfJsonRawMessage(ctx, typ) | ||
149 | if decoder != nil { | ||
150 | return decoder | ||
151 | } | ||
152 | decoder = createDecoderOfJsonNumber(ctx, typ) | ||
153 | if decoder != nil { | ||
154 | return decoder | ||
155 | } | ||
156 | decoder = createDecoderOfMarshaler(ctx, typ) | ||
157 | if decoder != nil { | ||
158 | return decoder | ||
159 | } | ||
160 | decoder = createDecoderOfAny(ctx, typ) | ||
161 | if decoder != nil { | ||
162 | return decoder | ||
163 | } | ||
164 | decoder = createDecoderOfNative(ctx, typ) | ||
165 | if decoder != nil { | ||
166 | return decoder | ||
167 | } | ||
168 | switch typ.Kind() { | ||
169 | case reflect.Interface: | ||
170 | ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) | ||
171 | if isIFace { | ||
172 | return &ifaceDecoder{valType: ifaceType} | ||
173 | } | ||
174 | return &efaceDecoder{} | ||
175 | case reflect.Struct: | ||
176 | return decoderOfStruct(ctx, typ) | ||
177 | case reflect.Array: | ||
178 | return decoderOfArray(ctx, typ) | ||
179 | case reflect.Slice: | ||
180 | return decoderOfSlice(ctx, typ) | ||
181 | case reflect.Map: | ||
182 | return decoderOfMap(ctx, typ) | ||
183 | case reflect.Ptr: | ||
184 | return decoderOfOptional(ctx, typ) | ||
185 | default: | ||
186 | return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} | ||
187 | } | ||
188 | } | ||
189 | |||
190 | func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { | ||
191 | cacheKey := typ.RType() | ||
192 | encoder := cfg.getEncoderFromCache(cacheKey) | ||
193 | if encoder != nil { | ||
194 | return encoder | ||
195 | } | ||
196 | ctx := &ctx{ | ||
197 | frozenConfig: cfg, | ||
198 | prefix: "", | ||
199 | decoders: map[reflect2.Type]ValDecoder{}, | ||
200 | encoders: map[reflect2.Type]ValEncoder{}, | ||
201 | } | ||
202 | encoder = encoderOfType(ctx, typ) | ||
203 | if typ.LikePtr() { | ||
204 | encoder = &onePtrEncoder{encoder} | ||
205 | } | ||
206 | cfg.addEncoderToCache(cacheKey, encoder) | ||
207 | return encoder | ||
208 | } | ||
209 | |||
210 | type onePtrEncoder struct { | ||
211 | encoder ValEncoder | ||
212 | } | ||
213 | |||
214 | func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||
215 | return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) | ||
216 | } | ||
217 | |||
218 | func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||
219 | encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) | ||
220 | } | ||
221 | |||
222 | func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { | ||
223 | encoder := getTypeEncoderFromExtension(ctx, typ) | ||
224 | if encoder != nil { | ||
225 | return encoder | ||
226 | } | ||
227 | encoder = createEncoderOfType(ctx, typ) | ||
228 | for _, extension := range extensions { | ||
229 | encoder = extension.DecorateEncoder(typ, encoder) | ||
230 | } | ||
231 | encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) | ||
232 | for _, extension := range ctx.extraExtensions { | ||
233 | encoder = extension.DecorateEncoder(typ, encoder) | ||
234 | } | ||
235 | return encoder | ||
236 | } | ||
237 | |||
238 | func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { | ||
239 | encoder := ctx.encoders[typ] | ||
240 | if encoder != nil { | ||
241 | return encoder | ||
242 | } | ||
243 | placeholder := &placeholderEncoder{} | ||
244 | ctx.encoders[typ] = placeholder | ||
245 | encoder = _createEncoderOfType(ctx, typ) | ||
246 | placeholder.encoder = encoder | ||
247 | return encoder | ||
248 | } | ||
249 | func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { | ||
250 | encoder := createEncoderOfJsonRawMessage(ctx, typ) | ||
251 | if encoder != nil { | ||
252 | return encoder | ||
253 | } | ||
254 | encoder = createEncoderOfJsonNumber(ctx, typ) | ||
255 | if encoder != nil { | ||
256 | return encoder | ||
257 | } | ||
258 | encoder = createEncoderOfMarshaler(ctx, typ) | ||
259 | if encoder != nil { | ||
260 | return encoder | ||
261 | } | ||
262 | encoder = createEncoderOfAny(ctx, typ) | ||
263 | if encoder != nil { | ||
264 | return encoder | ||
265 | } | ||
266 | encoder = createEncoderOfNative(ctx, typ) | ||
267 | if encoder != nil { | ||
268 | return encoder | ||
269 | } | ||
270 | kind := typ.Kind() | ||
271 | switch kind { | ||
272 | case reflect.Interface: | ||
273 | return &dynamicEncoder{typ} | ||
274 | case reflect.Struct: | ||
275 | return encoderOfStruct(ctx, typ) | ||
276 | case reflect.Array: | ||
277 | return encoderOfArray(ctx, typ) | ||
278 | case reflect.Slice: | ||
279 | return encoderOfSlice(ctx, typ) | ||
280 | case reflect.Map: | ||
281 | return encoderOfMap(ctx, typ) | ||
282 | case reflect.Ptr: | ||
283 | return encoderOfOptional(ctx, typ) | ||
284 | default: | ||
285 | return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} | ||
286 | } | ||
287 | } | ||
288 | |||
289 | type lazyErrorDecoder struct { | ||
290 | err error | ||
291 | } | ||
292 | |||
293 | func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { | ||
294 | if iter.WhatIsNext() != NilValue { | ||
295 | if iter.Error == nil { | ||
296 | iter.Error = decoder.err | ||
297 | } | ||
298 | } else { | ||
299 | iter.Skip() | ||
300 | } | ||
301 | } | ||
302 | |||
303 | type lazyErrorEncoder struct { | ||
304 | err error | ||
305 | } | ||
306 | |||
307 | func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||
308 | if ptr == nil { | ||
309 | stream.WriteNil() | ||
310 | } else if stream.Error == nil { | ||
311 | stream.Error = encoder.err | ||
312 | } | ||
313 | } | ||
314 | |||
315 | func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||
316 | return false | ||
317 | } | ||
318 | |||
319 | type placeholderDecoder struct { | ||
320 | decoder ValDecoder | ||
321 | } | ||
322 | |||
323 | func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { | ||
324 | decoder.decoder.Decode(ptr, iter) | ||
325 | } | ||
326 | |||
327 | type placeholderEncoder struct { | ||
328 | encoder ValEncoder | ||
329 | } | ||
330 | |||
331 | func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||
332 | encoder.encoder.Encode(ptr, stream) | ||
333 | } | ||
334 | |||
335 | func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||
336 | return encoder.encoder.IsEmpty(ptr) | ||
337 | } | ||