github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/Godeps/_workspace/src/gopkg.in/yaml.v1/decode.go (about) 1 package yaml 2 3 import ( 4 "reflect" 5 "strconv" 6 "time" 7 ) 8 9 const ( 10 documentNode = 1 << iota 11 mappingNode 12 sequenceNode 13 scalarNode 14 aliasNode 15 ) 16 17 type node struct { 18 kind int 19 line, column int 20 tag string 21 value string 22 implicit bool 23 children []*node 24 anchors map[string]*node 25 } 26 27 // ---------------------------------------------------------------------------- 28 // Parser, produces a node tree out of a libyaml event stream. 29 30 type parser struct { 31 parser yaml_parser_t 32 event yaml_event_t 33 doc *node 34 } 35 36 func newParser(b []byte) *parser { 37 p := parser{} 38 if !yaml_parser_initialize(&p.parser) { 39 panic("Failed to initialize YAML emitter") 40 } 41 42 if len(b) == 0 { 43 b = []byte{'\n'} 44 } 45 46 yaml_parser_set_input_string(&p.parser, b) 47 48 p.skip() 49 if p.event.typ != yaml_STREAM_START_EVENT { 50 panic("Expected stream start event, got " + strconv.Itoa(int(p.event.typ))) 51 } 52 p.skip() 53 return &p 54 } 55 56 func (p *parser) destroy() { 57 if p.event.typ != yaml_NO_EVENT { 58 yaml_event_delete(&p.event) 59 } 60 yaml_parser_delete(&p.parser) 61 } 62 63 func (p *parser) skip() { 64 if p.event.typ != yaml_NO_EVENT { 65 if p.event.typ == yaml_STREAM_END_EVENT { 66 panic("Attempted to go past the end of stream. Corrupted value?") 67 } 68 yaml_event_delete(&p.event) 69 } 70 if !yaml_parser_parse(&p.parser, &p.event) { 71 p.fail() 72 } 73 } 74 75 func (p *parser) fail() { 76 var where string 77 var line int 78 if p.parser.problem_mark.line != 0 { 79 line = p.parser.problem_mark.line 80 } else if p.parser.context_mark.line != 0 { 81 line = p.parser.context_mark.line 82 } 83 if line != 0 { 84 where = "line " + strconv.Itoa(line) + ": " 85 } 86 var msg string 87 if len(p.parser.problem) > 0 { 88 msg = p.parser.problem 89 } else { 90 msg = "Unknown problem parsing YAML content" 91 } 92 panic(where + msg) 93 } 94 95 func (p *parser) anchor(n *node, anchor []byte) { 96 if anchor != nil { 97 p.doc.anchors[string(anchor)] = n 98 } 99 } 100 101 func (p *parser) parse() *node { 102 switch p.event.typ { 103 case yaml_SCALAR_EVENT: 104 return p.scalar() 105 case yaml_ALIAS_EVENT: 106 return p.alias() 107 case yaml_MAPPING_START_EVENT: 108 return p.mapping() 109 case yaml_SEQUENCE_START_EVENT: 110 return p.sequence() 111 case yaml_DOCUMENT_START_EVENT: 112 return p.document() 113 case yaml_STREAM_END_EVENT: 114 // Happens when attempting to decode an empty buffer. 115 return nil 116 default: 117 panic("Attempted to parse unknown event: " + 118 strconv.Itoa(int(p.event.typ))) 119 } 120 panic("Unreachable") 121 } 122 123 func (p *parser) node(kind int) *node { 124 return &node{ 125 kind: kind, 126 line: p.event.start_mark.line, 127 column: p.event.start_mark.column, 128 } 129 } 130 131 func (p *parser) document() *node { 132 n := p.node(documentNode) 133 n.anchors = make(map[string]*node) 134 p.doc = n 135 p.skip() 136 n.children = append(n.children, p.parse()) 137 if p.event.typ != yaml_DOCUMENT_END_EVENT { 138 panic("Expected end of document event but got " + 139 strconv.Itoa(int(p.event.typ))) 140 } 141 p.skip() 142 return n 143 } 144 145 func (p *parser) alias() *node { 146 n := p.node(aliasNode) 147 n.value = string(p.event.anchor) 148 p.skip() 149 return n 150 } 151 152 func (p *parser) scalar() *node { 153 n := p.node(scalarNode) 154 n.value = string(p.event.value) 155 n.tag = string(p.event.tag) 156 n.implicit = p.event.implicit 157 p.anchor(n, p.event.anchor) 158 p.skip() 159 return n 160 } 161 162 func (p *parser) sequence() *node { 163 n := p.node(sequenceNode) 164 p.anchor(n, p.event.anchor) 165 p.skip() 166 for p.event.typ != yaml_SEQUENCE_END_EVENT { 167 n.children = append(n.children, p.parse()) 168 } 169 p.skip() 170 return n 171 } 172 173 func (p *parser) mapping() *node { 174 n := p.node(mappingNode) 175 p.anchor(n, p.event.anchor) 176 p.skip() 177 for p.event.typ != yaml_MAPPING_END_EVENT { 178 n.children = append(n.children, p.parse(), p.parse()) 179 } 180 p.skip() 181 return n 182 } 183 184 // ---------------------------------------------------------------------------- 185 // Decoder, unmarshals a node into a provided value. 186 187 type decoder struct { 188 doc *node 189 aliases map[string]bool 190 } 191 192 func newDecoder() *decoder { 193 d := &decoder{} 194 d.aliases = make(map[string]bool) 195 return d 196 } 197 198 // d.setter deals with setters and pointer dereferencing and initialization. 199 // 200 // It's a slightly convoluted case to handle properly: 201 // 202 // - nil pointers should be initialized, unless being set to nil 203 // - we don't know at this point yet what's the value to SetYAML() with. 204 // - we can't separate pointer deref/init and setter checking, because 205 // a setter may be found while going down a pointer chain. 206 // 207 // Thus, here is how it takes care of it: 208 // 209 // - out is provided as a pointer, so that it can be replaced. 210 // - when looking at a non-setter ptr, *out=ptr.Elem(), unless tag=!!null 211 // - when a setter is found, *out=interface{}, and a set() function is 212 // returned to call SetYAML() with the value of *out once it's defined. 213 // 214 func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()) { 215 if (*out).Kind() != reflect.Ptr && (*out).CanAddr() { 216 setter, _ := (*out).Addr().Interface().(Setter) 217 if setter != nil { 218 var arg interface{} 219 *out = reflect.ValueOf(&arg).Elem() 220 return func() { 221 *good = setter.SetYAML(tag, arg) 222 } 223 } 224 } 225 again := true 226 for again { 227 again = false 228 setter, _ := (*out).Interface().(Setter) 229 if tag != "!!null" || setter != nil { 230 if pv := (*out); pv.Kind() == reflect.Ptr { 231 if pv.IsNil() { 232 *out = reflect.New(pv.Type().Elem()).Elem() 233 pv.Set((*out).Addr()) 234 } else { 235 *out = pv.Elem() 236 } 237 setter, _ = pv.Interface().(Setter) 238 again = true 239 } 240 } 241 if setter != nil { 242 var arg interface{} 243 *out = reflect.ValueOf(&arg).Elem() 244 return func() { 245 *good = setter.SetYAML(tag, arg) 246 } 247 } 248 } 249 return nil 250 } 251 252 func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { 253 switch n.kind { 254 case documentNode: 255 good = d.document(n, out) 256 case scalarNode: 257 good = d.scalar(n, out) 258 case aliasNode: 259 good = d.alias(n, out) 260 case mappingNode: 261 good = d.mapping(n, out) 262 case sequenceNode: 263 good = d.sequence(n, out) 264 default: 265 panic("Internal error: unknown node kind: " + strconv.Itoa(n.kind)) 266 } 267 return 268 } 269 270 func (d *decoder) document(n *node, out reflect.Value) (good bool) { 271 if len(n.children) == 1 { 272 d.doc = n 273 d.unmarshal(n.children[0], out) 274 return true 275 } 276 return false 277 } 278 279 func (d *decoder) alias(n *node, out reflect.Value) (good bool) { 280 an, ok := d.doc.anchors[n.value] 281 if !ok { 282 panic("Unknown anchor '" + n.value + "' referenced") 283 } 284 if d.aliases[n.value] { 285 panic("Anchor '" + n.value + "' value contains itself") 286 } 287 d.aliases[n.value] = true 288 good = d.unmarshal(an, out) 289 delete(d.aliases, n.value) 290 return good 291 } 292 293 var durationType = reflect.TypeOf(time.Duration(0)) 294 295 func (d *decoder) scalar(n *node, out reflect.Value) (good bool) { 296 var tag string 297 var resolved interface{} 298 if n.tag == "" && !n.implicit { 299 tag = "!!str" 300 resolved = n.value 301 } else { 302 tag, resolved = resolve(n.tag, n.value) 303 } 304 if set := d.setter(tag, &out, &good); set != nil { 305 defer set() 306 } 307 switch out.Kind() { 308 case reflect.String: 309 if resolved != nil { 310 out.SetString(n.value) 311 good = true 312 } 313 case reflect.Interface: 314 if resolved == nil { 315 out.Set(reflect.Zero(out.Type())) 316 } else { 317 out.Set(reflect.ValueOf(resolved)) 318 } 319 good = true 320 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 321 switch resolved := resolved.(type) { 322 case int: 323 if !out.OverflowInt(int64(resolved)) { 324 out.SetInt(int64(resolved)) 325 good = true 326 } 327 case int64: 328 if !out.OverflowInt(resolved) { 329 out.SetInt(resolved) 330 good = true 331 } 332 case float64: 333 if resolved < 1<<63-1 && !out.OverflowInt(int64(resolved)) { 334 out.SetInt(int64(resolved)) 335 good = true 336 } 337 case string: 338 if out.Type() == durationType { 339 d, err := time.ParseDuration(resolved) 340 if err == nil { 341 out.SetInt(int64(d)) 342 good = true 343 } 344 } 345 } 346 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 347 switch resolved := resolved.(type) { 348 case int: 349 if resolved >= 0 { 350 out.SetUint(uint64(resolved)) 351 good = true 352 } 353 case int64: 354 if resolved >= 0 { 355 out.SetUint(uint64(resolved)) 356 good = true 357 } 358 case float64: 359 if resolved < 1<<64-1 && !out.OverflowUint(uint64(resolved)) { 360 out.SetUint(uint64(resolved)) 361 good = true 362 } 363 } 364 case reflect.Bool: 365 switch resolved := resolved.(type) { 366 case bool: 367 out.SetBool(resolved) 368 good = true 369 } 370 case reflect.Float32, reflect.Float64: 371 switch resolved := resolved.(type) { 372 case int: 373 out.SetFloat(float64(resolved)) 374 good = true 375 case int64: 376 out.SetFloat(float64(resolved)) 377 good = true 378 case float64: 379 out.SetFloat(resolved) 380 good = true 381 } 382 case reflect.Ptr: 383 switch resolved.(type) { 384 case nil: 385 out.Set(reflect.Zero(out.Type())) 386 good = true 387 default: 388 if out.Type().Elem() == reflect.TypeOf(resolved) { 389 elem := reflect.New(out.Type().Elem()) 390 elem.Elem().Set(reflect.ValueOf(resolved)) 391 out.Set(elem) 392 good = true 393 } 394 } 395 } 396 return good 397 } 398 399 func settableValueOf(i interface{}) reflect.Value { 400 v := reflect.ValueOf(i) 401 sv := reflect.New(v.Type()).Elem() 402 sv.Set(v) 403 return sv 404 } 405 406 func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { 407 if set := d.setter("!!seq", &out, &good); set != nil { 408 defer set() 409 } 410 var iface reflect.Value 411 if out.Kind() == reflect.Interface { 412 // No type hints. Will have to use a generic sequence. 413 iface = out 414 out = settableValueOf(make([]interface{}, 0)) 415 } 416 417 if out.Kind() != reflect.Slice { 418 return false 419 } 420 et := out.Type().Elem() 421 422 l := len(n.children) 423 for i := 0; i < l; i++ { 424 e := reflect.New(et).Elem() 425 if ok := d.unmarshal(n.children[i], e); ok { 426 out.Set(reflect.Append(out, e)) 427 } 428 } 429 if iface.IsValid() { 430 iface.Set(out) 431 } 432 return true 433 } 434 435 func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { 436 if set := d.setter("!!map", &out, &good); set != nil { 437 defer set() 438 } 439 if out.Kind() == reflect.Struct { 440 return d.mappingStruct(n, out) 441 } 442 443 if out.Kind() == reflect.Interface { 444 // No type hints. Will have to use a generic map. 445 iface := out 446 out = settableValueOf(make(map[interface{}]interface{})) 447 iface.Set(out) 448 } 449 450 if out.Kind() != reflect.Map { 451 return false 452 } 453 outt := out.Type() 454 kt := outt.Key() 455 et := outt.Elem() 456 457 if out.IsNil() { 458 out.Set(reflect.MakeMap(outt)) 459 } 460 l := len(n.children) 461 for i := 0; i < l; i += 2 { 462 if isMerge(n.children[i]) { 463 d.merge(n.children[i+1], out) 464 continue 465 } 466 k := reflect.New(kt).Elem() 467 if d.unmarshal(n.children[i], k) { 468 e := reflect.New(et).Elem() 469 if d.unmarshal(n.children[i+1], e) { 470 out.SetMapIndex(k, e) 471 } 472 } 473 } 474 return true 475 } 476 477 func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { 478 sinfo, err := getStructInfo(out.Type()) 479 if err != nil { 480 panic(err) 481 } 482 name := settableValueOf("") 483 l := len(n.children) 484 for i := 0; i < l; i += 2 { 485 ni := n.children[i] 486 if isMerge(ni) { 487 d.merge(n.children[i+1], out) 488 continue 489 } 490 if !d.unmarshal(ni, name) { 491 continue 492 } 493 if info, ok := sinfo.FieldsMap[name.String()]; ok { 494 var field reflect.Value 495 if info.Inline == nil { 496 field = out.Field(info.Num) 497 } else { 498 field = out.FieldByIndex(info.Inline) 499 } 500 d.unmarshal(n.children[i+1], field) 501 } 502 } 503 return true 504 } 505 506 func (d *decoder) merge(n *node, out reflect.Value) { 507 const wantMap = "map merge requires map or sequence of maps as the value" 508 switch n.kind { 509 case mappingNode: 510 d.unmarshal(n, out) 511 case aliasNode: 512 an, ok := d.doc.anchors[n.value] 513 if ok && an.kind != mappingNode { 514 panic(wantMap) 515 } 516 d.unmarshal(n, out) 517 case sequenceNode: 518 // Step backwards as earlier nodes take precedence. 519 for i := len(n.children)-1; i >= 0; i-- { 520 ni := n.children[i] 521 if ni.kind == aliasNode { 522 an, ok := d.doc.anchors[ni.value] 523 if ok && an.kind != mappingNode { 524 panic(wantMap) 525 } 526 } else if ni.kind != mappingNode { 527 panic(wantMap) 528 } 529 d.unmarshal(ni, out) 530 } 531 default: 532 panic(wantMap) 533 } 534 } 535 536 func isMerge(n *node) bool { 537 return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == "!!merge" || n.tag == "tag:yaml.org,2002:merge") 538 }