~juju-qa/ubuntu/trusty/juju/juju-1.25.6

« back to all changes in this revision

Viewing changes to src/gopkg.in/yaml.v2/decode.go

  • Committer: Martin Packman
  • Date: 2016-07-26 19:02:04 UTC
  • mfrom: (1.1.40)
  • Revision ID: martin.packman@canonical.com-20160726190204-fjtbndv4h46m40o9
Merge new upstream source 1.25.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package yaml
 
2
 
 
3
import (
 
4
        "encoding"
 
5
        "encoding/base64"
 
6
        "fmt"
 
7
        "math"
 
8
        "reflect"
 
9
        "strconv"
 
10
        "time"
 
11
)
 
12
 
 
13
const (
 
14
        documentNode = 1 << iota
 
15
        mappingNode
 
16
        sequenceNode
 
17
        scalarNode
 
18
        aliasNode
 
19
)
 
20
 
 
21
type node struct {
 
22
        kind         int
 
23
        line, column int
 
24
        tag          string
 
25
        value        string
 
26
        implicit     bool
 
27
        children     []*node
 
28
        anchors      map[string]*node
 
29
}
 
30
 
 
31
// ----------------------------------------------------------------------------
 
32
// Parser, produces a node tree out of a libyaml event stream.
 
33
 
 
34
type parser struct {
 
35
        parser yaml_parser_t
 
36
        event  yaml_event_t
 
37
        doc    *node
 
38
}
 
39
 
 
40
func newParser(b []byte) *parser {
 
41
        p := parser{}
 
42
        if !yaml_parser_initialize(&p.parser) {
 
43
                panic("failed to initialize YAML emitter")
 
44
        }
 
45
 
 
46
        if len(b) == 0 {
 
47
                b = []byte{'\n'}
 
48
        }
 
49
 
 
50
        yaml_parser_set_input_string(&p.parser, b)
 
51
 
 
52
        p.skip()
 
53
        if p.event.typ != yaml_STREAM_START_EVENT {
 
54
                panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
 
55
        }
 
56
        p.skip()
 
57
        return &p
 
58
}
 
59
 
 
60
func (p *parser) destroy() {
 
61
        if p.event.typ != yaml_NO_EVENT {
 
62
                yaml_event_delete(&p.event)
 
63
        }
 
64
        yaml_parser_delete(&p.parser)
 
65
}
 
66
 
 
67
func (p *parser) skip() {
 
68
        if p.event.typ != yaml_NO_EVENT {
 
69
                if p.event.typ == yaml_STREAM_END_EVENT {
 
70
                        failf("attempted to go past the end of stream; corrupted value?")
 
71
                }
 
72
                yaml_event_delete(&p.event)
 
73
        }
 
74
        if !yaml_parser_parse(&p.parser, &p.event) {
 
75
                p.fail()
 
76
        }
 
77
}
 
78
 
 
79
func (p *parser) fail() {
 
80
        var where string
 
81
        var line int
 
82
        if p.parser.problem_mark.line != 0 {
 
83
                line = p.parser.problem_mark.line
 
84
        } else if p.parser.context_mark.line != 0 {
 
85
                line = p.parser.context_mark.line
 
86
        }
 
87
        if line != 0 {
 
88
                where = "line " + strconv.Itoa(line) + ": "
 
89
        }
 
90
        var msg string
 
91
        if len(p.parser.problem) > 0 {
 
92
                msg = p.parser.problem
 
93
        } else {
 
94
                msg = "unknown problem parsing YAML content"
 
95
        }
 
96
        failf("%s%s", where, msg)
 
97
}
 
98
 
 
99
func (p *parser) anchor(n *node, anchor []byte) {
 
100
        if anchor != nil {
 
101
                p.doc.anchors[string(anchor)] = n
 
102
        }
 
103
}
 
