github.com/neilotoole/jsoncolor@v0.6.0/codec.go (about)

     1  package jsoncolor
     2  
     3  import (
     4  	"encoding"
     5  	"encoding/json"
     6  	"fmt"
     7  	"reflect"
     8  	"sort"
     9  	"strconv"
    10  	"strings"
    11  	"sync/atomic"
    12  	"time"
    13  	"unicode"
    14  	"unsafe"
    15  )
    16  
    17  type codec struct {
    18  	encode encodeFunc
    19  	decode decodeFunc
    20  }
    21  
    22  type encoder struct {
    23  	flags   AppendFlags
    24  	clrs    *Colors
    25  	indentr *indenter
    26  }
    27  type decoder struct{ flags ParseFlags }
    28  
    29  type encodeFunc func(encoder, []byte, unsafe.Pointer) ([]byte, error)
    30  type decodeFunc func(decoder, []byte, unsafe.Pointer) ([]byte, error)
    31  
    32  type emptyFunc func(unsafe.Pointer) bool
    33  type sortFunc func([]reflect.Value)
    34  
    35  var (
    36  	// Eventually consistent cache mapping go types to dynamically generated
    37  	// codecs.
    38  	//
    39  	// Note: using a uintptr as key instead of reflect.Type shaved ~15ns off of
    40  	// the ~30ns Marhsal/Unmarshal functions which were dominated by the map
    41  	// lookup time for simple types like bool, int, etc..
    42  	cache unsafe.Pointer // map[unsafe.Pointer]codec
    43  )
    44  
    45  func cacheLoad() map[unsafe.Pointer]codec {
    46  	p := atomic.LoadPointer(&cache)
    47  	return *(*map[unsafe.Pointer]codec)(unsafe.Pointer(&p))
    48  }
    49  
    50  func cacheStore(typ reflect.Type, cod codec, oldCodecs map[unsafe.Pointer]codec) {
    51  	newCodecs := make(map[unsafe.Pointer]codec, len(oldCodecs)+1)
    52  	newCodecs[typeid(typ)] = cod
    53  
    54  	for t, c := range oldCodecs {
    55  		newCodecs[t] = c
    56  	}
    57  
    58  	atomic.StorePointer(&cache, *(*unsafe.Pointer)(unsafe.Pointer(&newCodecs)))
    59  }
    60  
    61  func typeid(t reflect.Type) unsafe.Pointer {
    62  	return (*iface)(unsafe.Pointer(&t)).ptr
    63  }
    64  
    65  func constructCachedCodec(t reflect.Type, cache map[unsafe.Pointer]codec) codec {
    66  	c := constructCodec(t, map[reflect.Type]*structType{}, t.Kind() == reflect.Ptr)
    67  
    68  	if inlined(t) {
    69  		c.encode = constructInlineValueEncodeFunc(c.encode)
    70  	}
    71  
    72  	cacheStore(t, c, cache)
    73  	return c
    74  }
    75  
    76  func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) (c codec) {
    77  	switch t {
    78  	case nullType, nil:
    79  		c = codec{encode: encoder.encodeNull, decode: decoder.decodeNull}
    80  
    81  	case numberType:
    82  		c = codec{encode: encoder.encodeNumber, decode: decoder.decodeNumber}
    83  
    84  	case bytesType:
    85  		c = codec{encode: encoder.encodeBytes, decode: decoder.decodeBytes}
    86  
    87  	case durationType:
    88  		c = codec{encode: encoder.encodeDuration, decode: decoder.decodeDuration}
    89  
    90  	case timeType:
    91  		c = codec{encode: encoder.encodeTime, decode: decoder.decodeTime}
    92  
    93  	case interfaceType:
    94  		c = codec{encode: encoder.encodeInterface, decode: decoder.decodeInterface}
    95  
    96  	case rawMessageType:
    97  		c = codec{encode: encoder.encodeRawMessage, decode: decoder.decodeRawMessage}
    98  
    99  	case numberPtrType:
   100  		c = constructPointerCodec(numberPtrType, nil)
   101  
   102  	case durationPtrType:
   103  		c = constructPointerCodec(durationPtrType, nil)
   104  
   105  	case timePtrType:
   106  		c = constructPointerCodec(timePtrType, nil)
   107  
   108  	case rawMessagePtrType:
   109  		c = constructPointerCodec(rawMessagePtrType, nil)
   110  	}
   111  
   112  	if c.encode != nil {
   113  		return
   114  	}
   115  
   116  	switch t.Kind() {
   117  	case reflect.Bool:
   118  		c = codec{encode: encoder.encodeBool, decode: decoder.decodeBool}
   119  
   120  	case reflect.Int:
   121  		c = codec{encode: encoder.encodeInt, decode: decoder.decodeInt}
   122  
   123  	case reflect.Int8:
   124  		c = codec{encode: encoder.encodeInt8, decode: decoder.decodeInt8}
   125  
   126  	case reflect.Int16:
   127  		c = codec{encode: encoder.encodeInt16, decode: decoder.decodeInt16}
   128  
   129  	case reflect.Int32:
   130  		c = codec{encode: encoder.encodeInt32, decode: decoder.decodeInt32}
   131  
   132  	case reflect.Int64:
   133  		c = codec{encode: encoder.encodeInt64, decode: decoder.decodeInt64}
   134  
   135  	case reflect.Uint:
   136  		c = codec{encode: encoder.encodeUint, decode: decoder.decodeUint}
   137  
   138  	case reflect.Uintptr:
   139  		c = codec{encode: encoder.encodeUintptr, decode: decoder.decodeUintptr}
   140  
   141  	case reflect.Uint8:
   142  		c = codec{encode: encoder.encodeUint8, decode: decoder.decodeUint8}
   143  
   144  	case reflect.Uint16:
   145  		c = codec{encode: encoder.encodeUint16, decode: decoder.decodeUint16}
   146  
   147  	case reflect.Uint32:
   148  		c = codec{encode: encoder.encodeUint32, decode: decoder.decodeUint32}
   149  
   150  	case reflect.Uint64:
   151  		c = codec{encode: encoder.encodeUint64, decode: decoder.decodeUint64}
   152  
   153  	case reflect.Float32:
   154  		c = codec{encode: encoder.encodeFloat32, decode: decoder.decodeFloat32}
   155  
   156  	case reflect.Float64:
   157  		c = codec{encode: encoder.encodeFloat64, decode: decoder.decodeFloat64}
   158  
   159  	case reflect.String:
   160  		c = codec{encode: encoder.encodeString, decode: decoder.decodeString}
   161  
   162  	case reflect.Interface:
   163  		c = constructInterfaceCodec(t)
   164  
   165  	case reflect.Array:
   166  		c = constructArrayCodec(t, seen, canAddr)
   167  
   168  	case reflect.Slice:
   169  		c = constructSliceCodec(t, seen)
   170  
   171  	case reflect.Map:
   172  		c = constructMapCodec(t, seen)
   173  
   174  	case reflect.Struct:
   175  		c = constructStructCodec(t, seen, canAddr)
   176  
   177  	case reflect.Ptr:
   178  		c = constructPointerCodec(t, seen)
   179  
   180  	default:
   181  		c = constructUnsupportedTypeCodec(t)
   182  	}
   183  
   184  	p := reflect.PtrTo(t)
   185  
   186  	if canAddr {
   187  		switch {
   188  		case p.Implements(jsonMarshalerType):
   189  			c.encode = constructJSONMarshalerEncodeFunc(t, true)
   190  		case p.Implements(textMarshalerType):
   191  			c.encode = constructTextMarshalerEncodeFunc(t, true)
   192  		}
   193  	}
   194  
   195  	switch {
   196  	case t.Implements(jsonMarshalerType):
   197  		c.encode = constructJSONMarshalerEncodeFunc(t, false)
   198  	case t.Implements(textMarshalerType):
   199  		c.encode = constructTextMarshalerEncodeFunc(t, false)
   200  	}
   201  
   202  	switch {
   203  	case p.Implements(jsonUnmarshalerType):
   204  		c.decode = constructJSONUnmarshalerDecodeFunc(t, true)
   205  	case p.Implements(textUnmarshalerType):
   206  		c.decode = constructTextUnmarshalerDecodeFunc(t, true)
   207  	}
   208  
   209  	return
   210  }
   211  
   212  func constructStringCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec {
   213  	c := constructCodec(t, seen, canAddr)
   214  	return codec{
   215  		encode: constructStringEncodeFunc(c.encode),
   216  		decode: constructStringDecodeFunc(c.decode),
   217  	}
   218  }
   219  
   220  func constructStringEncodeFunc(encode encodeFunc) encodeFunc {
   221  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   222  		return e.encodeToString(b, p, encode)
   223  	}
   224  }
   225  
   226  func constructStringDecodeFunc(decode decodeFunc) decodeFunc {
   227  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   228  		return d.decodeFromString(b, p, decode)
   229  	}
   230  }
   231  
   232  func constructStringToIntDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc {
   233  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   234  		return d.decodeFromStringToInt(b, p, t, decode)
   235  	}
   236  }
   237  
   238  func constructArrayCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec {
   239  	e := t.Elem()
   240  	c := constructCodec(e, seen, canAddr)
   241  	s := alignedSize(e)
   242  	return codec{
   243  		encode: constructArrayEncodeFunc(s, t, c.encode),
   244  		decode: constructArrayDecodeFunc(s, t, c.decode),
   245  	}
   246  }
   247  
   248  func constructArrayEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc {
   249  	n := t.Len()
   250  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   251  		return e.encodeArray(b, p, n, size, t, encode)
   252  	}
   253  }
   254  
   255  func constructArrayDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) decodeFunc {
   256  	n := t.Len()
   257  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   258  		return d.decodeArray(b, p, n, size, t, decode)
   259  	}
   260  }
   261  
   262  func constructSliceCodec(t reflect.Type, seen map[reflect.Type]*structType) codec {
   263  	e := t.Elem()
   264  	s := alignedSize(e)
   265  
   266  	if e.Kind() == reflect.Uint8 {
   267  		// Go 1.7+ behavior: slices of byte types (and aliases) may override the
   268  		// default encoding and decoding behaviors by implementing marshaler and
   269  		// unmarshaler interfaces.
   270  		p := reflect.PtrTo(e)
   271  		c := codec{}
   272  
   273  		switch {
   274  		case e.Implements(jsonMarshalerType):
   275  			c.encode = constructJSONMarshalerEncodeFunc(e, false)
   276  		case e.Implements(textMarshalerType):
   277  			c.encode = constructTextMarshalerEncodeFunc(e, false)
   278  		case p.Implements(jsonMarshalerType):
   279  			c.encode = constructJSONMarshalerEncodeFunc(e, true)
   280  		case p.Implements(textMarshalerType):
   281  			c.encode = constructTextMarshalerEncodeFunc(e, true)
   282  		}
   283  
   284  		switch {
   285  		case e.Implements(jsonUnmarshalerType):
   286  			c.decode = constructJSONUnmarshalerDecodeFunc(e, false)
   287  		case e.Implements(textUnmarshalerType):
   288  			c.decode = constructTextUnmarshalerDecodeFunc(e, false)
   289  		case p.Implements(jsonUnmarshalerType):
   290  			c.decode = constructJSONUnmarshalerDecodeFunc(e, true)
   291  		case p.Implements(textUnmarshalerType):
   292  			c.decode = constructTextUnmarshalerDecodeFunc(e, true)
   293  		}
   294  
   295  		if c.encode != nil {
   296  			c.encode = constructSliceEncodeFunc(s, t, c.encode)
   297  		} else {
   298  			c.encode = encoder.encodeBytes
   299  		}
   300  
   301  		if c.decode != nil {
   302  			c.decode = constructSliceDecodeFunc(s, t, c.decode)
   303  		} else {
   304  			c.decode = decoder.decodeBytes
   305  		}
   306  
   307  		return c
   308  	}
   309  
   310  	c := constructCodec(e, seen, true)
   311  	return codec{
   312  		encode: constructSliceEncodeFunc(s, t, c.encode),
   313  		decode: constructSliceDecodeFunc(s, t, c.decode),
   314  	}
   315  }
   316  
   317  func constructSliceEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc {
   318  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   319  		return e.encodeSlice(b, p, size, t, encode)
   320  	}
   321  }
   322  
   323  func constructSliceDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) decodeFunc {
   324  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   325  		return d.decodeSlice(b, p, size, t, decode)
   326  	}
   327  }
   328  
   329  func constructMapCodec(t reflect.Type, seen map[reflect.Type]*structType) codec {
   330  	var sortKeys sortFunc
   331  	k := t.Key()
   332  	v := t.Elem()
   333  
   334  	// Faster implementations for some common cases.
   335  	switch {
   336  	case k == stringType && v == interfaceType:
   337  		return codec{
   338  			encode: encoder.encodeMapStringInterface,
   339  			decode: decoder.decodeMapStringInterface,
   340  		}
   341  
   342  	case k == stringType && v == rawMessageType:
   343  		return codec{
   344  			encode: encoder.encodeMapStringRawMessage,
   345  			decode: decoder.decodeMapStringRawMessage,
   346  		}
   347  	}
   348  
   349  	kc := codec{}
   350  	vc := constructCodec(v, seen, false)
   351  
   352  	if k.Implements(textMarshalerType) || reflect.PtrTo(k).Implements(textUnmarshalerType) {
   353  		kc.encode = constructTextMarshalerEncodeFunc(k, false)
   354  		kc.decode = constructTextUnmarshalerDecodeFunc(k, true)
   355  
   356  		sortKeys = func(keys []reflect.Value) {
   357  			sort.Slice(keys, func(i, j int) bool {
   358  				// This is a performance abomination but the use case is rare
   359  				// enough that it shouldn't be a problem in practice.
   360  				k1, _ := keys[i].Interface().(encoding.TextMarshaler).MarshalText()
   361  				k2, _ := keys[j].Interface().(encoding.TextMarshaler).MarshalText()
   362  				return string(k1) < string(k2)
   363  			})
   364  		}
   365  	} else {
   366  		switch k.Kind() {
   367  		case reflect.String:
   368  			kc.encode = encoder.encodeKey
   369  			kc.decode = decoder.decodeString
   370  
   371  			sortKeys = func(keys []reflect.Value) {
   372  				sort.Slice(keys, func(i, j int) bool { return keys[i].String() < keys[j].String() })
   373  			}
   374  
   375  		case reflect.Int,
   376  			reflect.Int8,
   377  			reflect.Int16,
   378  			reflect.Int32,
   379  			reflect.Int64:
   380  			kc = constructStringCodec(k, seen, false)
   381  
   382  			sortKeys = func(keys []reflect.Value) {
   383  				sort.Slice(keys, func(i, j int) bool { return intStringsAreSorted(keys[i].Int(), keys[j].Int()) })
   384  			}
   385  
   386  		case reflect.Uint,
   387  			reflect.Uintptr,
   388  			reflect.Uint8,
   389  			reflect.Uint16,
   390  			reflect.Uint32,
   391  			reflect.Uint64:
   392  			kc = constructStringCodec(k, seen, false)
   393  
   394  			sortKeys = func(keys []reflect.Value) {
   395  				sort.Slice(keys, func(i, j int) bool { return uintStringsAreSorted(keys[i].Uint(), keys[j].Uint()) })
   396  			}
   397  
   398  		default:
   399  			return constructUnsupportedTypeCodec(t)
   400  		}
   401  	}
   402  
   403  	if inlined(v) {
   404  		vc.encode = constructInlineValueEncodeFunc(vc.encode)
   405  	}
   406  
   407  	return codec{
   408  		encode: constructMapEncodeFunc(t, kc.encode, vc.encode, sortKeys),
   409  		decode: constructMapDecodeFunc(t, kc.decode, vc.decode),
   410  	}
   411  }
   412  
   413  func constructMapEncodeFunc(t reflect.Type, encodeKey, encodeValue encodeFunc, sortKeys sortFunc) encodeFunc {
   414  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   415  		return e.encodeMap(b, p, t, encodeKey, encodeValue, sortKeys)
   416  	}
   417  }
   418  
   419  func constructMapDecodeFunc(t reflect.Type, decodeKey, decodeValue decodeFunc) decodeFunc {
   420  	kt := t.Key()
   421  	vt := t.Elem()
   422  	kz := reflect.Zero(kt)
   423  	vz := reflect.Zero(vt)
   424  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   425  		return d.decodeMap(b, p, t, kt, vt, kz, vz, decodeKey, decodeValue)
   426  	}
   427  }
   428  
   429  func constructStructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec {
   430  	st := constructStructType(t, seen, canAddr)
   431  	return codec{
   432  		encode: constructStructEncodeFunc(st),
   433  		decode: constructStructDecodeFunc(st),
   434  	}
   435  }
   436  
   437  func constructStructType(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) *structType {
   438  	// Used for preventing infinite recursion on types that have pointers to
   439  	// themselves.
   440  	st := seen[t]
   441  
   442  	if st == nil {
   443  		st = &structType{
   444  			fields:      make([]structField, 0, t.NumField()),
   445  			fieldsIndex: make(map[string]*structField),
   446  			ficaseIndex: make(map[string]*structField),
   447  			typ:         t,
   448  		}
   449  
   450  		seen[t] = st
   451  		st.fields = appendStructFields(st.fields, t, 0, seen, canAddr)
   452  
   453  		for i := range st.fields {
   454  			f := &st.fields[i]
   455  			s := strings.ToLower(f.name)
   456  			st.fieldsIndex[f.name] = f
   457  			// When there is ambiguity because multiple fields have the same
   458  			// case-insensitive representation, the first field must win.
   459  			if _, exists := st.ficaseIndex[s]; !exists {
   460  				st.ficaseIndex[s] = f
   461  			}
   462  		}
   463  	}
   464  
   465  	return st
   466  }
   467  
   468  func constructStructEncodeFunc(st *structType) encodeFunc {
   469  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   470  		return e.encodeStruct(b, p, st)
   471  	}
   472  }
   473  
   474  func constructStructDecodeFunc(st *structType) decodeFunc {
   475  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   476  		return d.decodeStruct(b, p, st)
   477  	}
   478  }
   479  
   480  func constructEmbeddedStructPointerCodec(t reflect.Type, unexported bool, offset uintptr, field codec) codec {
   481  	return codec{
   482  		encode: constructEmbeddedStructPointerEncodeFunc(t, unexported, offset, field.encode),
   483  		decode: constructEmbeddedStructPointerDecodeFunc(t, unexported, offset, field.decode),
   484  	}
   485  }
   486  
   487  func constructEmbeddedStructPointerEncodeFunc(t reflect.Type, unexported bool, offset uintptr, encode encodeFunc) encodeFunc {
   488  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   489  		return e.encodeEmbeddedStructPointer(b, p, t, unexported, offset, encode)
   490  	}
   491  }
   492  
   493  func constructEmbeddedStructPointerDecodeFunc(t reflect.Type, unexported bool, offset uintptr, decode decodeFunc) decodeFunc {
   494  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   495  		return d.decodeEmbeddedStructPointer(b, p, t, unexported, offset, decode)
   496  	}
   497  }
   498  
   499  func appendStructFields(fields []structField, t reflect.Type, offset uintptr, seen map[reflect.Type]*structType, canAddr bool) []structField {
   500  	type embeddedField struct {
   501  		index      int
   502  		offset     uintptr
   503  		pointer    bool
   504  		unexported bool
   505  		subtype    *structType
   506  		subfield   *structField
   507  	}
   508  
   509  	names := make(map[string]struct{})
   510  	embedded := make([]embeddedField, 0, 10)
   511  
   512  	for i, n := 0, t.NumField(); i < n; i++ {
   513  		f := t.Field(i)
   514  
   515  		var (
   516  			name       = f.Name
   517  			anonymous  = f.Anonymous
   518  			tag        = false
   519  			omitempty  = false
   520  			stringify  = false
   521  			unexported = len(f.PkgPath) != 0
   522  		)
   523  
   524  		if unexported && !anonymous { // unexported
   525  			continue
   526  		}
   527  
   528  		if parts := strings.Split(f.Tag.Get("json"), ","); len(parts) != 0 {
   529  			if len(parts[0]) != 0 {
   530  				name, tag = parts[0], true
   531  			}
   532  
   533  			if name == "-" && len(parts) == 1 { // ignored
   534  				continue
   535  			}
   536  
   537  			if !isValidTag(name) {
   538  				name = f.Name
   539  			}
   540  
   541  			for _, tag := range parts[1:] {
   542  				switch tag {
   543  				case "omitempty":
   544  					omitempty = true
   545  				case "string":
   546  					stringify = true
   547  				}
   548  			}
   549  		}
   550  
   551  		if anonymous && !tag { // embedded
   552  			typ := f.Type
   553  			ptr := f.Type.Kind() == reflect.Ptr
   554  
   555  			if ptr {
   556  				typ = f.Type.Elem()
   557  			}
   558  
   559  			if typ.Kind() == reflect.Struct {
   560  				// When the embedded fields is inlined the fields can be looked
   561  				// up by offset from the address of the wrapping object, so we
   562  				// simply add the embedded struct fields to the list of fields
   563  				// of the current struct type.
   564  				subtype := constructStructType(typ, seen, canAddr)
   565  
   566  				for j := range subtype.fields {
   567  					embedded = append(embedded, embeddedField{
   568  						index:      i<<32 | j,
   569  						offset:     offset + f.Offset,
   570  						pointer:    ptr,
   571  						unexported: unexported,
   572  						subtype:    subtype,
   573  						subfield:   &subtype.fields[j],
   574  					})
   575  				}
   576  
   577  				continue
   578  			}
   579  
   580  			if unexported { // ignore unexported non-struct types
   581  				continue
   582  			}
   583  		}
   584  
   585  		codec := constructCodec(f.Type, seen, canAddr)
   586  
   587  		if stringify {
   588  			// https://golang.org/pkg/encoding/json/#Marshal
   589  			//
   590  			// The "string" option signals that a field is stored as JSON inside
   591  			// a JSON-encoded string. It applies only to fields of string,
   592  			// floating point, integer, or boolean types. This extra level of
   593  			// encoding is sometimes used when communicating with JavaScript
   594  			// programs:
   595  			typ := f.Type
   596  
   597  			if typ.Kind() == reflect.Ptr {
   598  				typ = typ.Elem()
   599  			}
   600  
   601  			switch typ.Kind() {
   602  			case reflect.Int,
   603  				reflect.Int8,
   604  				reflect.Int16,
   605  				reflect.Int32,
   606  				reflect.Int64,
   607  				reflect.Uint,
   608  				reflect.Uintptr,
   609  				reflect.Uint8,
   610  				reflect.Uint16,
   611  				reflect.Uint32,
   612  				reflect.Uint64:
   613  				codec.encode = constructStringEncodeFunc(codec.encode)
   614  				codec.decode = constructStringToIntDecodeFunc(typ, codec.decode)
   615  			case reflect.Bool,
   616  				reflect.Float32,
   617  				reflect.Float64,
   618  				reflect.String:
   619  				codec.encode = constructStringEncodeFunc(codec.encode)
   620  				codec.decode = constructStringDecodeFunc(codec.decode)
   621  			}
   622  		}
   623  
   624  		fields = append(fields, structField{
   625  			codec:     codec,
   626  			offset:    offset + f.Offset,
   627  			empty:     emptyFuncOf(f.Type),
   628  			tag:       tag,
   629  			omitempty: omitempty,
   630  			name:      name,
   631  			index:     i << 32,
   632  			typ:       f.Type,
   633  			zero:      reflect.Zero(f.Type),
   634  		})
   635  
   636  		names[name] = struct{}{}
   637  	}
   638  
   639  	// Only unambiguous embedded fields must be serialized.
   640  	ambiguousNames := make(map[string]int)
   641  	ambiguousTags := make(map[string]int)
   642  
   643  	// Embedded types can never override a field that was already present at
   644  	// the top-level.
   645  	for name := range names {
   646  		ambiguousNames[name]++
   647  		ambiguousTags[name]++
   648  	}
   649  
   650  	for _, embfield := range embedded {
   651  		ambiguousNames[embfield.subfield.name]++
   652  		if embfield.subfield.tag {
   653  			ambiguousTags[embfield.subfield.name]++
   654  		}
   655  	}
   656  
   657  	for _, embfield := range embedded {
   658  		subfield := *embfield.subfield
   659  
   660  		if ambiguousNames[subfield.name] > 1 && !(subfield.tag && ambiguousTags[subfield.name] == 1) {
   661  			continue // ambiguous embedded field
   662  		}
   663  
   664  		if embfield.pointer {
   665  			subfield.codec = constructEmbeddedStructPointerCodec(embfield.subtype.typ, embfield.unexported, subfield.offset, subfield.codec)
   666  			subfield.offset = embfield.offset
   667  		} else {
   668  			subfield.offset += embfield.offset
   669  		}
   670  
   671  		// To prevent dominant flags more than one level below the embedded one.
   672  		subfield.tag = false
   673  
   674  		// To ensure the order of the fields in the output is the same is in the
   675  		// struct type.
   676  		subfield.index = embfield.index
   677  
   678  		fields = append(fields, subfield)
   679  	}
   680  
   681  	for i := range fields {
   682  		fields[i].json = encodeString(fields[i].name, 0)
   683  		fields[i].html = encodeString(fields[i].name, EscapeHTML)
   684  	}
   685  
   686  	sort.Slice(fields, func(i, j int) bool { return fields[i].index < fields[j].index })
   687  	return fields
   688  }
   689  
   690  func encodeString(s string, flags AppendFlags) string {
   691  	b := make([]byte, 0, len(s)+2)
   692  	e := encoder{flags: flags}
   693  	b, _ = e.doEncodeString(b, unsafe.Pointer(&s))
   694  	return *(*string)(unsafe.Pointer(&b))
   695  }
   696  
   697  func constructPointerCodec(t reflect.Type, seen map[reflect.Type]*structType) codec {
   698  	e := t.Elem()
   699  	c := constructCodec(e, seen, true)
   700  	return codec{
   701  		encode: constructPointerEncodeFunc(e, c.encode),
   702  		decode: constructPointerDecodeFunc(e, c.decode),
   703  	}
   704  }
   705  
   706  func constructPointerEncodeFunc(t reflect.Type, encode encodeFunc) encodeFunc {
   707  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   708  		return e.encodePointer(b, p, t, encode)
   709  	}
   710  }
   711  
   712  func constructPointerDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc {
   713  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   714  		return d.decodePointer(b, p, t, decode)
   715  	}
   716  }
   717  
   718  func constructInterfaceCodec(t reflect.Type) codec {
   719  	return codec{
   720  		encode: constructMaybeEmptyInterfaceEncoderFunc(t),
   721  		decode: constructMaybeEmptyInterfaceDecoderFunc(t),
   722  	}
   723  }
   724  
   725  func constructMaybeEmptyInterfaceEncoderFunc(t reflect.Type) encodeFunc {
   726  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   727  		return e.encodeMaybeEmptyInterface(b, p, t)
   728  	}
   729  }
   730  
   731  func constructMaybeEmptyInterfaceDecoderFunc(t reflect.Type) decodeFunc {
   732  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   733  		return d.decodeMaybeEmptyInterface(b, p, t)
   734  	}
   735  }
   736  
   737  func constructUnsupportedTypeCodec(t reflect.Type) codec {
   738  	return codec{
   739  		encode: constructUnsupportedTypeEncodeFunc(t),
   740  		decode: constructUnsupportedTypeDecodeFunc(t),
   741  	}
   742  }
   743  
   744  func constructUnsupportedTypeEncodeFunc(t reflect.Type) encodeFunc {
   745  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   746  		return e.encodeUnsupportedTypeError(b, p, t)
   747  	}
   748  }
   749  
   750  func constructUnsupportedTypeDecodeFunc(t reflect.Type) decodeFunc {
   751  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   752  		return d.decodeUnmarshalTypeError(b, p, t)
   753  	}
   754  }
   755  
   756  func constructJSONMarshalerEncodeFunc(t reflect.Type, pointer bool) encodeFunc {
   757  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   758  		return e.encodeJSONMarshaler(b, p, t, pointer)
   759  	}
   760  }
   761  
   762  func constructJSONUnmarshalerDecodeFunc(t reflect.Type, pointer bool) decodeFunc {
   763  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   764  		return d.decodeJSONUnmarshaler(b, p, t, pointer)
   765  	}
   766  }
   767  
   768  func constructTextMarshalerEncodeFunc(t reflect.Type, pointer bool) encodeFunc {
   769  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   770  		return e.encodeTextMarshaler(b, p, t, pointer)
   771  	}
   772  }
   773  
   774  func constructTextUnmarshalerDecodeFunc(t reflect.Type, pointer bool) decodeFunc {
   775  	return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   776  		return d.decodeTextUnmarshaler(b, p, t, pointer)
   777  	}
   778  }
   779  
   780  func constructInlineValueEncodeFunc(encode encodeFunc) encodeFunc {
   781  	return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
   782  		return encode(e, b, noescape(unsafe.Pointer(&p)))
   783  	}
   784  }
   785  
   786  // noescape hides a pointer from escape analysis.  noescape is
   787  // the identity function but escape analysis doesn't think the
   788  // output depends on the input. noescape is inlined and currently
   789  // compiles down to zero instructions.
   790  // USE CAREFULLY!
   791  // This was copied from the runtime; see issues 23382 and 7921.
   792  //go:nosplit
   793  func noescape(p unsafe.Pointer) unsafe.Pointer {
   794  	x := uintptr(p)
   795  	return unsafe.Pointer(x ^ 0)
   796  }
   797  
   798  func alignedSize(t reflect.Type) uintptr {
   799  	a := t.Align()
   800  	s := t.Size()
   801  	return align(uintptr(a), uintptr(s))
   802  }
   803  
   804  func align(align, size uintptr) uintptr {
   805  	if align != 0 && (size%align) != 0 {
   806  		size = ((size / align) + 1) * align
   807  	}
   808  	return size
   809  }
   810  
   811  func inlined(t reflect.Type) bool {
   812  	switch t.Kind() {
   813  	case reflect.Ptr:
   814  		return true
   815  	case reflect.Map:
   816  		return true
   817  	case reflect.Struct:
   818  		return t.NumField() == 1 && inlined(t.Field(0).Type)
   819  	default:
   820  		return false
   821  	}
   822  }
   823  
   824  func isValidTag(s string) bool {
   825  	if s == "" {
   826  		return false
   827  	}
   828  	for _, c := range s {
   829  		switch {
   830  		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
   831  			// Backslash and quote chars are reserved, but
   832  			// otherwise any punctuation chars are allowed
   833  			// in a tag name.
   834  		default:
   835  			if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
   836  				return false
   837  			}
   838  		}
   839  	}
   840  	return true
   841  }
   842  
   843  func emptyFuncOf(t reflect.Type) emptyFunc {
   844  	switch t {
   845  	case bytesType, rawMessageType:
   846  		return func(p unsafe.Pointer) bool { return (*slice)(p).len == 0 }
   847  	}
   848  
   849  	switch t.Kind() {
   850  	case reflect.Array:
   851  		if t.Len() == 0 {
   852  			return func(unsafe.Pointer) bool { return true }
   853  		}
   854  
   855  	case reflect.Map:
   856  		return func(p unsafe.Pointer) bool { return reflect.NewAt(t, p).Elem().Len() == 0 }
   857  
   858  	case reflect.Slice:
   859  		return func(p unsafe.Pointer) bool { return (*slice)(p).len == 0 }
   860  
   861  	case reflect.String:
   862  		return func(p unsafe.Pointer) bool { return len(*(*string)(p)) == 0 }
   863  
   864  	case reflect.Bool:
   865  		return func(p unsafe.Pointer) bool { return !*(*bool)(p) }
   866  
   867  	case reflect.Int, reflect.Uint:
   868  		return func(p unsafe.Pointer) bool { return *(*uint)(p) == 0 }
   869  
   870  	case reflect.Uintptr:
   871  		return func(p unsafe.Pointer) bool { return *(*uintptr)(p) == 0 }
   872  
   873  	case reflect.Int8, reflect.Uint8:
   874  		return func(p unsafe.Pointer) bool { return *(*uint8)(p) == 0 }
   875  
   876  	case reflect.Int16, reflect.Uint16:
   877  		return func(p unsafe.Pointer) bool { return *(*uint16)(p) == 0 }
   878  
   879  	case reflect.Int32, reflect.Uint32:
   880  		return func(p unsafe.Pointer) bool { return *(*uint32)(p) == 0 }
   881  
   882  	case reflect.Int64, reflect.Uint64:
   883  		return func(p unsafe.Pointer) bool { return *(*uint64)(p) == 0 }
   884  
   885  	case reflect.Float32:
   886  		return func(p unsafe.Pointer) bool { return *(*float32)(p) == 0 }
   887  
   888  	case reflect.Float64:
   889  		return func(p unsafe.Pointer) bool { return *(*float64)(p) == 0 }
   890  
   891  	case reflect.Ptr:
   892  		return func(p unsafe.Pointer) bool { return *(*unsafe.Pointer)(p) == nil }
   893  
   894  	case reflect.Interface:
   895  		return func(p unsafe.Pointer) bool { return (*iface)(p).ptr == nil }
   896  	}
   897  
   898  	return func(unsafe.Pointer) bool { return false }
   899  }
   900  
   901  type iface struct {
   902  	typ unsafe.Pointer
   903  	ptr unsafe.Pointer
   904  }
   905  
   906  type slice struct {
   907  	data unsafe.Pointer
   908  	len  int
   909  	cap  int
   910  }
   911  
   912  type structType struct {
   913  	fields      []structField
   914  	fieldsIndex map[string]*structField
   915  	ficaseIndex map[string]*structField
   916  	typ         reflect.Type
   917  	inlined     bool
   918  }
   919  
   920  type structField struct {
   921  	codec     codec
   922  	offset    uintptr
   923  	empty     emptyFunc
   924  	tag       bool
   925  	omitempty bool
   926  	json      string
   927  	html      string
   928  	name      string
   929  	typ       reflect.Type
   930  	zero      reflect.Value
   931  	index     int
   932  }
   933  
   934  func unmarshalTypeError(b []byte, t reflect.Type) error {
   935  	return &UnmarshalTypeError{Value: strconv.Quote(prefix(b)), Type: t}
   936  }
   937  
   938  func unmarshalOverflow(b []byte, t reflect.Type) error {
   939  	return &UnmarshalTypeError{Value: "number " + prefix(b) + " overflows", Type: t}
   940  }
   941  
   942  func unexpectedEOF(b []byte) error {
   943  	return syntaxError(b, "unexpected end of JSON input")
   944  }
   945  
   946  var syntaxErrorMsgOffset = ^uintptr(0)
   947  
   948  func init() {
   949  	t := reflect.TypeOf(SyntaxError{})
   950  	for i, n := 0, t.NumField(); i < n; i++ {
   951  		if f := t.Field(i); f.Type.Kind() == reflect.String {
   952  			syntaxErrorMsgOffset = f.Offset
   953  		}
   954  	}
   955  }
   956  
   957  func syntaxError(b []byte, msg string, args ...interface{}) error {
   958  	e := new(SyntaxError)
   959  	i := syntaxErrorMsgOffset
   960  	if i != ^uintptr(0) {
   961  		s := "json: " + fmt.Sprintf(msg, args...) + ": " + prefix(b)
   962  		p := unsafe.Pointer(e)
   963  		// Hack to set the unexported `msg` field.
   964  		*(*string)(unsafe.Pointer(uintptr(p) + i)) = s
   965  	}
   966  	return e
   967  }
   968  
   969  func inputError(b []byte, t reflect.Type) ([]byte, error) {
   970  	if len(b) == 0 {
   971  		return nil, unexpectedEOF(b)
   972  	}
   973  	_, r, err := parseValue(b)
   974  	if err != nil {
   975  		return r, err
   976  	}
   977  	return skipSpaces(r), unmarshalTypeError(b, t)
   978  }
   979  
   980  func objectKeyError(b []byte, err error) ([]byte, error) {
   981  	if len(b) == 0 {
   982  		return nil, unexpectedEOF(b)
   983  	}
   984  	switch err.(type) {
   985  	case *UnmarshalTypeError:
   986  		err = syntaxError(b, "invalid character '%c' looking for beginning of object key", b[0])
   987  	}
   988  	return b, err
   989  }
   990  
   991  func prefix(b []byte) string {
   992  	if len(b) < 32 {
   993  		return string(b)
   994  	}
   995  	return string(b[:32]) + "..."
   996  }
   997  
   998  func intStringsAreSorted(i0, i1 int64) bool {
   999  	var b0, b1 [32]byte
  1000  	return string(strconv.AppendInt(b0[:0], i0, 10)) < string(strconv.AppendInt(b1[:0], i1, 10))
  1001  }
  1002  
  1003  func uintStringsAreSorted(u0, u1 uint64) bool {
  1004  	var b0, b1 [32]byte
  1005  	return string(strconv.AppendUint(b0[:0], u0, 10)) < string(strconv.AppendUint(b1[:0], u1, 10))
  1006  }
  1007  
  1008  //go:nosplit
  1009  func stringToBytes(s string) []byte {
  1010  	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ // nolint:govet // from segment's code
  1011  		Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data,
  1012  		Len:  len(s),
  1013  		Cap:  len(s),
  1014  	}))
  1015  }
  1016  
  1017  var (
  1018  	nullType = reflect.TypeOf(nil)
  1019  	boolType = reflect.TypeOf(false)
  1020  
  1021  	intType   = reflect.TypeOf(int(0))
  1022  	int8Type  = reflect.TypeOf(int8(0))
  1023  	int16Type = reflect.TypeOf(int16(0))
  1024  	int32Type = reflect.TypeOf(int32(0))
  1025  	int64Type = reflect.TypeOf(int64(0))
  1026  
  1027  	uintType    = reflect.TypeOf(uint(0))
  1028  	uint8Type   = reflect.TypeOf(uint8(0))
  1029  	uint16Type  = reflect.TypeOf(uint16(0))
  1030  	uint32Type  = reflect.TypeOf(uint32(0))
  1031  	uint64Type  = reflect.TypeOf(uint64(0))
  1032  	uintptrType = reflect.TypeOf(uintptr(0))
  1033  
  1034  	float32Type = reflect.TypeOf(float32(0))
  1035  	float64Type = reflect.TypeOf(float64(0))
  1036  
  1037  	numberType     = reflect.TypeOf(json.Number(""))
  1038  	stringType     = reflect.TypeOf("")
  1039  	bytesType      = reflect.TypeOf(([]byte)(nil))
  1040  	durationType   = reflect.TypeOf(time.Duration(0))
  1041  	timeType       = reflect.TypeOf(time.Time{})
  1042  	rawMessageType = reflect.TypeOf(RawMessage(nil))
  1043  
  1044  	numberPtrType     = reflect.PtrTo(numberType)
  1045  	durationPtrType   = reflect.PtrTo(durationType)
  1046  	timePtrType       = reflect.PtrTo(timeType)
  1047  	rawMessagePtrType = reflect.PtrTo(rawMessageType)
  1048  
  1049  	sliceInterfaceType      = reflect.TypeOf(([]interface{})(nil))
  1050  	mapStringInterfaceType  = reflect.TypeOf((map[string]interface{})(nil))
  1051  	mapStringRawMessageType = reflect.TypeOf((map[string]RawMessage)(nil))
  1052  
  1053  	interfaceType       = reflect.TypeOf((*interface{})(nil)).Elem()
  1054  	jsonMarshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
  1055  	jsonUnmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
  1056  	textMarshalerType   = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
  1057  	textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
  1058  )
  1059  
  1060  // =============================================================================
  1061  // Copyright 2009 The Go Authors. All rights reserved.
  1062  // Use of this source code is governed by a BSD-style
  1063  // license that can be found in the LICENSE file.
  1064  
  1065  // appendDuration appends a human-readable representation of d to b.
  1066  //
  1067  // The function copies the implementation of time.Duration.String but prevents
  1068  // Go from making a dynamic memory allocation on the returned value.
  1069  func appendDuration(b []byte, d time.Duration) []byte {
  1070  	// Largest time is 2540400h10m10.000000000s
  1071  	var buf [32]byte
  1072  	w := len(buf)
  1073  
  1074  	u := uint64(d)
  1075  	neg := d < 0
  1076  	if neg {
  1077  		u = -u
  1078  	}
  1079  
  1080  	if u < uint64(time.Second) {
  1081  		// Special case: if duration is smaller than a second,
  1082  		// use smaller units, like 1.2ms
  1083  		var prec int
  1084  		w--
  1085  		buf[w] = 's'
  1086  		w--
  1087  		switch {
  1088  		case u == 0:
  1089  			return append(b, '0', 's')
  1090  		case u < uint64(time.Microsecond):
  1091  			// print nanoseconds
  1092  			prec = 0
  1093  			buf[w] = 'n'
  1094  		case u < uint64(time.Millisecond):
  1095  			// print microseconds
  1096  			prec = 3
  1097  			// U+00B5 'µ' micro sign == 0xC2 0xB5
  1098  			w-- // Need room for two bytes.
  1099  			copy(buf[w:], "µ")
  1100  		default:
  1101  			// print milliseconds
  1102  			prec = 6
  1103  			buf[w] = 'm'
  1104  		}
  1105  		w, u = fmtFrac(buf[:w], u, prec)
  1106  		w = fmtInt(buf[:w], u)
  1107  	} else {
  1108  		w--
  1109  		buf[w] = 's'
  1110  
  1111  		w, u = fmtFrac(buf[:w], u, 9)
  1112  
  1113  		// u is now integer seconds
  1114  		w = fmtInt(buf[:w], u%60)
  1115  		u /= 60
  1116  
  1117  		// u is now integer minutes
  1118  		if u > 0 {
  1119  			w--
  1120  			buf[w] = 'm'
  1121  			w = fmtInt(buf[:w], u%60)
  1122  			u /= 60
  1123  
  1124  			// u is now integer hours
  1125  			// Stop at hours because days can be different lengths.
  1126  			if u > 0 {
  1127  				w--
  1128  				buf[w] = 'h'
  1129  				w = fmtInt(buf[:w], u)
  1130  			}
  1131  		}
  1132  	}
  1133  
  1134  	if neg {
  1135  		w--
  1136  		buf[w] = '-'
  1137  	}
  1138  
  1139  	return append(b, buf[w:]...)
  1140  }
  1141  
  1142  // fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the
  1143  // tail of buf, omitting trailing zeros.  it omits the decimal
  1144  // point too when the fraction is 0.  It returns the index where the
  1145  // output bytes begin and the value v/10**prec.
  1146  func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) {
  1147  	// Omit trailing zeros up to and including decimal point.
  1148  	w := len(buf)
  1149  	print := false
  1150  	for i := 0; i < prec; i++ {
  1151  		digit := v % 10
  1152  		print = print || digit != 0
  1153  		if print {
  1154  			w--
  1155  			buf[w] = byte(digit) + '0'
  1156  		}
  1157  		v /= 10
  1158  	}
  1159  	if print {
  1160  		w--
  1161  		buf[w] = '.'
  1162  	}
  1163  	return w, v
  1164  }
  1165  
  1166  // fmtInt formats v into the tail of buf.
  1167  // It returns the index where the output begins.
  1168  func fmtInt(buf []byte, v uint64) int {
  1169  	w := len(buf)
  1170  	if v == 0 {
  1171  		w--
  1172  		buf[w] = '0'
  1173  	} else {
  1174  		for v > 0 {
  1175  			w--
  1176  			buf[w] = byte(v%10) + '0'
  1177  			v /= 10
  1178  		}
  1179  	}
  1180  	return w
  1181  }
  1182  
  1183  // =============================================================================