blob: 39acb320ace720d5051e5178e655bafc0710b173 [file] [log] [blame]
khenaidooab1f7bd2019-11-14 14:00:27 -05001package jsoniter
2
3import (
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
21type 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).
28type ValEncoder interface {
29 IsEmpty(ptr unsafe.Pointer) bool
30 Encode(ptr unsafe.Pointer, stream *Stream)
31}
32
33type checkIsEmpty interface {
34 IsEmpty(ptr unsafe.Pointer) bool
35}
36
37type ctx struct {
38 *frozenConfig
39 prefix string
40 encoders map[reflect2.Type]ValEncoder
41 decoders map[reflect2.Type]ValDecoder
42}
43
44func (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
52func (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
62func (iter *Iterator) ReadVal(obj interface{}) {
khenaidood948f772021-08-11 17:49:24 -040063 depth := iter.depth
khenaidooab1f7bd2019-11-14 14:00:27 -050064 cacheKey := reflect2.RTypeOf(obj)
65 decoder := iter.cfg.getDecoderFromCache(cacheKey)
66 if decoder == nil {
67 typ := reflect2.TypeOf(obj)
khenaidood948f772021-08-11 17:49:24 -040068 if typ == nil || typ.Kind() != reflect.Ptr {
khenaidooab1f7bd2019-11-14 14:00:27 -050069 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)
khenaidood948f772021-08-11 17:49:24 -040080 if iter.depth != depth {
81 iter.ReportError("ReadVal", "unexpected mismatched nesting")
82 return
83 }
khenaidooab1f7bd2019-11-14 14:00:27 -050084}
85
86// WriteVal copy the go interface into underlying JSON, same as json.Marshal
87func (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
101func (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
119func 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
135func 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
147func _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
190func (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
210type onePtrEncoder struct {
211 encoder ValEncoder
212}
213
214func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool {
215 return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
216}
217
218func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
219 encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
220}
221
222func 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
238func 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}
249func _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
289type lazyErrorDecoder struct {
290 err error
291}
292
293func (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
303type lazyErrorEncoder struct {
304 err error
305}
306
307func (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
315func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool {
316 return false
317}
318
319type placeholderDecoder struct {
320 decoder ValDecoder
321}
322
323func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
324 decoder.decoder.Decode(ptr, iter)
325}
326
327type placeholderEncoder struct {
328 encoder ValEncoder
329}
330
331func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
332 encoder.encoder.Encode(ptr, stream)
333}
334
335func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
336 return encoder.encoder.IsEmpty(ptr)
337}