104
 
 
105
func (p *parser) parse() *node {
 
106
        switch p.event.typ {
 
107
        case yaml_SCALAR_EVENT:
 
108
                return p.scalar()
 
109
        case yaml_ALIAS_EVENT:
 
110
                return p.alias()
 
111
        case yaml_MAPPING_START_EVENT:
 
112
                return p.mapping()
 
113
        case yaml_SEQUENCE_START_EVENT:
 
114
                return p.sequence()
 
115
        case yaml_DOCUMENT_START_EVENT:
 
116
                return p.document()
 
117
        case yaml_STREAM_END_EVENT:
 
118
                // Happens when attempting to decode an empty buffer.
 
119
                return nil
 
120
        default:
 
121
                panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
 
122
        }
 
123
        panic("unreachable")
 
124
}
 
125
 
 
126
func (p *parser) node(kind int) *node {
 
127
        return &node{
 
128
                kind:   kind,
 
129
                line:   p.event.start_mark.line,
 
130
                column: p.event.start_mark.column,
 
131
        }
 
132
}
 
133
 
 
134
func (p *parser) document() *node {
 
135
        n := p.node(documentNode)
 
136
        n.anchors = make(map[string]*node)
 
137
        p.doc = n
 
138
        p.skip()
 
139
        n.children = append(n.children, p.parse())
 
140
        if p.event.typ != yaml_DOCUMENT_END_EVENT {
 
141
                panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
 
142
        }
 
143
        p.skip()
 
144
        return n
 
145
}
 
146
 
 
147
func (p *parser) alias() *node {
 
148
        n := p.node(aliasNode)
 
149
        n.value = string(p.event.anchor)
 
150
        p.skip()
 
151
        return n
 
152
}
 
153
 
 
154
func (p *parser) scalar() *node {
 
155
        n := p.node(scalarNode)
 
156
        n.value = string(p.event.value)
 
157
        n.tag = string(p.event.tag)
 
158
        n.implicit = p.event.implicit
 
159
        p.anchor(n, p.event.anchor)
 
160
        p.skip()
 
161
        return n
 
162
}
 
163
 
 
164
func (p *parser) sequence() *node {
 
165
        n := p.node(sequenceNode)
 
166
        p.anchor(n, p.event.anchor)
 
167
        p.skip()
 
168
        for p.event.typ != yaml_SEQUENCE_END_EVENT {
 
169
                n.children = append(n.children, p.parse())
 
170
        }
 
171
        p.skip()
 
172
        return n
 
173
}
 
174
 
 
175
func (p *parser) mapping() *node {
 
176
        n := p.node(mappingNode)
 
177
        p.anchor(n, p.event.anchor)
 
178
        p.skip()
 
179
        for p.event.typ != yaml_MAPPING_END_EVENT {
 
180
                n.children = append(n.children, p.parse(), p.parse())
 
181
        }
 
182
        p.skip()
 
183
        return n
 
184
}
 
185
 
 
186
// ----------------------------------------------------------------------------
 
187
// Decoder, unmarshals a node into a provided value.
 
188
 
 
189
type decoder struct {
 
190
        doc     *node
 
191
        aliases map[string]bool
 
192
        mapType reflect.Type
 
193
        terrors []string
 
194
}
 
195
 
 
196
var (
 
197
        mapItemType    = reflect.TypeOf(MapItem{})
 
198
        durationType   = reflect.TypeOf(time.Duration(0))
 
199
        defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
 
200
        ifaceType      = defaultMapType.Elem()
 
201
)
 
202
 
 
203
func newDecoder() *decoder {
 
204
        d := &decoder{mapType: defaultMapType}
 
205
        d.aliases = make(map[string]bool)
 
206
        return d
 
207
}
 
208
 
 
209
func (d *decoder) terror(n *node, tag string, out reflect.Value) {
 
210
        if n.tag != "" {
 
211
                tag = n.tag
 
212
        }
 
213
        value := n.value
 
214
        if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
 
215
                if len(value) > 10 {
 
216
                        value = " `" + value[:7] + "...`"
 
217
                } else {
 
218
                        value = " `" + value + "`"
 
219
                }
 
220
        }
 
221
        d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
 
222
}
 
223
 
 
224
func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
 
225
        terrlen := len(d.terrors)
 
