1package toml
2
3import (
4	"bytes"
5	"encoding"
6	"errors"
7	"fmt"
8	"io"
9	"reflect"
10	"sort"
11	"strconv"
12	"strings"
13	"time"
14)
15
16const (
17	tagFieldName    = "toml"
18	tagFieldComment = "comment"
19	tagCommented    = "commented"
20	tagMultiline    = "multiline"
21	tagLiteral      = "literal"
22	tagDefault      = "default"
23)
24
25type tomlOpts struct {
26	name         string
27	nameFromTag  bool
28	comment      string
29	commented    bool
30	multiline    bool
31	literal      bool
32	include      bool
33	omitempty    bool
34	defaultValue string
35}
36
37type encOpts struct {
38	quoteMapKeys            bool
39	arraysOneElementPerLine bool
40}
41
42var encOptsDefaults = encOpts{
43	quoteMapKeys: false,
44}
45
46type annotation struct {
47	tag          string
48	comment      string
49	commented    string
50	multiline    string
51	literal      string
52	defaultValue string
53}
54
55var annotationDefault = annotation{
56	tag:          tagFieldName,
57	comment:      tagFieldComment,
58	commented:    tagCommented,
59	multiline:    tagMultiline,
60	literal:      tagLiteral,
61	defaultValue: tagDefault,
62}
63
64type MarshalOrder int
65
66// Orders the Encoder can write the fields to the output stream.
67const (
68	// Sort fields alphabetically.
69	OrderAlphabetical MarshalOrder = iota + 1
70	// Preserve the order the fields are encountered. For example, the order of fields in
71	// a struct.
72	OrderPreserve
73)
74
75var timeType = reflect.TypeOf(time.Time{})
76var marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
77var unmarshalerType = reflect.TypeOf(new(Unmarshaler)).Elem()
78var textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
79var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
80var localDateType = reflect.TypeOf(LocalDate{})
81var localTimeType = reflect.TypeOf(LocalTime{})
82var localDateTimeType = reflect.TypeOf(LocalDateTime{})
83var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
84
85// Check if the given marshal type maps to a Tree primitive
86func isPrimitive(mtype reflect.Type) bool {
87	switch mtype.Kind() {
88	case reflect.Ptr:
89		return isPrimitive(mtype.Elem())
90	case reflect.Bool:
91		return true
92	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
93		return true
94	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
95		return true
96	case reflect.Float32, reflect.Float64:
97		return true
98	case reflect.String:
99		return true
100	case reflect.Struct:
101		return isTimeType(mtype)
102	default:
103		return false
104	}
105}
106
107func isTimeType(mtype reflect.Type) bool {
108	return mtype == timeType || mtype == localDateType || mtype == localDateTimeType || mtype == localTimeType
109}
110
111// Check if the given marshal type maps to a Tree slice or array
112func isTreeSequence(mtype reflect.Type) bool {
113	switch mtype.Kind() {
114	case reflect.Ptr:
115		return isTreeSequence(mtype.Elem())
116	case reflect.Slice, reflect.Array:
117		return isTree(mtype.Elem())
118	default:
119		return false
120	}
121}
122
123// Check if the given marshal type maps to a slice or array of a custom marshaler type
124func isCustomMarshalerSequence(mtype reflect.Type) bool {
125	switch mtype.Kind() {
126	case reflect.Ptr:
127		return isCustomMarshalerSequence(mtype.Elem())
128	case reflect.Slice, reflect.Array:
129		return isCustomMarshaler(mtype.Elem()) || isCustomMarshaler(reflect.New(mtype.Elem()).Type())
130	default:
131		return false
132	}
133}
134
135// Check if the given marshal type maps to a slice or array of a text marshaler type
136func isTextMarshalerSequence(mtype reflect.Type) bool {
137	switch mtype.Kind() {
138	case reflect.Ptr:
139		return isTextMarshalerSequence(mtype.Elem())
140	case reflect.Slice, reflect.Array:
141		return isTextMarshaler(mtype.Elem()) || isTextMarshaler(reflect.New(mtype.Elem()).Type())
142	default:
143		return false
144	}
145}
146
147// Check if the given marshal type maps to a non-Tree slice or array
148func isOtherSequence(mtype reflect.Type) bool {
149	switch mtype.Kind() {
150	case reflect.Ptr:
151		return isOtherSequence(mtype.Elem())
152	case reflect.Slice, reflect.Array:
153		return !isTreeSequence(mtype)
154	default:
155		return false
156	}
157}
158
159// Check if the given marshal type maps to a Tree
160func isTree(mtype reflect.Type) bool {
161	switch mtype.Kind() {
162	case reflect.Ptr:
163		return isTree(mtype.Elem())
164	case reflect.Map:
165		return true
166	case reflect.Struct:
167		return !isPrimitive(mtype)
168	default:
169		return false
170	}
171}
172
173func isCustomMarshaler(mtype reflect.Type) bool {
174	return mtype.Implements(marshalerType)
175}
176
177func callCustomMarshaler(mval reflect.Value) ([]byte, error) {
178	return mval.Interface().(Marshaler).MarshalTOML()
179}
180
181func isTextMarshaler(mtype reflect.Type) bool {
182	return mtype.Implements(textMarshalerType) && !isTimeType(mtype)
183}
184
185func callTextMarshaler(mval reflect.Value) ([]byte, error) {
186	return mval.Interface().(encoding.TextMarshaler).MarshalText()
187}
188
189func isCustomUnmarshaler(mtype reflect.Type) bool {
190	return mtype.Implements(unmarshalerType)
191}
192
193func callCustomUnmarshaler(mval reflect.Value, tval interface{}) error {
194	return mval.Interface().(Unmarshaler).UnmarshalTOML(tval)
195}
196
197func isTextUnmarshaler(mtype reflect.Type) bool {
198	return mtype.Implements(textUnmarshalerType)
199}
200
201func callTextUnmarshaler(mval reflect.Value, text []byte) error {
202	return mval.Interface().(encoding.TextUnmarshaler).UnmarshalText(text)
203}
204
205// Marshaler is the interface implemented by types that
206// can marshal themselves into valid TOML.
207type Marshaler interface {
208	MarshalTOML() ([]byte, error)
209}
210
211// Unmarshaler is the interface implemented by types that
212// can unmarshal a TOML description of themselves.
213type Unmarshaler interface {
214	UnmarshalTOML(interface{}) error
215}
216
217/*
218Marshal returns the TOML encoding of v.  Behavior is similar to the Go json
219encoder, except that there is no concept of a Marshaler interface or MarshalTOML
220function for sub-structs, and currently only definite types can be marshaled
221(i.e. no `interface{}`).
222
223The following struct annotations are supported:
224
225  toml:"Field"      Overrides the field's name to output.
226  omitempty         When set, empty values and groups are not emitted.
227  comment:"comment" Emits a # comment on the same line. This supports new lines.
228  commented:"true"  Emits the value as commented.
229
230Note that pointers are automatically assigned the "omitempty" option, as TOML
231explicitly does not handle null values (saying instead the label should be
232dropped).
233
234Tree structural types and corresponding marshal types:
235
236  *Tree                            (*)struct, (*)map[string]interface{}
237  []*Tree                          (*)[](*)struct, (*)[](*)map[string]interface{}
238  []interface{} (as interface{})   (*)[]primitive, (*)[]([]interface{})
239  interface{}                      (*)primitive
240
241Tree primitive types and corresponding marshal types:
242
243  uint64     uint, uint8-uint64, pointers to same
244  int64      int, int8-uint64, pointers to same
245  float64    float32, float64, pointers to same
246  string     string, pointers to same
247  bool       bool, pointers to same
248  time.LocalTime  time.LocalTime{}, pointers to same
249
250For additional flexibility, use the Encoder API.
251*/
252func Marshal(v interface{}) ([]byte, error) {
253	return NewEncoder(nil).marshal(v)
254}
255
256// Encoder writes TOML values to an output stream.
257type Encoder struct {
258	w io.Writer
259	encOpts
260	annotation
261	line        int
262	col         int
263	order       MarshalOrder
264	promoteAnon bool
265	indentation string
266}
267
268// NewEncoder returns a new encoder that writes to w.
269func NewEncoder(w io.Writer) *Encoder {
270	return &Encoder{
271		w:           w,
272		encOpts:     encOptsDefaults,
273		annotation:  annotationDefault,
274		line:        0,
275		col:         1,
276		order:       OrderAlphabetical,
277		indentation: "  ",
278	}
279}
280
281// Encode writes the TOML encoding of v to the stream.
282//
283// See the documentation for Marshal for details.
284func (e *Encoder) Encode(v interface{}) error {
285	b, err := e.marshal(v)
286	if err != nil {
287		return err
288	}
289	if _, err := e.w.Write(b); err != nil {
290		return err
291	}
292	return nil
293}
294
295// QuoteMapKeys sets up the encoder to encode
296// maps with string type keys with quoted TOML keys.
297//
298// This relieves the character limitations on map keys.
299func (e *Encoder) QuoteMapKeys(v bool) *Encoder {
300	e.quoteMapKeys = v
301	return e
302}
303
304// ArraysWithOneElementPerLine sets up the encoder to encode arrays
305// with more than one element on multiple lines instead of one.
306//
307// For example:
308//
309//   A = [1,2,3]
310//
311// Becomes
312//
313//   A = [
314//     1,
315//     2,
316//     3,
317//   ]
318func (e *Encoder) ArraysWithOneElementPerLine(v bool) *Encoder {
319	e.arraysOneElementPerLine = v
320	return e
321}
322
323// Order allows to change in which order fields will be written to the output stream.
324func (e *Encoder) Order(ord MarshalOrder) *Encoder {
325	e.order = ord
326	return e
327}
328
329// Indentation allows to change indentation when marshalling.
330func (e *Encoder) Indentation(indent string) *Encoder {
331	e.indentation = indent
332	return e
333}
334
335// SetTagName allows changing default tag "toml"
336func (e *Encoder) SetTagName(v string) *Encoder {
337	e.tag = v
338	return e
339}
340
341// SetTagComment allows changing default tag "comment"
342func (e *Encoder) SetTagComment(v string) *Encoder {
343	e.comment = v
344	return e
345}
346
347// SetTagCommented allows changing default tag "commented"
348func (e *Encoder) SetTagCommented(v string) *Encoder {
349	e.commented = v
350	return e
351}
352
353// SetTagMultiline allows changing default tag "multiline"
354func (e *Encoder) SetTagMultiline(v string) *Encoder {
355	e.multiline = v
356	return e
357}
358
359// PromoteAnonymous allows to change how anonymous struct fields are marshaled.
360// Usually, they are marshaled as if the inner exported fields were fields in
361// the outer struct. However, if an anonymous struct field is given a name in
362// its TOML tag, it is treated like a regular struct field with that name.
363// rather than being anonymous.
364//
365// In case anonymous promotion is enabled, all anonymous structs are promoted
366// and treated like regular struct fields.
367func (e *Encoder) PromoteAnonymous(promote bool) *Encoder {
368	e.promoteAnon = promote
369	return e
370}
371
372func (e *Encoder) marshal(v interface{}) ([]byte, error) {
373	// Check if indentation is valid
374	for _, char := range e.indentation {
375		if !isSpace(char) {
376			return []byte{}, fmt.Errorf("invalid indentation: must only contains space or tab characters")
377		}
378	}
379
380	mtype := reflect.TypeOf(v)
381	if mtype == nil {
382		return []byte{}, errors.New("nil cannot be marshaled to TOML")
383	}
384
385	switch mtype.Kind() {
386	case reflect.Struct, reflect.Map:
387	case reflect.Ptr:
388		if mtype.Elem().Kind() != reflect.Struct {
389			return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML")
390		}
391		if reflect.ValueOf(v).IsNil() {
392			return []byte{}, errors.New("nil pointer cannot be marshaled to TOML")
393		}
394	default:
395		return []byte{}, errors.New("Only a struct or map can be marshaled to TOML")
396	}
397
398	sval := reflect.ValueOf(v)
399	if isCustomMarshaler(mtype) {
400		return callCustomMarshaler(sval)
401	}
402	if isTextMarshaler(mtype) {
403		return callTextMarshaler(sval)
404	}
405	t, err := e.valueToTree(mtype, sval)
406	if err != nil {
407		return []byte{}, err
408	}
409
410	var buf bytes.Buffer
411	_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order, e.indentation, false)
412
413	return buf.Bytes(), err
414}
415
416// Create next tree with a position based on Encoder.line
417func (e *Encoder) nextTree() *Tree {
418	return newTreeWithPosition(Position{Line: e.line, Col: 1})
419}
420
421// Convert given marshal struct or map value to toml tree
422func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) {
423	if mtype.Kind() == reflect.Ptr {
424		return e.valueToTree(mtype.Elem(), mval.Elem())
425	}
426	tval := e.nextTree()
427	switch mtype.Kind() {
428	case reflect.Struct:
429		switch mval.Interface().(type) {
430		case Tree:
431			reflect.ValueOf(tval).Elem().Set(mval)
432		default:
433			for i := 0; i < mtype.NumField(); i++ {
434				mtypef, mvalf := mtype.Field(i), mval.Field(i)
435				opts := tomlOptions(mtypef, e.annotation)
436				if opts.include && ((mtypef.Type.Kind() != reflect.Interface && !opts.omitempty) || !isZero(mvalf)) {
437					val, err := e.valueToToml(mtypef.Type, mvalf)
438					if err != nil {
439						return nil, err
440					}
441					if tree, ok := val.(*Tree); ok && mtypef.Anonymous && !opts.nameFromTag && !e.promoteAnon {
442						e.appendTree(tval, tree)
443					} else {
444						val = e.wrapTomlValue(val, tval)
445						tval.SetPathWithOptions([]string{opts.name}, SetOptions{
446							Comment:   opts.comment,
447							Commented: opts.commented,
448							Multiline: opts.multiline,
449							Literal:   opts.literal,
450						}, val)
451					}
452				}
453			}
454		}
455	case reflect.Map:
456		keys := mval.MapKeys()
457		if e.order == OrderPreserve && len(keys) > 0 {
458			// Sorting []reflect.Value is not straight forward.
459			//
460			// OrderPreserve will support deterministic results when string is used
461			// as the key to maps.
462			typ := keys[0].Type()
463			kind := keys[0].Kind()
464			if kind == reflect.String {
465				ikeys := make([]string, len(keys))
466				for i := range keys {
467					ikeys[i] = keys[i].Interface().(string)
468				}
469				sort.Strings(ikeys)
470				for i := range ikeys {
471					keys[i] = reflect.ValueOf(ikeys[i]).Convert(typ)
472				}
473			}
474		}
475		for _, key := range keys {
476			mvalf := mval.MapIndex(key)
477			if (mtype.Elem().Kind() == reflect.Ptr || mtype.Elem().Kind() == reflect.Interface) && mvalf.IsNil() {
478				continue
479			}
480			val, err := e.valueToToml(mtype.Elem(), mvalf)
481			if err != nil {
482				return nil, err
483			}
484			val = e.wrapTomlValue(val, tval)
485			if e.quoteMapKeys {
486				keyStr, err := tomlValueStringRepresentation(key.String(), "", "", e.order, e.arraysOneElementPerLine)
487				if err != nil {
488					return nil, err
489				}
490				tval.SetPath([]string{keyStr}, val)
491			} else {
492				tval.SetPath([]string{key.String()}, val)
493			}
494		}
495	}
496	return tval, nil
497}
498
499// Convert given marshal slice to slice of Toml trees
500func (e *Encoder) valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) {
501	tval := make([]*Tree, mval.Len(), mval.Len())
502	for i := 0; i < mval.Len(); i++ {
503		val, err := e.valueToTree(mtype.Elem(), mval.Index(i))
504		if err != nil {
505			return nil, err
506		}
507		tval[i] = val
508	}
509	return tval, nil
510}
511
512// Convert given marshal slice to slice of toml values
513func (e *Encoder) valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
514	tval := make([]interface{}, mval.Len(), mval.Len())
515	for i := 0; i < mval.Len(); i++ {
516		val, err := e.valueToToml(mtype.Elem(), mval.Index(i))
517		if err != nil {
518			return nil, err
519		}
520		tval[i] = val
521	}
522	return tval, nil
523}
524
525// Convert given marshal value to toml value
526func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
527	if mtype.Kind() == reflect.Ptr {
528		switch {
529		case isCustomMarshaler(mtype):
530			return callCustomMarshaler(mval)
531		case isTextMarshaler(mtype):
532			b, err := callTextMarshaler(mval)
533			return string(b), err
534		default:
535			return e.valueToToml(mtype.Elem(), mval.Elem())
536		}
537	}
538	if mtype.Kind() == reflect.Interface {
539		return e.valueToToml(mval.Elem().Type(), mval.Elem())
540	}
541	switch {
542	case isCustomMarshaler(mtype):
543		return callCustomMarshaler(mval)
544	case isTextMarshaler(mtype):
545		b, err := callTextMarshaler(mval)
546		return string(b), err
547	case isTree(mtype):
548		return e.valueToTree(mtype, mval)
549	case isOtherSequence(mtype), isCustomMarshalerSequence(mtype), isTextMarshalerSequence(mtype):
550		return e.valueToOtherSlice(mtype, mval)
551	case isTreeSequence(mtype):
552		return e.valueToTreeSlice(mtype, mval)
553	default:
554		switch mtype.Kind() {
555		case reflect.Bool:
556			return mval.Bool(), nil
557		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
558			if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) {
559				return fmt.Sprint(mval), nil
560			}
561			return mval.Int(), nil
562		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
563			return mval.Uint(), nil
564		case reflect.Float32, reflect.Float64:
565			return mval.Float(), nil
566		case reflect.String:
567			return mval.String(), nil
568		case reflect.Struct:
569			return mval.Interface(), nil
570		default:
571			return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind())
572		}
573	}
574}
575
576func (e *Encoder) appendTree(t, o *Tree) error {
577	for key, value := range o.values {
578		if _, ok := t.values[key]; ok {
579			continue
580		}
581		if tomlValue, ok := value.(*tomlValue); ok {
582			tomlValue.position.Col = t.position.Col
583		}
584		t.values[key] = value
585	}
586	return nil
587}
588
589// Create a toml value with the current line number as the position line
590func (e *Encoder) wrapTomlValue(val interface{}, parent *Tree) interface{} {
591	_, isTree := val.(*Tree)
592	_, isTreeS := val.([]*Tree)
593	if isTree || isTreeS {
594		return val
595	}
596
597	ret := &tomlValue{
598		value: val,
599		position: Position{
600			e.line,
601			parent.position.Col,
602		},
603	}
604	e.line++
605	return ret
606}
607
608// Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v.
609// Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for
610// sub-structs, and only definite types can be unmarshaled.
611func (t *Tree) Unmarshal(v interface{}) error {
612	d := Decoder{tval: t, tagName: tagFieldName}
613	return d.unmarshal(v)
614}
615
616// Marshal returns the TOML encoding of Tree.
617// See Marshal() documentation for types mapping table.
618func (t *Tree) Marshal() ([]byte, error) {
619	var buf bytes.Buffer
620	_, err := t.WriteTo(&buf)
621	if err != nil {
622		return nil, err
623	}
624	return buf.Bytes(), nil
625}
626
627// Unmarshal parses the TOML-encoded data and stores the result in the value
628// pointed to by v. Behavior is similar to the Go json encoder, except that there
629// is no concept of an Unmarshaler interface or UnmarshalTOML function for
630// sub-structs, and currently only definite types can be unmarshaled to (i.e. no
631// `interface{}`).
632//
633// The following struct annotations are supported:
634//
635//   toml:"Field" Overrides the field's name to map to.
636//   default:"foo" Provides a default value.
637//
638// For default values, only fields of the following types are supported:
639//   * string
640//   * bool
641//   * int
642//   * int64
643//   * float64
644//
645// See Marshal() documentation for types mapping table.
646func Unmarshal(data []byte, v interface{}) error {
647	t, err := LoadReader(bytes.NewReader(data))
648	if err != nil {
649		return err
650	}
651	return t.Unmarshal(v)
652}
653
654// Decoder reads and decodes TOML values from an input stream.
655type Decoder struct {
656	r    io.Reader
657	tval *Tree
658	encOpts
659	tagName string
660	strict  bool
661	visitor visitorState
662}
663
664// NewDecoder returns a new decoder that reads from r.
665func NewDecoder(r io.Reader) *Decoder {
666	return &Decoder{
667		r:       r,
668		encOpts: encOptsDefaults,
669		tagName: tagFieldName,
670	}
671}
672
673// Decode reads a TOML-encoded value from it's input
674// and unmarshals it in the value pointed at by v.
675//
676// See the documentation for Marshal for details.
677func (d *Decoder) Decode(v interface{}) error {
678	var err error
679	d.tval, err = LoadReader(d.r)
680	if err != nil {
681		return err
682	}
683	return d.unmarshal(v)
684}
685
686// SetTagName allows changing default tag "toml"
687func (d *Decoder) SetTagName(v string) *Decoder {
688	d.tagName = v
689	return d
690}
691
692// Strict allows changing to strict decoding. Any fields that are found in the
693// input data and do not have a corresponding struct member cause an error.
694func (d *Decoder) Strict(strict bool) *Decoder {
695	d.strict = strict
696	return d
697}
698
699func (d *Decoder) unmarshal(v interface{}) error {
700	mtype := reflect.TypeOf(v)
701	if mtype == nil {
702		return errors.New("nil cannot be unmarshaled from TOML")
703	}
704	if mtype.Kind() != reflect.Ptr {
705		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
706	}
707
708	elem := mtype.Elem()
709
710	switch elem.Kind() {
711	case reflect.Struct, reflect.Map:
712	case reflect.Interface:
713		elem = mapStringInterfaceType
714	default:
715		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
716	}
717
718	if reflect.ValueOf(v).IsNil() {
719		return errors.New("nil pointer cannot be unmarshaled from TOML")
720	}
721
722	vv := reflect.ValueOf(v).Elem()
723
724	if d.strict {
725		d.visitor = newVisitorState(d.tval)
726	}
727
728	sval, err := d.valueFromTree(elem, d.tval, &vv)
729	if err != nil {
730		return err
731	}
732	if err := d.visitor.validate(); err != nil {
733		return err
734	}
735	reflect.ValueOf(v).Elem().Set(sval)
736	return nil
737}
738
739// Convert toml tree to marshal struct or map, using marshal type. When mval1
740// is non-nil, merge fields into the given value instead of allocating a new one.
741func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.Value) (reflect.Value, error) {
742	if mtype.Kind() == reflect.Ptr {
743		return d.unwrapPointer(mtype, tval, mval1)
744	}
745
746	// Check if pointer to value implements the Unmarshaler interface.
747	if mvalPtr := reflect.New(mtype); isCustomUnmarshaler(mvalPtr.Type()) {
748		d.visitor.visitAll()
749
750		if tval == nil {
751			return mvalPtr.Elem(), nil
752		}
753
754		if err := callCustomUnmarshaler(mvalPtr, tval.ToMap()); err != nil {
755			return reflect.ValueOf(nil), fmt.Errorf("unmarshal toml: %v", err)
756		}
757		return mvalPtr.Elem(), nil
758	}
759
760	var mval reflect.Value
761	switch mtype.Kind() {
762	case reflect.Struct:
763		if mval1 != nil {
764			mval = *mval1
765		} else {
766			mval = reflect.New(mtype).Elem()
767		}
768
769		switch mval.Interface().(type) {
770		case Tree:
771			mval.Set(reflect.ValueOf(tval).Elem())
772		default:
773			for i := 0; i < mtype.NumField(); i++ {
774				mtypef := mtype.Field(i)
775				an := annotation{tag: d.tagName}
776				opts := tomlOptions(mtypef, an)
777				if !opts.include {
778					continue
779				}
780				baseKey := opts.name
781				keysToTry := []string{
782					baseKey,
783					strings.ToLower(baseKey),
784					strings.ToTitle(baseKey),
785					strings.ToLower(string(baseKey[0])) + baseKey[1:],
786				}
787
788				found := false
789				if tval != nil {
790					for _, key := range keysToTry {
791						exists := tval.HasPath([]string{key})
792						if !exists {
793							continue
794						}
795
796						d.visitor.push(key)
797						val := tval.GetPath([]string{key})
798						fval := mval.Field(i)
799						mvalf, err := d.valueFromToml(mtypef.Type, val, &fval)
800						if err != nil {
801							return mval, formatError(err, tval.GetPositionPath([]string{key}))
802						}
803						mval.Field(i).Set(mvalf)
804						found = true
805						d.visitor.pop()
806						break
807					}
808				}
809
810				if !found && opts.defaultValue != "" {
811					mvalf := mval.Field(i)
812					var val interface{}
813					var err error
814					switch mvalf.Kind() {
815					case reflect.String:
816						val = opts.defaultValue
817					case reflect.Bool:
818						val, err = strconv.ParseBool(opts.defaultValue)
819					case reflect.Uint:
820						val, err = strconv.ParseUint(opts.defaultValue, 10, 0)
821					case reflect.Uint8:
822						val, err = strconv.ParseUint(opts.defaultValue, 10, 8)
823					case reflect.Uint16:
824						val, err = strconv.ParseUint(opts.defaultValue, 10, 16)
825					case reflect.Uint32:
826						val, err = strconv.ParseUint(opts.defaultValue, 10, 32)
827					case reflect.Uint64:
828						val, err = strconv.ParseUint(opts.defaultValue, 10, 64)
829					case reflect.Int:
830						val, err = strconv.ParseInt(opts.defaultValue, 10, 0)
831					case reflect.Int8:
832						val, err = strconv.ParseInt(opts.defaultValue, 10, 8)
833					case reflect.Int16:
834						val, err = strconv.ParseInt(opts.defaultValue, 10, 16)
835					case reflect.Int32:
836						val, err = strconv.ParseInt(opts.defaultValue, 10, 32)
837					case reflect.Int64:
838						// Check if the provided number has a non-numeric extension.
839						var hasExtension bool
840						if len(opts.defaultValue) > 0 {
841							lastChar := opts.defaultValue[len(opts.defaultValue)-1]
842							if lastChar < '0' || lastChar > '9' {
843								hasExtension = true
844							}
845						}
846						// If the value is a time.Duration with extension, parse as duration.
847						// If the value is an int64 or a time.Duration without extension, parse as number.
848						if hasExtension && mvalf.Type().String() == "time.Duration" {
849							val, err = time.ParseDuration(opts.defaultValue)
850						} else {
851							val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
852						}
853					case reflect.Float32:
854						val, err = strconv.ParseFloat(opts.defaultValue, 32)
855					case reflect.Float64:
856						val, err = strconv.ParseFloat(opts.defaultValue, 64)
857					default:
858						return mvalf, fmt.Errorf("unsupported field type for default option")
859					}
860
861					if err != nil {
862						return mvalf, err
863					}
864					mvalf.Set(reflect.ValueOf(val).Convert(mvalf.Type()))
865				}
866
867				// save the old behavior above and try to check structs
868				if !found && opts.defaultValue == "" && mtypef.Type.Kind() == reflect.Struct {
869					tmpTval := tval
870					if !mtypef.Anonymous {
871						tmpTval = nil
872					}
873					fval := mval.Field(i)
874					v, err := d.valueFromTree(mtypef.Type, tmpTval, &fval)
875					if err != nil {
876						return v, err
877					}
878					mval.Field(i).Set(v)
879				}
880			}
881		}
882	case reflect.Map:
883		mval = reflect.MakeMap(mtype)
884		for _, key := range tval.Keys() {
885			d.visitor.push(key)
886			// TODO: path splits key
887			val := tval.GetPath([]string{key})
888			mvalf, err := d.valueFromToml(mtype.Elem(), val, nil)
889			if err != nil {
890				return mval, formatError(err, tval.GetPositionPath([]string{key}))
891			}
892			mval.SetMapIndex(reflect.ValueOf(key).Convert(mtype.Key()), mvalf)
893			d.visitor.pop()
894		}
895	}
896	return mval, nil
897}
898
899// Convert toml value to marshal struct/map slice, using marshal type
900func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
901	mval, err := makeSliceOrArray(mtype, len(tval))
902	if err != nil {
903		return mval, err
904	}
905
906	for i := 0; i < len(tval); i++ {
907		d.visitor.push(strconv.Itoa(i))
908		val, err := d.valueFromTree(mtype.Elem(), tval[i], nil)
909		if err != nil {
910			return mval, err
911		}
912		mval.Index(i).Set(val)
913		d.visitor.pop()
914	}
915	return mval, nil
916}
917
918// Convert toml value to marshal primitive slice, using marshal type
919func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
920	mval, err := makeSliceOrArray(mtype, len(tval))
921	if err != nil {
922		return mval, err
923	}
924
925	for i := 0; i < len(tval); i++ {
926		val, err := d.valueFromToml(mtype.Elem(), tval[i], nil)
927		if err != nil {
928			return mval, err
929		}
930		mval.Index(i).Set(val)
931	}
932	return mval, nil
933}
934
935// Convert toml value to marshal primitive slice, using marshal type
936func (d *Decoder) valueFromOtherSliceI(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
937	val := reflect.ValueOf(tval)
938	length := val.Len()
939
940	mval, err := makeSliceOrArray(mtype, length)
941	if err != nil {
942		return mval, err
943	}
944
945	for i := 0; i < length; i++ {
946		val, err := d.valueFromToml(mtype.Elem(), val.Index(i).Interface(), nil)
947		if err != nil {
948			return mval, err
949		}
950		mval.Index(i).Set(val)
951	}
952	return mval, nil
953}
954
955// Create a new slice or a new array with specified length
956func makeSliceOrArray(mtype reflect.Type, tLength int) (reflect.Value, error) {
957	var mval reflect.Value
958	switch mtype.Kind() {
959	case reflect.Slice:
960		mval = reflect.MakeSlice(mtype, tLength, tLength)
961	case reflect.Array:
962		mval = reflect.New(reflect.ArrayOf(mtype.Len(), mtype.Elem())).Elem()
963		if tLength > mtype.Len() {
964			return mval, fmt.Errorf("unmarshal: TOML array length (%v) exceeds destination array length (%v)", tLength, mtype.Len())
965		}
966	}
967	return mval, nil
968}
969
970// Convert toml value to marshal value, using marshal type. When mval1 is non-nil
971// and the given type is a struct value, merge fields into it.
972func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) {
973	if mtype.Kind() == reflect.Ptr {
974		return d.unwrapPointer(mtype, tval, mval1)
975	}
976
977	switch t := tval.(type) {
978	case *Tree:
979		var mval11 *reflect.Value
980		if mtype.Kind() == reflect.Struct {
981			mval11 = mval1
982		}
983
984		if isTree(mtype) {
985			return d.valueFromTree(mtype, t, mval11)
986		}
987
988		if mtype.Kind() == reflect.Interface {
989			if mval1 == nil || mval1.IsNil() {
990				return d.valueFromTree(reflect.TypeOf(map[string]interface{}{}), t, nil)
991			} else {
992				return d.valueFromToml(mval1.Elem().Type(), t, nil)
993			}
994		}
995
996		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
997	case []*Tree:
998		if isTreeSequence(mtype) {
999			return d.valueFromTreeSlice(mtype, t)
1000		}
1001		if mtype.Kind() == reflect.Interface {
1002			if mval1 == nil || mval1.IsNil() {
1003				return d.valueFromTreeSlice(reflect.TypeOf([]map[string]interface{}{}), t)
1004			} else {
1005				ival := mval1.Elem()
1006				return d.valueFromToml(mval1.Elem().Type(), t, &ival)
1007			}
1008		}
1009		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
1010	case []interface{}:
1011		d.visitor.visit()
1012		if isOtherSequence(mtype) {
1013			return d.valueFromOtherSlice(mtype, t)
1014		}
1015		if mtype.Kind() == reflect.Interface {
1016			if mval1 == nil || mval1.IsNil() {
1017				return d.valueFromOtherSlice(reflect.TypeOf([]interface{}{}), t)
1018			} else {
1019				ival := mval1.Elem()
1020				return d.valueFromToml(mval1.Elem().Type(), t, &ival)
1021			}
1022		}
1023		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
1024	default:
1025		d.visitor.visit()
1026		mvalPtr := reflect.New(mtype)
1027
1028		// Check if pointer to value implements the Unmarshaler interface.
1029		if isCustomUnmarshaler(mvalPtr.Type()) {
1030			if err := callCustomUnmarshaler(mvalPtr, tval); err != nil {
1031				return reflect.ValueOf(nil), fmt.Errorf("unmarshal toml: %v", err)
1032			}
1033			return mvalPtr.Elem(), nil
1034		}
1035
1036		// Check if pointer to value implements the encoding.TextUnmarshaler.
1037		if isTextUnmarshaler(mvalPtr.Type()) && !isTimeType(mtype) {
1038			if err := d.unmarshalText(tval, mvalPtr); err != nil {
1039				return reflect.ValueOf(nil), fmt.Errorf("unmarshal text: %v", err)
1040			}
1041			return mvalPtr.Elem(), nil
1042		}
1043
1044		switch mtype.Kind() {
1045		case reflect.Bool, reflect.Struct:
1046			val := reflect.ValueOf(tval)
1047
1048			switch val.Type() {
1049			case localDateType:
1050				localDate := val.Interface().(LocalDate)
1051				switch mtype {
1052				case timeType:
1053					return reflect.ValueOf(time.Date(localDate.Year, localDate.Month, localDate.Day, 0, 0, 0, 0, time.Local)), nil
1054				}
1055			case localDateTimeType:
1056				localDateTime := val.Interface().(LocalDateTime)
1057				switch mtype {
1058				case timeType:
1059					return reflect.ValueOf(time.Date(
1060						localDateTime.Date.Year,
1061						localDateTime.Date.Month,
1062						localDateTime.Date.Day,
1063						localDateTime.Time.Hour,
1064						localDateTime.Time.Minute,
1065						localDateTime.Time.Second,
1066						localDateTime.Time.Nanosecond,
1067						time.Local)), nil
1068				}
1069			}
1070
1071			// if this passes for when mtype is reflect.Struct, tval is a time.LocalTime
1072			if !val.Type().ConvertibleTo(mtype) {
1073				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
1074			}
1075
1076			return val.Convert(mtype), nil
1077		case reflect.String:
1078			val := reflect.ValueOf(tval)
1079			// stupidly, int64 is convertible to string. So special case this.
1080			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Int64 {
1081				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
1082			}
1083
1084			return val.Convert(mtype), nil
1085		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1086			val := reflect.ValueOf(tval)
1087			if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) && val.Kind() == reflect.String {
1088				d, err := time.ParseDuration(val.String())
1089				if err != nil {
1090					return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err)
1091				}
1092				return reflect.ValueOf(d), nil
1093			}
1094			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Float64 {
1095				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
1096			}
1097			if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(reflect.TypeOf(int64(0))).Int()) {
1098				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
1099			}
1100
1101			return val.Convert(mtype), nil
1102		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1103			val := reflect.ValueOf(tval)
1104			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Float64 {
1105				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
1106			}
1107
1108			if val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
1109				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
1110			}
1111			if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) {
1112				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
1113			}
1114
1115			return val.Convert(mtype), nil
1116		case reflect.Float32, reflect.Float64:
1117			val := reflect.ValueOf(tval)
1118			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Int64 {
1119				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
1120			}
1121			if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(reflect.TypeOf(float64(0))).Float()) {
1122				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
1123			}
1124
1125			return val.Convert(mtype), nil
1126		case reflect.Interface:
1127			if mval1 == nil || mval1.IsNil() {
1128				return reflect.ValueOf(tval), nil
1129			} else {
1130				ival := mval1.Elem()
1131				return d.valueFromToml(mval1.Elem().Type(), t, &ival)
1132			}
1133		case reflect.Slice, reflect.Array:
1134			if isOtherSequence(mtype) && isOtherSequence(reflect.TypeOf(t)) {
1135				return d.valueFromOtherSliceI(mtype, t)
1136			}
1137			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
1138		default:
1139			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
1140		}
1141	}
1142}
1143
1144func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) {
1145	var melem *reflect.Value
1146
1147	if mval1 != nil && !mval1.IsNil() && (mtype.Elem().Kind() == reflect.Struct || mtype.Elem().Kind() == reflect.Interface) {
1148		elem := mval1.Elem()
1149		melem = &elem
1150	}
1151
1152	val, err := d.valueFromToml(mtype.Elem(), tval, melem)
1153	if err != nil {
1154		return reflect.ValueOf(nil), err
1155	}
1156	mval := reflect.New(mtype.Elem())
1157	mval.Elem().Set(val)
1158	return mval, nil
1159}
1160
1161func (d *Decoder) unmarshalText(tval interface{}, mval reflect.Value) error {
1162	var buf bytes.Buffer
1163	fmt.Fprint(&buf, tval)
1164	return callTextUnmarshaler(mval, buf.Bytes())
1165}
1166
1167func tomlOptions(vf reflect.StructField, an annotation) tomlOpts {
1168	tag := vf.Tag.Get(an.tag)
1169	parse := strings.Split(tag, ",")
1170	var comment string
1171	if c := vf.Tag.Get(an.comment); c != "" {
1172		comment = c
1173	}
1174	commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented))
1175	multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline))
1176	literal, _ := strconv.ParseBool(vf.Tag.Get(an.literal))
1177	defaultValue := vf.Tag.Get(tagDefault)
1178	result := tomlOpts{
1179		name:         vf.Name,
1180		nameFromTag:  false,
1181		comment:      comment,
1182		commented:    commented,
1183		multiline:    multiline,
1184		literal:      literal,
1185		include:      true,
1186		omitempty:    false,
1187		defaultValue: defaultValue,
1188	}
1189	if parse[0] != "" {
1190		if parse[0] == "-" && len(parse) == 1 {
1191			result.include = false
1192		} else {
1193			result.name = strings.Trim(parse[0], " ")
1194			result.nameFromTag = true
1195		}
1196	}
1197	if vf.PkgPath != "" {
1198		result.include = false
1199	}
1200	if len(parse) > 1 && strings.Trim(parse[1], " ") == "omitempty" {
1201		result.omitempty = true
1202	}
1203	if vf.Type.Kind() == reflect.Ptr {
1204		result.omitempty = true
1205	}
1206	return result
1207}
1208
1209func isZero(val reflect.Value) bool {
1210	switch val.Type().Kind() {
1211	case reflect.Slice, reflect.Array, reflect.Map:
1212		return val.Len() == 0
1213	default:
1214		return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface())
1215	}
1216}
1217
1218func formatError(err error, pos Position) error {
1219	if err.Error()[0] == '(' { // Error already contains position information
1220		return err
1221	}
1222	return fmt.Errorf("%s: %s", pos, err)
1223}
1224
1225// visitorState keeps track of which keys were unmarshaled.
1226type visitorState struct {
1227	tree   *Tree
1228	path   []string
1229	keys   map[string]struct{}
1230	active bool
1231}
1232
1233func newVisitorState(tree *Tree) visitorState {
1234	path, result := []string{}, map[string]struct{}{}
1235	insertKeys(path, result, tree)
1236	return visitorState{
1237		tree:   tree,
1238		path:   path[:0],
1239		keys:   result,
1240		active: true,
1241	}
1242}
1243
1244func (s *visitorState) push(key string) {
1245	if s.active {
1246		s.path = append(s.path, key)
1247	}
1248}
1249
1250func (s *visitorState) pop() {
1251	if s.active {
1252		s.path = s.path[:len(s.path)-1]
1253	}
1254}
1255
1256func (s *visitorState) visit() {
1257	if s.active {
1258		delete(s.keys, strings.Join(s.path, "."))
1259	}
1260}
1261
1262func (s *visitorState) visitAll() {
1263	if s.active {
1264		for k := range s.keys {
1265			if strings.HasPrefix(k, strings.Join(s.path, ".")) {
1266				delete(s.keys, k)
1267			}
1268		}
1269	}
1270}
1271
1272func (s *visitorState) validate() error {
1273	if !s.active {
1274		return nil
1275	}
1276	undecoded := make([]string, 0, len(s.keys))
1277	for key := range s.keys {
1278		undecoded = append(undecoded, key)
1279	}
1280	sort.Strings(undecoded)
1281	if len(undecoded) > 0 {
1282		return fmt.Errorf("undecoded keys: %q", undecoded)
1283	}
1284	return nil
1285}
1286
1287func insertKeys(path []string, m map[string]struct{}, tree *Tree) {
1288	for k, v := range tree.values {
1289		switch node := v.(type) {
1290		case []*Tree:
1291			for i, item := range node {
1292				insertKeys(append(path, k, strconv.Itoa(i)), m, item)
1293			}
1294		case *Tree:
1295			insertKeys(append(path, k), m, node)
1296		case *tomlValue:
1297			m[strings.Join(append(path, k), ".")] = struct{}{}
1298		}
1299	}
1300}
1301