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