Scott Baker | e7144bc | 2019-10-01 14:16:47 -0700 | [diff] [blame^] | 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 | cacheKey := reflect2.RTypeOf(obj) |
| 64 | decoder := iter.cfg.getDecoderFromCache(cacheKey) |
| 65 | if decoder == nil { |
| 66 | typ := reflect2.TypeOf(obj) |
| 67 | if typ.Kind() != reflect.Ptr { |
| 68 | iter.ReportError("ReadVal", "can only unmarshal into pointer") |
| 69 | return |
| 70 | } |
| 71 | decoder = iter.cfg.DecoderOf(typ) |
| 72 | } |
| 73 | ptr := reflect2.PtrOf(obj) |
| 74 | if ptr == nil { |
| 75 | iter.ReportError("ReadVal", "can not read into nil pointer") |
| 76 | return |
| 77 | } |
| 78 | decoder.Decode(ptr, iter) |
| 79 | } |
| 80 | |
| 81 | // WriteVal copy the go interface into underlying JSON, same as json.Marshal |
| 82 | func (stream *Stream) WriteVal(val interface{}) { |
| 83 | if nil == val { |
| 84 | stream.WriteNil() |
| 85 | return |
| 86 | } |
| 87 | cacheKey := reflect2.RTypeOf(val) |
| 88 | encoder := stream.cfg.getEncoderFromCache(cacheKey) |
| 89 | if encoder == nil { |
| 90 | typ := reflect2.TypeOf(val) |
| 91 | encoder = stream.cfg.EncoderOf(typ) |
| 92 | } |
| 93 | encoder.Encode(reflect2.PtrOf(val), stream) |
| 94 | } |
| 95 | |
| 96 | func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { |
| 97 | cacheKey := typ.RType() |
| 98 | decoder := cfg.getDecoderFromCache(cacheKey) |
| 99 | if decoder != nil { |
| 100 | return decoder |
| 101 | } |
| 102 | ctx := &ctx{ |
| 103 | frozenConfig: cfg, |
| 104 | prefix: "", |
| 105 | decoders: map[reflect2.Type]ValDecoder{}, |
| 106 | encoders: map[reflect2.Type]ValEncoder{}, |
| 107 | } |
| 108 | ptrType := typ.(*reflect2.UnsafePtrType) |
| 109 | decoder = decoderOfType(ctx, ptrType.Elem()) |
| 110 | cfg.addDecoderToCache(cacheKey, decoder) |
| 111 | return decoder |
| 112 | } |
| 113 | |
| 114 | func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { |
| 115 | decoder := getTypeDecoderFromExtension(ctx, typ) |
| 116 | if decoder != nil { |
| 117 | return decoder |
| 118 | } |
| 119 | decoder = createDecoderOfType(ctx, typ) |
| 120 | for _, extension := range extensions { |
| 121 | decoder = extension.DecorateDecoder(typ, decoder) |
| 122 | } |
| 123 | decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) |
| 124 | for _, extension := range ctx.extraExtensions { |
| 125 | decoder = extension.DecorateDecoder(typ, decoder) |
| 126 | } |
| 127 | return decoder |
| 128 | } |
| 129 | |
| 130 | func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { |
| 131 | decoder := ctx.decoders[typ] |
| 132 | if decoder != nil { |
| 133 | return decoder |
| 134 | } |
| 135 | placeholder := &placeholderDecoder{} |
| 136 | ctx.decoders[typ] = placeholder |
| 137 | decoder = _createDecoderOfType(ctx, typ) |
| 138 | placeholder.decoder = decoder |
| 139 | return decoder |
| 140 | } |
| 141 | |
| 142 | func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { |
| 143 | decoder := createDecoderOfJsonRawMessage(ctx, typ) |
| 144 | if decoder != nil { |
| 145 | return decoder |
| 146 | } |
| 147 | decoder = createDecoderOfJsonNumber(ctx, typ) |
| 148 | if decoder != nil { |
| 149 | return decoder |
| 150 | } |
| 151 | decoder = createDecoderOfMarshaler(ctx, typ) |
| 152 | if decoder != nil { |
| 153 | return decoder |
| 154 | } |
| 155 | decoder = createDecoderOfAny(ctx, typ) |
| 156 | if decoder != nil { |
| 157 | return decoder |
| 158 | } |
| 159 | decoder = createDecoderOfNative(ctx, typ) |
| 160 | if decoder != nil { |
| 161 | return decoder |
| 162 | } |
| 163 | switch typ.Kind() { |
| 164 | case reflect.Interface: |
| 165 | ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) |
| 166 | if isIFace { |
| 167 | return &ifaceDecoder{valType: ifaceType} |
| 168 | } |
| 169 | return &efaceDecoder{} |
| 170 | case reflect.Struct: |
| 171 | return decoderOfStruct(ctx, typ) |
| 172 | case reflect.Array: |
| 173 | return decoderOfArray(ctx, typ) |
| 174 | case reflect.Slice: |
| 175 | return decoderOfSlice(ctx, typ) |
| 176 | case reflect.Map: |
| 177 | return decoderOfMap(ctx, typ) |
| 178 | case reflect.Ptr: |
| 179 | return decoderOfOptional(ctx, typ) |
| 180 | default: |
| 181 | return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { |
| 186 | cacheKey := typ.RType() |
| 187 | encoder := cfg.getEncoderFromCache(cacheKey) |
| 188 | if encoder != nil { |
| 189 | return encoder |
| 190 | } |
| 191 | ctx := &ctx{ |
| 192 | frozenConfig: cfg, |
| 193 | prefix: "", |
| 194 | decoders: map[reflect2.Type]ValDecoder{}, |
| 195 | encoders: map[reflect2.Type]ValEncoder{}, |
| 196 | } |
| 197 | encoder = encoderOfType(ctx, typ) |
| 198 | if typ.LikePtr() { |
| 199 | encoder = &onePtrEncoder{encoder} |
| 200 | } |
| 201 | cfg.addEncoderToCache(cacheKey, encoder) |
| 202 | return encoder |
| 203 | } |
| 204 | |
| 205 | type onePtrEncoder struct { |
| 206 | encoder ValEncoder |
| 207 | } |
| 208 | |
| 209 | func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { |
| 210 | return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) |
| 211 | } |
| 212 | |
| 213 | func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { |
| 214 | encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) |
| 215 | } |
| 216 | |
| 217 | func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { |
| 218 | encoder := getTypeEncoderFromExtension(ctx, typ) |
| 219 | if encoder != nil { |
| 220 | return encoder |
| 221 | } |
| 222 | encoder = createEncoderOfType(ctx, typ) |
| 223 | for _, extension := range extensions { |
| 224 | encoder = extension.DecorateEncoder(typ, encoder) |
| 225 | } |
| 226 | encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) |
| 227 | for _, extension := range ctx.extraExtensions { |
| 228 | encoder = extension.DecorateEncoder(typ, encoder) |
| 229 | } |
| 230 | return encoder |
| 231 | } |
| 232 | |
| 233 | func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { |
| 234 | encoder := ctx.encoders[typ] |
| 235 | if encoder != nil { |
| 236 | return encoder |
| 237 | } |
| 238 | placeholder := &placeholderEncoder{} |
| 239 | ctx.encoders[typ] = placeholder |
| 240 | encoder = _createEncoderOfType(ctx, typ) |
| 241 | placeholder.encoder = encoder |
| 242 | return encoder |
| 243 | } |
| 244 | func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { |
| 245 | encoder := createEncoderOfJsonRawMessage(ctx, typ) |
| 246 | if encoder != nil { |
| 247 | return encoder |
| 248 | } |
| 249 | encoder = createEncoderOfJsonNumber(ctx, typ) |
| 250 | if encoder != nil { |
| 251 | return encoder |
| 252 | } |
| 253 | encoder = createEncoderOfMarshaler(ctx, typ) |
| 254 | if encoder != nil { |
| 255 | return encoder |
| 256 | } |
| 257 | encoder = createEncoderOfAny(ctx, typ) |
| 258 | if encoder != nil { |
| 259 | return encoder |
| 260 | } |
| 261 | encoder = createEncoderOfNative(ctx, typ) |
| 262 | if encoder != nil { |
| 263 | return encoder |
| 264 | } |
| 265 | kind := typ.Kind() |
| 266 | switch kind { |
| 267 | case reflect.Interface: |
| 268 | return &dynamicEncoder{typ} |
| 269 | case reflect.Struct: |
| 270 | return encoderOfStruct(ctx, typ) |
| 271 | case reflect.Array: |
| 272 | return encoderOfArray(ctx, typ) |
| 273 | case reflect.Slice: |
| 274 | return encoderOfSlice(ctx, typ) |
| 275 | case reflect.Map: |
| 276 | return encoderOfMap(ctx, typ) |
| 277 | case reflect.Ptr: |
| 278 | return encoderOfOptional(ctx, typ) |
| 279 | default: |
| 280 | return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | type lazyErrorDecoder struct { |
| 285 | err error |
| 286 | } |
| 287 | |
| 288 | func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { |
| 289 | if iter.WhatIsNext() != NilValue { |
| 290 | if iter.Error == nil { |
| 291 | iter.Error = decoder.err |
| 292 | } |
| 293 | } else { |
| 294 | iter.Skip() |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | type lazyErrorEncoder struct { |
| 299 | err error |
| 300 | } |
| 301 | |
| 302 | func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { |
| 303 | if ptr == nil { |
| 304 | stream.WriteNil() |
| 305 | } else if stream.Error == nil { |
| 306 | stream.Error = encoder.err |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { |
| 311 | return false |
| 312 | } |
| 313 | |
| 314 | type placeholderDecoder struct { |
| 315 | decoder ValDecoder |
| 316 | } |
| 317 | |
| 318 | func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { |
| 319 | decoder.decoder.Decode(ptr, iter) |
| 320 | } |
| 321 | |
| 322 | type placeholderEncoder struct { |
| 323 | encoder ValEncoder |
| 324 | } |
| 325 | |
| 326 | func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { |
| 327 | encoder.encoder.Encode(ptr, stream) |
| 328 | } |
| 329 | |
| 330 | func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { |
| 331 | return encoder.encoder.IsEmpty(ptr) |
| 332 | } |