github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/encoding/kmgYaml/decode.go (about) 1 package kmgYaml 2 3 import ( 4 "encoding" 5 "reflect" 6 "strconv" 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 } 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 if out.CanAddr() { 294 marhsaler, ok := (out).Addr().Interface().(encoding.TextUnmarshaler) 295 if ok { 296 err := marhsaler.UnmarshalText([]byte(n.value)) 297 if err != nil { 298 panic(err) 299 } 300 return true 301 } 302 } 303 switch out.Kind() { 304 case reflect.String: 305 if resolved != nil { 306 out.SetString(n.value) 307 good = true 308 } 309 case reflect.Interface: 310 if resolved == nil { 311 out.Set(reflect.Zero(out.Type())) 312 } else { 313 out.Set(reflect.ValueOf(resolved)) 314 } 315 good = true 316 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 317 switch resolved := resolved.(type) { 318 case int: 319 if !out.OverflowInt(int64(resolved)) { 320 out.SetInt(int64(resolved)) 321 good = true 322 } 323 case int64: 324 if !out.OverflowInt(resolved) { 325 out.SetInt(resolved) 326 good = true 327 } 328 } 329 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 330 switch resolved := resolved.(type) { 331 case int: 332 if resolved >= 0 { 333 out.SetUint(uint64(resolved)) 334 good = true 335 } 336 case int64: 337 if resolved >= 0 { 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 float64: 351 out.SetFloat(resolved) 352 good = true 353 case int: 354 out.SetFloat(float64(resolved)) 355 good = true 356 case int64: 357 out.SetFloat(float64(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 et := out.Type().Elem() 397 398 l := len(n.children) 399 for i := 0; i < l; i++ { 400 e := reflect.New(et).Elem() 401 if ok := d.unmarshal(n.children[i], e); ok { 402 out.Set(reflect.Append(out, e)) 403 } 404 } 405 if iface.IsValid() { 406 iface.Set(out) 407 } 408 return true 409 } else if out.Kind() == reflect.Array { 410 et := out.Type().Elem() 411 412 l := len(n.children) 413 // cut elements more than type allowed 414 if l > out.Type().Len() { 415 l = out.Type().Len() 416 } 417 for i := 0; i < l; i++ { 418 e := reflect.New(et).Elem() 419 if ok := d.unmarshal(n.children[i], e); ok { 420 out.Index(i).Set(e) 421 } 422 } 423 if iface.IsValid() { 424 iface.Set(out) 425 } 426 return true 427 } 428 panic("Type not match, can not set slice to " + out.Kind().String()) 429 return false 430 } 431 432 func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { 433 if set := d.setter("!!map", &out, &good); set != nil { 434 defer set() 435 } 436 if out.Kind() == reflect.Struct { 437 return d.mappingStruct(n, out) 438 } 439 440 if out.Kind() == reflect.Interface { 441 // No type hints. Will have to use a generic map. 442 iface := out 443 out = settableValueOf(make(map[interface{}]interface{})) 444 iface.Set(out) 445 } 446 447 if out.Kind() != reflect.Map { 448 panic("Type not match, can not set map to " + out.Kind().String()) 449 return false 450 } 451 outt := out.Type() 452 kt := outt.Key() 453 et := outt.Elem() 454 455 if out.IsNil() { 456 out.Set(reflect.MakeMap(outt)) 457 } 458 l := len(n.children) 459 for i := 0; i < l; i += 2 { 460 k := reflect.New(kt).Elem() 461 if d.unmarshal(n.children[i], k) { 462 e := reflect.New(et).Elem() 463 if d.unmarshal(n.children[i+1], e) { 464 out.SetMapIndex(k, e) 465 } 466 } 467 } 468 return true 469 } 470 471 func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { 472 sinfo, err := getStructInfo(out.Type()) 473 if err != nil { 474 panic(err) 475 } 476 name := settableValueOf("") 477 l := len(n.children) 478 for i := 0; i < l; i += 2 { 479 if !d.unmarshal(n.children[i], name) { 480 continue 481 } 482 if info, ok := sinfo.FieldsMap[name.String()]; ok { 483 var field reflect.Value 484 if info.Inline == nil { 485 field = out.Field(info.Num) 486 } else { 487 field = out.FieldByIndex(info.Inline) 488 } 489 d.unmarshal(n.children[i+1], field) 490 } 491 } 492 return true 493 }