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