1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  
    10  
    11  package json
    12  
    13  import (
    14  	"bytes"
    15  	"encoding"
    16  	"encoding/base64"
    17  	"fmt"
    18  	"math"
    19  	"reflect"
    20  	"slices"
    21  	"sort"
    22  	"strconv"
    23  	"strings"
    24  	"sync"
    25  	"unicode"
    26  	"unicode/utf8"
    27  )
    28  
    29  
    30  
    31  
    32  
    33  
    34  
    35  
    36  
    37  
    38  
    39  
    40  
    41  
    42  
    43  
    44  
    45  
    46  
    47  
    48  
    49  
    50  
    51  
    52  
    53  
    54  
    55  
    56  
    57  
    58  
    59  
    60  
    61  
    62  
    63  
    64  
    65  
    66  
    67  
    68  
    69  
    70  
    71  
    72  
    73  
    74  
    75  
    76  
    77  
    78  
    79  
    80  
    81  
    82  
    83  
    84  
    85  
    86  
    87  
    88  
    89  
    90  
    91  
    92  
    93  
    94  
    95  
    96  
    97  
    98  
    99  
   100  
   101  
   102  
   103  
   104  
   105  
   106  
   107  
   108  
   109  
   110  
   111  
   112  
   113  
   114  
   115  
   116  
   117  
   118  
   119  
   120  
   121  
   122  
   123  
   124  
   125  
   126  
   127  
   128  
   129  
   130  
   131  
   132  
   133  
   134  
   135  
   136  
   137  
   138  
   139  
   140  
   141  
   142  
   143  
   144  
   145  
   146  
   147  
   148  
   149  
   150  
   151  
   152  
   153  
   154  
   155  
   156  
   157  
   158  
   159  func Marshal(v any) ([]byte, error) {
   160  	e := newEncodeState()
   161  	defer encodeStatePool.Put(e)
   162  
   163  	err := e.marshal(v, encOpts{escapeHTML: true})
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  	buf := append([]byte(nil), e.Bytes()...)
   168  
   169  	return buf, nil
   170  }
   171  
   172  
   173  
   174  
   175  func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
   176  	b, err := Marshal(v)
   177  	if err != nil {
   178  		return nil, err
   179  	}
   180  	b2 := make([]byte, 0, indentGrowthFactor*len(b))
   181  	b2, err = appendIndent(b2, b, prefix, indent)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  	return b2, nil
   186  }
   187  
   188  
   189  
   190  type Marshaler interface {
   191  	MarshalJSON() ([]byte, error)
   192  }
   193  
   194  
   195  
   196  type UnsupportedTypeError struct {
   197  	Type reflect.Type
   198  }
   199  
   200  func (e *UnsupportedTypeError) Error() string {
   201  	return "json: unsupported type: " + e.Type.String()
   202  }
   203  
   204  
   205  
   206  type UnsupportedValueError struct {
   207  	Value reflect.Value
   208  	Str   string
   209  }
   210  
   211  func (e *UnsupportedValueError) Error() string {
   212  	return "json: unsupported value: " + e.Str
   213  }
   214  
   215  
   216  
   217  
   218  
   219  
   220  
   221  type InvalidUTF8Error struct {
   222  	S string 
   223  }
   224  
   225  func (e *InvalidUTF8Error) Error() string {
   226  	return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
   227  }
   228  
   229  
   230  
   231  type MarshalerError struct {
   232  	Type       reflect.Type
   233  	Err        error
   234  	sourceFunc string
   235  }
   236  
   237  func (e *MarshalerError) Error() string {
   238  	srcFunc := e.sourceFunc
   239  	if srcFunc == "" {
   240  		srcFunc = "MarshalJSON"
   241  	}
   242  	return "json: error calling " + srcFunc +
   243  		" for type " + e.Type.String() +
   244  		": " + e.Err.Error()
   245  }
   246  
   247  
   248  func (e *MarshalerError) Unwrap() error { return e.Err }
   249  
   250  const hex = "0123456789abcdef"
   251  
   252  
   253  type encodeState struct {
   254  	bytes.Buffer 
   255  
   256  	
   257  	
   258  	
   259  	
   260  	
   261  	ptrLevel uint
   262  	ptrSeen  map[any]struct{}
   263  }
   264  
   265  const startDetectingCyclesAfter = 1000
   266  
   267  var encodeStatePool sync.Pool
   268  
   269  func newEncodeState() *encodeState {
   270  	if v := encodeStatePool.Get(); v != nil {
   271  		e := v.(*encodeState)
   272  		e.Reset()
   273  		if len(e.ptrSeen) > 0 {
   274  			panic("ptrEncoder.encode should have emptied ptrSeen via defers")
   275  		}
   276  		e.ptrLevel = 0
   277  		return e
   278  	}
   279  	return &encodeState{ptrSeen: make(map[any]struct{})}
   280  }
   281  
   282  
   283  
   284  
   285  type jsonError struct{ error }
   286  
   287  func (e *encodeState) marshal(v any, opts encOpts) (err error) {
   288  	defer func() {
   289  		if r := recover(); r != nil {
   290  			if je, ok := r.(jsonError); ok {
   291  				err = je.error
   292  			} else {
   293  				panic(r)
   294  			}
   295  		}
   296  	}()
   297  	e.reflectValue(reflect.ValueOf(v), opts)
   298  	return nil
   299  }
   300  
   301  
   302  func (e *encodeState) error(err error) {
   303  	panic(jsonError{err})
   304  }
   305  
   306  func isEmptyValue(v reflect.Value) bool {
   307  	switch v.Kind() {
   308  	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
   309  		return v.Len() == 0
   310  	case reflect.Bool,
   311  		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
   312  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
   313  		reflect.Float32, reflect.Float64,
   314  		reflect.Interface, reflect.Pointer:
   315  		return v.IsZero()
   316  	}
   317  	return false
   318  }
   319  
   320  func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
   321  	valueEncoder(v)(e, v, opts)
   322  }
   323  
   324  type encOpts struct {
   325  	
   326  	quoted bool
   327  	
   328  	escapeHTML bool
   329  }
   330  
   331  type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
   332  
   333  var encoderCache sync.Map 
   334  
   335  func valueEncoder(v reflect.Value) encoderFunc {
   336  	if !v.IsValid() {
   337  		return invalidValueEncoder
   338  	}
   339  	return typeEncoder(v.Type())
   340  }
   341  
   342  func typeEncoder(t reflect.Type) encoderFunc {
   343  	if fi, ok := encoderCache.Load(t); ok {
   344  		return fi.(encoderFunc)
   345  	}
   346  
   347  	
   348  	
   349  	
   350  	
   351  	var (
   352  		wg sync.WaitGroup
   353  		f  encoderFunc
   354  	)
   355  	wg.Add(1)
   356  	fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
   357  		wg.Wait()
   358  		f(e, v, opts)
   359  	}))
   360  	if loaded {
   361  		return fi.(encoderFunc)
   362  	}
   363  
   364  	
   365  	f = newTypeEncoder(t, true)
   366  	wg.Done()
   367  	encoderCache.Store(t, f)
   368  	return f
   369  }
   370  
   371  var (
   372  	marshalerType     = reflect.TypeFor[Marshaler]()
   373  	textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]()
   374  )
   375  
   376  
   377  
   378  func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
   379  	
   380  	
   381  	
   382  	
   383  	if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
   384  		return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
   385  	}
   386  	if t.Implements(marshalerType) {
   387  		return marshalerEncoder
   388  	}
   389  	if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
   390  		return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
   391  	}
   392  	if t.Implements(textMarshalerType) {
   393  		return textMarshalerEncoder
   394  	}
   395  
   396  	switch t.Kind() {
   397  	case reflect.Bool:
   398  		return boolEncoder
   399  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   400  		return intEncoder
   401  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   402  		return uintEncoder
   403  	case reflect.Float32:
   404  		return float32Encoder
   405  	case reflect.Float64:
   406  		return float64Encoder
   407  	case reflect.String:
   408  		return stringEncoder
   409  	case reflect.Interface:
   410  		return interfaceEncoder
   411  	case reflect.Struct:
   412  		return newStructEncoder(t)
   413  	case reflect.Map:
   414  		return newMapEncoder(t)
   415  	case reflect.Slice:
   416  		return newSliceEncoder(t)
   417  	case reflect.Array:
   418  		return newArrayEncoder(t)
   419  	case reflect.Pointer:
   420  		return newPtrEncoder(t)
   421  	default:
   422  		return unsupportedTypeEncoder
   423  	}
   424  }
   425  
   426  func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
   427  	e.WriteString("null")
   428  }
   429  
   430  func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   431  	if v.Kind() == reflect.Pointer && v.IsNil() {
   432  		e.WriteString("null")
   433  		return
   434  	}
   435  	m, ok := v.Interface().(Marshaler)
   436  	if !ok {
   437  		e.WriteString("null")
   438  		return
   439  	}
   440  	b, err := m.MarshalJSON()
   441  	if err == nil {
   442  		e.Grow(len(b))
   443  		out := e.AvailableBuffer()
   444  		out, err = appendCompact(out, b, opts.escapeHTML)
   445  		e.Buffer.Write(out)
   446  	}
   447  	if err != nil {
   448  		e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
   449  	}
   450  }
   451  
   452  func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   453  	va := v.Addr()
   454  	if va.IsNil() {
   455  		e.WriteString("null")
   456  		return
   457  	}
   458  	m := va.Interface().(Marshaler)
   459  	b, err := m.MarshalJSON()
   460  	if err == nil {
   461  		e.Grow(len(b))
   462  		out := e.AvailableBuffer()
   463  		out, err = appendCompact(out, b, opts.escapeHTML)
   464  		e.Buffer.Write(out)
   465  	}
   466  	if err != nil {
   467  		e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
   468  	}
   469  }
   470  
   471  func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   472  	if v.Kind() == reflect.Pointer && v.IsNil() {
   473  		e.WriteString("null")
   474  		return
   475  	}
   476  	m, ok := v.Interface().(encoding.TextMarshaler)
   477  	if !ok {
   478  		e.WriteString("null")
   479  		return
   480  	}
   481  	b, err := m.MarshalText()
   482  	if err != nil {
   483  		e.error(&MarshalerError{v.Type(), err, "MarshalText"})
   484  	}
   485  	e.Write(appendString(e.AvailableBuffer(), b, opts.escapeHTML))
   486  }
   487  
   488  func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   489  	va := v.Addr()
   490  	if va.IsNil() {
   491  		e.WriteString("null")
   492  		return
   493  	}
   494  	m := va.Interface().(encoding.TextMarshaler)
   495  	b, err := m.MarshalText()
   496  	if err != nil {
   497  		e.error(&MarshalerError{v.Type(), err, "MarshalText"})
   498  	}
   499  	e.Write(appendString(e.AvailableBuffer(), b, opts.escapeHTML))
   500  }
   501  
   502  func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   503  	b := e.AvailableBuffer()
   504  	b = mayAppendQuote(b, opts.quoted)
   505  	b = strconv.AppendBool(b, v.Bool())
   506  	b = mayAppendQuote(b, opts.quoted)
   507  	e.Write(b)
   508  }
   509  
   510  func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   511  	b := e.AvailableBuffer()
   512  	b = mayAppendQuote(b, opts.quoted)
   513  	b = strconv.AppendInt(b, v.Int(), 10)
   514  	b = mayAppendQuote(b, opts.quoted)
   515  	e.Write(b)
   516  }
   517  
   518  func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   519  	b := e.AvailableBuffer()
   520  	b = mayAppendQuote(b, opts.quoted)
   521  	b = strconv.AppendUint(b, v.Uint(), 10)
   522  	b = mayAppendQuote(b, opts.quoted)
   523  	e.Write(b)
   524  }
   525  
   526  type floatEncoder int 
   527  
   528  func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   529  	f := v.Float()
   530  	if math.IsInf(f, 0) || math.IsNaN(f) {
   531  		e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
   532  	}
   533  
   534  	
   535  	
   536  	
   537  	
   538  	
   539  	b := e.AvailableBuffer()
   540  	b = mayAppendQuote(b, opts.quoted)
   541  	abs := math.Abs(f)
   542  	fmt := byte('f')
   543  	
   544  	if abs != 0 {
   545  		if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
   546  			fmt = 'e'
   547  		}
   548  	}
   549  	b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
   550  	if fmt == 'e' {
   551  		
   552  		n := len(b)
   553  		if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
   554  			b[n-2] = b[n-1]
   555  			b = b[:n-1]
   556  		}
   557  	}
   558  	b = mayAppendQuote(b, opts.quoted)
   559  	e.Write(b)
   560  }
   561  
   562  var (
   563  	float32Encoder = (floatEncoder(32)).encode
   564  	float64Encoder = (floatEncoder(64)).encode
   565  )
   566  
   567  func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   568  	if v.Type() == numberType {
   569  		numStr := v.String()
   570  		
   571  		
   572  		if numStr == "" {
   573  			numStr = "0" 
   574  		}
   575  		if !isValidNumber(numStr) {
   576  			e.error(fmt.Errorf("json: invalid number literal %q", numStr))
   577  		}
   578  		b := e.AvailableBuffer()
   579  		b = mayAppendQuote(b, opts.quoted)
   580  		b = append(b, numStr...)
   581  		b = mayAppendQuote(b, opts.quoted)
   582  		e.Write(b)
   583  		return
   584  	}
   585  	if opts.quoted {
   586  		b := appendString(nil, v.String(), opts.escapeHTML)
   587  		e.Write(appendString(e.AvailableBuffer(), b, false)) 
   588  	} else {
   589  		e.Write(appendString(e.AvailableBuffer(), v.String(), opts.escapeHTML))
   590  	}
   591  }
   592  
   593  
   594  func isValidNumber(s string) bool {
   595  	
   596  	
   597  	
   598  
   599  	if s == "" {
   600  		return false
   601  	}
   602  
   603  	
   604  	if s[0] == '-' {
   605  		s = s[1:]
   606  		if s == "" {
   607  			return false
   608  		}
   609  	}
   610  
   611  	
   612  	switch {
   613  	default:
   614  		return false
   615  
   616  	case s[0] == '0':
   617  		s = s[1:]
   618  
   619  	case '1' <= s[0] && s[0] <= '9':
   620  		s = s[1:]
   621  		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
   622  			s = s[1:]
   623  		}
   624  	}
   625  
   626  	
   627  	if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
   628  		s = s[2:]
   629  		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
   630  			s = s[1:]
   631  		}
   632  	}
   633  
   634  	
   635  	
   636  	if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
   637  		s = s[1:]
   638  		if s[0] == '+' || s[0] == '-' {
   639  			s = s[1:]
   640  			if s == "" {
   641  				return false
   642  			}
   643  		}
   644  		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
   645  			s = s[1:]
   646  		}
   647  	}
   648  
   649  	
   650  	return s == ""
   651  }
   652  
   653  func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
   654  	if v.IsNil() {
   655  		e.WriteString("null")
   656  		return
   657  	}
   658  	e.reflectValue(v.Elem(), opts)
   659  }
   660  
   661  func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
   662  	e.error(&UnsupportedTypeError{v.Type()})
   663  }
   664  
   665  type structEncoder struct {
   666  	fields structFields
   667  }
   668  
   669  type structFields struct {
   670  	list         []field
   671  	byExactName  map[string]*field
   672  	byFoldedName map[string]*field
   673  }
   674  
   675  func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   676  	next := byte('{')
   677  FieldLoop:
   678  	for i := range se.fields.list {
   679  		f := &se.fields.list[i]
   680  
   681  		
   682  		fv := v
   683  		for _, i := range f.index {
   684  			if fv.Kind() == reflect.Pointer {
   685  				if fv.IsNil() {
   686  					continue FieldLoop
   687  				}
   688  				fv = fv.Elem()
   689  			}
   690  			fv = fv.Field(i)
   691  		}
   692  
   693  		if f.omitEmpty && isEmptyValue(fv) {
   694  			continue
   695  		}
   696  		e.WriteByte(next)
   697  		next = ','
   698  		if opts.escapeHTML {
   699  			e.WriteString(f.nameEscHTML)
   700  		} else {
   701  			e.WriteString(f.nameNonEsc)
   702  		}
   703  		opts.quoted = f.quoted
   704  		f.encoder(e, fv, opts)
   705  	}
   706  	if next == '{' {
   707  		e.WriteString("{}")
   708  	} else {
   709  		e.WriteByte('}')
   710  	}
   711  }
   712  
   713  func newStructEncoder(t reflect.Type) encoderFunc {
   714  	se := structEncoder{fields: cachedTypeFields(t)}
   715  	return se.encode
   716  }
   717  
   718  type mapEncoder struct {
   719  	elemEnc encoderFunc
   720  }
   721  
   722  func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   723  	if v.IsNil() {
   724  		e.WriteString("null")
   725  		return
   726  	}
   727  	if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
   728  		
   729  		
   730  		ptr := v.UnsafePointer()
   731  		if _, ok := e.ptrSeen[ptr]; ok {
   732  			e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
   733  		}
   734  		e.ptrSeen[ptr] = struct{}{}
   735  		defer delete(e.ptrSeen, ptr)
   736  	}
   737  	e.WriteByte('{')
   738  
   739  	
   740  	var (
   741  		sv  = make([]reflectWithString, v.Len())
   742  		mi  = v.MapRange()
   743  		err error
   744  	)
   745  	for i := 0; mi.Next(); i++ {
   746  		if sv[i].ks, err = resolveKeyName(mi.Key()); err != nil {
   747  			e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
   748  		}
   749  		sv[i].v = mi.Value()
   750  	}
   751  	slices.SortFunc(sv, func(i, j reflectWithString) int {
   752  		return strings.Compare(i.ks, j.ks)
   753  	})
   754  
   755  	for i, kv := range sv {
   756  		if i > 0 {
   757  			e.WriteByte(',')
   758  		}
   759  		e.Write(appendString(e.AvailableBuffer(), kv.ks, opts.escapeHTML))
   760  		e.WriteByte(':')
   761  		me.elemEnc(e, kv.v, opts)
   762  	}
   763  	e.WriteByte('}')
   764  	e.ptrLevel--
   765  }
   766  
   767  func newMapEncoder(t reflect.Type) encoderFunc {
   768  	switch t.Key().Kind() {
   769  	case reflect.String,
   770  		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
   771  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   772  	default:
   773  		if !t.Key().Implements(textMarshalerType) {
   774  			return unsupportedTypeEncoder
   775  		}
   776  	}
   777  	me := mapEncoder{typeEncoder(t.Elem())}
   778  	return me.encode
   779  }
   780  
   781  func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
   782  	if v.IsNil() {
   783  		e.WriteString("null")
   784  		return
   785  	}
   786  
   787  	s := v.Bytes()
   788  	b := e.AvailableBuffer()
   789  	b = append(b, '"')
   790  	b = base64.StdEncoding.AppendEncode(b, s)
   791  	b = append(b, '"')
   792  	e.Write(b)
   793  }
   794  
   795  
   796  type sliceEncoder struct {
   797  	arrayEnc encoderFunc
   798  }
   799  
   800  func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   801  	if v.IsNil() {
   802  		e.WriteString("null")
   803  		return
   804  	}
   805  	if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
   806  		
   807  		
   808  		
   809  		
   810  		ptr := struct {
   811  			ptr interface{} 
   812  			len int
   813  		}{v.UnsafePointer(), v.Len()}
   814  		if _, ok := e.ptrSeen[ptr]; ok {
   815  			e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
   816  		}
   817  		e.ptrSeen[ptr] = struct{}{}
   818  		defer delete(e.ptrSeen, ptr)
   819  	}
   820  	se.arrayEnc(e, v, opts)
   821  	e.ptrLevel--
   822  }
   823  
   824  func newSliceEncoder(t reflect.Type) encoderFunc {
   825  	
   826  	if t.Elem().Kind() == reflect.Uint8 {
   827  		p := reflect.PointerTo(t.Elem())
   828  		if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
   829  			return encodeByteSlice
   830  		}
   831  	}
   832  	enc := sliceEncoder{newArrayEncoder(t)}
   833  	return enc.encode
   834  }
   835  
   836  type arrayEncoder struct {
   837  	elemEnc encoderFunc
   838  }
   839  
   840  func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   841  	e.WriteByte('[')
   842  	n := v.Len()
   843  	for i := 0; i < n; i++ {
   844  		if i > 0 {
   845  			e.WriteByte(',')
   846  		}
   847  		ae.elemEnc(e, v.Index(i), opts)
   848  	}
   849  	e.WriteByte(']')
   850  }
   851  
   852  func newArrayEncoder(t reflect.Type) encoderFunc {
   853  	enc := arrayEncoder{typeEncoder(t.Elem())}
   854  	return enc.encode
   855  }
   856  
   857  type ptrEncoder struct {
   858  	elemEnc encoderFunc
   859  }
   860  
   861  func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   862  	if v.IsNil() {
   863  		e.WriteString("null")
   864  		return
   865  	}
   866  	if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
   867  		
   868  		
   869  		ptr := v.Interface()
   870  		if _, ok := e.ptrSeen[ptr]; ok {
   871  			e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
   872  		}
   873  		e.ptrSeen[ptr] = struct{}{}
   874  		defer delete(e.ptrSeen, ptr)
   875  	}
   876  	pe.elemEnc(e, v.Elem(), opts)
   877  	e.ptrLevel--
   878  }
   879  
   880  func newPtrEncoder(t reflect.Type) encoderFunc {
   881  	enc := ptrEncoder{typeEncoder(t.Elem())}
   882  	return enc.encode
   883  }
   884  
   885  type condAddrEncoder struct {
   886  	canAddrEnc, elseEnc encoderFunc
   887  }
   888  
   889  func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
   890  	if v.CanAddr() {
   891  		ce.canAddrEnc(e, v, opts)
   892  	} else {
   893  		ce.elseEnc(e, v, opts)
   894  	}
   895  }
   896  
   897  
   898  
   899  func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
   900  	enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
   901  	return enc.encode
   902  }
   903  
   904  func isValidTag(s string) bool {
   905  	if s == "" {
   906  		return false
   907  	}
   908  	for _, c := range s {
   909  		switch {
   910  		case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
   911  			
   912  			
   913  			
   914  		case !unicode.IsLetter(c) && !unicode.IsDigit(c):
   915  			return false
   916  		}
   917  	}
   918  	return true
   919  }
   920  
   921  func typeByIndex(t reflect.Type, index []int) reflect.Type {
   922  	for _, i := range index {
   923  		if t.Kind() == reflect.Pointer {
   924  			t = t.Elem()
   925  		}
   926  		t = t.Field(i).Type
   927  	}
   928  	return t
   929  }
   930  
   931  type reflectWithString struct {
   932  	v  reflect.Value
   933  	ks string
   934  }
   935  
   936  func resolveKeyName(k reflect.Value) (string, error) {
   937  	if k.Kind() == reflect.String {
   938  		return k.String(), nil
   939  	}
   940  	if tm, ok := k.Interface().(encoding.TextMarshaler); ok {
   941  		if k.Kind() == reflect.Pointer && k.IsNil() {
   942  			return "", nil
   943  		}
   944  		buf, err := tm.MarshalText()
   945  		return string(buf), err
   946  	}
   947  	switch k.Kind() {
   948  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   949  		return strconv.FormatInt(k.Int(), 10), nil
   950  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   951  		return strconv.FormatUint(k.Uint(), 10), nil
   952  	}
   953  	panic("unexpected map key type")
   954  }
   955  
   956  func appendString[Bytes []byte | string](dst []byte, src Bytes, escapeHTML bool) []byte {
   957  	dst = append(dst, '"')
   958  	start := 0
   959  	for i := 0; i < len(src); {
   960  		if b := src[i]; b < utf8.RuneSelf {
   961  			if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
   962  				i++
   963  				continue
   964  			}
   965  			dst = append(dst, src[start:i]...)
   966  			switch b {
   967  			case '\\', '"':
   968  				dst = append(dst, '\\', b)
   969  			case '\b':
   970  				dst = append(dst, '\\', 'b')
   971  			case '\f':
   972  				dst = append(dst, '\\', 'f')
   973  			case '\n':
   974  				dst = append(dst, '\\', 'n')
   975  			case '\r':
   976  				dst = append(dst, '\\', 'r')
   977  			case '\t':
   978  				dst = append(dst, '\\', 't')
   979  			default:
   980  				
   981  				
   982  				
   983  				
   984  				
   985  				dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
   986  			}
   987  			i++
   988  			start = i
   989  			continue
   990  		}
   991  		
   992  		
   993  		
   994  		
   995  		n := len(src) - i
   996  		if n > utf8.UTFMax {
   997  			n = utf8.UTFMax
   998  		}
   999  		c, size := utf8.DecodeRuneInString(string(src[i : i+n]))
  1000  		if c == utf8.RuneError && size == 1 {
  1001  			dst = append(dst, src[start:i]...)
  1002  			dst = append(dst, `\ufffd`...)
  1003  			i += size
  1004  			start = i
  1005  			continue
  1006  		}
  1007  		
  1008  		
  1009  		
  1010  		
  1011  		
  1012  		
  1013  		
  1014  		if c == '\u2028' || c == '\u2029' {
  1015  			dst = append(dst, src[start:i]...)
  1016  			dst = append(dst, '\\', 'u', '2', '0', '2', hex[c&0xF])
  1017  			i += size
  1018  			start = i
  1019  			continue
  1020  		}
  1021  		i += size
  1022  	}
  1023  	dst = append(dst, src[start:]...)
  1024  	dst = append(dst, '"')
  1025  	return dst
  1026  }
  1027  
  1028  
  1029  type field struct {
  1030  	name      string
  1031  	nameBytes []byte 
  1032  
  1033  	nameNonEsc  string 
  1034  	nameEscHTML string 
  1035  
  1036  	tag       bool
  1037  	index     []int
  1038  	typ       reflect.Type
  1039  	omitEmpty bool
  1040  	quoted    bool
  1041  
  1042  	encoder encoderFunc
  1043  }
  1044  
  1045  
  1046  type byIndex []field
  1047  
  1048  func (x byIndex) Len() int { return len(x) }
  1049  
  1050  func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  1051  
  1052  func (x byIndex) Less(i, j int) bool {
  1053  	for k, xik := range x[i].index {
  1054  		if k >= len(x[j].index) {
  1055  			return false
  1056  		}
  1057  		if xik != x[j].index[k] {
  1058  			return xik < x[j].index[k]
  1059  		}
  1060  	}
  1061  	return len(x[i].index) < len(x[j].index)
  1062  }
  1063  
  1064  
  1065  
  1066  
  1067  func typeFields(t reflect.Type) structFields {
  1068  	
  1069  	current := []field{}
  1070  	next := []field{{typ: t}}
  1071  
  1072  	
  1073  	var count, nextCount map[reflect.Type]int
  1074  
  1075  	
  1076  	visited := map[reflect.Type]bool{}
  1077  
  1078  	
  1079  	var fields []field
  1080  
  1081  	
  1082  	var nameEscBuf []byte
  1083  
  1084  	for len(next) > 0 {
  1085  		current, next = next, current[:0]
  1086  		count, nextCount = nextCount, map[reflect.Type]int{}
  1087  
  1088  		for _, f := range current {
  1089  			if visited[f.typ] {
  1090  				continue
  1091  			}
  1092  			visited[f.typ] = true
  1093  
  1094  			
  1095  			for i := 0; i < f.typ.NumField(); i++ {
  1096  				sf := f.typ.Field(i)
  1097  				if sf.Anonymous {
  1098  					t := sf.Type
  1099  					if t.Kind() == reflect.Pointer {
  1100  						t = t.Elem()
  1101  					}
  1102  					if !sf.IsExported() && t.Kind() != reflect.Struct {
  1103  						
  1104  						continue
  1105  					}
  1106  					
  1107  					
  1108  				} else if !sf.IsExported() {
  1109  					
  1110  					continue
  1111  				}
  1112  				tag := sf.Tag.Get("json")
  1113  				if tag == "-" {
  1114  					continue
  1115  				}
  1116  				name, opts := parseTag(tag)
  1117  				if !isValidTag(name) {
  1118  					name = ""
  1119  				}
  1120  				index := make([]int, len(f.index)+1)
  1121  				copy(index, f.index)
  1122  				index[len(f.index)] = i
  1123  
  1124  				ft := sf.Type
  1125  				if ft.Name() == "" && ft.Kind() == reflect.Pointer {
  1126  					
  1127  					ft = ft.Elem()
  1128  				}
  1129  
  1130  				
  1131  				quoted := false
  1132  				if opts.Contains("string") {
  1133  					switch ft.Kind() {
  1134  					case reflect.Bool,
  1135  						reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  1136  						reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
  1137  						reflect.Float32, reflect.Float64,
  1138  						reflect.String:
  1139  						quoted = true
  1140  					}
  1141  				}
  1142  
  1143  				
  1144  				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
  1145  					tagged := name != ""
  1146  					if name == "" {
  1147  						name = sf.Name
  1148  					}
  1149  					field := field{
  1150  						name:      name,
  1151  						tag:       tagged,
  1152  						index:     index,
  1153  						typ:       ft,
  1154  						omitEmpty: opts.Contains("omitempty"),
  1155  						quoted:    quoted,
  1156  					}
  1157  					field.nameBytes = []byte(field.name)
  1158  
  1159  					
  1160  					nameEscBuf = appendHTMLEscape(nameEscBuf[:0], field.nameBytes)
  1161  					field.nameEscHTML = `"` + string(nameEscBuf) + `":`
  1162  					field.nameNonEsc = `"` + field.name + `":`
  1163  
  1164  					fields = append(fields, field)
  1165  					if count[f.typ] > 1 {
  1166  						
  1167  						
  1168  						
  1169  						
  1170  						fields = append(fields, fields[len(fields)-1])
  1171  					}
  1172  					continue
  1173  				}
  1174  
  1175  				
  1176  				nextCount[ft]++
  1177  				if nextCount[ft] == 1 {
  1178  					next = append(next, field{name: ft.Name(), index: index, typ: ft})
  1179  				}
  1180  			}
  1181  		}
  1182  	}
  1183  
  1184  	sort.Slice(fields, func(i, j int) bool {
  1185  		x := fields
  1186  		
  1187  		
  1188  		
  1189  		if x[i].name != x[j].name {
  1190  			return x[i].name < x[j].name
  1191  		}
  1192  		if len(x[i].index) != len(x[j].index) {
  1193  			return len(x[i].index) < len(x[j].index)
  1194  		}
  1195  		if x[i].tag != x[j].tag {
  1196  			return x[i].tag
  1197  		}
  1198  		return byIndex(x).Less(i, j)
  1199  	})
  1200  
  1201  	
  1202  	
  1203  
  1204  	
  1205  	
  1206  	
  1207  	out := fields[:0]
  1208  	for advance, i := 0, 0; i < len(fields); i += advance {
  1209  		
  1210  		
  1211  		fi := fields[i]
  1212  		name := fi.name
  1213  		for advance = 1; i+advance < len(fields); advance++ {
  1214  			fj := fields[i+advance]
  1215  			if fj.name != name {
  1216  				break
  1217  			}
  1218  		}
  1219  		if advance == 1 { 
  1220  			out = append(out, fi)
  1221  			continue
  1222  		}
  1223  		dominant, ok := dominantField(fields[i : i+advance])
  1224  		if ok {
  1225  			out = append(out, dominant)
  1226  		}
  1227  	}
  1228  
  1229  	fields = out
  1230  	sort.Sort(byIndex(fields))
  1231  
  1232  	for i := range fields {
  1233  		f := &fields[i]
  1234  		f.encoder = typeEncoder(typeByIndex(t, f.index))
  1235  	}
  1236  	exactNameIndex := make(map[string]*field, len(fields))
  1237  	foldedNameIndex := make(map[string]*field, len(fields))
  1238  	for i, field := range fields {
  1239  		exactNameIndex[field.name] = &fields[i]
  1240  		
  1241  		if _, ok := foldedNameIndex[string(foldName(field.nameBytes))]; !ok {
  1242  			foldedNameIndex[string(foldName(field.nameBytes))] = &fields[i]
  1243  		}
  1244  	}
  1245  	return structFields{fields, exactNameIndex, foldedNameIndex}
  1246  }
  1247  
  1248  
  1249  
  1250  
  1251  
  1252  
  1253  
  1254  func dominantField(fields []field) (field, bool) {
  1255  	
  1256  	
  1257  	
  1258  	if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
  1259  		return field{}, false
  1260  	}
  1261  	return fields[0], true
  1262  }
  1263  
  1264  var fieldCache sync.Map 
  1265  
  1266  
  1267  func cachedTypeFields(t reflect.Type) structFields {
  1268  	if f, ok := fieldCache.Load(t); ok {
  1269  		return f.(structFields)
  1270  	}
  1271  	f, _ := fieldCache.LoadOrStore(t, typeFields(t))
  1272  	return f.(structFields)
  1273  }
  1274  
  1275  func mayAppendQuote(b []byte, quoted bool) []byte {
  1276  	if quoted {
  1277  		b = append(b, '"')
  1278  	}
  1279  	return b
  1280  }
  1281  
View as plain text