226
        err := u.UnmarshalYAML(func(v interface{}) (err error) {
 
227
                defer handleErr(&err)
 
228
                d.unmarshal(n, reflect.ValueOf(v))
 
229
                if len(d.terrors) > terrlen {
 
230
                        issues := d.terrors[terrlen:]
 
231
                        d.terrors = d.terrors[:terrlen]
 
232
                        return &TypeError{issues}
 
233
                }
 
234
                return nil
 
235
        })
 
236
        if e, ok := err.(*TypeError); ok {
 
237
                d.terrors = append(d.terrors, e.Errors...)
 
238
                return false
 
239
        }
 
240
        if err != nil {
 
241
                fail(err)
 
242
        }
 
243
        return true
 
244
}
 
245
 
 
246
// d.prepare initializes and dereferences pointers and calls UnmarshalYAML
 
247
// if a value is found to implement it.
 
248
// It returns the initialized and dereferenced out value, whether
 
249
// unmarshalling was already done by UnmarshalYAML, and if so whether
 
250
// its types unmarshalled appropriately.
 
251
//
 
252
// If n holds a null value, prepare returns before doing anything.
 
253
func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
 
254
        if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
 
255
                return out, false, false
 
256
        }
 
257
        again := true
 
258
        for again {
 
259
                again = false
 
260
                if out.Kind() == reflect.Ptr {
 
261
                        if out.IsNil() {
 
262
                                out.Set(reflect.New(out.Type().Elem()))
 
263
                        }
 
264
                        out = out.Elem()
 
265
                        again = true
 
266
                }
 
267
                if out.CanAddr() {
 
268
                        if u, ok := out.Addr().Interface().(Unmarshaler); ok {
 
269
                                good = d.callUnmarshaler(n, u)
 
270
                                return out, true, good
 
271
                        }
 
272
                }
 
273
        }
 
274
        return out, false, false
 
275
}
 
276
 
 
277
func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
 
278
        switch n.kind {
 
279
        case documentNode:
 
280
                return d.document(n, out)
 
281
        case aliasNode:
 
282
                return d.alias(n, out)
 
283
        }
 
284
        out, unmarshaled, good := d.prepare(n, out)
 
285
        if unmarshaled {
 
286
                return good
 
287
        }
 
288
        switch n.kind {
 
289
        case scalarNode:
 
290
                good = d.scalar(n, out)
 
291
        case mappingNode:
 
292
                good = d.mapping(n, out)
 
293
        case sequenceNode:
 
294
                good = d.sequence(n, out)
 
295
        default:
 
296
                panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
 
297
        }
 
298
        return good
 
299
}
 
300
 
 
301
func (d *decoder) document(n *node, out reflect.Value) (good bool) {
 
302
        if len(n.children) == 1 {
 
303
                d.doc = n
 
304
                d.unmarshal(n.children[0], out)
 
305
                return true
 
306
        }
 
307
        return false
 
308
}
 
309
 
 
310
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
 
311
        an, ok := d.doc.anchors[n.value]
 
312
        if !ok {
 
313
                failf("unknown anchor '%s' referenced", n.value)
 
314
        }
 
315
        if d.aliases[n.value] {
 
316
                failf("anchor '%s' value contains itself", n.value)
 
317
        }
 
318
        d.aliases[n.value] = true
 
319
        good = d.unmarshal(an, out)
 
320
        delete(d.aliases, n.value)
 
321
        return good
 
322
}
 
323
 
 
324
var zeroValue reflect.Value
 
325
 
 
326
func resetMap(out reflect.Value) {
 
327
        for _, k := range out.MapKeys() {
 
328
                out.SetMapIndex(k, zeroValue)
 
329
        }
 
330
}
 
331
 
 
332
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 
333
        var tag string
 
334
        var resolved interface{}
 
335
        if n.tag == "" && !n.implicit {
 
336
                tag = yaml_STR_TAG
 
337
                resolved = n.value
 
338
        } else {
 
339
                tag, resolved = resolve(n.tag, n.value)
 
340
                if tag == yaml_BINARY_TAG {
 
341
                        data, err := base64.StdEncoding.DecodeString(resolved.(string))
 
342
                        if err != nil {
 
343
                                failf("!!binary value contains invalid base64 data")
 
344
                        }
 
345
                        resolved = string(data)
 
346
                }
 
347
        }
 
