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