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  }