348
        if resolved == nil {
 
349
                if out.Kind() == reflect.Map && !out.CanAddr() {
 
350
                        resetMap(out)
 
351
                } else {
 
352
                        out.Set(reflect.Zero(out.Type()))
 
353
                }
 
354
                return true
 
355
        }
 
356
        if s, ok := resolved.(string); ok && out.CanAddr() {
 
357
                if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
 
358
                        err := u.UnmarshalText([]byte(s))
 
359
                        if err != nil {
 
360
                                fail(err)
 
361
                        }
 
362
                        return true
 
363
                }
 
364
        }
 
365
        switch out.Kind() {
 
366
        case reflect.String:
 
367
                if tag == yaml_BINARY_TAG {
 
368
                        out.SetString(resolved.(string))
 
369
                        good = true
 
370
                } else if resolved != nil {
 
371
                        out.SetString(n.value)
 
372
                        good = true
 
373
                }
 
374
        case reflect.Interface:
 
375
                if resolved == nil {
 
376
                        out.Set(reflect.Zero(out.Type()))
 
377
                } else {
 
378
                        out.Set(reflect.ValueOf(resolved))
 
379
                }
 
380
                good = true
 
381
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 
382
                switch resolved := resolved.(type) {
 
383
                case int:
 
384
                        if !out.OverflowInt(int64(resolved)) {
 
385
                                out.SetInt(int64(resolved))
 
386
                                good = true
 
387
                        }
 
388
                case int64:
 
389
                        if !out.OverflowInt(resolved) {
 
390
                                out.SetInt(resolved)
 
391
                                good = true
 
392
                        }
 
393
                case uint64:
 
394
                        if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 
395
                                out.SetInt(int64(resolved))
 
396
                                good = true
 
397
                        }
 
398
                case float64:
 
399
                        if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 
400
                                out.SetInt(int64(resolved))
 
401
                                good = true
 
402
                        }
 
403
                case string:
 
404
                        if out.Type() == durationType {
 
405
                                d, err := time.ParseDuration(resolved)
 
406
                                if err == nil {
 
407
                                        out.SetInt(int64(d))
 
408
                                        good = true
 
409
                                }
 
410
                        }
 
411
                }
 
412
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 
413
                switch resolved := resolved.(type) {
 
414
                case int:
 
415
                        if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 
416
                                out.SetUint(uint64(resolved))
 
417
                                good = true
 
418
                        }
 
419
                case int64:
 
420
                        if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 
421
                                out.SetUint(uint64(resolved))
 
422
                                good = true
 
423
                        }
 
424
                case uint64:
 
425
                        if !out.OverflowUint(uint64(resolved)) {
 
426
                                out.SetUint(uint64(resolved))
 
427
                                good = true
 
428
                        }
 
429
                case float64:
 
430
                        if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
 
431
                                out.SetUint(uint64(resolved))
 
432
                                good = true
 
433
                        }
 
434
                }
 
435
        case reflect.Bool:
 
436
                switch resolved := resolved.(type) {
 
437
                case bool:
 
438
                        out.SetBool(resolved)
 
439
                        good = true
 
440
                }
 
441
        case reflect.Float32, reflect.Float64:
 
442
                switch resolved := resolved.(type) {
 
443
                case int:
 
444
                        out.SetFloat(float64(resolved))
 
445
                        good = true
 
446
                case int64:
 
447
                        out.SetFloat(float64(resolved))
 
448
                        good = true
 
449
                case uint64:
 
450
                        out.SetFloat(float64(resolved))
 
451
                        good = true
 
452
                case float64:
 
453
                        out.SetFloat(resolved)
 
454
                        good = true
 
455
                }
 
456
        case reflect.Ptr:
 
457
                if out.Type().Elem() == reflect.TypeOf(resolved) {
 
458
                        // TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
 
459
                        elem := reflect.New(out.Type().Elem())
 
460
                        elem.Elem().Set(reflect.ValueOf(resolved))
 
461
                        out.Set(elem)
 
462
                        good = true
 
463
                }
 
