github.com/3JoB/go-json@v0.10.4/internal/decoder/compile.go (about)

     1  package decoder
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  	"sync/atomic"
     8  	"unicode"
     9  	"unsafe"
    10  
    11  	"github.com/3JoB/go-reflect"
    12  
    13  	"github.com/3JoB/go-json/internal/runtime"
    14  )
    15  
    16  var (
    17  	jsonNumberType   = reflect.TypeOf(json.Number(""))
    18  	typeAddr         *runtime.TypeAddr
    19  	cachedDecoderMap unsafe.Pointer // map[uintptr]decoder
    20  	cachedDecoder    []Decoder
    21  )
    22  
    23  func init() {
    24  	typeAddr = runtime.AnalyzeTypeAddr()
    25  	if typeAddr == nil {
    26  		typeAddr = &runtime.TypeAddr{}
    27  	}
    28  	cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift+1)
    29  }
    30  
    31  func loadDecoderMap() map[uintptr]Decoder {
    32  	p := atomic.LoadPointer(&cachedDecoderMap)
    33  	return *(*map[uintptr]Decoder)(unsafe.Pointer(&p))
    34  }
    35  
    36  func storeDecoder(typ uintptr, dec Decoder, m map[uintptr]Decoder) {
    37  	newDecoderMap := make(map[uintptr]Decoder, len(m)+1)
    38  	newDecoderMap[typ] = dec
    39  
    40  	for k, v := range m {
    41  		newDecoderMap[k] = v
    42  	}
    43  
    44  	atomic.StorePointer(&cachedDecoderMap, *(*unsafe.Pointer)(unsafe.Pointer(&newDecoderMap)))
    45  }
    46  
    47  func compileToGetDecoderSlowPath(typeptr uintptr, typ *runtime.Type) (Decoder, error) {
    48  	decoderMap := loadDecoderMap()
    49  	if dec, exists := decoderMap[typeptr]; exists {
    50  		return dec, nil
    51  	}
    52  
    53  	dec, err := compileHead(typ, map[uintptr]Decoder{})
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	storeDecoder(typeptr, dec, decoderMap)
    58  	return dec, nil
    59  }
    60  
    61  func compileHead(typ *runtime.Type, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
    62  	switch {
    63  	case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
    64  		return newUnmarshalJSONDecoder(runtime.PtrTo(typ), "", ""), nil
    65  	case runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)):
    66  		return newUnmarshalTextDecoder(runtime.PtrTo(typ), "", ""), nil
    67  	}
    68  	return compile(typ.Elem(), "", "", structTypeToDecoder)
    69  }
    70  
    71  func compile(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
    72  	switch {
    73  	case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
    74  		return newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName), nil
    75  	case runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)):
    76  		return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
    77  	}
    78  
    79  	switch typ.Kind() {
    80  	case reflect.Ptr:
    81  		return compilePtr(typ, structName, fieldName, structTypeToDecoder)
    82  	case reflect.Struct:
    83  		return compileStruct(typ, structName, fieldName, structTypeToDecoder)
    84  	case reflect.Slice:
    85  		elem := typ.Elem()
    86  		if elem.Kind() == reflect.Uint8 {
    87  			return compileBytes(elem, structName, fieldName)
    88  		}
    89  		return compileSlice(typ, structName, fieldName, structTypeToDecoder)
    90  	case reflect.Array:
    91  		return compileArray(typ, structName, fieldName, structTypeToDecoder)
    92  	case reflect.Map:
    93  		return compileMap(typ, structName, fieldName, structTypeToDecoder)
    94  	case reflect.Interface:
    95  		return compileInterface(typ, structName, fieldName)
    96  	case reflect.Uintptr:
    97  		return compileUint(typ, structName, fieldName)
    98  	case reflect.Int:
    99  		return compileInt(typ, structName, fieldName)
   100  	case reflect.Int8:
   101  		return compileInt8(typ, structName, fieldName)
   102  	case reflect.Int16:
   103  		return compileInt16(typ, structName, fieldName)
   104  	case reflect.Int32:
   105  		return compileInt32(typ, structName, fieldName)
   106  	case reflect.Int64:
   107  		return compileInt64(typ, structName, fieldName)
   108  	case reflect.Uint:
   109  		return compileUint(typ, structName, fieldName)
   110  	case reflect.Uint8:
   111  		return compileUint8(typ, structName, fieldName)
   112  	case reflect.Uint16:
   113  		return compileUint16(typ, structName, fieldName)
   114  	case reflect.Uint32:
   115  		return compileUint32(typ, structName, fieldName)
   116  	case reflect.Uint64:
   117  		return compileUint64(typ, structName, fieldName)
   118  	case reflect.String:
   119  		return compileString(typ, structName, fieldName)
   120  	case reflect.Bool:
   121  		return compileBool(structName, fieldName)
   122  	case reflect.Float32:
   123  		return compileFloat32(structName, fieldName)
   124  	case reflect.Float64:
   125  		return compileFloat64(structName, fieldName)
   126  	case reflect.Func:
   127  		return compileFunc(typ, structName, fieldName)
   128  	}
   129  	return newInvalidDecoder(typ, structName, fieldName), nil
   130  }
   131  
   132  func isStringTagSupportedType(typ *runtime.Type) bool {
   133  	switch {
   134  	case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
   135  		return false
   136  	case runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)):
   137  		return false
   138  	}
   139  	switch typ.Kind() {
   140  	case reflect.Map:
   141  		return false
   142  	case reflect.Slice:
   143  		return false
   144  	case reflect.Array:
   145  		return false
   146  	case reflect.Struct:
   147  		return false
   148  	case reflect.Interface:
   149  		return false
   150  	}
   151  	return true
   152  }
   153  
   154  func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
   155  	if runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)) {
   156  		return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
   157  	}
   158  	if typ.Kind() == reflect.String {
   159  		return newStringDecoder(structName, fieldName), nil
   160  	}
   161  	dec, err := compile(typ, structName, fieldName, structTypeToDecoder)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	for {
   166  		switch t := dec.(type) {
   167  		case *stringDecoder, *interfaceDecoder:
   168  			return dec, nil
   169  		case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder:
   170  			return newWrappedStringDecoder(typ, dec, structName, fieldName), nil
   171  		case *ptrDecoder:
   172  			dec = t.dec
   173  		default:
   174  			return newInvalidDecoder(typ, structName, fieldName), nil
   175  		}
   176  	}
   177  }
   178  
   179  func compilePtr(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
   180  	dec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  	return newPtrDecoder(dec, typ.Elem(), structName, fieldName), nil
   185  }
   186  
   187  func compileInt(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   188  	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
   189  		*(*int)(p) = int(v)
   190  	}), nil
   191  }
   192  
   193  func compileInt8(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   194  	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
   195  		*(*int8)(p) = int8(v)
   196  	}), nil
   197  }
   198  
   199  func compileInt16(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   200  	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
   201  		*(*int16)(p) = int16(v)
   202  	}), nil
   203  }
   204  
   205  func compileInt32(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   206  	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
   207  		*(*int32)(p) = int32(v)
   208  	}), nil
   209  }
   210  
   211  func compileInt64(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   212  	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
   213  		*(*int64)(p) = v
   214  	}), nil
   215  }
   216  
   217  func compileUint(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   218  	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
   219  		*(*uint)(p) = uint(v)
   220  	}), nil
   221  }
   222  
   223  func compileUint8(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   224  	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
   225  		*(*uint8)(p) = uint8(v)
   226  	}), nil
   227  }
   228  
   229  func compileUint16(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   230  	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
   231  		*(*uint16)(p) = uint16(v)
   232  	}), nil
   233  }
   234  
   235  func compileUint32(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   236  	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
   237  		*(*uint32)(p) = uint32(v)
   238  	}), nil
   239  }
   240  
   241  func compileUint64(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   242  	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
   243  		*(*uint64)(p) = v
   244  	}), nil
   245  }
   246  
   247  func compileFloat32(structName, fieldName string) (Decoder, error) {
   248  	return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
   249  		*(*float32)(p) = float32(v)
   250  	}), nil
   251  }
   252  
   253  func compileFloat64(structName, fieldName string) (Decoder, error) {
   254  	return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
   255  		*(*float64)(p) = v
   256  	}), nil
   257  }
   258  
   259  func compileString(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   260  	if typ == runtime.Type2RType(reflect.ToRT(jsonNumberType)) {
   261  		return newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
   262  			*(*json.Number)(p) = v
   263  		}), nil
   264  	}
   265  	return newStringDecoder(structName, fieldName), nil
   266  }
   267  
   268  func compileBool(structName, fieldName string) (Decoder, error) {
   269  	return newBoolDecoder(structName, fieldName), nil
   270  }
   271  
   272  func compileBytes(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   273  	return newBytesDecoder(typ, structName, fieldName), nil
   274  }
   275  
   276  func compileSlice(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
   277  	elem := typ.Elem()
   278  	decoder, err := compile(elem, structName, fieldName, structTypeToDecoder)
   279  	if err != nil {
   280  		return nil, err
   281  	}
   282  	return newSliceDecoder(decoder, elem, elem.Size(), structName, fieldName), nil
   283  }
   284  
   285  func compileArray(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
   286  	elem := typ.Elem()
   287  	decoder, err := compile(elem, structName, fieldName, structTypeToDecoder)
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  	return newArrayDecoder(decoder, elem, typ.Len(), structName, fieldName), nil
   292  }
   293  
   294  func compileMap(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
   295  	keyDec, err := compileMapKey(typ.Key(), structName, fieldName, structTypeToDecoder)
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  	valueDec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder)
   300  	if err != nil {
   301  		return nil, err
   302  	}
   303  	return newMapDecoder(typ, typ.Key(), keyDec, typ.Elem(), valueDec, structName, fieldName), nil
   304  }
   305  
   306  func compileInterface(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
   307  	return newInterfaceDecoder(typ, structName, fieldName), nil
   308  }
   309  
   310  func compileFunc(typ *runtime.Type, strutName, fieldName string) (Decoder, error) {
   311  	return newFuncDecoder(typ, strutName, fieldName), nil
   312  }
   313  
   314  func typeToStructTags(typ *runtime.Type) runtime.StructTags {
   315  	tags := runtime.StructTags{}
   316  	fieldNum := typ.NumField()
   317  	for i := 0; i < fieldNum; i++ {
   318  		field := typ.Field(i)
   319  		if runtime.IsIgnoredStructField(field) {
   320  			continue
   321  		}
   322  		tags = append(tags, runtime.StructTagFromField(field))
   323  	}
   324  	return tags
   325  }
   326  
   327  func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
   328  	fieldNum := typ.NumField()
   329  	fieldMap := map[string]*structFieldSet{}
   330  	typeptr := uintptr(unsafe.Pointer(typ))
   331  	if dec, exists := structTypeToDecoder[typeptr]; exists {
   332  		return dec, nil
   333  	}
   334  	structDec := newStructDecoder(structName, fieldName, fieldMap)
   335  	structTypeToDecoder[typeptr] = structDec
   336  	structName = typ.Name()
   337  	tags := typeToStructTags(typ)
   338  	allFields := []*structFieldSet{}
   339  	for i := 0; i < fieldNum; i++ {
   340  		field := typ.Field(i)
   341  		if runtime.IsIgnoredStructField(field) {
   342  			continue
   343  		}
   344  		isUnexportedField := unicode.IsLower([]rune(field.Name)[0])
   345  		tag := runtime.StructTagFromField(field)
   346  		dec, err := compile(runtime.Type2RType(field.Type), structName, field.Name, structTypeToDecoder)
   347  		if err != nil {
   348  			return nil, err
   349  		}
   350  		if field.Anonymous && !tag.IsTaggedKey {
   351  			if stDec, ok := dec.(*structDecoder); ok {
   352  				if runtime.Type2RType(field.Type) == typ {
   353  					// recursive definition
   354  					continue
   355  				}
   356  				for k, v := range stDec.fieldMap {
   357  					if tags.ExistsKey(k) {
   358  						continue
   359  					}
   360  					fieldSet := &structFieldSet{
   361  						dec:         v.dec,
   362  						offset:      field.Offset + v.offset,
   363  						isTaggedKey: v.isTaggedKey,
   364  						key:         k,
   365  						keyLen:      int64(len(k)),
   366  					}
   367  					allFields = append(allFields, fieldSet)
   368  				}
   369  			} else if pdec, ok := dec.(*ptrDecoder); ok {
   370  				contentDec := pdec.contentDecoder()
   371  				if pdec.typ == typ {
   372  					// recursive definition
   373  					continue
   374  				}
   375  				var fieldSetErr error
   376  				if isUnexportedField {
   377  					fieldSetErr = fmt.Errorf(
   378  						"json: cannot set embedded pointer to unexported struct: %v",
   379  						field.Type.Elem(),
   380  					)
   381  				}
   382  				if dec, ok := contentDec.(*structDecoder); ok {
   383  					for k, v := range dec.fieldMap {
   384  						if tags.ExistsKey(k) {
   385  							continue
   386  						}
   387  						fieldSet := &structFieldSet{
   388  							dec:         newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
   389  							offset:      field.Offset,
   390  							isTaggedKey: v.isTaggedKey,
   391  							key:         k,
   392  							keyLen:      int64(len(k)),
   393  							err:         fieldSetErr,
   394  						}
   395  						allFields = append(allFields, fieldSet)
   396  					}
   397  				} else {
   398  					fieldSet := &structFieldSet{
   399  						dec:         pdec,
   400  						offset:      field.Offset,
   401  						isTaggedKey: tag.IsTaggedKey,
   402  						key:         field.Name,
   403  						keyLen:      int64(len(field.Name)),
   404  					}
   405  					allFields = append(allFields, fieldSet)
   406  				}
   407  			} else {
   408  				fieldSet := &structFieldSet{
   409  					dec:         dec,
   410  					offset:      field.Offset,
   411  					isTaggedKey: tag.IsTaggedKey,
   412  					key:         field.Name,
   413  					keyLen:      int64(len(field.Name)),
   414  				}
   415  				allFields = append(allFields, fieldSet)
   416  			}
   417  		} else {
   418  			if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) {
   419  				dec = newWrappedStringDecoder(runtime.Type2RType(field.Type), dec, structName, field.Name)
   420  			}
   421  			var key string
   422  			if tag.Key != "" {
   423  				key = tag.Key
   424  			} else {
   425  				key = field.Name
   426  			}
   427  			fieldSet := &structFieldSet{
   428  				dec:         dec,
   429  				offset:      field.Offset,
   430  				isTaggedKey: tag.IsTaggedKey,
   431  				key:         key,
   432  				keyLen:      int64(len(key)),
   433  			}
   434  			allFields = append(allFields, fieldSet)
   435  		}
   436  	}
   437  	for _, set := range filterDuplicatedFields(allFields) {
   438  		fieldMap[set.key] = set
   439  		lower := strings.ToLower(set.key)
   440  		if _, exists := fieldMap[lower]; !exists {
   441  			// first win
   442  			fieldMap[lower] = set
   443  		}
   444  	}
   445  	delete(structTypeToDecoder, typeptr)
   446  	structDec.tryOptimize()
   447  	return structDec, nil
   448  }
   449  
   450  func filterDuplicatedFields(allFields []*structFieldSet) []*structFieldSet {
   451  	fieldMap := map[string][]*structFieldSet{}
   452  	for _, field := range allFields {
   453  		fieldMap[field.key] = append(fieldMap[field.key], field)
   454  	}
   455  	duplicatedFieldMap := map[string]struct{}{}
   456  	for k, sets := range fieldMap {
   457  		sets = filterFieldSets(sets)
   458  		if len(sets) != 1 {
   459  			duplicatedFieldMap[k] = struct{}{}
   460  		}
   461  	}
   462  
   463  	filtered := make([]*structFieldSet, 0, len(allFields))
   464  	for _, field := range allFields {
   465  		if _, exists := duplicatedFieldMap[field.key]; exists {
   466  			continue
   467  		}
   468  		filtered = append(filtered, field)
   469  	}
   470  	return filtered
   471  }
   472  
   473  func filterFieldSets(sets []*structFieldSet) []*structFieldSet {
   474  	if len(sets) == 1 {
   475  		return sets
   476  	}
   477  	filtered := make([]*structFieldSet, 0, len(sets))
   478  	for _, set := range sets {
   479  		if set.isTaggedKey {
   480  			filtered = append(filtered, set)
   481  		}
   482  	}
   483  	return filtered
   484  }
   485  
   486  func implementsUnmarshalJSONType(typ *runtime.Type) bool {
   487  	return typ.Implements(reflect.ToRT(unmarshalJSONType)) || typ.Implements(reflect.ToRT(unmarshalJSONContextType))
   488  }