1package toml
2
3import (
4	"encoding"
5	"errors"
6	"fmt"
7	"io"
8	"io/ioutil"
9	"math"
10	"reflect"
11	"strings"
12	"sync"
13	"time"
14
15	"github.com/pelletier/go-toml/v2/internal/ast"
16	"github.com/pelletier/go-toml/v2/internal/tracker"
17)
18
19// Unmarshal deserializes a TOML document into a Go value.
20//
21// It is a shortcut for Decoder.Decode() with the default options.
22func Unmarshal(data []byte, v interface{}) error {
23	p := parser{}
24	p.Reset(data)
25	d := decoder{p: &p}
26
27	return d.FromParser(v)
28}
29
30// Decoder reads and decode a TOML document from an input stream.
31type Decoder struct {
32	// input
33	r io.Reader
34
35	// global settings
36	strict bool
37}
38
39// NewDecoder creates a new Decoder that will read from r.
40func NewDecoder(r io.Reader) *Decoder {
41	return &Decoder{r: r}
42}
43
44// SetStrict toggles decoding in stict mode.
45//
46// When the decoder is in strict mode, it will record fields from the document
47// that could not be set on the target value. In that case, the decoder returns
48// a StrictMissingError that can be used to retrieve the individual errors as
49// well as generate a human readable description of the missing fields.
50func (d *Decoder) SetStrict(strict bool) {
51	d.strict = strict
52}
53
54// Decode the whole content of r into v.
55//
56// By default, values in the document that don't exist in the target Go value
57// are ignored. See Decoder.SetStrict() to change this behavior.
58//
59// When a TOML local date, time, or date-time is decoded into a time.Time, its
60// value is represented in time.Local timezone. Otherwise the approriate Local*
61// structure is used.
62//
63// Empty tables decoded in an interface{} create an empty initialized
64// map[string]interface{}.
65//
66// Types implementing the encoding.TextUnmarshaler interface are decoded from a
67// TOML string.
68//
69// When decoding a number, go-toml will return an error if the number is out of
70// bounds for the target type (which includes negative numbers when decoding
71// into an unsigned int).
72//
73// Type mapping
74//
75// List of supported TOML types and their associated accepted Go types:
76//
77//   String           -> string
78//   Integer          -> uint*, int*, depending on size
79//   Float            -> float*, depending on size
80//   Boolean          -> bool
81//   Offset Date-Time -> time.Time
82//   Local Date-time  -> LocalDateTime, time.Time
83//   Local Date       -> LocalDate, time.Time
84//   Local Time       -> LocalTime, time.Time
85//   Array            -> slice and array, depending on elements types
86//   Table            -> map and struct
87//   Inline Table     -> same as Table
88//   Array of Tables  -> same as Array and Table
89func (d *Decoder) Decode(v interface{}) error {
90	b, err := ioutil.ReadAll(d.r)
91	if err != nil {
92		return fmt.Errorf("toml: %w", err)
93	}
94
95	p := parser{}
96	p.Reset(b)
97	dec := decoder{
98		p: &p,
99		strict: strict{
100			Enabled: d.strict,
101		},
102	}
103
104	return dec.FromParser(v)
105}
106
107type decoder struct {
108	// Which parser instance in use for this decoding session.
109	p *parser
110
111	// Flag indicating that the current expression is stashed.
112	// If set to true, calling nextExpr will not actually pull a new expression
113	// but turn off the flag instead.
114	stashedExpr bool
115
116	// Skip expressions until a table is found. This is set to true when a
117	// table could not be create (missing field in map), so all KV expressions
118	// need to be skipped.
119	skipUntilTable bool
120
121	// Tracks position in Go arrays.
122	// This is used when decoding [[array tables]] into Go arrays. Given array
123	// tables are separate TOML expression, we need to keep track of where we
124	// are at in the Go array, as we can't just introspect its size.
125	arrayIndexes map[reflect.Value]int
126
127	// Tracks keys that have been seen, with which type.
128	seen tracker.SeenTracker
129
130	// Strict mode
131	strict strict
132}
133
134func (d *decoder) expr() *ast.Node {
135	return d.p.Expression()
136}
137
138func (d *decoder) nextExpr() bool {
139	if d.stashedExpr {
140		d.stashedExpr = false
141		return true
142	}
143	return d.p.NextExpression()
144}
145
146func (d *decoder) stashExpr() {
147	d.stashedExpr = true
148}
149
150func (d *decoder) arrayIndex(shouldAppend bool, v reflect.Value) int {
151	if d.arrayIndexes == nil {
152		d.arrayIndexes = make(map[reflect.Value]int, 1)
153	}
154
155	idx, ok := d.arrayIndexes[v]
156
157	if !ok {
158		d.arrayIndexes[v] = 0
159	} else if shouldAppend {
160		idx++
161		d.arrayIndexes[v] = idx
162	}
163
164	return idx
165}
166
167func (d *decoder) FromParser(v interface{}) error {
168	r := reflect.ValueOf(v)
169	if r.Kind() != reflect.Ptr {
170		return fmt.Errorf("toml: decoding can only be performed into a pointer, not %s", r.Kind())
171	}
172
173	if r.IsNil() {
174		return fmt.Errorf("toml: decoding pointer target cannot be nil")
175	}
176
177	err := d.fromParser(r.Elem())
178	if err == nil {
179		return d.strict.Error(d.p.data)
180	}
181
182	var e *decodeError
183	if errors.As(err, &e) {
184		return wrapDecodeError(d.p.data, e)
185	}
186
187	return err
188}
189
190func (d *decoder) fromParser(root reflect.Value) error {
191	for d.nextExpr() {
192		err := d.handleRootExpression(d.expr(), root)
193		if err != nil {
194			return err
195		}
196	}
197
198	return d.p.Error()
199}
200
201/*
202Rules for the unmarshal code:
203
204- The stack is used to keep track of which values need to be set where.
205- handle* functions <=> switch on a given ast.Kind.
206- unmarshalX* functions need to unmarshal a node of kind X.
207- An "object" is either a struct or a map.
208*/
209
210func (d *decoder) handleRootExpression(expr *ast.Node, v reflect.Value) error {
211	var x reflect.Value
212	var err error
213
214	if !(d.skipUntilTable && expr.Kind == ast.KeyValue) {
215		err = d.seen.CheckExpression(expr)
216		if err != nil {
217			return err
218		}
219	}
220
221	switch expr.Kind {
222	case ast.KeyValue:
223		if d.skipUntilTable {
224			return nil
225		}
226		x, err = d.handleKeyValue(expr, v)
227	case ast.Table:
228		d.skipUntilTable = false
229		d.strict.EnterTable(expr)
230		x, err = d.handleTable(expr.Key(), v)
231	case ast.ArrayTable:
232		d.skipUntilTable = false
233		d.strict.EnterArrayTable(expr)
234		x, err = d.handleArrayTable(expr.Key(), v)
235	default:
236		panic(fmt.Errorf("parser should not permit expression of kind %s at document root", expr.Kind))
237	}
238
239	if d.skipUntilTable {
240		if expr.Kind == ast.Table || expr.Kind == ast.ArrayTable {
241			d.strict.MissingTable(expr)
242		}
243	} else if err == nil && x.IsValid() {
244		v.Set(x)
245	}
246
247	return err
248}
249
250func (d *decoder) handleArrayTable(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
251	if key.Next() {
252		return d.handleArrayTablePart(key, v)
253	}
254	return d.handleKeyValues(v)
255}
256
257func (d *decoder) handleArrayTableCollectionLast(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
258	switch v.Kind() {
259	case reflect.Interface:
260		elem := v.Elem()
261		if !elem.IsValid() {
262			elem = reflect.New(sliceInterfaceType).Elem()
263			elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
264		} else if elem.Kind() == reflect.Slice {
265			if elem.Type() != sliceInterfaceType {
266				elem = reflect.New(sliceInterfaceType).Elem()
267				elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
268			} else if !elem.CanSet() {
269				nelem := reflect.New(sliceInterfaceType).Elem()
270				nelem.Set(reflect.MakeSlice(sliceInterfaceType, elem.Len(), elem.Cap()))
271				reflect.Copy(nelem, elem)
272				elem = nelem
273			}
274		}
275		return d.handleArrayTableCollectionLast(key, elem)
276	case reflect.Ptr:
277		elem := v.Elem()
278		if !elem.IsValid() {
279			ptr := reflect.New(v.Type().Elem())
280			v.Set(ptr)
281			elem = ptr.Elem()
282		}
283
284		elem, err := d.handleArrayTableCollectionLast(key, elem)
285		if err != nil {
286			return reflect.Value{}, err
287		}
288		v.Elem().Set(elem)
289
290		return v, nil
291	case reflect.Slice:
292		elemType := v.Type().Elem()
293		if elemType.Kind() == reflect.Interface {
294			elemType = mapStringInterfaceType
295		}
296		elem := reflect.New(elemType).Elem()
297		elem2, err := d.handleArrayTable(key, elem)
298		if err != nil {
299			return reflect.Value{}, err
300		}
301		if elem2.IsValid() {
302			elem = elem2
303		}
304		return reflect.Append(v, elem), nil
305	case reflect.Array:
306		idx := d.arrayIndex(true, v)
307		if idx >= v.Len() {
308			return v, fmt.Errorf("toml: cannot decode array table into %s at position %d", v.Type(), idx)
309		}
310		elem := v.Index(idx)
311		_, err := d.handleArrayTable(key, elem)
312		return v, err
313	}
314
315	return d.handleArrayTable(key, v)
316}
317
318// When parsing an array table expression, each part of the key needs to be
319// evaluated like a normal key, but if it returns a collection, it also needs to
320// point to the last element of the collection. Unless it is the last part of
321// the key, then it needs to create a new element at the end.
322func (d *decoder) handleArrayTableCollection(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
323	if key.IsLast() {
324		return d.handleArrayTableCollectionLast(key, v)
325	}
326
327	switch v.Kind() {
328	case reflect.Ptr:
329		elem := v.Elem()
330		if !elem.IsValid() {
331			ptr := reflect.New(v.Type().Elem())
332			v.Set(ptr)
333			elem = ptr.Elem()
334		}
335
336		elem, err := d.handleArrayTableCollection(key, elem)
337		if err != nil {
338			return reflect.Value{}, err
339		}
340		v.Elem().Set(elem)
341
342		return v, nil
343	case reflect.Slice:
344		elem := v.Index(v.Len() - 1)
345		x, err := d.handleArrayTable(key, elem)
346		if err != nil || d.skipUntilTable {
347			return reflect.Value{}, err
348		}
349		if x.IsValid() {
350			elem.Set(x)
351		}
352
353		return v, err
354	case reflect.Array:
355		idx := d.arrayIndex(false, v)
356		if idx >= v.Len() {
357			return v, fmt.Errorf("toml: cannot decode array table into %s at position %d", v.Type(), idx)
358		}
359		elem := v.Index(idx)
360		_, err := d.handleArrayTable(key, elem)
361		return v, err
362	}
363
364	return d.handleArrayTable(key, v)
365}
366
367func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
368	var rv reflect.Value
369
370	// First, dispatch over v to make sure it is a valid object.
371	// There is no guarantee over what it could be.
372	switch v.Kind() {
373	case reflect.Ptr:
374		elem := v.Elem()
375		if !elem.IsValid() {
376			v.Set(reflect.New(v.Type().Elem()))
377		}
378		elem = v.Elem()
379		return d.handleKeyPart(key, elem, nextFn, makeFn)
380	case reflect.Map:
381		// Create the key for the map element. For now assume it's a string.
382		mk := reflect.ValueOf(string(key.Node().Data))
383
384		// If the map does not exist, create it.
385		if v.IsNil() {
386			v = reflect.MakeMap(v.Type())
387			rv = v
388		}
389
390		mv := v.MapIndex(mk)
391		set := false
392		if !mv.IsValid() {
393			// If there is no value in the map, create a new one according to
394			// the map type. If the element type is interface, create either a
395			// map[string]interface{} or a []interface{} depending on whether
396			// this is the last part of the array table key.
397
398			t := v.Type().Elem()
399			if t.Kind() == reflect.Interface {
400				mv = makeFn()
401			} else {
402				mv = reflect.New(t).Elem()
403			}
404			set = true
405		} else if mv.Kind() == reflect.Interface {
406			mv = mv.Elem()
407			if !mv.IsValid() {
408				mv = makeFn()
409			}
410			set = true
411		}
412
413		x, err := nextFn(key, mv)
414		if err != nil {
415			return reflect.Value{}, err
416		}
417
418		if x.IsValid() {
419			mv = x
420			set = true
421		}
422
423		if set {
424			v.SetMapIndex(mk, mv)
425		}
426	case reflect.Struct:
427		f, found := structField(v, string(key.Node().Data))
428		if !found {
429			d.skipUntilTable = true
430			return reflect.Value{}, nil
431		}
432
433		x, err := nextFn(key, f)
434		if err != nil || d.skipUntilTable {
435			return reflect.Value{}, err
436		}
437		if x.IsValid() {
438			f.Set(x)
439		}
440	case reflect.Interface:
441		if v.Elem().IsValid() {
442			v = v.Elem()
443		} else {
444			v = reflect.MakeMap(mapStringInterfaceType)
445		}
446
447		x, err := d.handleKeyPart(key, v, nextFn, makeFn)
448		if err != nil {
449			return reflect.Value{}, err
450		}
451		if x.IsValid() {
452			v = x
453		}
454		rv = v
455	default:
456		panic(fmt.Errorf("unhandled part: %s", v.Kind()))
457	}
458
459	return rv, nil
460}
461
462// HandleArrayTablePart navigates the Go structure v using the key v. It is
463// only used for the prefix (non-last) parts of an array-table. When
464// encountering a collection, it should go to the last element.
465func (d *decoder) handleArrayTablePart(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
466	var makeFn valueMakerFn
467	if key.IsLast() {
468		makeFn = makeSliceInterface
469	} else {
470		makeFn = makeMapStringInterface
471	}
472	return d.handleKeyPart(key, v, d.handleArrayTableCollection, makeFn)
473}
474
475// HandleTable returns a reference when it has checked the next expression but
476// cannot handle it.
477func (d *decoder) handleTable(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
478	if v.Kind() == reflect.Slice {
479		elem := v.Index(v.Len() - 1)
480		x, err := d.handleTable(key, elem)
481		if err != nil {
482			return reflect.Value{}, err
483		}
484		if x.IsValid() {
485			elem.Set(x)
486		}
487		return reflect.Value{}, nil
488	}
489	if key.Next() {
490		// Still scoping the key
491		return d.handleTablePart(key, v)
492	}
493	// Done scoping the key.
494	// Now handle all the key-value expressions in this table.
495	return d.handleKeyValues(v)
496}
497
498// Handle root expressions until the end of the document or the next
499// non-key-value.
500func (d *decoder) handleKeyValues(v reflect.Value) (reflect.Value, error) {
501	var rv reflect.Value
502	for d.nextExpr() {
503		expr := d.expr()
504		if expr.Kind != ast.KeyValue {
505			// Stash the expression so that fromParser can just loop and use
506			// the right handler.
507			// We could just recurse ourselves here, but at least this gives a
508			// chance to pop the stack a bit.
509			d.stashExpr()
510			break
511		}
512
513		x, err := d.handleKeyValue(expr, v)
514		if err != nil {
515			return reflect.Value{}, err
516		}
517		if x.IsValid() {
518			v = x
519			rv = x
520		}
521	}
522	return rv, nil
523}
524
525type (
526	handlerFn    func(key ast.Iterator, v reflect.Value) (reflect.Value, error)
527	valueMakerFn func() reflect.Value
528)
529
530func makeMapStringInterface() reflect.Value {
531	return reflect.MakeMap(mapStringInterfaceType)
532}
533
534func makeSliceInterface() reflect.Value {
535	return reflect.MakeSlice(sliceInterfaceType, 0, 16)
536}
537
538func (d *decoder) handleTablePart(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
539	return d.handleKeyPart(key, v, d.handleTable, makeMapStringInterface)
540}
541
542func (d *decoder) tryTextUnmarshaler(node *ast.Node, v reflect.Value) (bool, error) {
543	if v.Kind() != reflect.Struct {
544		return false, nil
545	}
546
547	// Special case for time, because we allow to unmarshal to it from
548	// different kind of AST nodes.
549	if v.Type() == timeType {
550		return false, nil
551	}
552
553	if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) {
554		err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
555		if err != nil {
556			return false, newDecodeError(d.p.Raw(node.Raw), "error calling UnmarshalText: %w", err)
557		}
558
559		return true, nil
560	}
561
562	return false, nil
563}
564
565func (d *decoder) handleValue(value *ast.Node, v reflect.Value) error {
566	for v.Kind() == reflect.Ptr {
567		v = initAndDereferencePointer(v)
568	}
569
570	ok, err := d.tryTextUnmarshaler(value, v)
571	if ok || err != nil {
572		return err
573	}
574
575	switch value.Kind {
576	case ast.String:
577		return d.unmarshalString(value, v)
578	case ast.Integer:
579		return d.unmarshalInteger(value, v)
580	case ast.Float:
581		return d.unmarshalFloat(value, v)
582	case ast.Bool:
583		return d.unmarshalBool(value, v)
584	case ast.DateTime:
585		return d.unmarshalDateTime(value, v)
586	case ast.LocalDate:
587		return d.unmarshalLocalDate(value, v)
588	case ast.LocalTime:
589		return d.unmarshalLocalTime(value, v)
590	case ast.LocalDateTime:
591		return d.unmarshalLocalDateTime(value, v)
592	case ast.InlineTable:
593		return d.unmarshalInlineTable(value, v)
594	case ast.Array:
595		return d.unmarshalArray(value, v)
596	default:
597		panic(fmt.Errorf("handleValue not implemented for %s", value.Kind))
598	}
599}
600
601func (d *decoder) unmarshalArray(array *ast.Node, v reflect.Value) error {
602	switch v.Kind() {
603	case reflect.Slice:
604		if v.IsNil() {
605			v.Set(reflect.MakeSlice(v.Type(), 0, 16))
606		} else {
607			v.SetLen(0)
608		}
609	case reflect.Array:
610		// arrays are always initialized
611	case reflect.Interface:
612		elem := v.Elem()
613		if !elem.IsValid() {
614			elem = reflect.New(sliceInterfaceType).Elem()
615			elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
616		} else if elem.Kind() == reflect.Slice {
617			if elem.Type() != sliceInterfaceType {
618				elem = reflect.New(sliceInterfaceType).Elem()
619				elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
620			} else if !elem.CanSet() {
621				nelem := reflect.New(sliceInterfaceType).Elem()
622				nelem.Set(reflect.MakeSlice(sliceInterfaceType, elem.Len(), elem.Cap()))
623				reflect.Copy(nelem, elem)
624				elem = nelem
625			}
626		}
627		err := d.unmarshalArray(array, elem)
628		if err != nil {
629			return err
630		}
631		v.Set(elem)
632		return nil
633	default:
634		// TODO: use newDecodeError, but first the parser needs to fill
635		//   array.Data.
636		return fmt.Errorf("toml: cannot store array in Go type %s", v.Kind())
637	}
638
639	elemType := v.Type().Elem()
640
641	it := array.Children()
642	idx := 0
643	for it.Next() {
644		n := it.Node()
645
646		// TODO: optimize
647		if v.Kind() == reflect.Slice {
648			elem := reflect.New(elemType).Elem()
649
650			err := d.handleValue(n, elem)
651			if err != nil {
652				return err
653			}
654
655			v.Set(reflect.Append(v, elem))
656		} else { // array
657			if idx >= v.Len() {
658				return nil
659			}
660			elem := v.Index(idx)
661			err := d.handleValue(n, elem)
662			if err != nil {
663				return err
664			}
665			idx++
666		}
667	}
668
669	return nil
670}
671
672func (d *decoder) unmarshalInlineTable(itable *ast.Node, v reflect.Value) error {
673	// Make sure v is an initialized object.
674	switch v.Kind() {
675	case reflect.Map:
676		if v.IsNil() {
677			v.Set(reflect.MakeMap(v.Type()))
678		}
679	case reflect.Struct:
680	// structs are always initialized.
681	case reflect.Interface:
682		elem := v.Elem()
683		if !elem.IsValid() {
684			elem = reflect.MakeMap(mapStringInterfaceType)
685			v.Set(elem)
686		}
687		return d.unmarshalInlineTable(itable, elem)
688	default:
689		return newDecodeError(itable.Data, "cannot store inline table in Go type %s", v.Kind())
690	}
691
692	it := itable.Children()
693	for it.Next() {
694		n := it.Node()
695
696		x, err := d.handleKeyValue(n, v)
697		if err != nil {
698			return err
699		}
700		if x.IsValid() {
701			v = x
702		}
703	}
704
705	return nil
706}
707
708func (d *decoder) unmarshalDateTime(value *ast.Node, v reflect.Value) error {
709	dt, err := parseDateTime(value.Data)
710	if err != nil {
711		return err
712	}
713
714	v.Set(reflect.ValueOf(dt))
715	return nil
716}
717
718func (d *decoder) unmarshalLocalDate(value *ast.Node, v reflect.Value) error {
719	ld, err := parseLocalDate(value.Data)
720	if err != nil {
721		return err
722	}
723
724	if v.Type() == timeType {
725		cast := ld.AsTime(time.Local)
726		v.Set(reflect.ValueOf(cast))
727		return nil
728	}
729
730	v.Set(reflect.ValueOf(ld))
731
732	return nil
733}
734
735func (d *decoder) unmarshalLocalTime(value *ast.Node, v reflect.Value) error {
736	lt, rest, err := parseLocalTime(value.Data)
737	if err != nil {
738		return err
739	}
740
741	if len(rest) > 0 {
742		return newDecodeError(rest, "extra characters at the end of a local time")
743	}
744
745	v.Set(reflect.ValueOf(lt))
746	return nil
747}
748
749func (d *decoder) unmarshalLocalDateTime(value *ast.Node, v reflect.Value) error {
750	ldt, rest, err := parseLocalDateTime(value.Data)
751	if err != nil {
752		return err
753	}
754
755	if len(rest) > 0 {
756		return newDecodeError(rest, "extra characters at the end of a local date time")
757	}
758
759	if v.Type() == timeType {
760		cast := ldt.AsTime(time.Local)
761
762		v.Set(reflect.ValueOf(cast))
763		return nil
764	}
765
766	v.Set(reflect.ValueOf(ldt))
767
768	return nil
769}
770
771func (d *decoder) unmarshalBool(value *ast.Node, v reflect.Value) error {
772	b := value.Data[0] == 't'
773
774	switch v.Kind() {
775	case reflect.Bool:
776		v.SetBool(b)
777	case reflect.Interface:
778		v.Set(reflect.ValueOf(b))
779	default:
780		return newDecodeError(value.Data, "cannot assign boolean to a %t", b)
781	}
782
783	return nil
784}
785
786func (d *decoder) unmarshalFloat(value *ast.Node, v reflect.Value) error {
787	f, err := parseFloat(value.Data)
788	if err != nil {
789		return err
790	}
791
792	switch v.Kind() {
793	case reflect.Float64:
794		v.SetFloat(f)
795	case reflect.Float32:
796		if f > math.MaxFloat32 {
797			return newDecodeError(value.Data, "number %f does not fit in a float32", f)
798		}
799		v.SetFloat(f)
800	case reflect.Interface:
801		v.Set(reflect.ValueOf(f))
802	default:
803		return newDecodeError(value.Data, "float cannot be assigned to %s", v.Kind())
804	}
805
806	return nil
807}
808
809func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
810	const (
811		maxInt = int64(^uint(0) >> 1)
812		minInt = -maxInt - 1
813	)
814
815	i, err := parseInteger(value.Data)
816	if err != nil {
817		return err
818	}
819
820	switch v.Kind() {
821	case reflect.Int64:
822		v.SetInt(i)
823	case reflect.Int32:
824		if i < math.MinInt32 || i > math.MaxInt32 {
825			return fmt.Errorf("toml: number %d does not fit in an int32", i)
826		}
827
828		v.Set(reflect.ValueOf(int32(i)))
829		return nil
830	case reflect.Int16:
831		if i < math.MinInt16 || i > math.MaxInt16 {
832			return fmt.Errorf("toml: number %d does not fit in an int16", i)
833		}
834
835		v.Set(reflect.ValueOf(int16(i)))
836	case reflect.Int8:
837		if i < math.MinInt8 || i > math.MaxInt8 {
838			return fmt.Errorf("toml: number %d does not fit in an int8", i)
839		}
840
841		v.Set(reflect.ValueOf(int8(i)))
842	case reflect.Int:
843		if i < minInt || i > maxInt {
844			return fmt.Errorf("toml: number %d does not fit in an int", i)
845		}
846
847		v.Set(reflect.ValueOf(int(i)))
848	case reflect.Uint64:
849		if i < 0 {
850			return fmt.Errorf("toml: negative number %d does not fit in an uint64", i)
851		}
852
853		v.Set(reflect.ValueOf(uint64(i)))
854	case reflect.Uint32:
855		if i < 0 || i > math.MaxUint32 {
856			return fmt.Errorf("toml: negative number %d does not fit in an uint32", i)
857		}
858
859		v.Set(reflect.ValueOf(uint32(i)))
860	case reflect.Uint16:
861		if i < 0 || i > math.MaxUint16 {
862			return fmt.Errorf("toml: negative number %d does not fit in an uint16", i)
863		}
864
865		v.Set(reflect.ValueOf(uint16(i)))
866	case reflect.Uint8:
867		if i < 0 || i > math.MaxUint8 {
868			return fmt.Errorf("toml: negative number %d does not fit in an uint8", i)
869		}
870
871		v.Set(reflect.ValueOf(uint8(i)))
872	case reflect.Uint:
873		if i < 0 {
874			return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
875		}
876
877		v.Set(reflect.ValueOf(uint(i)))
878	case reflect.Interface:
879		v.Set(reflect.ValueOf(i))
880	default:
881		err = fmt.Errorf("toml: cannot store TOML integer into a Go %s", v.Kind())
882	}
883
884	return err
885}
886
887func (d *decoder) unmarshalString(value *ast.Node, v reflect.Value) error {
888	var err error
889
890	switch v.Kind() {
891	case reflect.String:
892		v.SetString(string(value.Data))
893	case reflect.Interface:
894		v.Set(reflect.ValueOf(string(value.Data)))
895	default:
896		err = newDecodeError(d.p.Raw(value.Raw), "cannot store TOML string into a Go %s", v.Kind())
897	}
898
899	return err
900}
901
902func (d *decoder) handleKeyValue(expr *ast.Node, v reflect.Value) (reflect.Value, error) {
903	d.strict.EnterKeyValue(expr)
904
905	v, err := d.handleKeyValueInner(expr.Key(), expr.Value(), v)
906	if d.skipUntilTable {
907		d.strict.MissingField(expr)
908		d.skipUntilTable = false
909	}
910
911	d.strict.ExitKeyValue(expr)
912
913	return v, err
914}
915
916func (d *decoder) handleKeyValueInner(key ast.Iterator, value *ast.Node, v reflect.Value) (reflect.Value, error) {
917	if key.Next() {
918		// Still scoping the key
919		return d.handleKeyValuePart(key, value, v)
920	}
921	// Done scoping the key.
922	// v is whatever Go value we need to fill.
923	return reflect.Value{}, d.handleValue(value, v)
924}
925
926func (d *decoder) handleKeyValuePart(key ast.Iterator, value *ast.Node, v reflect.Value) (reflect.Value, error) {
927	// contains the replacement for v
928	var rv reflect.Value
929
930	// First, dispatch over v to make sure it is a valid object.
931	// There is no guarantee over what it could be.
932	switch v.Kind() {
933	case reflect.Map:
934		mk := reflect.ValueOf(string(key.Node().Data))
935
936		keyType := v.Type().Key()
937		if !mk.Type().AssignableTo(keyType) {
938			if !mk.Type().ConvertibleTo(keyType) {
939				return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", mk.Type(), keyType)
940			}
941
942			mk = mk.Convert(keyType)
943		}
944
945		// If the map does not exist, create it.
946		if v.IsNil() {
947			v = reflect.MakeMap(v.Type())
948			rv = v
949		}
950
951		mv := v.MapIndex(mk)
952		set := false
953		if !mv.IsValid() {
954			set = true
955			mv = reflect.New(v.Type().Elem()).Elem()
956		} else {
957			if key.IsLast() {
958				var x interface{}
959				mv = reflect.ValueOf(&x).Elem()
960				set = true
961			}
962		}
963
964		nv, err := d.handleKeyValueInner(key, value, mv)
965		if err != nil {
966			return reflect.Value{}, err
967		}
968		if nv.IsValid() {
969			mv = nv
970			set = true
971		}
972
973		if set {
974			v.SetMapIndex(mk, mv)
975		}
976	case reflect.Struct:
977		f, found := structField(v, string(key.Node().Data))
978		if !found {
979			d.skipUntilTable = true
980			break
981		}
982
983		x, err := d.handleKeyValueInner(key, value, f)
984		if err != nil {
985			return reflect.Value{}, err
986		}
987
988		if x.IsValid() {
989			f.Set(x)
990		}
991	case reflect.Interface:
992		v = v.Elem()
993
994		// Following encoding/toml: decoding an object into an interface{}, it
995		// needs to always hold a map[string]interface{}. This is for the types
996		// to be consistent whether a previous value was set or not.
997		if !v.IsValid() || v.Type() != mapStringInterfaceType {
998			v = reflect.MakeMap(mapStringInterfaceType)
999		}
1000
1001		x, err := d.handleKeyValuePart(key, value, v)
1002		if err != nil {
1003			return reflect.Value{}, err
1004		}
1005		if x.IsValid() {
1006			v = x
1007		}
1008		rv = v
1009	case reflect.Ptr:
1010		elem := v.Elem()
1011		if !elem.IsValid() {
1012			ptr := reflect.New(v.Type().Elem())
1013			v.Set(ptr)
1014			rv = v
1015			elem = ptr.Elem()
1016		}
1017
1018		elem2, err := d.handleKeyValuePart(key, value, elem)
1019		if err != nil {
1020			return reflect.Value{}, err
1021		}
1022		if elem2.IsValid() {
1023			elem = elem2
1024		}
1025		v.Elem().Set(elem)
1026	default:
1027		return reflect.Value{}, fmt.Errorf("unhandled kv part: %s", v.Kind())
1028	}
1029
1030	return rv, nil
1031}
1032
1033func initAndDereferencePointer(v reflect.Value) reflect.Value {
1034	var elem reflect.Value
1035	if v.IsNil() {
1036		ptr := reflect.New(v.Type().Elem())
1037		v.Set(ptr)
1038	}
1039	elem = v.Elem()
1040	return elem
1041}
1042
1043type fieldPathsMap = map[string][]int
1044
1045type fieldPathsCache struct {
1046	m map[reflect.Type]fieldPathsMap
1047	l sync.RWMutex
1048}
1049
1050func (c *fieldPathsCache) get(t reflect.Type) (fieldPathsMap, bool) {
1051	c.l.RLock()
1052	paths, ok := c.m[t]
1053	c.l.RUnlock()
1054
1055	return paths, ok
1056}
1057
1058func (c *fieldPathsCache) set(t reflect.Type, m fieldPathsMap) {
1059	c.l.Lock()
1060	c.m[t] = m
1061	c.l.Unlock()
1062}
1063
1064var globalFieldPathsCache = fieldPathsCache{
1065	m: map[reflect.Type]fieldPathsMap{},
1066	l: sync.RWMutex{},
1067}
1068
1069func structField(v reflect.Value, name string) (reflect.Value, bool) {
1070	//nolint:godox
1071	// TODO: cache this, and reduce allocations
1072	fieldPaths, ok := globalFieldPathsCache.get(v.Type())
1073	if !ok {
1074		fieldPaths = map[string][]int{}
1075
1076		path := make([]int, 0, 16)
1077
1078		var walk func(reflect.Value)
1079		walk = func(v reflect.Value) {
1080			t := v.Type()
1081			for i := 0; i < t.NumField(); i++ {
1082				l := len(path)
1083				path = append(path, i)
1084				f := t.Field(i)
1085
1086				if f.Anonymous {
1087					walk(v.Field(i))
1088				} else if f.PkgPath == "" {
1089					// only consider exported fields
1090					fieldName, ok := f.Tag.Lookup("toml")
1091					if !ok {
1092						fieldName = f.Name
1093					}
1094
1095					pathCopy := make([]int, len(path))
1096					copy(pathCopy, path)
1097
1098					fieldPaths[fieldName] = pathCopy
1099					// extra copy for the case-insensitive match
1100					fieldPaths[strings.ToLower(fieldName)] = pathCopy
1101				}
1102				path = path[:l]
1103			}
1104		}
1105
1106		walk(v)
1107
1108		globalFieldPathsCache.set(v.Type(), fieldPaths)
1109	}
1110
1111	path, ok := fieldPaths[name]
1112	if !ok {
1113		path, ok = fieldPaths[strings.ToLower(name)]
1114	}
1115
1116	if !ok {
1117		return reflect.Value{}, false
1118	}
1119
1120	return v.FieldByIndex(path), true
1121}
1122