464
        }
 
465
        if !good {
 
466
                d.terror(n, tag, out)
 
467
        }
 
468
        return good
 
469
}
 
470
 
 
471
func settableValueOf(i interface{}) reflect.Value {
 
472
        v := reflect.ValueOf(i)
 
473
        sv := reflect.New(v.Type()).Elem()
 
474
        sv.Set(v)
 
475
        return sv
 
476
}
 
477
 
 
478
func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 
479
        l := len(n.children)
 
480
 
 
481
        var iface reflect.Value
 
482
        switch out.Kind() {
 
483
        case reflect.Slice:
 
484
                out.Set(reflect.MakeSlice(out.Type(), l, l))
 
485
        case reflect.Interface:
 
486
                // No type hints. Will have to use a generic sequence.
 
487
                iface = out
 
488
                out = settableValueOf(make([]interface{}, l))
 
489
        default:
 
490
                d.terror(n, yaml_SEQ_TAG, out)
 
491
                return false
 
492
        }
 
493
        et := out.Type().Elem()
 
494
 
 
495
        j := 0
 
496
        for i := 0; i < l; i++ {
 
497
                e := reflect.New(et).Elem()
 
498
                if ok := d.unmarshal(n.children[i], e); ok {
 
499
                        out.Index(j).Set(e)
 
500
                        j++
 
501
                }
 
502
        }
 
503
        out.Set(out.Slice(0, j))
 
504
        if iface.IsValid() {
 
505
                iface.Set(out)
 
506
        }
 
507
        return true
 
508
}
 
509
 
 
510
func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 
511
        switch out.Kind() {
 
512
        case reflect.Struct:
 
513
                return d.mappingStruct(n, out)
 
514
        case reflect.Slice:
 
515
                return d.mappingSlice(n, out)
 
516
        case reflect.Map:
 
517
                // okay
 
518
        case reflect.Interface:
 
519
                if d.mapType.Kind() == reflect.Map {
 
520
                        iface := out
 
521
                        out = reflect.MakeMap(d.mapType)
 
522
                        iface.Set(out)
 
523
                } else {
 
524
                        slicev := reflect.New(d.mapType).Elem()
 
525
                        if !d.mappingSlice(n, slicev) {
 
526
                                return false
 
527
                        }
 
528
                        out.Set(slicev)
 
529
                        return true
 
530
                }
 
531
        default:
 
532
                d.terror(n, yaml_MAP_TAG, out)
 
533
                return false
 
534
        }
 
535
        outt := out.Type()
 
536
        kt := outt.Key()
 
537
        et := outt.Elem()
 
538
 
 
539
        mapType := d.mapType
 
540
        if outt.Key() == ifaceType && outt.Elem() == ifaceType {
 
541
                d.mapType = outt
 
542
        }
 
543
 
 
544
        if out.IsNil() {
 
545
                out.Set(reflect.MakeMap(outt))
 
546
        }
 
547
        l := len(n.children)
 
548
        for i := 0; i < l; i += 2 {
 
549
                if isMerge(n.children[i]) {
 
550
                        d.merge(n.children[i+1], out)
 
551
                        continue
 
552
                }
 
553
                k := reflect.New(kt).Elem()
 
554
                if d.unmarshal(n.children[i], k) {
 
555
                        kkind := k.Kind()
 
556
                        if kkind == reflect.Interface {
 
557
                                kkind = k.Elem().Kind()
 
558
                        }
 
559
                        if kkind == reflect.Map || kkind == reflect.Slice {
 
560
                                failf("invalid map key: %#v", k.Interface())
 
561
                        }
 
562
                        e := reflect.New(et).Elem()
 
563
                        if d.unmarshal(n.children[i+1], e) {
 
564
                                out.SetMapIndex(k, e)
 
565
                        }
 
566
                }
 
567
        }
 
568
        d.mapType = mapType
 
569
        return true
 
570
}
 
571
 
 
572
func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
 
573
        outt := out.Type()
 
