github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/reflect_extension.go (about)

     1  package jsoni
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  	"sort"
     8  	"strings"
     9  	"unicode"
    10  	"unsafe"
    11  
    12  	"github.com/modern-go/reflect2"
    13  )
    14  
    15  type Extensions []Extension
    16  
    17  func (es Extensions) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
    18  	for _, extension := range es {
    19  		extension.UpdateStructDescriptor(structDescriptor)
    20  	}
    21  }
    22  
    23  func (es Extensions) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
    24  	for _, extension := range es {
    25  		if v := extension.CreateMapKeyEncoder(typ); v != nil {
    26  			return v
    27  		}
    28  	}
    29  	return nil
    30  }
    31  
    32  func (es Extensions) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
    33  	for _, extension := range es {
    34  		if v := extension.CreateMapKeyDecoder(typ); v != nil {
    35  			return v
    36  		}
    37  	}
    38  	return nil
    39  }
    40  
    41  func (es Extensions) createEncoder(typ reflect2.Type) ValEncoder {
    42  	for _, extension := range es {
    43  		if e := extension.CreateEncoder(typ); e != nil {
    44  			return e
    45  		}
    46  	}
    47  	return nil
    48  }
    49  
    50  func (es Extensions) createDecoder(typ reflect2.Type) ValDecoder {
    51  	for _, extension := range es {
    52  		if d := extension.CreateDecoder(typ); d != nil {
    53  			return d
    54  		}
    55  	}
    56  	return nil
    57  }
    58  
    59  func (es Extensions) decorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
    60  	for _, extension := range es {
    61  		encoder = extension.DecorateEncoder(typ, encoder)
    62  	}
    63  	return encoder
    64  }
    65  
    66  func (es Extensions) decorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
    67  	for _, extension := range es {
    68  		decoder = extension.DecorateDecoder(typ, decoder)
    69  	}
    70  	return decoder
    71  }
    72  
    73  // StructDescriptor describe how should we encode/decode the struct
    74  type StructDescriptor struct {
    75  	Type   reflect2.Type
    76  	Fields []*Binding
    77  }
    78  
    79  // GetField get one field from the descriptor by its name.
    80  // Can not use map here to keep field orders.
    81  func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
    82  	for _, binding := range structDescriptor.Fields {
    83  		if binding.Field.Name() == fieldName {
    84  			return binding
    85  		}
    86  	}
    87  	return nil
    88  }
    89  
    90  // Binding describe how should we encode/decode the struct field
    91  type Binding struct {
    92  	levels    []int
    93  	Field     reflect2.StructField
    94  	FromNames []string
    95  	ToNames   []string
    96  	Encoder   ValEncoder
    97  	Decoder   ValDecoder
    98  }
    99  
   100  // Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder.
   101  // Can also rename fields by UpdateStructDescriptor.
   102  
   103  type Extension interface {
   104  	UpdateStructDescriptor(structDescriptor *StructDescriptor)
   105  	CreateMapKeyDecoder(typ reflect2.Type) ValDecoder
   106  	CreateMapKeyEncoder(typ reflect2.Type) ValEncoder
   107  	CreateDecoder(typ reflect2.Type) ValDecoder
   108  	CreateEncoder(typ reflect2.Type) ValEncoder
   109  
   110  	DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
   111  	DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder
   112  }
   113  
   114  // DummyExtension embed this type get dummy implementation for all methods of Extension
   115  type DummyExtension struct{}
   116  
   117  // UpdateStructDescriptor No-op
   118  func (e *DummyExtension) UpdateStructDescriptor(*StructDescriptor) {}
   119  
   120  // CreateMapKeyDecoder No-op
   121  func (e *DummyExtension) CreateMapKeyDecoder(reflect2.Type) ValDecoder { return nil }
   122  
   123  // CreateMapKeyEncoder No-op
   124  func (e *DummyExtension) CreateMapKeyEncoder(reflect2.Type) ValEncoder { return nil }
   125  
   126  // CreateDecoder No-op
   127  func (e *DummyExtension) CreateDecoder(reflect2.Type) ValDecoder { return nil }
   128  
   129  // CreateEncoder No-op
   130  func (e *DummyExtension) CreateEncoder(reflect2.Type) ValEncoder { return nil }
   131  
   132  // DecorateDecoder No-op
   133  func (e *DummyExtension) DecorateDecoder(_ reflect2.Type, v ValDecoder) ValDecoder { return v }
   134  
   135  // DecorateEncoder No-op
   136  func (e *DummyExtension) DecorateEncoder(_ reflect2.Type, v ValEncoder) ValEncoder { return v }
   137  
   138  type EncoderExtension map[reflect2.Type]ValEncoder
   139  
   140  // UpdateStructDescriptor No-op
   141  func (e EncoderExtension) UpdateStructDescriptor(*StructDescriptor) {}
   142  
   143  // CreateDecoder No-op
   144  func (e EncoderExtension) CreateDecoder(reflect2.Type) ValDecoder { return nil }
   145  
   146  // CreateEncoder get encoder from map
   147  func (e EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { return e[typ] }
   148  
   149  // CreateMapKeyDecoder No-op
   150  func (e EncoderExtension) CreateMapKeyDecoder(reflect2.Type) ValDecoder { return nil }
   151  
   152  // CreateMapKeyEncoder No-op
   153  func (e EncoderExtension) CreateMapKeyEncoder(reflect2.Type) ValEncoder { return nil }
   154  
   155  // DecorateDecoder No-op
   156  func (e EncoderExtension) DecorateDecoder(_ reflect2.Type, v ValDecoder) ValDecoder { return v }
   157  
   158  // DecorateEncoder No-op
   159  func (e EncoderExtension) DecorateEncoder(_ reflect2.Type, v ValEncoder) ValEncoder { return v }
   160  
   161  type DecoderExtension map[reflect2.Type]ValDecoder
   162  
   163  // UpdateStructDescriptor No-op
   164  func (e DecoderExtension) UpdateStructDescriptor(*StructDescriptor) {}
   165  
   166  // CreateMapKeyDecoder No-op
   167  func (e DecoderExtension) CreateMapKeyDecoder(reflect2.Type) ValDecoder { return nil }
   168  
   169  // CreateMapKeyEncoder No-op
   170  func (e DecoderExtension) CreateMapKeyEncoder(reflect2.Type) ValEncoder { return nil }
   171  
   172  // CreateDecoder get decoder from map
   173  func (e DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { return e[typ] }
   174  
   175  // CreateEncoder No-op
   176  func (e DecoderExtension) CreateEncoder(reflect2.Type) ValEncoder { return nil }
   177  
   178  // DecorateDecoder No-op
   179  func (e DecoderExtension) DecorateDecoder(_ reflect2.Type, v ValDecoder) ValDecoder { return v }
   180  
   181  // DecorateEncoder No-op
   182  func (e DecoderExtension) DecorateEncoder(_ reflect2.Type, v ValEncoder) ValEncoder { return v }
   183  
   184  type funcDecoder struct {
   185  	fun DecoderFunc
   186  }
   187  
   188  func (f *funcDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) {
   189  	f.fun(ctx, ptr, iter)
   190  }
   191  
   192  type funcEncoder struct {
   193  	fn        EncoderFunc
   194  	isEmptyFn IsEmptyFn
   195  }
   196  
   197  func (e *funcEncoder) Encode(ctx context.Context, p unsafe.Pointer, stream *Stream) {
   198  	e.fn(ctx, p, stream)
   199  }
   200  
   201  func (e *funcEncoder) IsEmpty(ctx context.Context, p unsafe.Pointer, checkZero bool) bool {
   202  	return e.isEmptyFn != nil && e.isEmptyFn(ctx, p, checkZero)
   203  }
   204  
   205  type IsEmptyFn func(ctx context.Context, ptr unsafe.Pointer, checkZero bool) bool
   206  
   207  // DecoderFunc the function form of TypeDecoder
   208  type DecoderFunc func(ctx context.Context, ptr unsafe.Pointer, iter *Iterator)
   209  
   210  // EncoderFunc the function form of TypeEncoder
   211  type EncoderFunc func(ctx context.Context, ptr unsafe.Pointer, stream *Stream)
   212  
   213  // RegisterTypeDecoderFunc register TypeDecoder for a type with function
   214  func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
   215  	(ConfigDefault.(*frozenConfig)).RegisterTypeDecoderFunc(typ, fun)
   216  }
   217  
   218  // RegisterTypeDecoderFunc register TypeDecoder for a type with function
   219  func (c *frozenConfig) RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
   220  	c.typeDecoders[typ] = &funcDecoder{fun}
   221  }
   222  
   223  // RegisterTypeDecoder register TypeDecoder for a typ.
   224  func RegisterTypeDecoder(typ string, decoder ValDecoder) {
   225  	(ConfigDefault.(*frozenConfig)).RegisterTypeDecoder(typ, decoder)
   226  }
   227  
   228  // RegisterTypeDecoder register TypeDecoder for a typ.
   229  func (c *frozenConfig) RegisterTypeDecoder(typ string, decoder ValDecoder) {
   230  	c.typeDecoders[typ] = decoder
   231  }
   232  
   233  // RegisterFieldDecoderFunc register TypeDecoder for a struct field with function
   234  func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) {
   235  	RegisterFieldDecoder(typ, field, &funcDecoder{fun})
   236  }
   237  
   238  // RegisterFieldDecoder register TypeDecoder for a struct field
   239  func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {
   240  	(ConfigDefault.(*frozenConfig)).RegisterFieldDecoder(typ, field, decoder)
   241  }
   242  
   243  // RegisterFieldDecoder register TypeDecoder for a struct field
   244  func (c *frozenConfig) RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {
   245  	c.fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder
   246  }
   247  
   248  // RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function
   249  func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc IsEmptyFn) {
   250  	(ConfigDefault.(*frozenConfig)).RegisterTypeEncoderFunc(typ, fun, isEmptyFunc)
   251  }
   252  
   253  // RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function
   254  func (c *frozenConfig) RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc IsEmptyFn) {
   255  	c.typeEncoders[typ] = &funcEncoder{fn: fun, isEmptyFn: isEmptyFunc}
   256  }
   257  
   258  // RegisterTypeEncoder register TypeEncoder for a type
   259  func RegisterTypeEncoder(typ string, encoder ValEncoder) {
   260  	(ConfigDefault.(*frozenConfig)).RegisterTypeEncoder(typ, encoder)
   261  }
   262  
   263  // RegisterTypeEncoder register TypeEncoder for a type
   264  func (c *frozenConfig) RegisterTypeEncoder(typ string, encoder ValEncoder) {
   265  	c.typeEncoders[typ] = encoder
   266  }
   267  
   268  // RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function
   269  func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc IsEmptyFn) {
   270  	RegisterFieldEncoder(typ, field, &funcEncoder{fn: fun, isEmptyFn: isEmptyFunc})
   271  }
   272  
   273  // RegisterFieldEncoder register TypeEncoder for a struct field
   274  func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
   275  	(ConfigDefault.(*frozenConfig)).RegisterFieldEncoder(typ, field, encoder)
   276  }
   277  
   278  // RegisterFieldEncoder register TypeEncoder for a struct field
   279  func (c *frozenConfig) RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
   280  	c.fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder
   281  }
   282  
   283  // RegisterExtension register extension
   284  func RegisterExtension(extension Extension) {
   285  	(ConfigDefault.(*frozenConfig)).RegisterExtension(extension)
   286  }
   287  
   288  func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
   289  	d := _getTypeDecoderFromExtension(ctx, typ)
   290  	if d == nil {
   291  		return nil
   292  	}
   293  
   294  	d = ctx.frozenConfig.extensions.decorateDecoder(typ, d)
   295  	d = ctx.decoderExtension.DecorateDecoder(typ, d)
   296  	d = ctx.extensions.decorateDecoder(typ, d)
   297  
   298  	return d
   299  }
   300  
   301  func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
   302  	if d := ctx.frozenConfig.extensions.createDecoder(typ); d != nil {
   303  		return d
   304  	}
   305  	if d := ctx.decoderExtension.CreateDecoder(typ); d != nil {
   306  		return d
   307  	}
   308  	if d := ctx.extensions.createDecoder(typ); d != nil {
   309  		return d
   310  	}
   311  	if d := ctx.frozenConfig.typeDecoders[typ.String()]; d != nil {
   312  		return d
   313  	}
   314  	if typ.Kind() == reflect.Ptr {
   315  		ptrType := typ.(*reflect2.UnsafePtrType)
   316  		if d := ctx.frozenConfig.typeDecoders[ptrType.Elem().String()]; d != nil {
   317  			return &OptionalDecoder{ptrType.Elem(), d}
   318  		}
   319  	}
   320  	return nil
   321  }
   322  
   323  func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
   324  	e := _getTypeEncoderFromExtension(ctx, typ)
   325  	if e == nil {
   326  		return nil
   327  	}
   328  
   329  	e = ctx.frozenConfig.extensions.decorateEncoder(typ, e)
   330  	e = ctx.encoderExtension.DecorateEncoder(typ, e)
   331  	e = ctx.extensions.decorateEncoder(typ, e)
   332  
   333  	return e
   334  }
   335  
   336  func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
   337  	if e := ctx.frozenConfig.extensions.createEncoder(typ); e != nil {
   338  		return e
   339  	}
   340  	if e := ctx.encoderExtension.CreateEncoder(typ); e != nil {
   341  		return e
   342  	}
   343  	if e := ctx.extensions.createEncoder(typ); e != nil {
   344  		return e
   345  	}
   346  	if e := ctx.frozenConfig.typeEncoders[typ.String()]; e != nil {
   347  		return e
   348  	}
   349  	if typ.Kind() == reflect.Ptr {
   350  		if e := ctx.frozenConfig.typeEncoders[typ.(*reflect2.UnsafePtrType).Elem().String()]; e != nil {
   351  			return &OptionalEncoder{e}
   352  		}
   353  	}
   354  	return nil
   355  }
   356  
   357  func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
   358  	var embeddedBindings []*Binding
   359  	var bindings []*Binding
   360  	structType := typ.(*reflect2.UnsafeStructType)
   361  	for i := 0; i < structType.NumField(); i++ {
   362  		field := structType.Field(i)
   363  		tag, hasTag := field.Tag().Lookup(ctx.getTagKey())
   364  		if ctx.onlyTaggedField && !hasTag && !field.Anonymous() {
   365  			continue
   366  		}
   367  		if tag == "-" || field.Name() == "_" {
   368  			continue
   369  		}
   370  		tagParts := strings.Split(tag, ",")
   371  		if field.Anonymous() && (tag == "" || tagParts[0] == "") {
   372  			switch kind := field.Type().Kind(); kind {
   373  			case reflect.Struct:
   374  				structDescriptor := describeStruct(ctx, field.Type())
   375  				for _, b := range structDescriptor.Fields {
   376  					b.levels = append([]int{i}, b.levels...)
   377  					fieldEncoder := b.Encoder.(*structFieldEncoder)
   378  					omitempty := fieldEncoder.omitempty
   379  					nilAsEmpty := fieldEncoder.nilAsEmpty
   380  					b.Encoder = &structFieldEncoder{
   381  						field: field, fieldEncoder: b.Encoder,
   382  						omitempty: omitempty, nilAsEmpty: nilAsEmpty,
   383  					}
   384  					b.Decoder = &structFieldDecoder{field: field, fieldDecoder: b.Decoder}
   385  					embeddedBindings = append(embeddedBindings, b)
   386  				}
   387  				continue
   388  			case reflect.Ptr:
   389  				ptrType := field.Type().(*reflect2.UnsafePtrType)
   390  				if ptrType.Elem().Kind() == reflect.Struct {
   391  					structDescriptor := describeStruct(ctx, ptrType.Elem())
   392  					for _, b := range structDescriptor.Fields {
   393  						b.levels = append([]int{i}, b.levels...)
   394  						fieldEncoder := b.Encoder.(*structFieldEncoder)
   395  						omitempty := fieldEncoder.omitempty
   396  						nilAsEmpty := fieldEncoder.nilAsEmpty
   397  						b.Encoder = &dereferenceEncoder{ValueEncoder: b.Encoder}
   398  						b.Encoder = &structFieldEncoder{
   399  							field: field, fieldEncoder: b.Encoder,
   400  							omitempty: omitempty, nilAsEmpty: nilAsEmpty,
   401  						}
   402  						b.Decoder = &dereferenceDecoder{valueType: ptrType.Elem(), valueDecoder: b.Decoder}
   403  						b.Decoder = &structFieldDecoder{field: field, fieldDecoder: b.Decoder}
   404  						embeddedBindings = append(embeddedBindings, b)
   405  					}
   406  					continue
   407  				}
   408  			}
   409  		}
   410  		fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)
   411  		fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name())
   412  		decoder := ctx.frozenConfig.fieldDecoders[fieldCacheKey]
   413  		if decoder == nil {
   414  			decoder = decoderOfType(ctx.append(field.Name()), field.Type())
   415  		}
   416  		encoder := ctx.frozenConfig.fieldEncoders[fieldCacheKey]
   417  		if encoder == nil {
   418  			encoder = encoderOfType(ctx.append(field.Name()), field.Type())
   419  		}
   420  		binding := &Binding{
   421  			Field: field, FromNames: fieldNames, ToNames: fieldNames,
   422  			Decoder: decoder, Encoder: encoder,
   423  		}
   424  		binding.levels = []int{i}
   425  		bindings = append(bindings, binding)
   426  	}
   427  	return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
   428  }
   429  
   430  func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding,
   431  	embeddedBindings []*Binding,
   432  ) *StructDescriptor {
   433  	structDescriptor := &StructDescriptor{Type: typ, Fields: bindings}
   434  	ctx.frozenConfig.extensions.UpdateStructDescriptor(structDescriptor)
   435  	ctx.encoderExtension.UpdateStructDescriptor(structDescriptor)
   436  	ctx.decoderExtension.UpdateStructDescriptor(structDescriptor)
   437  	ctx.extensions.UpdateStructDescriptor(structDescriptor)
   438  	processTags(structDescriptor, ctx.frozenConfig)
   439  	// merge normal & embedded bindings & sort with original order
   440  	allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
   441  	sort.Sort(allBindings)
   442  	structDescriptor.Fields = allBindings
   443  	return structDescriptor
   444  }
   445  
   446  type sortableBindings []*Binding
   447  
   448  func (b sortableBindings) Len() int      { return len(b) }
   449  func (b sortableBindings) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
   450  
   451  func (b sortableBindings) Less(i, j int) bool {
   452  	left := b[i].levels
   453  	right := b[j].levels
   454  	k := 0
   455  	for {
   456  		if left[k] < right[k] {
   457  			return true
   458  		} else if left[k] > right[k] {
   459  			return false
   460  		}
   461  		k++
   462  	}
   463  }
   464  
   465  func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {
   466  	for _, b := range structDescriptor.Fields {
   467  		shouldOmitEmpty := cfg.omitEmptyStructField
   468  		nilAsEmpty := cfg.nilAsEmpty
   469  		clearQuotes := cfg.clearQuotes
   470  		tagParts := strings.Split(b.Field.Tag().Get(cfg.getTagKey()), ",")
   471  		for _, tagPart := range tagParts[1:] {
   472  			switch tagPart {
   473  			case "nilasempty":
   474  				nilAsEmpty = true
   475  			case "omitempty":
   476  				shouldOmitEmpty = true
   477  			case "clearQuotes":
   478  				clearQuotes = true
   479  			case "string":
   480  				switch k := b.Field.Type().Kind(); k {
   481  				case reflect.String:
   482  					b.Decoder = &stringModeStringDecoder{b.Decoder, cfg}
   483  					b.Encoder = &stringModeStringEncoder{b.Encoder, cfg}
   484  				default:
   485  					if (k == reflect.Int64 || k == reflect.Uint64) && cfg.int64AsString {
   486  						// ignore
   487  					} else {
   488  						b.Decoder = &stringModeNumberDecoder{b.Decoder}
   489  						b.Encoder = &stringModeNumberEncoder{b.Encoder}
   490  					}
   491  				}
   492  			}
   493  		}
   494  		b.Decoder = &structFieldDecoder{field: b.Field, fieldDecoder: b.Decoder}
   495  		b.Encoder = &structFieldEncoder{
   496  			field: b.Field, fieldEncoder: b.Encoder,
   497  			omitempty: shouldOmitEmpty, nilAsEmpty: nilAsEmpty, clearQuotes: clearQuotes,
   498  		}
   499  	}
   500  }
   501  
   502  func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {
   503  	// ignore?
   504  	if wholeTag == "-" {
   505  		return []string{}
   506  	}
   507  	// rename?
   508  	var fieldNames []string
   509  	if tagProvidedFieldName == "" {
   510  		fieldNames = []string{originalFieldName}
   511  	} else {
   512  		fieldNames = []string{tagProvidedFieldName}
   513  	}
   514  	// private?
   515  	isNotExported := unicode.IsLower(rune(originalFieldName[0])) || originalFieldName[0] == '_'
   516  	if isNotExported {
   517  		fieldNames = []string{}
   518  	}
   519  	return fieldNames
   520  }