decode.go raw

   1  package yaml
   2  
   3  import (
   4  	"encoding"
   5  	"encoding/base64"
   6  	"fmt"
   7  	"io"
   8  	"math"
   9  	"reflect"
  10  	"strconv"
  11  	"time"
  12  )
  13  
  14  const (
  15  	documentNode = 1 << iota
  16  	mappingNode
  17  	sequenceNode
  18  	scalarNode
  19  	aliasNode
  20  )
  21  
  22  type node struct {
  23  	kind         int
  24  	line, column int
  25  	tag          string
  26  	// For an alias node, alias holds the resolved alias.
  27  	alias    *node
  28  	value    string
  29  	implicit bool
  30  	children []*node
  31  	anchors  map[string]*node
  32  }
  33  
  34  // ----------------------------------------------------------------------------
  35  // Parser, produces a node tree out of a libyaml event stream.
  36  
  37  type parser struct {
  38  	parser   yaml_parser_t
  39  	event    yaml_event_t
  40  	doc      *node
  41  	doneInit bool
  42  }
  43  
  44  func newParser(b []byte) *parser {
  45  	p := parser{}
  46  	if !yaml_parser_initialize(&p.parser) {
  47  		panic("failed to initialize YAML emitter")
  48  	}
  49  	if len(b) == 0 {
  50  		b = []byte{'\n'}
  51  	}
  52  	yaml_parser_set_input_string(&p.parser, b)
  53  	return &p
  54  }
  55  
  56  func newParserFromReader(r io.Reader) *parser {
  57  	p := parser{}
  58  	if !yaml_parser_initialize(&p.parser) {
  59  		panic("failed to initialize YAML emitter")
  60  	}
  61  	yaml_parser_set_input_reader(&p.parser, r)
  62  	return &p
  63  }
  64  
  65  func (p *parser) init() {
  66  	if p.doneInit {
  67  		return
  68  	}
  69  	p.expect(yaml_STREAM_START_EVENT)
  70  	p.doneInit = true
  71  }
  72  
  73  func (p *parser) destroy() {
  74  	if p.event.typ != yaml_NO_EVENT {
  75  		yaml_event_delete(&p.event)
  76  	}
  77  	yaml_parser_delete(&p.parser)
  78  }
  79  
  80  // expect consumes an event from the event stream and
  81  // checks that it's of the expected type.
  82  func (p *parser) expect(e yaml_event_type_t) {
  83  	if p.event.typ == yaml_NO_EVENT {
  84  		if !yaml_parser_parse(&p.parser, &p.event) {
  85  			p.fail()
  86  		}
  87  	}
  88  	if p.event.typ == yaml_STREAM_END_EVENT {
  89  		failf("attempted to go past the end of stream; corrupted value?")
  90  	}
  91  	if p.event.typ != e {
  92  		p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
  93  		p.fail()
  94  	}
  95  	yaml_event_delete(&p.event)
  96  	p.event.typ = yaml_NO_EVENT
  97  }
  98  
  99  // peek peeks at the next event in the event stream,
 100  // puts the results into p.event and returns the event type.
 101  func (p *parser) peek() yaml_event_type_t {
 102  	if p.event.typ != yaml_NO_EVENT {
 103  		return p.event.typ
 104  	}
 105  	if !yaml_parser_parse(&p.parser, &p.event) {
 106  		p.fail()
 107  	}
 108  	return p.event.typ
 109  }
 110  
 111  func (p *parser) fail() {
 112  	var where string
 113  	var line int
 114  	if p.parser.problem_mark.line != 0 {
 115  		line = p.parser.problem_mark.line
 116  		// Scanner errors don't iterate line before returning error
 117  		if p.parser.error == yaml_SCANNER_ERROR {
 118  			line++
 119  		}
 120  	} else if p.parser.context_mark.line != 0 {
 121  		line = p.parser.context_mark.line
 122  	}
 123  	if line != 0 {
 124  		where = "line " + strconv.Itoa(line) + ": "
 125  	}
 126  	var msg string
 127  	if len(p.parser.problem) > 0 {
 128  		msg = p.parser.problem
 129  	} else {
 130  		msg = "unknown problem parsing YAML content"
 131  	}
 132  	failf("%s%s", where, msg)
 133  }
 134  
 135  func (p *parser) anchor(n *node, anchor []byte) {
 136  	if anchor != nil {
 137  		p.doc.anchors[string(anchor)] = n
 138  	}
 139  }
 140  
 141  func (p *parser) parse() *node {
 142  	p.init()
 143  	switch p.peek() {
 144  	case yaml_SCALAR_EVENT:
 145  		return p.scalar()
 146  	case yaml_ALIAS_EVENT:
 147  		return p.alias()
 148  	case yaml_MAPPING_START_EVENT:
 149  		return p.mapping()
 150  	case yaml_SEQUENCE_START_EVENT:
 151  		return p.sequence()
 152  	case yaml_DOCUMENT_START_EVENT:
 153  		return p.document()
 154  	case yaml_STREAM_END_EVENT:
 155  		// Happens when attempting to decode an empty buffer.
 156  		return nil
 157  	default:
 158  		panic("attempted to parse unknown event: " + p.event.typ.String())
 159  	}
 160  }
 161  
 162  func (p *parser) node(kind int) *node {
 163  	return &node{
 164  		kind:   kind,
 165  		line:   p.event.start_mark.line,
 166  		column: p.event.start_mark.column,
 167  	}
 168  }
 169  
 170  func (p *parser) document() *node {
 171  	n := p.node(documentNode)
 172  	n.anchors = make(map[string]*node)
 173  	p.doc = n
 174  	p.expect(yaml_DOCUMENT_START_EVENT)
 175  	n.children = append(n.children, p.parse())
 176  	p.expect(yaml_DOCUMENT_END_EVENT)
 177  	return n
 178  }
 179  
 180  func (p *parser) alias() *node {
 181  	n := p.node(aliasNode)
 182  	n.value = string(p.event.anchor)
 183  	n.alias = p.doc.anchors[n.value]
 184  	if n.alias == nil {
 185  		failf("unknown anchor '%s' referenced", n.value)
 186  	}
 187  	p.expect(yaml_ALIAS_EVENT)
 188  	return n
 189  }
 190  
 191  func (p *parser) scalar() *node {
 192  	n := p.node(scalarNode)
 193  	n.value = string(p.event.value)
 194  	n.tag = string(p.event.tag)
 195  	n.implicit = p.event.implicit
 196  	p.anchor(n, p.event.anchor)
 197  	p.expect(yaml_SCALAR_EVENT)
 198  	return n
 199  }
 200  
 201  func (p *parser) sequence() *node {
 202  	n := p.node(sequenceNode)
 203  	p.anchor(n, p.event.anchor)
 204  	p.expect(yaml_SEQUENCE_START_EVENT)
 205  	for p.peek() != yaml_SEQUENCE_END_EVENT {
 206  		n.children = append(n.children, p.parse())
 207  	}
 208  	p.expect(yaml_SEQUENCE_END_EVENT)
 209  	return n
 210  }
 211  
 212  func (p *parser) mapping() *node {
 213  	n := p.node(mappingNode)
 214  	p.anchor(n, p.event.anchor)
 215  	p.expect(yaml_MAPPING_START_EVENT)
 216  	for p.peek() != yaml_MAPPING_END_EVENT {
 217  		n.children = append(n.children, p.parse(), p.parse())
 218  	}
 219  	p.expect(yaml_MAPPING_END_EVENT)
 220  	return n
 221  }
 222  
 223  // ----------------------------------------------------------------------------
 224  // Decoder, unmarshals a node into a provided value.
 225  
 226  type decoder struct {
 227  	doc     *node
 228  	aliases map[*node]bool
 229  	mapType reflect.Type
 230  	terrors []string
 231  	strict  bool
 232  
 233  	decodeCount int
 234  	aliasCount  int
 235  	aliasDepth  int
 236  }
 237  
 238  var (
 239  	mapItemType    = reflect.TypeOf(MapItem{})
 240  	durationType   = reflect.TypeOf(time.Duration(0))
 241  	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
 242  	ifaceType      = defaultMapType.Elem()
 243  	timeType       = reflect.TypeOf(time.Time{})
 244  	ptrTimeType    = reflect.TypeOf(&time.Time{})
 245  )
 246  
 247  func newDecoder(strict bool) *decoder {
 248  	d := &decoder{mapType: defaultMapType, strict: strict}
 249  	d.aliases = make(map[*node]bool)
 250  	return d
 251  }
 252  
 253  func (d *decoder) terror(n *node, tag string, out reflect.Value) {
 254  	if n.tag != "" {
 255  		tag = n.tag
 256  	}
 257  	value := n.value
 258  	if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
 259  		if len(value) > 10 {
 260  			value = " `" + value[:7] + "...`"
 261  		} else {
 262  			value = " `" + value + "`"
 263  		}
 264  	}
 265  	d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
 266  }
 267  
 268  func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
 269  	terrlen := len(d.terrors)
 270  	err := u.UnmarshalYAML(func(v interface{}) (err error) {
 271  		defer handleErr(&err)
 272  		d.unmarshal(n, reflect.ValueOf(v))
 273  		if len(d.terrors) > terrlen {
 274  			issues := d.terrors[terrlen:]
 275  			d.terrors = d.terrors[:terrlen]
 276  			return &TypeError{issues}
 277  		}
 278  		return nil
 279  	})
 280  	if e, ok := err.(*TypeError); ok {
 281  		d.terrors = append(d.terrors, e.Errors...)
 282  		return false
 283  	}
 284  	if err != nil {
 285  		fail(err)
 286  	}
 287  	return true
 288  }
 289  
 290  // d.prepare initializes and dereferences pointers and calls UnmarshalYAML
 291  // if a value is found to implement it.
 292  // It returns the initialized and dereferenced out value, whether
 293  // unmarshalling was already done by UnmarshalYAML, and if so whether
 294  // its types unmarshalled appropriately.
 295  //
 296  // If n holds a null value, prepare returns before doing anything.
 297  func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
 298  	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
 299  		return out, false, false
 300  	}
 301  	again := true
 302  	for again {
 303  		again = false
 304  		if out.Kind() == reflect.Ptr {
 305  			if out.IsNil() {
 306  				out.Set(reflect.New(out.Type().Elem()))
 307  			}
 308  			out = out.Elem()
 309  			again = true
 310  		}
 311  		if out.CanAddr() {
 312  			if u, ok := out.Addr().Interface().(Unmarshaler); ok {
 313  				good = d.callUnmarshaler(n, u)
 314  				return out, true, good
 315  			}
 316  		}
 317  	}
 318  	return out, false, false
 319  }
 320  
 321  const (
 322  	// 400,000 decode operations is ~500kb of dense object declarations, or
 323  	// ~5kb of dense object declarations with 10000% alias expansion
 324  	alias_ratio_range_low = 400000
 325  
 326  	// 4,000,000 decode operations is ~5MB of dense object declarations, or
 327  	// ~4.5MB of dense object declarations with 10% alias expansion
 328  	alias_ratio_range_high = 4000000
 329  
 330  	// alias_ratio_range is the range over which we scale allowed alias ratios
 331  	alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low)
 332  )
 333  
 334  func allowedAliasRatio(decodeCount int) float64 {
 335  	switch {
 336  	case decodeCount <= alias_ratio_range_low:
 337  		// allow 99% to come from alias expansion for small-to-medium documents
 338  		return 0.99
 339  	case decodeCount >= alias_ratio_range_high:
 340  		// allow 10% to come from alias expansion for very large documents
 341  		return 0.10
 342  	default:
 343  		// scale smoothly from 99% down to 10% over the range.
 344  		// this maps to 396,000 - 400,000 allowed alias-driven decodes over the range.
 345  		// 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps).
 346  		return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range)
 347  	}
 348  }
 349  
 350  func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
 351  	d.decodeCount++
 352  	if d.aliasDepth > 0 {
 353  		d.aliasCount++
 354  	}
 355  	if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) {
 356  		failf("document contains excessive aliasing")
 357  	}
 358  	switch n.kind {
 359  	case documentNode:
 360  		return d.document(n, out)
 361  	case aliasNode:
 362  		return d.alias(n, out)
 363  	}
 364  	out, unmarshaled, good := d.prepare(n, out)
 365  	if unmarshaled {
 366  		return good
 367  	}
 368  	switch n.kind {
 369  	case scalarNode:
 370  		good = d.scalar(n, out)
 371  	case mappingNode:
 372  		good = d.mapping(n, out)
 373  	case sequenceNode:
 374  		good = d.sequence(n, out)
 375  	default:
 376  		panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
 377  	}
 378  	return good
 379  }
 380  
 381  func (d *decoder) document(n *node, out reflect.Value) (good bool) {
 382  	if len(n.children) == 1 {
 383  		d.doc = n
 384  		d.unmarshal(n.children[0], out)
 385  		return true
 386  	}
 387  	return false
 388  }
 389  
 390  func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
 391  	if d.aliases[n] {
 392  		// TODO this could actually be allowed in some circumstances.
 393  		failf("anchor '%s' value contains itself", n.value)
 394  	}
 395  	d.aliases[n] = true
 396  	d.aliasDepth++
 397  	good = d.unmarshal(n.alias, out)
 398  	d.aliasDepth--
 399  	delete(d.aliases, n)
 400  	return good
 401  }
 402  
 403  var zeroValue reflect.Value
 404  
 405  func resetMap(out reflect.Value) {
 406  	for _, k := range out.MapKeys() {
 407  		out.SetMapIndex(k, zeroValue)
 408  	}
 409  }
 410  
 411  func (d *decoder) scalar(n *node, out reflect.Value) bool {
 412  	var tag string
 413  	var resolved interface{}
 414  	if n.tag == "" && !n.implicit {
 415  		tag = yaml_STR_TAG
 416  		resolved = n.value
 417  	} else {
 418  		tag, resolved = resolve(n.tag, n.value)
 419  		if tag == yaml_BINARY_TAG {
 420  			data, err := base64.StdEncoding.DecodeString(resolved.(string))
 421  			if err != nil {
 422  				failf("!!binary value contains invalid base64 data")
 423  			}
 424  			resolved = string(data)
 425  		}
 426  	}
 427  	if resolved == nil {
 428  		if out.Kind() == reflect.Map && !out.CanAddr() {
 429  			resetMap(out)
 430  		} else {
 431  			out.Set(reflect.Zero(out.Type()))
 432  		}
 433  		return true
 434  	}
 435  	if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
 436  		// We've resolved to exactly the type we want, so use that.
 437  		out.Set(resolvedv)
 438  		return true
 439  	}
 440  	// Perhaps we can use the value as a TextUnmarshaler to
 441  	// set its value.
 442  	if out.CanAddr() {
 443  		u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
 444  		if ok {
 445  			var text []byte
 446  			if tag == yaml_BINARY_TAG {
 447  				text = []byte(resolved.(string))
 448  			} else {
 449  				// We let any value be unmarshaled into TextUnmarshaler.
 450  				// That might be more lax than we'd like, but the
 451  				// TextUnmarshaler itself should bowl out any dubious values.
 452  				text = []byte(n.value)
 453  			}
 454  			err := u.UnmarshalText(text)
 455  			if err != nil {
 456  				fail(err)
 457  			}
 458  			return true
 459  		}
 460  	}
 461  	switch out.Kind() {
 462  	case reflect.String:
 463  		if tag == yaml_BINARY_TAG {
 464  			out.SetString(resolved.(string))
 465  			return true
 466  		}
 467  		if resolved != nil {
 468  			out.SetString(n.value)
 469  			return true
 470  		}
 471  	case reflect.Interface:
 472  		if resolved == nil {
 473  			out.Set(reflect.Zero(out.Type()))
 474  		} else if tag == yaml_TIMESTAMP_TAG {
 475  			// It looks like a timestamp but for backward compatibility
 476  			// reasons we set it as a string, so that code that unmarshals
 477  			// timestamp-like values into interface{} will continue to
 478  			// see a string and not a time.Time.
 479  			// TODO(v3) Drop this.
 480  			out.Set(reflect.ValueOf(n.value))
 481  		} else {
 482  			out.Set(reflect.ValueOf(resolved))
 483  		}
 484  		return true
 485  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 486  		switch resolved := resolved.(type) {
 487  		case int:
 488  			if !out.OverflowInt(int64(resolved)) {
 489  				out.SetInt(int64(resolved))
 490  				return true
 491  			}
 492  		case int64:
 493  			if !out.OverflowInt(resolved) {
 494  				out.SetInt(resolved)
 495  				return true
 496  			}
 497  		case uint64:
 498  			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 499  				out.SetInt(int64(resolved))
 500  				return true
 501  			}
 502  		case float64:
 503  			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 504  				out.SetInt(int64(resolved))
 505  				return true
 506  			}
 507  		case string:
 508  			if out.Type() == durationType {
 509  				d, err := time.ParseDuration(resolved)
 510  				if err == nil {
 511  					out.SetInt(int64(d))
 512  					return true
 513  				}
 514  			}
 515  		}
 516  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 517  		switch resolved := resolved.(type) {
 518  		case int:
 519  			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 520  				out.SetUint(uint64(resolved))
 521  				return true
 522  			}
 523  		case int64:
 524  			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 525  				out.SetUint(uint64(resolved))
 526  				return true
 527  			}
 528  		case uint64:
 529  			if !out.OverflowUint(uint64(resolved)) {
 530  				out.SetUint(uint64(resolved))
 531  				return true
 532  			}
 533  		case float64:
 534  			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
 535  				out.SetUint(uint64(resolved))
 536  				return true
 537  			}
 538  		}
 539  	case reflect.Bool:
 540  		switch resolved := resolved.(type) {
 541  		case bool:
 542  			out.SetBool(resolved)
 543  			return true
 544  		}
 545  	case reflect.Float32, reflect.Float64:
 546  		switch resolved := resolved.(type) {
 547  		case int:
 548  			out.SetFloat(float64(resolved))
 549  			return true
 550  		case int64:
 551  			out.SetFloat(float64(resolved))
 552  			return true
 553  		case uint64:
 554  			out.SetFloat(float64(resolved))
 555  			return true
 556  		case float64:
 557  			out.SetFloat(resolved)
 558  			return true
 559  		}
 560  	case reflect.Struct:
 561  		if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
 562  			out.Set(resolvedv)
 563  			return true
 564  		}
 565  	case reflect.Ptr:
 566  		if out.Type().Elem() == reflect.TypeOf(resolved) {
 567  			// TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
 568  			elem := reflect.New(out.Type().Elem())
 569  			elem.Elem().Set(reflect.ValueOf(resolved))
 570  			out.Set(elem)
 571  			return true
 572  		}
 573  	}
 574  	d.terror(n, tag, out)
 575  	return false
 576  }
 577  
 578  func settableValueOf(i interface{}) reflect.Value {
 579  	v := reflect.ValueOf(i)
 580  	sv := reflect.New(v.Type()).Elem()
 581  	sv.Set(v)
 582  	return sv
 583  }
 584  
 585  func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 586  	l := len(n.children)
 587  
 588  	var iface reflect.Value
 589  	switch out.Kind() {
 590  	case reflect.Slice:
 591  		out.Set(reflect.MakeSlice(out.Type(), l, l))
 592  	case reflect.Array:
 593  		if l != out.Len() {
 594  			failf("invalid array: want %d elements but got %d", out.Len(), l)
 595  		}
 596  	case reflect.Interface:
 597  		// No type hints. Will have to use a generic sequence.
 598  		iface = out
 599  		out = settableValueOf(make([]interface{}, l))
 600  	default:
 601  		d.terror(n, yaml_SEQ_TAG, out)
 602  		return false
 603  	}
 604  	et := out.Type().Elem()
 605  
 606  	j := 0
 607  	for i := 0; i < l; i++ {
 608  		e := reflect.New(et).Elem()
 609  		if ok := d.unmarshal(n.children[i], e); ok {
 610  			out.Index(j).Set(e)
 611  			j++
 612  		}
 613  	}
 614  	if out.Kind() != reflect.Array {
 615  		out.Set(out.Slice(0, j))
 616  	}
 617  	if iface.IsValid() {
 618  		iface.Set(out)
 619  	}
 620  	return true
 621  }
 622  
 623  func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 624  	switch out.Kind() {
 625  	case reflect.Struct:
 626  		return d.mappingStruct(n, out)
 627  	case reflect.Slice:
 628  		return d.mappingSlice(n, out)
 629  	case reflect.Map:
 630  		// okay
 631  	case reflect.Interface:
 632  		if d.mapType.Kind() == reflect.Map {
 633  			iface := out
 634  			out = reflect.MakeMap(d.mapType)
 635  			iface.Set(out)
 636  		} else {
 637  			slicev := reflect.New(d.mapType).Elem()
 638  			if !d.mappingSlice(n, slicev) {
 639  				return false
 640  			}
 641  			out.Set(slicev)
 642  			return true
 643  		}
 644  	default:
 645  		d.terror(n, yaml_MAP_TAG, out)
 646  		return false
 647  	}
 648  	outt := out.Type()
 649  	kt := outt.Key()
 650  	et := outt.Elem()
 651  
 652  	mapType := d.mapType
 653  	if outt.Key() == ifaceType && outt.Elem() == ifaceType {
 654  		d.mapType = outt
 655  	}
 656  
 657  	if out.IsNil() {
 658  		out.Set(reflect.MakeMap(outt))
 659  	}
 660  	l := len(n.children)
 661  	for i := 0; i < l; i += 2 {
 662  		if isMerge(n.children[i]) {
 663  			d.merge(n.children[i+1], out)
 664  			continue
 665  		}
 666  		k := reflect.New(kt).Elem()
 667  		if d.unmarshal(n.children[i], k) {
 668  			kkind := k.Kind()
 669  			if kkind == reflect.Interface {
 670  				kkind = k.Elem().Kind()
 671  			}
 672  			if kkind == reflect.Map || kkind == reflect.Slice {
 673  				failf("invalid map key: %#v", k.Interface())
 674  			}
 675  			e := reflect.New(et).Elem()
 676  			if d.unmarshal(n.children[i+1], e) {
 677  				d.setMapIndex(n.children[i+1], out, k, e)
 678  			}
 679  		}
 680  	}
 681  	d.mapType = mapType
 682  	return true
 683  }
 684  
 685  func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
 686  	if d.strict && out.MapIndex(k) != zeroValue {
 687  		d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
 688  		return
 689  	}
 690  	out.SetMapIndex(k, v)
 691  }
 692  
 693  func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
 694  	outt := out.Type()
 695  	if outt.Elem() != mapItemType {
 696  		d.terror(n, yaml_MAP_TAG, out)
 697  		return false
 698  	}
 699  
 700  	mapType := d.mapType
 701  	d.mapType = outt
 702  
 703  	var slice []MapItem
 704  	var l = len(n.children)
 705  	for i := 0; i < l; i += 2 {
 706  		if isMerge(n.children[i]) {
 707  			d.merge(n.children[i+1], out)
 708  			continue
 709  		}
 710  		item := MapItem{}
 711  		k := reflect.ValueOf(&item.Key).Elem()
 712  		if d.unmarshal(n.children[i], k) {
 713  			v := reflect.ValueOf(&item.Value).Elem()
 714  			if d.unmarshal(n.children[i+1], v) {
 715  				slice = append(slice, item)
 716  			}
 717  		}
 718  	}
 719  	out.Set(reflect.ValueOf(slice))
 720  	d.mapType = mapType
 721  	return true
 722  }
 723  
 724  func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 725  	sinfo, err := getStructInfo(out.Type())
 726  	if err != nil {
 727  		panic(err)
 728  	}
 729  	name := settableValueOf("")
 730  	l := len(n.children)
 731  
 732  	var inlineMap reflect.Value
 733  	var elemType reflect.Type
 734  	if sinfo.InlineMap != -1 {
 735  		inlineMap = out.Field(sinfo.InlineMap)
 736  		inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
 737  		elemType = inlineMap.Type().Elem()
 738  	}
 739  
 740  	var doneFields []bool
 741  	if d.strict {
 742  		doneFields = make([]bool, len(sinfo.FieldsList))
 743  	}
 744  	for i := 0; i < l; i += 2 {
 745  		ni := n.children[i]
 746  		if isMerge(ni) {
 747  			d.merge(n.children[i+1], out)
 748  			continue
 749  		}
 750  		if !d.unmarshal(ni, name) {
 751  			continue
 752  		}
 753  		if info, ok := sinfo.FieldsMap[name.String()]; ok {
 754  			if d.strict {
 755  				if doneFields[info.Id] {
 756  					d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
 757  					continue
 758  				}
 759  				doneFields[info.Id] = true
 760  			}
 761  			var field reflect.Value
 762  			if info.Inline == nil {
 763  				field = out.Field(info.Num)
 764  			} else {
 765  				field = out.FieldByIndex(info.Inline)
 766  			}
 767  			d.unmarshal(n.children[i+1], field)
 768  		} else if sinfo.InlineMap != -1 {
 769  			if inlineMap.IsNil() {
 770  				inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
 771  			}
 772  			value := reflect.New(elemType).Elem()
 773  			d.unmarshal(n.children[i+1], value)
 774  			d.setMapIndex(n.children[i+1], inlineMap, name, value)
 775  		} else if d.strict {
 776  			d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
 777  		}
 778  	}
 779  	return true
 780  }
 781  
 782  func failWantMap() {
 783  	failf("map merge requires map or sequence of maps as the value")
 784  }
 785  
 786  func (d *decoder) merge(n *node, out reflect.Value) {
 787  	switch n.kind {
 788  	case mappingNode:
 789  		d.unmarshal(n, out)
 790  	case aliasNode:
 791  		if n.alias != nil && n.alias.kind != mappingNode {
 792  			failWantMap()
 793  		}
 794  		d.unmarshal(n, out)
 795  	case sequenceNode:
 796  		// Step backwards as earlier nodes take precedence.
 797  		for i := len(n.children) - 1; i >= 0; i-- {
 798  			ni := n.children[i]
 799  			if ni.kind == aliasNode {
 800  				if ni.alias != nil && ni.alias.kind != mappingNode {
 801  					failWantMap()
 802  				}
 803  			} else if ni.kind != mappingNode {
 804  				failWantMap()
 805  			}
 806  			d.unmarshal(ni, out)
 807  		}
 808  	default:
 809  		failWantMap()
 810  	}
 811  }
 812  
 813  func isMerge(n *node) bool {
 814  	return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
 815  }
 816