cuelang.org/go@v0.10.1/cue/decode.go (about)

     1  // Copyright 2021 CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package cue
    16  
    17  import (
    18  	"bytes"
    19  	"cmp"
    20  	"encoding"
    21  	"encoding/json"
    22  	"reflect"
    23  	"slices"
    24  	"strconv"
    25  	"strings"
    26  	"sync"
    27  	"unicode"
    28  	"unicode/utf8"
    29  
    30  	"cuelang.org/go/cue/errors"
    31  	"cuelang.org/go/internal/core/adt"
    32  )
    33  
    34  // Decode initializes the value pointed to by x with Value v.
    35  // An error is returned if x is nil or not a pointer.
    36  //
    37  // If x is a struct, Decode will validate the constraints specified in the field tags.
    38  //
    39  // If x contains a [Value], that part of x will be set to the value
    40  // at the corresponding part of v. This allows decoding values
    41  // that aren't entirely concrete into a Go type.
    42  func (v Value) Decode(x interface{}) error {
    43  	var d decoder
    44  	w := reflect.ValueOf(x)
    45  	if w.Kind() != reflect.Pointer || w.IsNil() {
    46  		d.addErr(errors.Newf(v.Pos(), "cannot decode into unsettable value"))
    47  		return d.errs
    48  	}
    49  	d.decode(w.Elem(), v, false)
    50  	return d.errs
    51  }
    52  
    53  type decoder struct {
    54  	errs errors.Error
    55  }
    56  
    57  func (d *decoder) addErr(err error) {
    58  	if err != nil {
    59  		d.errs = errors.Append(d.errs, errors.Promote(err, ""))
    60  	}
    61  }
    62  
    63  func incompleteError(v Value) errors.Error {
    64  	return &valueError{
    65  		v: v,
    66  		err: &adt.Bottom{
    67  			Code: adt.IncompleteError,
    68  			Err: errors.Newf(v.Pos(),
    69  				"cannot convert non-concrete value %v", v)},
    70  	}
    71  }
    72  
    73  func (d *decoder) clear(x reflect.Value) {
    74  	if x.CanSet() {
    75  		x.SetZero()
    76  	}
    77  }
    78  
    79  var valueType = reflect.TypeFor[Value]()
    80  
    81  func (d *decoder) decode(x reflect.Value, v Value, isPtr bool) {
    82  	if !x.IsValid() {
    83  		d.addErr(errors.Newf(v.Pos(), "cannot decode into invalid value"))
    84  		return
    85  	}
    86  
    87  	v, _ = v.Default()
    88  	if v.v == nil {
    89  		d.clear(x)
    90  		return
    91  	}
    92  
    93  	if err := v.Err(); err != nil {
    94  		d.addErr(err)
    95  		return
    96  	}
    97  	if x.Type() == valueType {
    98  		x.Set(reflect.ValueOf(v))
    99  		return
   100  	}
   101  
   102  	switch x.Kind() {
   103  	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface:
   104  		// nullable types
   105  		if v.IsNull() || !v.IsConcrete() {
   106  			d.clear(x)
   107  			return
   108  		}
   109  
   110  	default:
   111  		// TODO: allow incomplete values.
   112  		if !v.IsConcrete() {
   113  			d.addErr(incompleteError(v))
   114  			return
   115  		}
   116  	}
   117  
   118  	ij, it, x := indirect(x, v.IsNull())
   119  
   120  	if ij != nil {
   121  		b, err := v.marshalJSON()
   122  		d.addErr(err)
   123  		d.addErr(ij.UnmarshalJSON(b))
   124  		return
   125  	}
   126  
   127  	if it != nil {
   128  		b, err := v.Bytes()
   129  		if err != nil {
   130  			err = errors.Wrapf(err, v.Pos(), "Decode")
   131  			d.addErr(err)
   132  			return
   133  		}
   134  		d.addErr(it.UnmarshalText(b))
   135  		return
   136  	}
   137  
   138  	kind := x.Kind()
   139  
   140  	if kind == reflect.Interface {
   141  		value := d.interfaceValue(v)
   142  		x.Set(reflect.ValueOf(value))
   143  		return
   144  	}
   145  
   146  	switch kind {
   147  	case reflect.Ptr:
   148  		d.decode(x.Elem(), v, true)
   149  
   150  	case reflect.Bool:
   151  		b, err := v.Bool()
   152  		d.addErr(err)
   153  		x.SetBool(b)
   154  
   155  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   156  		i, err := v.Int64()
   157  		d.addErr(err)
   158  		if x.OverflowInt(i) {
   159  			d.addErr(errors.Newf(v.Pos(), "integer %d overflows %s", i, kind))
   160  			break
   161  		}
   162  		x.SetInt(i)
   163  
   164  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   165  		i, err := v.Uint64()
   166  		d.addErr(err)
   167  		if x.OverflowUint(i) {
   168  			d.addErr(errors.Newf(v.Pos(), "integer %d overflows %s", i, kind))
   169  			break
   170  		}
   171  		x.SetUint(i)
   172  
   173  	case reflect.Float32, reflect.Float64:
   174  		f, err := v.Float64()
   175  		d.addErr(err)
   176  		if x.OverflowFloat(f) {
   177  			d.addErr(errors.Newf(v.Pos(), "float %g overflows %s", f, kind))
   178  			break
   179  		}
   180  		x.SetFloat(f)
   181  
   182  	case reflect.String:
   183  		s, err := v.String()
   184  		d.addErr(err)
   185  		x.SetString(s)
   186  
   187  	case reflect.Array:
   188  		d.clear(x)
   189  
   190  		t := x.Type()
   191  		n := x.Len()
   192  
   193  		if t.Elem().Kind() == reflect.Uint8 && v.Kind() == BytesKind {
   194  			b, err := v.Bytes()
   195  			d.addErr(err)
   196  			for i, c := range b {
   197  				if i >= n {
   198  					break
   199  				}
   200  				x.Index(i).SetUint(uint64(c))
   201  			}
   202  			break
   203  		}
   204  
   205  		var a []Value
   206  		list, err := v.List()
   207  		d.addErr(err)
   208  		for list.Next() {
   209  			a = append(a, list.Value())
   210  		}
   211  
   212  		for i, v := range a {
   213  			if i >= n {
   214  				break
   215  			}
   216  			d.decode(x.Index(i), v, false)
   217  		}
   218  
   219  	case reflect.Slice:
   220  		t := x.Type()
   221  		if t.Elem().Kind() == reflect.Uint8 && v.Kind() == BytesKind {
   222  			b, err := v.Bytes()
   223  			d.addErr(err)
   224  			x.SetBytes(b)
   225  			break
   226  		}
   227  
   228  		var a []Value
   229  		list, err := v.List()
   230  		d.addErr(err)
   231  		for list.Next() {
   232  			a = append(a, list.Value())
   233  		}
   234  
   235  		switch cap := x.Cap(); {
   236  		case cap == 0, // force a non-nil list
   237  			cap < len(a):
   238  			x.Set(reflect.MakeSlice(t, len(a), len(a)))
   239  
   240  		default:
   241  			x.SetLen(len(a))
   242  		}
   243  
   244  		for i, v := range a {
   245  			d.decode(x.Index(i), v, false)
   246  		}
   247  
   248  	case reflect.Struct:
   249  		d.convertStruct(x, v)
   250  
   251  	case reflect.Map:
   252  		d.convertMap(x, v)
   253  
   254  	default:
   255  		d.clear(x)
   256  	}
   257  }
   258  
   259  func (d *decoder) interfaceValue(v Value) (x interface{}) {
   260  	var err error
   261  	v, _ = v.Default()
   262  	switch v.Kind() {
   263  	case NullKind:
   264  		return nil
   265  
   266  	case BoolKind:
   267  		x, err = v.Bool()
   268  
   269  	case IntKind:
   270  		if i, err := v.Int64(); err == nil {
   271  			return int(i)
   272  		}
   273  		x, err = v.Int(nil)
   274  
   275  	case FloatKind:
   276  		x, err = v.Float64() // or big int or
   277  
   278  	case StringKind:
   279  		x, err = v.String()
   280  
   281  	case BytesKind:
   282  		x, err = v.Bytes()
   283  
   284  	case ListKind:
   285  		var a []interface{}
   286  		list, err := v.List()
   287  		d.addErr(err)
   288  		for list.Next() {
   289  			a = append(a, d.interfaceValue(list.Value()))
   290  		}
   291  		if a == nil {
   292  			a = []interface{}{}
   293  		}
   294  		x = a
   295  
   296  	case StructKind:
   297  		m := map[string]interface{}{}
   298  		iter, err := v.Fields()
   299  		d.addErr(err)
   300  		for iter.Next() {
   301  			m[iter.Label()] = d.interfaceValue(iter.Value())
   302  		}
   303  		x = m
   304  
   305  	default:
   306  		err = incompleteError(v)
   307  	}
   308  
   309  	d.addErr(err)
   310  	return x
   311  }
   312  
   313  var textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]()
   314  
   315  // convertMap keeps an existing map and overwrites any entry found in v,
   316  // keeping other preexisting entries.
   317  func (d *decoder) convertMap(x reflect.Value, v Value) {
   318  	// Delete existing elements
   319  	t := x.Type()
   320  
   321  	// Map key must either have string kind, have an integer kind,
   322  	// or be an encoding.TextUnmarshaler.
   323  	switch t.Key().Kind() {
   324  	case reflect.String,
   325  		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
   326  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   327  	default:
   328  		if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) {
   329  			d.addErr(errors.Newf(v.Pos(), "unsupported key type %v", t.Key()))
   330  			return
   331  		}
   332  	}
   333  
   334  	if x.IsNil() {
   335  		x.Set(reflect.MakeMap(t))
   336  	}
   337  
   338  	var mapElem reflect.Value
   339  
   340  	iter, err := v.Fields()
   341  	d.addErr(err)
   342  	for iter.Next() {
   343  		key := iter.Label()
   344  
   345  		var kv reflect.Value
   346  		kt := t.Key()
   347  		if reflect.PointerTo(kt).Implements(textUnmarshalerType) {
   348  			kv = reflect.New(kt)
   349  			err := kv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(key))
   350  			d.addErr(err)
   351  			kv = kv.Elem()
   352  		} else {
   353  			switch kt.Kind() {
   354  			case reflect.String:
   355  				kv = reflect.ValueOf(key).Convert(kt)
   356  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   357  				n, err := strconv.ParseInt(key, 10, 64)
   358  				d.addErr(err)
   359  				if reflect.Zero(kt).OverflowInt(n) {
   360  					d.addErr(errors.Newf(v.Pos(), "key integer %d overflows %s", n, kt))
   361  					break
   362  				}
   363  				kv = reflect.ValueOf(n).Convert(kt)
   364  
   365  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   366  				n, err := strconv.ParseUint(key, 10, 64)
   367  				d.addErr(err)
   368  				if reflect.Zero(kt).OverflowUint(n) {
   369  					d.addErr(errors.Newf(v.Pos(), "key integer %d overflows %s", n, kt))
   370  					break
   371  				}
   372  				kv = reflect.ValueOf(n).Convert(kt)
   373  
   374  			default:
   375  				panic("json: Unexpected key type") // should never occur
   376  			}
   377  		}
   378  
   379  		if !mapElem.IsValid() {
   380  			mapElem = reflect.New(t.Elem()).Elem()
   381  		} else {
   382  			mapElem.SetZero()
   383  		}
   384  		d.decode(mapElem, iter.Value(), false)
   385  
   386  		if kv.IsValid() {
   387  			x.SetMapIndex(kv, mapElem)
   388  		}
   389  	}
   390  }
   391  
   392  func (d *decoder) convertStruct(x reflect.Value, v Value) {
   393  	t := x.Type()
   394  	fields := cachedTypeFields(t)
   395  
   396  	iter, err := v.Fields()
   397  	d.addErr(err)
   398  	for iter.Next() {
   399  
   400  		var f *goField
   401  		key := iter.Label()
   402  		if i, ok := fields.nameIndex[key]; ok {
   403  			// Found an exact name match.
   404  			f = &fields.list[i]
   405  		} else {
   406  			// Fall back to the expensive case-insensitive
   407  			// linear search.
   408  			key := []byte(key)
   409  			for i := range fields.list {
   410  				ff := &fields.list[i]
   411  				if ff.equalFold(ff.nameBytes, key) {
   412  					f = ff
   413  					break
   414  				}
   415  			}
   416  		}
   417  
   418  		if f == nil {
   419  			continue
   420  		}
   421  
   422  		// Figure out field corresponding to key.
   423  		subv := x
   424  		for _, i := range f.index {
   425  			if subv.Kind() == reflect.Ptr {
   426  				if subv.IsNil() {
   427  					// If a struct embeds a pointer to an unexported type,
   428  					// it is not possible to set a newly allocated value
   429  					// since the field is unexported.
   430  					//
   431  					// See https://golang.org/issue/21357
   432  					if !subv.CanSet() {
   433  						d.addErr(errors.Newf(v.Pos(),
   434  							"cannot set embedded pointer to unexported struct: %v",
   435  							subv.Type().Elem()))
   436  						subv = reflect.Value{}
   437  						break
   438  					}
   439  					subv.Set(reflect.New(subv.Type().Elem()))
   440  				}
   441  				subv = subv.Elem()
   442  			}
   443  			subv = subv.Field(i)
   444  		}
   445  
   446  		// TODO: make this an option
   447  		//  else if d.disallowUnknownFields {
   448  		// 	d.saveError(fmt.Errorf("json: unknown field %q", key))
   449  		// }
   450  
   451  		d.decode(subv, iter.Value(), false)
   452  	}
   453  }
   454  
   455  type structFields struct {
   456  	list      []goField
   457  	nameIndex map[string]int
   458  }
   459  
   460  func isValidTag(s string) bool {
   461  	if s == "" {
   462  		return false
   463  	}
   464  	for _, c := range s {
   465  		switch {
   466  		case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
   467  			// Backslash and quote chars are reserved, but
   468  			// otherwise any punctuation chars are allowed
   469  			// in a tag name.
   470  		case !unicode.IsLetter(c) && !unicode.IsDigit(c):
   471  			return false
   472  		}
   473  	}
   474  	return true
   475  }
   476  
   477  // A field represents a single Go field found in a struct.
   478  type goField struct {
   479  	name      string
   480  	nameBytes []byte                 // []byte(name)
   481  	equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
   482  
   483  	nameNonEsc  string // `"` + name + `":`
   484  	nameEscHTML string // `"` + HTMLEscape(name) + `":`
   485  
   486  	tag       bool
   487  	index     []int
   488  	typ       reflect.Type
   489  	omitEmpty bool
   490  }
   491  
   492  func compareFieldByIndex(a, b goField) int {
   493  	for i, x := range a.index {
   494  		if i >= len(b.index) {
   495  			break
   496  		}
   497  		if c := cmp.Compare(x, b.index[i]); c != 0 {
   498  			return c
   499  		}
   500  	}
   501  	return cmp.Compare(len(a.index), len(b.index))
   502  }
   503  
   504  // typeFields returns a list of fields that JSON should recognize for the given type.
   505  // The algorithm is breadth-first search over the set of structs to include - the top struct
   506  // and then any reachable anonymous structs.
   507  func typeFields(t reflect.Type) structFields {
   508  	// Anonymous fields to explore at the current level and the next.
   509  	current := []goField{}
   510  	next := []goField{{typ: t}}
   511  
   512  	// Count of queued names for current level and the next.
   513  	var count, nextCount map[reflect.Type]int
   514  
   515  	// Types already visited at an earlier level.
   516  	visited := map[reflect.Type]bool{}
   517  
   518  	// Fields found.
   519  	var fields []goField
   520  
   521  	// Buffer to run HTMLEscape on field names.
   522  	var nameEscBuf bytes.Buffer
   523  
   524  	for len(next) > 0 {
   525  		current, next = next, current[:0]
   526  		count, nextCount = nextCount, map[reflect.Type]int{}
   527  
   528  		for _, f := range current {
   529  			if visited[f.typ] {
   530  				continue
   531  			}
   532  			visited[f.typ] = true
   533  
   534  			// Scan f.typ for fields to include.
   535  			for i := 0; i < f.typ.NumField(); i++ {
   536  				sf := f.typ.Field(i)
   537  				isUnexported := sf.PkgPath != ""
   538  				if sf.Anonymous {
   539  					t := sf.Type
   540  					if t.Kind() == reflect.Ptr {
   541  						t = t.Elem()
   542  					}
   543  					if isUnexported && t.Kind() != reflect.Struct {
   544  						// Ignore embedded fields of unexported non-struct types.
   545  						continue
   546  					}
   547  					// Do not ignore embedded fields of unexported struct types
   548  					// since they may have exported fields.
   549  				} else if isUnexported {
   550  					// Ignore unexported non-embedded fields.
   551  					continue
   552  				}
   553  				tag := sf.Tag.Get("json")
   554  				if tag == "-" {
   555  					continue
   556  				}
   557  				name, opts := parseTag(tag)
   558  				if !isValidTag(name) {
   559  					name = ""
   560  				}
   561  				index := make([]int, len(f.index)+1)
   562  				copy(index, f.index)
   563  				index[len(f.index)] = i
   564  
   565  				ft := sf.Type
   566  				if ft.Name() == "" && ft.Kind() == reflect.Ptr {
   567  					// Follow pointer.
   568  					ft = ft.Elem()
   569  				}
   570  
   571  				// Record found field and index sequence.
   572  				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
   573  					tagged := name != ""
   574  					if name == "" {
   575  						name = sf.Name
   576  					}
   577  					field := goField{
   578  						name:      name,
   579  						tag:       tagged,
   580  						index:     index,
   581  						typ:       ft,
   582  						omitEmpty: opts.Contains("omitempty"),
   583  					}
   584  					field.nameBytes = []byte(field.name)
   585  					field.equalFold = foldFunc(field.nameBytes)
   586  
   587  					// Build nameEscHTML and nameNonEsc ahead of time.
   588  					nameEscBuf.Reset()
   589  					nameEscBuf.WriteString(`"`)
   590  					json.HTMLEscape(&nameEscBuf, field.nameBytes)
   591  					nameEscBuf.WriteString(`":`)
   592  					field.nameEscHTML = nameEscBuf.String()
   593  					field.nameNonEsc = `"` + field.name + `":`
   594  
   595  					fields = append(fields, field)
   596  					if count[f.typ] > 1 {
   597  						// If there were multiple instances, add a second,
   598  						// so that the annihilation code will see a duplicate.
   599  						// It only cares about the distinction between 1 or 2,
   600  						// so don't bother generating any more copies.
   601  						fields = append(fields, fields[len(fields)-1])
   602  					}
   603  					continue
   604  				}
   605  
   606  				// Record new anonymous struct to explore in next round.
   607  				nextCount[ft]++
   608  				if nextCount[ft] == 1 {
   609  					next = append(next, goField{name: ft.Name(), index: index, typ: ft})
   610  				}
   611  			}
   612  		}
   613  	}
   614  
   615  	slices.SortFunc(fields, func(a, b goField) int {
   616  		// sort field by name, breaking ties with depth, then
   617  		// breaking ties with "name came from json tag", then
   618  		// breaking ties with index sequence.
   619  		if c := cmp.Compare(a.name, b.name); c != 0 {
   620  			return c
   621  		}
   622  		if c := cmp.Compare(len(a.index), len(b.index)); c != 0 {
   623  			return c
   624  		}
   625  		if a.tag != b.tag {
   626  			if a.tag {
   627  				return 1
   628  			} else {
   629  				return -1
   630  			}
   631  		}
   632  		return compareFieldByIndex(a, b)
   633  	})
   634  
   635  	// Delete all fields that are hidden by the Go rules for embedded fields,
   636  	// except that fields with JSON tags are promoted.
   637  
   638  	// The fields are sorted in primary order of name, secondary order
   639  	// of field index length. Loop over names; for each name, delete
   640  	// hidden fields by choosing the one dominant field that survives.
   641  	out := fields[:0]
   642  	for advance, i := 0, 0; i < len(fields); i += advance {
   643  		// One iteration per name.
   644  		// Find the sequence of fields with the name of this first field.
   645  		fi := fields[i]
   646  		name := fi.name
   647  		for advance = 1; i+advance < len(fields); advance++ {
   648  			fj := fields[i+advance]
   649  			if fj.name != name {
   650  				break
   651  			}
   652  		}
   653  		if advance == 1 { // Only one field with this name
   654  			out = append(out, fi)
   655  			continue
   656  		}
   657  		dominant, ok := dominantField(fields[i : i+advance])
   658  		if ok {
   659  			out = append(out, dominant)
   660  		}
   661  	}
   662  
   663  	fields = out
   664  	slices.SortFunc(fields, compareFieldByIndex)
   665  
   666  	nameIndex := make(map[string]int, len(fields))
   667  	for i, field := range fields {
   668  		nameIndex[field.name] = i
   669  	}
   670  	return structFields{fields, nameIndex}
   671  }
   672  
   673  // dominantField looks through the fields, all of which are known to
   674  // have the same name, to find the single field that dominates the
   675  // others using Go's embedding rules, modified by the presence of
   676  // JSON tags. If there are multiple top-level fields, the boolean
   677  // will be false: This condition is an error in Go and we skip all
   678  // the fields.
   679  func dominantField(fields []goField) (goField, bool) {
   680  	// The fields are sorted in increasing index-length order, then by presence of tag.
   681  	// That means that the first field is the dominant one. We need only check
   682  	// for error cases: two fields at top level, either both tagged or neither tagged.
   683  	if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
   684  		return goField{}, false
   685  	}
   686  	return fields[0], true
   687  }
   688  
   689  var fieldCache sync.Map // map[reflect.Type]structFields
   690  
   691  // cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
   692  func cachedTypeFields(t reflect.Type) structFields {
   693  	if f, ok := fieldCache.Load(t); ok {
   694  		return f.(structFields)
   695  	}
   696  	f, _ := fieldCache.LoadOrStore(t, typeFields(t))
   697  	return f.(structFields)
   698  }
   699  
   700  // tagOptions is the string following a comma in a struct field's "json"
   701  // tag, or the empty string. It does not include the leading comma.
   702  type tagOptions string
   703  
   704  // parseTag splits a struct field's json tag into its name and
   705  // comma-separated options.
   706  func parseTag(tag string) (string, tagOptions) {
   707  	if idx := strings.Index(tag, ","); idx != -1 {
   708  		return tag[:idx], tagOptions(tag[idx+1:])
   709  	}
   710  	return tag, tagOptions("")
   711  }
   712  
   713  // Contains reports whether a comma-separated list of options
   714  // contains a particular substr flag. substr must be surrounded by a
   715  // string boundary or commas.
   716  func (o tagOptions) Contains(optionName string) bool {
   717  	if len(o) == 0 {
   718  		return false
   719  	}
   720  	s := string(o)
   721  	for s != "" {
   722  		var next string
   723  		i := strings.Index(s, ",")
   724  		if i >= 0 {
   725  			s, next = s[:i], s[i+1:]
   726  		}
   727  		if s == optionName {
   728  			return true
   729  		}
   730  		s = next
   731  	}
   732  	return false
   733  }
   734  
   735  // foldFunc returns one of four different case folding equivalence
   736  // functions, from most general (and slow) to fastest:
   737  //
   738  // 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
   739  // 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
   740  // 3) asciiEqualFold, no special, but includes non-letters (including _)
   741  // 4) simpleLetterEqualFold, no specials, no non-letters.
   742  //
   743  // The letters S and K are special because they map to 3 runes, not just 2:
   744  //   - S maps to s and to U+017F 'ſ' Latin small letter long s
   745  //   - k maps to K and to U+212A 'K' Kelvin sign
   746  //
   747  // See https://play.golang.org/p/tTxjOc0OGo
   748  //
   749  // The returned function is specialized for matching against s and
   750  // should only be given s. It's not curried for performance reasons.
   751  func foldFunc(s []byte) func(s, t []byte) bool {
   752  	nonLetter := false
   753  	special := false // special letter
   754  	for _, b := range s {
   755  		if b >= utf8.RuneSelf {
   756  			return bytes.EqualFold
   757  		}
   758  		upper := b & caseMask
   759  		if upper < 'A' || upper > 'Z' {
   760  			nonLetter = true
   761  		} else if upper == 'K' || upper == 'S' {
   762  			// See above for why these letters are special.
   763  			special = true
   764  		}
   765  	}
   766  	if special {
   767  		return equalFoldRight
   768  	}
   769  	if nonLetter {
   770  		return asciiEqualFold
   771  	}
   772  	return simpleLetterEqualFold
   773  }
   774  
   775  const (
   776  	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII.
   777  	kelvin       = '\u212a'
   778  	smallLongEss = '\u017f'
   779  )
   780  
   781  // equalFoldRight is a specialization of bytes.EqualFold when s is
   782  // known to be all ASCII (including punctuation), but contains an 's',
   783  // 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
   784  // See comments on foldFunc.
   785  func equalFoldRight(s, t []byte) bool {
   786  	for _, sb := range s {
   787  		if len(t) == 0 {
   788  			return false
   789  		}
   790  		tb := t[0]
   791  		if tb < utf8.RuneSelf {
   792  			if sb != tb {
   793  				sbUpper := sb & caseMask
   794  				if 'A' <= sbUpper && sbUpper <= 'Z' {
   795  					if sbUpper != tb&caseMask {
   796  						return false
   797  					}
   798  				} else {
   799  					return false
   800  				}
   801  			}
   802  			t = t[1:]
   803  			continue
   804  		}
   805  		// sb is ASCII and t is not. t must be either kelvin
   806  		// sign or long s; sb must be s, S, k, or K.
   807  		tr, size := utf8.DecodeRune(t)
   808  		switch sb {
   809  		case 's', 'S':
   810  			if tr != smallLongEss {
   811  				return false
   812  			}
   813  		case 'k', 'K':
   814  			if tr != kelvin {
   815  				return false
   816  			}
   817  		default:
   818  			return false
   819  		}
   820  		t = t[size:]
   821  
   822  	}
   823  	return len(t) == 0
   824  }
   825  
   826  // asciiEqualFold is a specialization of bytes.EqualFold for use when
   827  // s is all ASCII (but may contain non-letters) and contains no
   828  // special-folding letters.
   829  // See comments on foldFunc.
   830  func asciiEqualFold(s, t []byte) bool {
   831  	if len(s) != len(t) {
   832  		return false
   833  	}
   834  	for i, sb := range s {
   835  		tb := t[i]
   836  		if sb == tb {
   837  			continue
   838  		}
   839  		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
   840  			if sb&caseMask != tb&caseMask {
   841  				return false
   842  			}
   843  		} else {
   844  			return false
   845  		}
   846  	}
   847  	return true
   848  }
   849  
   850  // simpleLetterEqualFold is a specialization of bytes.EqualFold for
   851  // use when s is all ASCII letters (no underscores, etc) and also
   852  // doesn't contain 'k', 'K', 's', or 'S'.
   853  // See comments on foldFunc.
   854  func simpleLetterEqualFold(s, t []byte) bool {
   855  	if len(s) != len(t) {
   856  		return false
   857  	}
   858  	for i, b := range s {
   859  		if b&caseMask != t[i]&caseMask {
   860  			return false
   861  		}
   862  	}
   863  	return true
   864  }
   865  
   866  // indirect walks down v allocating pointers as needed,
   867  // until it gets to a non-pointer.
   868  // If it encounters an Unmarshaler, indirect stops and returns that.
   869  // If decodingNull is true, indirect stops at the first settable pointer so it
   870  // can be set to nil.
   871  func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
   872  	// Issue #24153 indicates that it is generally not a guaranteed property
   873  	// that you may round-trip a reflect.Value by calling Value.Addr().Elem()
   874  	// and expect the value to still be settable for values derived from
   875  	// unexported embedded struct fields.
   876  	//
   877  	// The logic below effectively does this when it first addresses the value
   878  	// (to satisfy possible pointer methods) and continues to dereference
   879  	// subsequent pointers as necessary.
   880  	//
   881  	// After the first round-trip, we set v back to the original value to
   882  	// preserve the original RW flags contained in reflect.Value.
   883  	v0 := v
   884  	haveAddr := false
   885  
   886  	// If v is a named type and is addressable,
   887  	// start with its address, so that if the type has pointer methods,
   888  	// we find them.
   889  	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
   890  		haveAddr = true
   891  		v = v.Addr()
   892  	}
   893  	for {
   894  		// Load value from interface, but only if the result will be
   895  		// usefully addressable.
   896  		if v.Kind() == reflect.Interface && !v.IsNil() {
   897  			e := v.Elem()
   898  			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
   899  				haveAddr = false
   900  				v = e
   901  				continue
   902  			}
   903  		}
   904  
   905  		if v.Kind() != reflect.Ptr {
   906  			break
   907  		}
   908  
   909  		if decodingNull && v.CanSet() {
   910  			break
   911  		}
   912  
   913  		// Prevent infinite loop if v is an interface pointing to its own address:
   914  		//     var v interface{}
   915  		//     v = &v
   916  		if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
   917  			v = v.Elem()
   918  			break
   919  		}
   920  		if v.IsNil() {
   921  			v.Set(reflect.New(v.Type().Elem()))
   922  		}
   923  		if v.Type().NumMethod() > 0 && v.CanInterface() {
   924  			if u, ok := v.Interface().(json.Unmarshaler); ok {
   925  				return u, nil, reflect.Value{}
   926  			}
   927  			if !decodingNull {
   928  				if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
   929  					return nil, u, reflect.Value{}
   930  				}
   931  			}
   932  		}
   933  
   934  		if haveAddr {
   935  			v = v0 // restore original value after round-trip Value.Addr().Elem()
   936  			haveAddr = false
   937  		} else {
   938  			v = v.Elem()
   939  		}
   940  	}
   941  	return nil, nil, v
   942  }