574
        if outt.Elem() != mapItemType {
 
575
                d.terror(n, yaml_MAP_TAG, out)
 
576
                return false
 
577
        }
 
578
 
 
579
        mapType := d.mapType
 
580
        d.mapType = outt
 
581
 
 
582
        var slice []MapItem
 
583
        var l = len(n.children)
 
584
        for i := 0; i < l; i += 2 {
 
585
                if isMerge(n.children[i]) {
 
586
                        d.merge(n.children[i+1], out)
 
587
                        continue
 
588
                }
 
589
                item := MapItem{}
 
590
                k := reflect.ValueOf(&item.Key).Elem()
 
591
                if d.unmarshal(n.children[i], k) {
 
592
                        v := reflect.ValueOf(&item.Value).Elem()
 
593
                        if d.unmarshal(n.children[i+1], v) {
 
594
                                slice = append(slice, item)
 
595
                        }
 
596
                }
 
597
        }
 
598
        out.Set(reflect.ValueOf(slice))
 
599
        d.mapType = mapType
 
600
        return true
 
601
}
 
602
 
 
603
func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 
604
        sinfo, err := getStructInfo(out.Type())
 
605
        if err != nil {
 
606
                panic(err)
 
607
        }
 
608
        name := settableValueOf("")
 
609
        l := len(n.children)
 
610
 
 
611
        var inlineMap reflect.Value
 
612
        var elemType reflect.Type
 
613
        if sinfo.InlineMap != -1 {
 
614
                inlineMap = out.Field(sinfo.InlineMap)
 
615
                inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
 
616
                elemType = inlineMap.Type().Elem()
 
617
        }
 
618
 
 
619
        for i := 0; i < l; i += 2 {
 
620
                ni := n.children[i]
 
621
                if isMerge(ni) {
 
622
                        d.merge(n.children[i+1], out)
 
623
                        continue
 
624
                }
 
625
                if !d.unmarshal(ni, name) {
 
626
                        continue
 
627
                }
 
628
                if info, ok := sinfo.FieldsMap[name.String()]; ok {
 
629
                        var field reflect.Value
 
630
                        if info.Inline == nil {
 
631
                                field = out.Field(info.Num)
 
632
                        } else {
 
633
                                field = out.FieldByIndex(info.Inline)
 
634
                        }
 
635
                        d.unmarshal(n.children[i+1], field)
 
636
                } else if sinfo.InlineMap != -1 {
 
637
                        if inlineMap.IsNil() {
 
638
                                inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
 
639
                        }
 
640
                        value := reflect.New(elemType).Elem()
 
641
                        d.unmarshal(n.children[i+1], value)
 
642
                        inlineMap.SetMapIndex(name, value)
 
643
                }
 
644
        }
 
645
        return true
 
646
}
 
647
 
 
648
func failWantMap() {
 
649
        failf("map merge requires map or sequence of maps as the value")
 
650
}
 
651
 
 
652
func (d *decoder) merge(n *node, out reflect.Value) {
 
653
        switch n.kind {
 
654
        case mappingNode:
 
655
                d.unmarshal(n, out)
 
656
        case aliasNode:
 
657
                an, ok := d.doc.anchors[n.value]
 
658
                if ok && an.kind != mappingNode {
 
659
                        failWantMap()
 
660
                }
 
661
                d.unmarshal(n, out)
 
662
        case sequenceNode:
 
663
                // Step backwards as earlier nodes take precedence.
 
664
                for i := len(n.children) - 1; i >= 0; i-- {
 
665
                        ni := n.children[i]
 
666
                        if ni.kind == aliasNode {
 
667
                                an, ok := d.doc.anchors[ni.value]
 
668
                                if ok && an.kind != mappingNode {
 
669
                                        failWantMap()
 
670
                                }
 
671
                        } else if ni.kind != mappingNode {
 
672
                                failWantMap()
 
673
                        }
 
674
                        d.unmarshal(ni, out)
 
675
                }
 
676
        default:
 
677
                failWantMap()
 
678
        }
 
679
}
 
680
 
 
681
func isMerge(n *node) bool {
 
682
        return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
 
683
}