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