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