github.com/ssube/gitlab-ci-multi-runner@v1.2.1-0.20160607142738-b8d1285632e6/Godeps/_workspace/src/gopkg.in/yaml.v1/decode.go (about) 1 package yaml 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "reflect" 7 "strconv" 8 "time" 9 ) 10 11 const ( 12 documentNode = 1 << iota 13 mappingNode 14 sequenceNode 15 scalarNode 16 aliasNode 17 ) 18 19 type node struct { 20 kind int 21 line, column int 22 tag string 23 value string 24 implicit bool 25 children []*node 26 anchors map[string]*node 27 } 28 29 // ---------------------------------------------------------------------------- 30 // Parser, produces a node tree out of a libyaml event stream. 31 32 type parser struct { 33 parser yaml_parser_t 34 event yaml_event_t 35 doc *node 36 } 37 38 func newParser(b []byte) *parser { 39 p := parser{} 40 if !yaml_parser_initialize(&p.parser) { 41 panic("Failed to initialize YAML emitter") 42 } 43 44 if len(b) == 0 { 45 b = []byte{'\n'} 46 } 47 48 yaml_parser_set_input_string(&p.parser, b) 49 50 p.skip() 51 if p.event.typ != yaml_STREAM_START_EVENT { 52 panic("Expected stream start event, got " + strconv.Itoa(int(p.event.typ))) 53 } 54 p.skip() 55 return &p 56 } 57 58 func (p *parser) destroy() { 59 if p.event.typ != yaml_NO_EVENT { 60 yaml_event_delete(&p.event) 61 } 62 yaml_parser_delete(&p.parser) 63 } 64 65 func (p *parser) skip() { 66 if p.event.typ != yaml_NO_EVENT { 67 if p.event.typ == yaml_STREAM_END_EVENT { 68 fail("Attempted to go past the end of stream. Corrupted value?") 69 } 70 yaml_event_delete(&p.event) 71 } 72 if !yaml_parser_parse(&p.parser, &p.event) { 73 p.fail() 74 } 75 } 76 77 func (p *parser) fail() { 78 var where string 79 var line int 80 if p.parser.problem_mark.line != 0 { 81 line = p.parser.problem_mark.line 82 } else if p.parser.context_mark.line != 0 { 83 line = p.parser.context_mark.line 84 } 85 if line != 0 { 86 where = "line " + strconv.Itoa(line) + ": " 87 } 88 var msg string 89 if len(p.parser.problem) > 0 { 90 msg = p.parser.problem 91 } else { 92 msg = "Unknown problem parsing YAML content" 93 } 94 fail(where + msg) 95 } 96 97 func (p *parser) anchor(n *node, anchor []byte) { 98 if anchor != nil { 99 p.doc.anchors[string(anchor)] = n 100 } 101 } 102 103 func (p *parser) parse() *node { 104 switch p.event.typ { 105 case yaml_SCALAR_EVENT: 106 return p.scalar() 107 case yaml_ALIAS_EVENT: 108 return p.alias() 109 case yaml_MAPPING_START_EVENT: 110 return p.mapping() 111 case yaml_SEQUENCE_START_EVENT: 112 return p.sequence() 113 case yaml_DOCUMENT_START_EVENT: 114 return p.document() 115 case yaml_STREAM_END_EVENT: 116 // Happens when attempting to decode an empty buffer. 117 return nil 118 default: 119 panic("Attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ))) 120 } 121 panic("unreachable") 122 } 123 124 func (p *parser) node(kind int) *node { 125 return &node{ 126 kind: kind, 127 line: p.event.start_mark.line, 128 column: p.event.start_mark.column, 129 } 130 } 131 132 func (p *parser) document() *node { 133 n := p.node(documentNode) 134 n.anchors = make(map[string]*node) 135 p.doc = n 136 p.skip() 137 n.children = append(n.children, p.parse()) 138 if p.event.typ != yaml_DOCUMENT_END_EVENT { 139 panic("Expected end of document event but got " + 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(shortTag(tag), arg) 222 } 223 } 224 } 225 again := true 226 for again { 227 again = false 228 setter, _ := (*out).Interface().(Setter) 229 if tag != yaml_NULL_TAG || 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(shortTag(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 fail("Unknown anchor '" + n.value + "' referenced") 283 } 284 if d.aliases[n.value] { 285 fail("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 zeroValue reflect.Value 294 295 func resetMap(out reflect.Value) { 296 for _, k := range out.MapKeys() { 297 out.SetMapIndex(k, zeroValue) 298 } 299 } 300 301 var durationType = reflect.TypeOf(time.Duration(0)) 302 303 func (d *decoder) scalar(n *node, out reflect.Value) (good bool) { 304 var tag string 305 var resolved interface{} 306 if n.tag == "" && !n.implicit { 307 tag = yaml_STR_TAG 308 resolved = n.value 309 } else { 310 tag, resolved = resolve(n.tag, n.value) 311 if tag == yaml_BINARY_TAG { 312 data, err := base64.StdEncoding.DecodeString(resolved.(string)) 313 if err != nil { 314 fail("!!binary value contains invalid base64 data") 315 } 316 resolved = string(data) 317 } 318 } 319 if set := d.setter(tag, &out, &good); set != nil { 320 defer set() 321 } 322 if resolved == nil { 323 if out.Kind() == reflect.Map && !out.CanAddr() { 324 resetMap(out) 325 } else { 326 out.Set(reflect.Zero(out.Type())) 327 } 328 good = true 329 return 330 } 331 switch out.Kind() { 332 case reflect.String: 333 if tag == yaml_BINARY_TAG { 334 out.SetString(resolved.(string)) 335 good = true 336 } else if resolved != nil { 337 out.SetString(n.value) 338 good = true 339 } 340 case reflect.Interface: 341 if resolved == nil { 342 out.Set(reflect.Zero(out.Type())) 343 } else { 344 out.Set(reflect.ValueOf(resolved)) 345 } 346 good = true 347 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 348 switch resolved := resolved.(type) { 349 case int: 350 if !out.OverflowInt(int64(resolved)) { 351 out.SetInt(int64(resolved)) 352 good = true 353 } 354 case int64: 355 if !out.OverflowInt(resolved) { 356 out.SetInt(resolved) 357 good = true 358 } 359 case float64: 360 if resolved < 1<<63-1 && !out.OverflowInt(int64(resolved)) { 361 out.SetInt(int64(resolved)) 362 good = true 363 } 364 case string: 365 if out.Type() == durationType { 366 d, err := time.ParseDuration(resolved) 367 if err == nil { 368 out.SetInt(int64(d)) 369 good = true 370 } 371 } 372 } 373 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 374 switch resolved := resolved.(type) { 375 case int: 376 if resolved >= 0 { 377 out.SetUint(uint64(resolved)) 378 good = true 379 } 380 case int64: 381 if resolved >= 0 { 382 out.SetUint(uint64(resolved)) 383 good = true 384 } 385 case float64: 386 if resolved < 1<<64-1 && !out.OverflowUint(uint64(resolved)) { 387 out.SetUint(uint64(resolved)) 388 good = true 389 } 390 } 391 case reflect.Bool: 392 switch resolved := resolved.(type) { 393 case bool: 394 out.SetBool(resolved) 395 good = true 396 } 397 case reflect.Float32, reflect.Float64: 398 switch resolved := resolved.(type) { 399 case int: 400 out.SetFloat(float64(resolved)) 401 good = true 402 case int64: 403 out.SetFloat(float64(resolved)) 404 good = true 405 case float64: 406 out.SetFloat(resolved) 407 good = true 408 } 409 case reflect.Ptr: 410 if out.Type().Elem() == reflect.TypeOf(resolved) { 411 elem := reflect.New(out.Type().Elem()) 412 elem.Elem().Set(reflect.ValueOf(resolved)) 413 out.Set(elem) 414 good = true 415 } 416 } 417 return good 418 } 419 420 func settableValueOf(i interface{}) reflect.Value { 421 v := reflect.ValueOf(i) 422 sv := reflect.New(v.Type()).Elem() 423 sv.Set(v) 424 return sv 425 } 426 427 func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { 428 if set := d.setter(yaml_SEQ_TAG, &out, &good); set != nil { 429 defer set() 430 } 431 var iface reflect.Value 432 if out.Kind() == reflect.Interface { 433 // No type hints. Will have to use a generic sequence. 434 iface = out 435 out = settableValueOf(make([]interface{}, 0)) 436 } 437 438 if out.Kind() != reflect.Slice { 439 return false 440 } 441 et := out.Type().Elem() 442 443 l := len(n.children) 444 for i := 0; i < l; i++ { 445 e := reflect.New(et).Elem() 446 if ok := d.unmarshal(n.children[i], e); ok { 447 out.Set(reflect.Append(out, e)) 448 } 449 } 450 if iface.IsValid() { 451 iface.Set(out) 452 } 453 return true 454 } 455 456 func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { 457 if set := d.setter(yaml_MAP_TAG, &out, &good); set != nil { 458 defer set() 459 } 460 if out.Kind() == reflect.Struct { 461 return d.mappingStruct(n, out) 462 } 463 464 if out.Kind() == reflect.Interface { 465 // No type hints. Will have to use a generic map. 466 iface := out 467 out = settableValueOf(make(map[interface{}]interface{})) 468 iface.Set(out) 469 } 470 471 if out.Kind() != reflect.Map { 472 return false 473 } 474 outt := out.Type() 475 kt := outt.Key() 476 et := outt.Elem() 477 478 if out.IsNil() { 479 out.Set(reflect.MakeMap(outt)) 480 } 481 l := len(n.children) 482 for i := 0; i < l; i += 2 { 483 if isMerge(n.children[i]) { 484 d.merge(n.children[i+1], out) 485 continue 486 } 487 k := reflect.New(kt).Elem() 488 if d.unmarshal(n.children[i], k) { 489 kkind := k.Kind() 490 if kkind == reflect.Interface { 491 kkind = k.Elem().Kind() 492 } 493 if kkind == reflect.Map || kkind == reflect.Slice { 494 fail(fmt.Sprintf("invalid map key: %#v", k.Interface())) 495 } 496 e := reflect.New(et).Elem() 497 if d.unmarshal(n.children[i+1], e) { 498 out.SetMapIndex(k, e) 499 } 500 } 501 } 502 return true 503 } 504 505 func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { 506 sinfo, err := getStructInfo(out.Type()) 507 if err != nil { 508 panic(err) 509 } 510 name := settableValueOf("") 511 l := len(n.children) 512 for i := 0; i < l; i += 2 { 513 ni := n.children[i] 514 if isMerge(ni) { 515 d.merge(n.children[i+1], out) 516 continue 517 } 518 if !d.unmarshal(ni, name) { 519 continue 520 } 521 if info, ok := sinfo.FieldsMap[name.String()]; ok { 522 var field reflect.Value 523 if info.Inline == nil { 524 field = out.Field(info.Num) 525 } else { 526 field = out.FieldByIndex(info.Inline) 527 } 528 d.unmarshal(n.children[i+1], field) 529 } 530 } 531 return true 532 } 533 534 func (d *decoder) merge(n *node, out reflect.Value) { 535 const wantMap = "map merge requires map or sequence of maps as the value" 536 switch n.kind { 537 case mappingNode: 538 d.unmarshal(n, out) 539 case aliasNode: 540 an, ok := d.doc.anchors[n.value] 541 if ok && an.kind != mappingNode { 542 fail(wantMap) 543 } 544 d.unmarshal(n, out) 545 case sequenceNode: 546 // Step backwards as earlier nodes take precedence. 547 for i := len(n.children) - 1; i >= 0; i-- { 548 ni := n.children[i] 549 if ni.kind == aliasNode { 550 an, ok := d.doc.anchors[ni.value] 551 if ok && an.kind != mappingNode { 552 fail(wantMap) 553 } 554 } else if ni.kind != mappingNode { 555 fail(wantMap) 556 } 557 d.unmarshal(ni, out) 558 } 559 default: 560 fail(wantMap) 561 } 562 } 563 564 func isMerge(n *node) bool { 565 return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) 566 }