| package yaml | 
 |  | 
 | import ( | 
 | 	"encoding" | 
 | 	"encoding/base64" | 
 | 	"fmt" | 
 | 	"math" | 
 | 	"reflect" | 
 | 	"strconv" | 
 | 	"time" | 
 | ) | 
 |  | 
 | const ( | 
 | 	documentNode = 1 << iota | 
 | 	mappingNode | 
 | 	sequenceNode | 
 | 	scalarNode | 
 | 	aliasNode | 
 | ) | 
 |  | 
 | type node struct { | 
 | 	kind         int | 
 | 	line, column int | 
 | 	tag          string | 
 | 	value        string | 
 | 	implicit     bool | 
 | 	children     []*node | 
 | 	anchors      map[string]*node | 
 | } | 
 |  | 
 | // ---------------------------------------------------------------------------- | 
 | // Parser, produces a node tree out of a libyaml event stream. | 
 |  | 
 | type parser struct { | 
 | 	parser yaml_parser_t | 
 | 	event  yaml_event_t | 
 | 	doc    *node | 
 | } | 
 |  | 
 | func newParser(b []byte) *parser { | 
 | 	p := parser{} | 
 | 	if !yaml_parser_initialize(&p.parser) { | 
 | 		panic("failed to initialize YAML emitter") | 
 | 	} | 
 |  | 
 | 	if len(b) == 0 { | 
 | 		b = []byte{'\n'} | 
 | 	} | 
 |  | 
 | 	yaml_parser_set_input_string(&p.parser, b) | 
 |  | 
 | 	p.skip() | 
 | 	if p.event.typ != yaml_STREAM_START_EVENT { | 
 | 		panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ))) | 
 | 	} | 
 | 	p.skip() | 
 | 	return &p | 
 | } | 
 |  | 
 | func (p *parser) destroy() { | 
 | 	if p.event.typ != yaml_NO_EVENT { | 
 | 		yaml_event_delete(&p.event) | 
 | 	} | 
 | 	yaml_parser_delete(&p.parser) | 
 | } | 
 |  | 
 | func (p *parser) skip() { | 
 | 	if p.event.typ != yaml_NO_EVENT { | 
 | 		if p.event.typ == yaml_STREAM_END_EVENT { | 
 | 			failf("attempted to go past the end of stream; corrupted value?") | 
 | 		} | 
 | 		yaml_event_delete(&p.event) | 
 | 	} | 
 | 	if !yaml_parser_parse(&p.parser, &p.event) { | 
 | 		p.fail() | 
 | 	} | 
 | } | 
 |  | 
 | func (p *parser) fail() { | 
 | 	var where string | 
 | 	var line int | 
 | 	if p.parser.problem_mark.line != 0 { | 
 | 		line = p.parser.problem_mark.line | 
 | 	} else if p.parser.context_mark.line != 0 { | 
 | 		line = p.parser.context_mark.line | 
 | 	} | 
 | 	if line != 0 { | 
 | 		where = "line " + strconv.Itoa(line) + ": " | 
 | 	} | 
 | 	var msg string | 
 | 	if len(p.parser.problem) > 0 { | 
 | 		msg = p.parser.problem | 
 | 	} else { | 
 | 		msg = "unknown problem parsing YAML content" | 
 | 	} | 
 | 	failf("%s%s", where, msg) | 
 | } | 
 |  | 
 | func (p *parser) anchor(n *node, anchor []byte) { | 
 | 	if anchor != nil { | 
 | 		p.doc.anchors[string(anchor)] = n | 
 | 	} | 
 | } | 
 |  | 
 | func (p *parser) parse() *node { | 
 | 	switch p.event.typ { | 
 | 	case yaml_SCALAR_EVENT: | 
 | 		return p.scalar() | 
 | 	case yaml_ALIAS_EVENT: | 
 | 		return p.alias() | 
 | 	case yaml_MAPPING_START_EVENT: | 
 | 		return p.mapping() | 
 | 	case yaml_SEQUENCE_START_EVENT: | 
 | 		return p.sequence() | 
 | 	case yaml_DOCUMENT_START_EVENT: | 
 | 		return p.document() | 
 | 	case yaml_STREAM_END_EVENT: | 
 | 		// Happens when attempting to decode an empty buffer. | 
 | 		return nil | 
 | 	default: | 
 | 		panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ))) | 
 | 	} | 
 | 	panic("unreachable") | 
 | } | 
 |  | 
 | func (p *parser) node(kind int) *node { | 
 | 	return &node{ | 
 | 		kind:   kind, | 
 | 		line:   p.event.start_mark.line, | 
 | 		column: p.event.start_mark.column, | 
 | 	} | 
 | } | 
 |  | 
 | func (p *parser) document() *node { | 
 | 	n := p.node(documentNode) | 
 | 	n.anchors = make(map[string]*node) | 
 | 	p.doc = n | 
 | 	p.skip() | 
 | 	n.children = append(n.children, p.parse()) | 
 | 	if p.event.typ != yaml_DOCUMENT_END_EVENT { | 
 | 		panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ))) | 
 | 	} | 
 | 	p.skip() | 
 | 	return n | 
 | } | 
 |  | 
 | func (p *parser) alias() *node { | 
 | 	n := p.node(aliasNode) | 
 | 	n.value = string(p.event.anchor) | 
 | 	p.skip() | 
 | 	return n | 
 | } | 
 |  | 
 | func (p *parser) scalar() *node { | 
 | 	n := p.node(scalarNode) | 
 | 	n.value = string(p.event.value) | 
 | 	n.tag = string(p.event.tag) | 
 | 	n.implicit = p.event.implicit | 
 | 	p.anchor(n, p.event.anchor) | 
 | 	p.skip() | 
 | 	return n | 
 | } | 
 |  | 
 | func (p *parser) sequence() *node { | 
 | 	n := p.node(sequenceNode) | 
 | 	p.anchor(n, p.event.anchor) | 
 | 	p.skip() | 
 | 	for p.event.typ != yaml_SEQUENCE_END_EVENT { | 
 | 		n.children = append(n.children, p.parse()) | 
 | 	} | 
 | 	p.skip() | 
 | 	return n | 
 | } | 
 |  | 
 | func (p *parser) mapping() *node { | 
 | 	n := p.node(mappingNode) | 
 | 	p.anchor(n, p.event.anchor) | 
 | 	p.skip() | 
 | 	for p.event.typ != yaml_MAPPING_END_EVENT { | 
 | 		n.children = append(n.children, p.parse(), p.parse()) | 
 | 	} | 
 | 	p.skip() | 
 | 	return n | 
 | } | 
 |  | 
 | // ---------------------------------------------------------------------------- | 
 | // Decoder, unmarshals a node into a provided value. | 
 |  | 
 | type decoder struct { | 
 | 	doc     *node | 
 | 	aliases map[string]bool | 
 | 	mapType reflect.Type | 
 | 	terrors []string | 
 | } | 
 |  | 
 | var ( | 
 | 	mapItemType    = reflect.TypeOf(MapItem{}) | 
 | 	durationType   = reflect.TypeOf(time.Duration(0)) | 
 | 	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) | 
 | 	ifaceType      = defaultMapType.Elem() | 
 | ) | 
 |  | 
 | func newDecoder() *decoder { | 
 | 	d := &decoder{mapType: defaultMapType} | 
 | 	d.aliases = make(map[string]bool) | 
 | 	return d | 
 | } | 
 |  | 
 | func (d *decoder) terror(n *node, tag string, out reflect.Value) { | 
 | 	if n.tag != "" { | 
 | 		tag = n.tag | 
 | 	} | 
 | 	value := n.value | 
 | 	if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG { | 
 | 		if len(value) > 10 { | 
 | 			value = " `" + value[:7] + "...`" | 
 | 		} else { | 
 | 			value = " `" + value + "`" | 
 | 		} | 
 | 	} | 
 | 	d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) | 
 | } | 
 |  | 
 | func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { | 
 | 	terrlen := len(d.terrors) | 
 | 	err := u.UnmarshalYAML(func(v interface{}) (err error) { | 
 | 		defer handleErr(&err) | 
 | 		d.unmarshal(n, reflect.ValueOf(v)) | 
 | 		if len(d.terrors) > terrlen { | 
 | 			issues := d.terrors[terrlen:] | 
 | 			d.terrors = d.terrors[:terrlen] | 
 | 			return &TypeError{issues} | 
 | 		} | 
 | 		return nil | 
 | 	}) | 
 | 	if e, ok := err.(*TypeError); ok { | 
 | 		d.terrors = append(d.terrors, e.Errors...) | 
 | 		return false | 
 | 	} | 
 | 	if err != nil { | 
 | 		fail(err) | 
 | 	} | 
 | 	return true | 
 | } | 
 |  | 
 | // d.prepare initializes and dereferences pointers and calls UnmarshalYAML | 
 | // if a value is found to implement it. | 
 | // It returns the initialized and dereferenced out value, whether | 
 | // unmarshalling was already done by UnmarshalYAML, and if so whether | 
 | // its types unmarshalled appropriately. | 
 | // | 
 | // If n holds a null value, prepare returns before doing anything. | 
 | func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { | 
 | 	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") { | 
 | 		return out, false, false | 
 | 	} | 
 | 	again := true | 
 | 	for again { | 
 | 		again = false | 
 | 		if out.Kind() == reflect.Ptr { | 
 | 			if out.IsNil() { | 
 | 				out.Set(reflect.New(out.Type().Elem())) | 
 | 			} | 
 | 			out = out.Elem() | 
 | 			again = true | 
 | 		} | 
 | 		if out.CanAddr() { | 
 | 			if u, ok := out.Addr().Interface().(Unmarshaler); ok { | 
 | 				good = d.callUnmarshaler(n, u) | 
 | 				return out, true, good | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	return out, false, false | 
 | } | 
 |  | 
 | func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { | 
 | 	switch n.kind { | 
 | 	case documentNode: | 
 | 		return d.document(n, out) | 
 | 	case aliasNode: | 
 | 		return d.alias(n, out) | 
 | 	} | 
 | 	out, unmarshaled, good := d.prepare(n, out) | 
 | 	if unmarshaled { | 
 | 		return good | 
 | 	} | 
 | 	switch n.kind { | 
 | 	case scalarNode: | 
 | 		good = d.scalar(n, out) | 
 | 	case mappingNode: | 
 | 		good = d.mapping(n, out) | 
 | 	case sequenceNode: | 
 | 		good = d.sequence(n, out) | 
 | 	default: | 
 | 		panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) | 
 | 	} | 
 | 	return good | 
 | } | 
 |  | 
 | func (d *decoder) document(n *node, out reflect.Value) (good bool) { | 
 | 	if len(n.children) == 1 { | 
 | 		d.doc = n | 
 | 		d.unmarshal(n.children[0], out) | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (d *decoder) alias(n *node, out reflect.Value) (good bool) { | 
 | 	an, ok := d.doc.anchors[n.value] | 
 | 	if !ok { | 
 | 		failf("unknown anchor '%s' referenced", n.value) | 
 | 	} | 
 | 	if d.aliases[n.value] { | 
 | 		failf("anchor '%s' value contains itself", n.value) | 
 | 	} | 
 | 	d.aliases[n.value] = true | 
 | 	good = d.unmarshal(an, out) | 
 | 	delete(d.aliases, n.value) | 
 | 	return good | 
 | } | 
 |  | 
 | var zeroValue reflect.Value | 
 |  | 
 | func resetMap(out reflect.Value) { | 
 | 	for _, k := range out.MapKeys() { | 
 | 		out.SetMapIndex(k, zeroValue) | 
 | 	} | 
 | } | 
 |  | 
 | func (d *decoder) scalar(n *node, out reflect.Value) (good bool) { | 
 | 	var tag string | 
 | 	var resolved interface{} | 
 | 	if n.tag == "" && !n.implicit { | 
 | 		tag = yaml_STR_TAG | 
 | 		resolved = n.value | 
 | 	} else { | 
 | 		tag, resolved = resolve(n.tag, n.value) | 
 | 		if tag == yaml_BINARY_TAG { | 
 | 			data, err := base64.StdEncoding.DecodeString(resolved.(string)) | 
 | 			if err != nil { | 
 | 				failf("!!binary value contains invalid base64 data") | 
 | 			} | 
 | 			resolved = string(data) | 
 | 		} | 
 | 	} | 
 | 	if resolved == nil { | 
 | 		if out.Kind() == reflect.Map && !out.CanAddr() { | 
 | 			resetMap(out) | 
 | 		} else { | 
 | 			out.Set(reflect.Zero(out.Type())) | 
 | 		} | 
 | 		return true | 
 | 	} | 
 | 	if s, ok := resolved.(string); ok && out.CanAddr() { | 
 | 		if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok { | 
 | 			err := u.UnmarshalText([]byte(s)) | 
 | 			if err != nil { | 
 | 				fail(err) | 
 | 			} | 
 | 			return true | 
 | 		} | 
 | 	} | 
 | 	switch out.Kind() { | 
 | 	case reflect.String: | 
 | 		if tag == yaml_BINARY_TAG { | 
 | 			out.SetString(resolved.(string)) | 
 | 			good = true | 
 | 		} else if resolved != nil { | 
 | 			out.SetString(n.value) | 
 | 			good = true | 
 | 		} | 
 | 	case reflect.Interface: | 
 | 		if resolved == nil { | 
 | 			out.Set(reflect.Zero(out.Type())) | 
 | 		} else { | 
 | 			out.Set(reflect.ValueOf(resolved)) | 
 | 		} | 
 | 		good = true | 
 | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | 
 | 		switch resolved := resolved.(type) { | 
 | 		case int: | 
 | 			if !out.OverflowInt(int64(resolved)) { | 
 | 				out.SetInt(int64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		case int64: | 
 | 			if !out.OverflowInt(resolved) { | 
 | 				out.SetInt(resolved) | 
 | 				good = true | 
 | 			} | 
 | 		case uint64: | 
 | 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { | 
 | 				out.SetInt(int64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		case float64: | 
 | 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { | 
 | 				out.SetInt(int64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		case string: | 
 | 			if out.Type() == durationType { | 
 | 				d, err := time.ParseDuration(resolved) | 
 | 				if err == nil { | 
 | 					out.SetInt(int64(d)) | 
 | 					good = true | 
 | 				} | 
 | 			} | 
 | 		} | 
 | 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: | 
 | 		switch resolved := resolved.(type) { | 
 | 		case int: | 
 | 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { | 
 | 				out.SetUint(uint64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		case int64: | 
 | 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { | 
 | 				out.SetUint(uint64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		case uint64: | 
 | 			if !out.OverflowUint(uint64(resolved)) { | 
 | 				out.SetUint(uint64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		case float64: | 
 | 			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { | 
 | 				out.SetUint(uint64(resolved)) | 
 | 				good = true | 
 | 			} | 
 | 		} | 
 | 	case reflect.Bool: | 
 | 		switch resolved := resolved.(type) { | 
 | 		case bool: | 
 | 			out.SetBool(resolved) | 
 | 			good = true | 
 | 		} | 
 | 	case reflect.Float32, reflect.Float64: | 
 | 		switch resolved := resolved.(type) { | 
 | 		case int: | 
 | 			out.SetFloat(float64(resolved)) | 
 | 			good = true | 
 | 		case int64: | 
 | 			out.SetFloat(float64(resolved)) | 
 | 			good = true | 
 | 		case uint64: | 
 | 			out.SetFloat(float64(resolved)) | 
 | 			good = true | 
 | 		case float64: | 
 | 			out.SetFloat(resolved) | 
 | 			good = true | 
 | 		} | 
 | 	case reflect.Ptr: | 
 | 		if out.Type().Elem() == reflect.TypeOf(resolved) { | 
 | 			// TODO DOes this make sense? When is out a Ptr except when decoding a nil value? | 
 | 			elem := reflect.New(out.Type().Elem()) | 
 | 			elem.Elem().Set(reflect.ValueOf(resolved)) | 
 | 			out.Set(elem) | 
 | 			good = true | 
 | 		} | 
 | 	} | 
 | 	if !good { | 
 | 		d.terror(n, tag, out) | 
 | 	} | 
 | 	return good | 
 | } | 
 |  | 
 | func settableValueOf(i interface{}) reflect.Value { | 
 | 	v := reflect.ValueOf(i) | 
 | 	sv := reflect.New(v.Type()).Elem() | 
 | 	sv.Set(v) | 
 | 	return sv | 
 | } | 
 |  | 
 | func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { | 
 | 	l := len(n.children) | 
 |  | 
 | 	var iface reflect.Value | 
 | 	switch out.Kind() { | 
 | 	case reflect.Slice: | 
 | 		out.Set(reflect.MakeSlice(out.Type(), l, l)) | 
 | 	case reflect.Interface: | 
 | 		// No type hints. Will have to use a generic sequence. | 
 | 		iface = out | 
 | 		out = settableValueOf(make([]interface{}, l)) | 
 | 	default: | 
 | 		d.terror(n, yaml_SEQ_TAG, out) | 
 | 		return false | 
 | 	} | 
 | 	et := out.Type().Elem() | 
 |  | 
 | 	j := 0 | 
 | 	for i := 0; i < l; i++ { | 
 | 		e := reflect.New(et).Elem() | 
 | 		if ok := d.unmarshal(n.children[i], e); ok { | 
 | 			out.Index(j).Set(e) | 
 | 			j++ | 
 | 		} | 
 | 	} | 
 | 	out.Set(out.Slice(0, j)) | 
 | 	if iface.IsValid() { | 
 | 		iface.Set(out) | 
 | 	} | 
 | 	return true | 
 | } | 
 |  | 
 | func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { | 
 | 	switch out.Kind() { | 
 | 	case reflect.Struct: | 
 | 		return d.mappingStruct(n, out) | 
 | 	case reflect.Slice: | 
 | 		return d.mappingSlice(n, out) | 
 | 	case reflect.Map: | 
 | 		// okay | 
 | 	case reflect.Interface: | 
 | 		if d.mapType.Kind() == reflect.Map { | 
 | 			iface := out | 
 | 			out = reflect.MakeMap(d.mapType) | 
 | 			iface.Set(out) | 
 | 		} else { | 
 | 			slicev := reflect.New(d.mapType).Elem() | 
 | 			if !d.mappingSlice(n, slicev) { | 
 | 				return false | 
 | 			} | 
 | 			out.Set(slicev) | 
 | 			return true | 
 | 		} | 
 | 	default: | 
 | 		d.terror(n, yaml_MAP_TAG, out) | 
 | 		return false | 
 | 	} | 
 | 	outt := out.Type() | 
 | 	kt := outt.Key() | 
 | 	et := outt.Elem() | 
 |  | 
 | 	mapType := d.mapType | 
 | 	if outt.Key() == ifaceType && outt.Elem() == ifaceType { | 
 | 		d.mapType = outt | 
 | 	} | 
 |  | 
 | 	if out.IsNil() { | 
 | 		out.Set(reflect.MakeMap(outt)) | 
 | 	} | 
 | 	l := len(n.children) | 
 | 	for i := 0; i < l; i += 2 { | 
 | 		if isMerge(n.children[i]) { | 
 | 			d.merge(n.children[i+1], out) | 
 | 			continue | 
 | 		} | 
 | 		k := reflect.New(kt).Elem() | 
 | 		if d.unmarshal(n.children[i], k) { | 
 | 			kkind := k.Kind() | 
 | 			if kkind == reflect.Interface { | 
 | 				kkind = k.Elem().Kind() | 
 | 			} | 
 | 			if kkind == reflect.Map || kkind == reflect.Slice { | 
 | 				failf("invalid map key: %#v", k.Interface()) | 
 | 			} | 
 | 			e := reflect.New(et).Elem() | 
 | 			if d.unmarshal(n.children[i+1], e) { | 
 | 				out.SetMapIndex(k, e) | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	d.mapType = mapType | 
 | 	return true | 
 | } | 
 |  | 
 | func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { | 
 | 	outt := out.Type() | 
 | 	if outt.Elem() != mapItemType { | 
 | 		d.terror(n, yaml_MAP_TAG, out) | 
 | 		return false | 
 | 	} | 
 |  | 
 | 	mapType := d.mapType | 
 | 	d.mapType = outt | 
 |  | 
 | 	var slice []MapItem | 
 | 	var l = len(n.children) | 
 | 	for i := 0; i < l; i += 2 { | 
 | 		if isMerge(n.children[i]) { | 
 | 			d.merge(n.children[i+1], out) | 
 | 			continue | 
 | 		} | 
 | 		item := MapItem{} | 
 | 		k := reflect.ValueOf(&item.Key).Elem() | 
 | 		if d.unmarshal(n.children[i], k) { | 
 | 			v := reflect.ValueOf(&item.Value).Elem() | 
 | 			if d.unmarshal(n.children[i+1], v) { | 
 | 				slice = append(slice, item) | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	out.Set(reflect.ValueOf(slice)) | 
 | 	d.mapType = mapType | 
 | 	return true | 
 | } | 
 |  | 
 | func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { | 
 | 	sinfo, err := getStructInfo(out.Type()) | 
 | 	if err != nil { | 
 | 		panic(err) | 
 | 	} | 
 | 	name := settableValueOf("") | 
 | 	l := len(n.children) | 
 |  | 
 | 	var inlineMap reflect.Value | 
 | 	var elemType reflect.Type | 
 | 	if sinfo.InlineMap != -1 { | 
 | 		inlineMap = out.Field(sinfo.InlineMap) | 
 | 		inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) | 
 | 		elemType = inlineMap.Type().Elem() | 
 | 	} | 
 |  | 
 | 	for i := 0; i < l; i += 2 { | 
 | 		ni := n.children[i] | 
 | 		if isMerge(ni) { | 
 | 			d.merge(n.children[i+1], out) | 
 | 			continue | 
 | 		} | 
 | 		if !d.unmarshal(ni, name) { | 
 | 			continue | 
 | 		} | 
 | 		if info, ok := sinfo.FieldsMap[name.String()]; ok { | 
 | 			var field reflect.Value | 
 | 			if info.Inline == nil { | 
 | 				field = out.Field(info.Num) | 
 | 			} else { | 
 | 				field = out.FieldByIndex(info.Inline) | 
 | 			} | 
 | 			d.unmarshal(n.children[i+1], field) | 
 | 		} else if sinfo.InlineMap != -1 { | 
 | 			if inlineMap.IsNil() { | 
 | 				inlineMap.Set(reflect.MakeMap(inlineMap.Type())) | 
 | 			} | 
 | 			value := reflect.New(elemType).Elem() | 
 | 			d.unmarshal(n.children[i+1], value) | 
 | 			inlineMap.SetMapIndex(name, value) | 
 | 		} | 
 | 	} | 
 | 	return true | 
 | } | 
 |  | 
 | func failWantMap() { | 
 | 	failf("map merge requires map or sequence of maps as the value") | 
 | } | 
 |  | 
 | func (d *decoder) merge(n *node, out reflect.Value) { | 
 | 	switch n.kind { | 
 | 	case mappingNode: | 
 | 		d.unmarshal(n, out) | 
 | 	case aliasNode: | 
 | 		an, ok := d.doc.anchors[n.value] | 
 | 		if ok && an.kind != mappingNode { | 
 | 			failWantMap() | 
 | 		} | 
 | 		d.unmarshal(n, out) | 
 | 	case sequenceNode: | 
 | 		// Step backwards as earlier nodes take precedence. | 
 | 		for i := len(n.children) - 1; i >= 0; i-- { | 
 | 			ni := n.children[i] | 
 | 			if ni.kind == aliasNode { | 
 | 				an, ok := d.doc.anchors[ni.value] | 
 | 				if ok && an.kind != mappingNode { | 
 | 					failWantMap() | 
 | 				} | 
 | 			} else if ni.kind != mappingNode { | 
 | 				failWantMap() | 
 | 			} | 
 | 			d.unmarshal(ni, out) | 
 | 		} | 
 | 	default: | 
 | 		failWantMap() | 
 | 	} | 
 | } | 
 |  | 
 | func isMerge(n *node) bool { | 
 | 	return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) | 
 | } |