1package 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{}) { 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.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 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} 338