github.com/go-xe2/third@v1.0.3/gopkg.in/yaml.v2/decode.go (about) 1 package yaml 2 3 import ( 4 "encoding" 5 "encoding/base64" 6 "fmt" 7 "math" 8 "reflect" 9 "strconv" 10 "time" 11 ) 12 13 const ( 14 documentNode = 1 << iota 15 mappingNode 16 sequenceNode 17 scalarNode 18 aliasNode 19 ) 20 21 type node struct { 22 kind int 23 line, column int 24 tag string 25 value string 26 implicit bool 27 children []*node 28 anchors map[string]*node 29 } 30 31 // ---------------------------------------------------------------------------- 32 // Parser, produces a node tree out of a libyaml event stream. 33 34 type parser struct { 35 parser yaml_parser_t 36 event yaml_event_t 37 doc *node 38 } 39 40 func newParser(b []byte) *parser { 41 p := parser{} 42 if !yaml_parser_initialize(&p.parser) { 43 panic("failed to initialize YAML emitter") 44 } 45 46 if len(b) == 0 { 47 b = []byte{'\n'} 48 } 49 50 yaml_parser_set_input_string(&p.parser, b) 51 52 p.skip() 53 if p.event.typ != yaml_STREAM_START_EVENT { 54 panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ))) 55 } 56 p.skip() 57 return &p 58 } 59 60 func (p *parser) destroy() { 61 if p.event.typ != yaml_NO_EVENT { 62 yaml_event_delete(&p.event) 63 } 64 yaml_parser_delete(&p.parser) 65 } 66 67 func (p *parser) skip() { 68 if p.event.typ != yaml_NO_EVENT { 69 if p.event.typ == yaml_STREAM_END_EVENT { 70 failf("attempted to go past the end of stream; corrupted value?") 71 } 72 yaml_event_delete(&p.event) 73 } 74 if !yaml_parser_parse(&p.parser, &p.event) { 75 p.fail() 76 } 77 } 78 79 func (p *parser) fail() { 80 var where string 81 var line int 82 if p.parser.problem_mark.line != 0 { 83 line = p.parser.problem_mark.line 84 } else if p.parser.context_mark.line != 0 { 85 line = p.parser.context_mark.line 86 } 87 if line != 0 { 88 where = "line " + strconv.Itoa(line) + ": " 89 } 90 var msg string 91 if len(p.parser.problem) > 0 { 92 msg = p.parser.problem 93 } else { 94 msg = "unknown problem parsing YAML content" 95 } 96 failf("%s%s", where, msg) 97 } 98 99 func (p *parser) anchor(n *node, anchor []byte) { 100 if anchor != nil { 101 p.doc.anchors[string(anchor)] = n 102 } 103 } 104 105 func (p *parser) parse() *node { 106 switch p.event.typ { 107 case yaml_SCALAR_EVENT: 108 return p.scalar() 109 case yaml_ALIAS_EVENT: 110 return p.alias() 111 case yaml_MAPPING_START_EVENT: 112 return p.mapping() 113 case yaml_SEQUENCE_START_EVENT: 114 return p.sequence() 115 case yaml_DOCUMENT_START_EVENT: 116 return p.document() 117 case yaml_STREAM_END_EVENT: 118 // Happens when attempting to decode an empty buffer. 119 return nil 120 default: 121 panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ))) 122 } 123 } 124 125 func (p *parser) node(kind int) *node { 126 return &node{ 127 kind: kind, 128 line: p.event.start_mark.line, 129 column: p.event.start_mark.column, 130 } 131 } 132 133 func (p *parser) document() *node { 134 n := p.node(documentNode) 135 n.anchors = make(map[string]*node) 136 p.doc = n 137 p.skip() 138 n.children = append(n.children, p.parse()) 139 if p.event.typ != yaml_DOCUMENT_END_EVENT { 140 panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ))) 141 } 142 p.skip() 143 return n 144 } 145 146 func (p *parser) alias() *node { 147 n := p.node(aliasNode) 148 n.value = string(p.event.anchor) 149 p.skip() 150 return n 151 } 152 153 func (p *parser) scalar() *node { 154 n := p.node(scalarNode) 155 n.value = string(p.event.value) 156 n.tag = string(p.event.tag) 157 n.implicit = p.event.implicit 158 p.anchor(n, p.event.anchor) 159 p.skip() 160 return n 161 } 162 163 func (p *parser) sequence() *node { 164 n := p.node(sequenceNode) 165 p.anchor(n, p.event.anchor) 166 p.skip() 167 for p.event.typ != yaml_SEQUENCE_END_EVENT { 168 n.children = append(n.children, p.parse()) 169 } 170 p.skip() 171 return n 172 } 173 174 func (p *parser) mapping() *node { 175 n := p.node(mappingNode) 176 p.anchor(n, p.event.anchor) 177 p.skip() 178 for p.event.typ != yaml_MAPPING_END_EVENT { 179 n.children = append(n.children, p.parse(), p.parse()) 180 } 181 p.skip() 182 return n 183 } 184 185 // ---------------------------------------------------------------------------- 186 // Decoder, unmarshals a node into a provided value. 187 188 type decoder struct { 189 doc *node 190 aliases map[string]bool 191 mapType reflect.Type 192 terrors []string 193 strict bool 194 } 195 196 var ( 197 mapItemType = reflect.TypeOf(MapItem{}) 198 durationType = reflect.TypeOf(time.Duration(0)) 199 defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) 200 ifaceType = defaultMapType.Elem() 201 ) 202 203 func newDecoder(strict bool) *decoder { 204 d := &decoder{mapType: defaultMapType, strict: strict} 205 d.aliases = make(map[string]bool) 206 return d 207 } 208 209 func (d *decoder) terror(n *node, tag string, out reflect.Value) { 210 if n.tag != "" { 211 tag = n.tag 212 } 213 value := n.value 214 if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG { 215 if len(value) > 10 { 216 value = " `" + value[:7] + "...`" 217 } else { 218 value = " `" + value + "`" 219 } 220 } 221 d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) 222 } 223 224 func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { 225 terrlen := len(d.terrors) 226 err := u.UnmarshalYAML(func(v interface{}) (err error) { 227 defer handleErr(&err) 228 d.unmarshal(n, reflect.ValueOf(v)) 229 if len(d.terrors) > terrlen { 230 issues := d.terrors[terrlen:] 231 d.terrors = d.terrors[:terrlen] 232 return &TypeError{issues} 233 } 234 return nil 235 }) 236 if e, ok := err.(*TypeError); ok { 237 d.terrors = append(d.terrors, e.Errors...) 238 return false 239 } 240 if err != nil { 241 fail(err) 242 } 243 return true 244 } 245 246 // d.prepare initializes and dereferences pointers and calls UnmarshalYAML 247 // if a value is found to implement it. 248 // It returns the initialized and dereferenced out value, whether 249 // unmarshalling was already done by UnmarshalYAML, and if so whether 250 // its types unmarshalled appropriately. 251 // 252 // If n holds a null value, prepare returns before doing anything. 253 func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { 254 if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) { 255 return out, false, false 256 } 257 again := true 258 for again { 259 again = false 260 if out.Kind() == reflect.Ptr { 261 if out.IsNil() { 262 out.Set(reflect.New(out.Type().Elem())) 263 } 264 out = out.Elem() 265 again = true 266 } 267 if out.CanAddr() { 268 if u, ok := out.Addr().Interface().(Unmarshaler); ok { 269 good = d.callUnmarshaler(n, u) 270 return out, true, good 271 } 272 } 273 } 274 return out, false, false 275 } 276 277 func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { 278 switch n.kind { 279 case documentNode: 280 return d.document(n, out) 281 case aliasNode: 282 return d.alias(n, out) 283 } 284 out, unmarshaled, good := d.prepare(n, out) 285 if unmarshaled { 286 return good 287 } 288 switch n.kind { 289 case scalarNode: 290 good = d.scalar(n, out) 291 case mappingNode: 292 good = d.mapping(n, out) 293 case sequenceNode: 294 good = d.sequence(n, out) 295 default: 296 panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) 297 } 298 return good 299 } 300 301 func (d *decoder) document(n *node, out reflect.Value) (good bool) { 302 if len(n.children) == 1 { 303 d.doc = n 304 d.unmarshal(n.children[0], out) 305 return true 306 } 307 return false 308 } 309 310 func (d *decoder) alias(n *node, out reflect.Value) (good bool) { 311 an, ok := d.doc.anchors[n.value] 312 if !ok { 313 failf("unknown anchor '%s' referenced", n.value) 314 } 315 if d.aliases[n.value] { 316 failf("anchor '%s' value contains itself", n.value) 317 } 318 d.aliases[n.value] = true 319 good = d.unmarshal(an, out) 320 delete(d.aliases, n.value) 321 return good 322 } 323 324 var zeroValue reflect.Value 325 326 func resetMap(out reflect.Value) { 327 for _, k := range out.MapKeys() { 328 out.SetMapIndex(k, zeroValue) 329 } 330 } 331 332 func (d *decoder) scalar(n *node, out reflect.Value) (good bool) { 333 var tag string 334 var resolved interface{} 335 if n.tag == "" && !n.implicit { 336 tag = yaml_STR_TAG 337 resolved = n.value 338 } else { 339 tag, resolved = resolve(n.tag, n.value) 340 if tag == yaml_BINARY_TAG { 341 data, err := base64.StdEncoding.DecodeString(resolved.(string)) 342 if err != nil { 343 failf("!!binary value contains invalid base64 data") 344 } 345 resolved = string(data) 346 } 347 } 348 if resolved == nil { 349 if out.Kind() == reflect.Map && !out.CanAddr() { 350 resetMap(out) 351 } else { 352 out.Set(reflect.Zero(out.Type())) 353 } 354 return true 355 } 356 if s, ok := resolved.(string); ok && out.CanAddr() { 357 if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok { 358 err := u.UnmarshalText([]byte(s)) 359 if err != nil { 360 fail(err) 361 } 362 return true 363 } 364 } 365 switch out.Kind() { 366 case reflect.String: 367 if tag == yaml_BINARY_TAG { 368 out.SetString(resolved.(string)) 369 good = true 370 } else if resolved != nil { 371 out.SetString(n.value) 372 good = true 373 } 374 case reflect.Interface: 375 if resolved == nil { 376 out.Set(reflect.Zero(out.Type())) 377 } else { 378 out.Set(reflect.ValueOf(resolved)) 379 } 380 good = true 381 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 382 switch resolved := resolved.(type) { 383 case int: 384 if !out.OverflowInt(int64(resolved)) { 385 out.SetInt(int64(resolved)) 386 good = true 387 } 388 case int64: 389 if !out.OverflowInt(resolved) { 390 out.SetInt(resolved) 391 good = true 392 } 393 case uint64: 394 if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 395 out.SetInt(int64(resolved)) 396 good = true 397 } 398 case float64: 399 if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 400 out.SetInt(int64(resolved)) 401 good = true 402 } 403 case string: 404 if out.Type() == durationType { 405 d, err := time.ParseDuration(resolved) 406 if err == nil { 407 out.SetInt(int64(d)) 408 good = true 409 } 410 } 411 } 412 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 413 switch resolved := resolved.(type) { 414 case int: 415 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 416 out.SetUint(uint64(resolved)) 417 good = true 418 } 419 case int64: 420 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 421 out.SetUint(uint64(resolved)) 422 good = true 423 } 424 case uint64: 425 if !out.OverflowUint(uint64(resolved)) { 426 out.SetUint(uint64(resolved)) 427 good = true 428 } 429 case float64: 430 if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { 431 out.SetUint(uint64(resolved)) 432 good = true 433 } 434 } 435 case reflect.Bool: 436 switch resolved := resolved.(type) { 437 case bool: 438 out.SetBool(resolved) 439 good = true 440 } 441 case reflect.Float32, reflect.Float64: 442 switch resolved := resolved.(type) { 443 case int: 444 out.SetFloat(float64(resolved)) 445 good = true 446 case int64: 447 out.SetFloat(float64(resolved)) 448 good = true 449 case uint64: 450 out.SetFloat(float64(resolved)) 451 good = true 452 case float64: 453 out.SetFloat(resolved) 454 good = true 455 } 456 case reflect.Ptr: 457 if out.Type().Elem() == reflect.TypeOf(resolved) { 458 // TODO DOes this make sense? When is out a Ptr except when decoding a nil value? 459 elem := reflect.New(out.Type().Elem()) 460 elem.Elem().Set(reflect.ValueOf(resolved)) 461 out.Set(elem) 462 good = true 463 } 464 } 465 if !good { 466 d.terror(n, tag, out) 467 } 468 return good 469 } 470 471 func settableValueOf(i interface{}) reflect.Value { 472 v := reflect.ValueOf(i) 473 sv := reflect.New(v.Type()).Elem() 474 sv.Set(v) 475 return sv 476 } 477 478 func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { 479 l := len(n.children) 480 481 var iface reflect.Value 482 switch out.Kind() { 483 case reflect.Slice: 484 out.Set(reflect.MakeSlice(out.Type(), l, l)) 485 case reflect.Interface: 486 // No type hints. Will have to use a generic sequence. 487 iface = out 488 out = settableValueOf(make([]interface{}, l)) 489 default: 490 d.terror(n, yaml_SEQ_TAG, out) 491 return false 492 } 493 et := out.Type().Elem() 494 495 j := 0 496 for i := 0; i < l; i++ { 497 e := reflect.New(et).Elem() 498 if ok := d.unmarshal(n.children[i], e); ok { 499 out.Index(j).Set(e) 500 j++ 501 } 502 } 503 out.Set(out.Slice(0, j)) 504 if iface.IsValid() { 505 iface.Set(out) 506 } 507 return true 508 } 509 510 func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { 511 switch out.Kind() { 512 case reflect.Struct: 513 return d.mappingStruct(n, out) 514 case reflect.Slice: 515 return d.mappingSlice(n, out) 516 case reflect.Map: 517 // okay 518 case reflect.Interface: 519 if d.mapType.Kind() == reflect.Map { 520 iface := out 521 out = reflect.MakeMap(d.mapType) 522 iface.Set(out) 523 } else { 524 slicev := reflect.New(d.mapType).Elem() 525 if !d.mappingSlice(n, slicev) { 526 return false 527 } 528 out.Set(slicev) 529 return true 530 } 531 default: 532 d.terror(n, yaml_MAP_TAG, out) 533 return false 534 } 535 outt := out.Type() 536 kt := outt.Key() 537 et := outt.Elem() 538 539 mapType := d.mapType 540 if outt.Key() == ifaceType && outt.Elem() == ifaceType { 541 d.mapType = outt 542 } 543 544 if out.IsNil() { 545 out.Set(reflect.MakeMap(outt)) 546 } 547 l := len(n.children) 548 for i := 0; i < l; i += 2 { 549 if isMerge(n.children[i]) { 550 d.merge(n.children[i+1], out) 551 continue 552 } 553 k := reflect.New(kt).Elem() 554 if d.unmarshal(n.children[i], k) { 555 kkind := k.Kind() 556 if kkind == reflect.Interface { 557 kkind = k.Elem().Kind() 558 } 559 if kkind == reflect.Map || kkind == reflect.Slice { 560 failf("invalid map key: %#v", k.Interface()) 561 } 562 e := reflect.New(et).Elem() 563 if d.unmarshal(n.children[i+1], e) { 564 out.SetMapIndex(k, e) 565 } 566 } 567 } 568 d.mapType = mapType 569 return true 570 } 571 572 func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { 573 outt := out.Type() 574 if outt.Elem() != mapItemType { 575 d.terror(n, yaml_MAP_TAG, out) 576 return false 577 } 578 579 mapType := d.mapType 580 d.mapType = outt 581 582 var slice []MapItem 583 var l = len(n.children) 584 for i := 0; i < l; i += 2 { 585 if isMerge(n.children[i]) { 586 d.merge(n.children[i+1], out) 587 continue 588 } 589 item := MapItem{} 590 k := reflect.ValueOf(&item.Key).Elem() 591 if d.unmarshal(n.children[i], k) { 592 v := reflect.ValueOf(&item.Value).Elem() 593 if d.unmarshal(n.children[i+1], v) { 594 slice = append(slice, item) 595 } 596 } 597 } 598 out.Set(reflect.ValueOf(slice)) 599 d.mapType = mapType 600 return true 601 } 602 603 func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { 604 sinfo, err := getStructInfo(out.Type()) 605 if err != nil { 606 panic(err) 607 } 608 name := settableValueOf("") 609 l := len(n.children) 610 611 var inlineMap reflect.Value 612 var elemType reflect.Type 613 if sinfo.InlineMap != -1 { 614 inlineMap = out.Field(sinfo.InlineMap) 615 inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) 616 elemType = inlineMap.Type().Elem() 617 } 618 619 for i := 0; i < l; i += 2 { 620 ni := n.children[i] 621 if isMerge(ni) { 622 d.merge(n.children[i+1], out) 623 continue 624 } 625 if !d.unmarshal(ni, name) { 626 continue 627 } 628 if info, ok := sinfo.FieldsMap[name.String()]; ok { 629 var field reflect.Value 630 if info.Inline == nil { 631 field = out.Field(info.Num) 632 } else { 633 field = out.FieldByIndex(info.Inline) 634 } 635 d.unmarshal(n.children[i+1], field) 636 } else if sinfo.InlineMap != -1 { 637 if inlineMap.IsNil() { 638 inlineMap.Set(reflect.MakeMap(inlineMap.Type())) 639 } 640 value := reflect.New(elemType).Elem() 641 d.unmarshal(n.children[i+1], value) 642 inlineMap.SetMapIndex(name, value) 643 } else if d.strict { 644 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in struct %s", ni.line+1, name.String(), out.Type())) 645 } 646 } 647 return true 648 } 649 650 func failWantMap() { 651 failf("map merge requires map or sequence of maps as the value") 652 } 653 654 func (d *decoder) merge(n *node, out reflect.Value) { 655 switch n.kind { 656 case mappingNode: 657 d.unmarshal(n, out) 658 case aliasNode: 659 an, ok := d.doc.anchors[n.value] 660 if ok && an.kind != mappingNode { 661 failWantMap() 662 } 663 d.unmarshal(n, out) 664 case sequenceNode: 665 // Step backwards as earlier nodes take precedence. 666 for i := len(n.children) - 1; i >= 0; i-- { 667 ni := n.children[i] 668 if ni.kind == aliasNode { 669 an, ok := d.doc.anchors[ni.value] 670 if ok && an.kind != mappingNode { 671 failWantMap() 672 } 673 } else if ni.kind != mappingNode { 674 failWantMap() 675 } 676 d.unmarshal(ni, out) 677 } 678 default: 679 failWantMap() 680 } 681 } 682 683 func isMerge(n *node) bool { 684 return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) 685 }