ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/aya/vendor/gopkg.in/yaml.v3/decode.go
Revision: 1.1
Committed: Mon Sep 30 00:42:06 2024 UTC (6 weeks, 4 days ago) by yakumo_izuru
Branch: MAIN
CVS Tags: HEAD
Log Message:
Mirrored from https://git.chaotic.ninja/git/yakumo_izuru/aya

File Contents

# User Rev Content
1 yakumo_izuru 1.1 //
2     // Copyright (c) 2011-2019 Canonical Ltd
3     //
4     // Licensed under the Apache License, Version 2.0 (the "License");
5     // you may not use this file except in compliance with the License.
6     // You may obtain a copy of the License at
7     //
8     // http://www.apache.org/licenses/LICENSE-2.0
9     //
10     // Unless required by applicable law or agreed to in writing, software
11     // distributed under the License is distributed on an "AS IS" BASIS,
12     // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     // See the License for the specific language governing permissions and
14     // limitations under the License.
15    
16     package yaml
17    
18     import (
19     "encoding"
20     "encoding/base64"
21     "fmt"
22     "io"
23     "math"
24     "reflect"
25     "strconv"
26     "time"
27     )
28    
29     // ----------------------------------------------------------------------------
30     // Parser, produces a node tree out of a libyaml event stream.
31    
32     type parser struct {
33     parser yaml_parser_t
34     event yaml_event_t
35     doc *Node
36     anchors map[string]*Node
37     doneInit bool
38     textless bool
39     }
40    
41     func newParser(b []byte) *parser {
42     p := parser{}
43     if !yaml_parser_initialize(&p.parser) {
44     panic("failed to initialize YAML emitter")
45     }
46     if len(b) == 0 {
47     b = []byte{'\n'}
48     }
49     yaml_parser_set_input_string(&p.parser, b)
50     return &p
51     }
52    
53     func newParserFromReader(r io.Reader) *parser {
54     p := parser{}
55     if !yaml_parser_initialize(&p.parser) {
56     panic("failed to initialize YAML emitter")
57     }
58     yaml_parser_set_input_reader(&p.parser, r)
59     return &p
60     }
61    
62     func (p *parser) init() {
63     if p.doneInit {
64     return
65     }
66     p.anchors = make(map[string]*Node)
67     p.expect(yaml_STREAM_START_EVENT)
68     p.doneInit = true
69     }
70    
71     func (p *parser) destroy() {
72     if p.event.typ != yaml_NO_EVENT {
73     yaml_event_delete(&p.event)
74     }
75     yaml_parser_delete(&p.parser)
76     }
77    
78     // expect consumes an event from the event stream and
79     // checks that it's of the expected type.
80     func (p *parser) expect(e yaml_event_type_t) {
81     if p.event.typ == yaml_NO_EVENT {
82     if !yaml_parser_parse(&p.parser, &p.event) {
83     p.fail()
84     }
85     }
86     if p.event.typ == yaml_STREAM_END_EVENT {
87     failf("attempted to go past the end of stream; corrupted value?")
88     }
89     if p.event.typ != e {
90     p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
91     p.fail()
92     }
93     yaml_event_delete(&p.event)
94     p.event.typ = yaml_NO_EVENT
95     }
96    
97     // peek peeks at the next event in the event stream,
98     // puts the results into p.event and returns the event type.
99     func (p *parser) peek() yaml_event_type_t {
100     if p.event.typ != yaml_NO_EVENT {
101     return p.event.typ
102     }
103     // It's curious choice from the underlying API to generally return a
104     // positive result on success, but on this case return true in an error
105     // scenario. This was the source of bugs in the past (issue #666).
106     if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR {
107     p.fail()
108     }
109     return p.event.typ
110     }
111    
112     func (p *parser) fail() {
113     var where string
114     var line int
115     if p.parser.context_mark.line != 0 {
116     line = p.parser.context_mark.line
117     // Scanner errors don't iterate line before returning error
118     if p.parser.error == yaml_SCANNER_ERROR {
119     line++
120     }
121     } else if p.parser.problem_mark.line != 0 {
122     line = p.parser.problem_mark.line
123     // Scanner errors don't iterate line before returning error
124     if p.parser.error == yaml_SCANNER_ERROR {
125     line++
126     }
127     }
128     if line != 0 {
129     where = "line " + strconv.Itoa(line) + ": "
130     }
131     var msg string
132     if len(p.parser.problem) > 0 {
133     msg = p.parser.problem
134     } else {
135     msg = "unknown problem parsing YAML content"
136     }
137     failf("%s%s", where, msg)
138     }
139    
140     func (p *parser) anchor(n *Node, anchor []byte) {
141     if anchor != nil {
142     n.Anchor = string(anchor)
143     p.anchors[n.Anchor] = n
144     }
145     }
146    
147     func (p *parser) parse() *Node {
148     p.init()
149     switch p.peek() {
150     case yaml_SCALAR_EVENT:
151     return p.scalar()
152     case yaml_ALIAS_EVENT:
153     return p.alias()
154     case yaml_MAPPING_START_EVENT:
155     return p.mapping()
156     case yaml_SEQUENCE_START_EVENT:
157     return p.sequence()
158     case yaml_DOCUMENT_START_EVENT:
159     return p.document()
160     case yaml_STREAM_END_EVENT:
161     // Happens when attempting to decode an empty buffer.
162     return nil
163     case yaml_TAIL_COMMENT_EVENT:
164     panic("internal error: unexpected tail comment event (please report)")
165     default:
166     panic("internal error: attempted to parse unknown event (please report): " + p.event.typ.String())
167     }
168     }
169    
170     func (p *parser) node(kind Kind, defaultTag, tag, value string) *Node {
171     var style Style
172     if tag != "" && tag != "!" {
173     tag = shortTag(tag)
174     style = TaggedStyle
175     } else if defaultTag != "" {
176     tag = defaultTag
177     } else if kind == ScalarNode {
178     tag, _ = resolve("", value)
179     }
180     n := &Node{
181     Kind: kind,
182     Tag: tag,
183     Value: value,
184     Style: style,
185     }
186     if !p.textless {
187     n.Line = p.event.start_mark.line + 1
188     n.Column = p.event.start_mark.column + 1
189     n.HeadComment = string(p.event.head_comment)
190     n.LineComment = string(p.event.line_comment)
191     n.FootComment = string(p.event.foot_comment)
192     }
193     return n
194     }
195    
196     func (p *parser) parseChild(parent *Node) *Node {
197     child := p.parse()
198     parent.Content = append(parent.Content, child)
199     return child
200     }
201    
202     func (p *parser) document() *Node {
203     n := p.node(DocumentNode, "", "", "")
204     p.doc = n
205     p.expect(yaml_DOCUMENT_START_EVENT)
206     p.parseChild(n)
207     if p.peek() == yaml_DOCUMENT_END_EVENT {
208     n.FootComment = string(p.event.foot_comment)
209     }
210     p.expect(yaml_DOCUMENT_END_EVENT)
211     return n
212     }
213    
214     func (p *parser) alias() *Node {
215     n := p.node(AliasNode, "", "", string(p.event.anchor))
216     n.Alias = p.anchors[n.Value]
217     if n.Alias == nil {
218     failf("unknown anchor '%s' referenced", n.Value)
219     }
220     p.expect(yaml_ALIAS_EVENT)
221     return n
222     }
223    
224     func (p *parser) scalar() *Node {
225     var parsedStyle = p.event.scalar_style()
226     var nodeStyle Style
227     switch {
228     case parsedStyle&yaml_DOUBLE_QUOTED_SCALAR_STYLE != 0:
229     nodeStyle = DoubleQuotedStyle
230     case parsedStyle&yaml_SINGLE_QUOTED_SCALAR_STYLE != 0:
231     nodeStyle = SingleQuotedStyle
232     case parsedStyle&yaml_LITERAL_SCALAR_STYLE != 0:
233     nodeStyle = LiteralStyle
234     case parsedStyle&yaml_FOLDED_SCALAR_STYLE != 0:
235     nodeStyle = FoldedStyle
236     }
237     var nodeValue = string(p.event.value)
238     var nodeTag = string(p.event.tag)
239     var defaultTag string
240     if nodeStyle == 0 {
241     if nodeValue == "<<" {
242     defaultTag = mergeTag
243     }
244     } else {
245     defaultTag = strTag
246     }
247     n := p.node(ScalarNode, defaultTag, nodeTag, nodeValue)
248     n.Style |= nodeStyle
249     p.anchor(n, p.event.anchor)
250     p.expect(yaml_SCALAR_EVENT)
251     return n
252     }
253    
254     func (p *parser) sequence() *Node {
255     n := p.node(SequenceNode, seqTag, string(p.event.tag), "")
256     if p.event.sequence_style()&yaml_FLOW_SEQUENCE_STYLE != 0 {
257     n.Style |= FlowStyle
258     }
259     p.anchor(n, p.event.anchor)
260     p.expect(yaml_SEQUENCE_START_EVENT)
261     for p.peek() != yaml_SEQUENCE_END_EVENT {
262     p.parseChild(n)
263     }
264     n.LineComment = string(p.event.line_comment)
265     n.FootComment = string(p.event.foot_comment)
266     p.expect(yaml_SEQUENCE_END_EVENT)
267     return n
268     }
269    
270     func (p *parser) mapping() *Node {
271     n := p.node(MappingNode, mapTag, string(p.event.tag), "")
272     block := true
273     if p.event.mapping_style()&yaml_FLOW_MAPPING_STYLE != 0 {
274     block = false
275     n.Style |= FlowStyle
276     }
277     p.anchor(n, p.event.anchor)
278     p.expect(yaml_MAPPING_START_EVENT)
279     for p.peek() != yaml_MAPPING_END_EVENT {
280     k := p.parseChild(n)
281     if block && k.FootComment != "" {
282     // Must be a foot comment for the prior value when being dedented.
283     if len(n.Content) > 2 {
284     n.Content[len(n.Content)-3].FootComment = k.FootComment
285     k.FootComment = ""
286     }
287     }
288     v := p.parseChild(n)
289     if k.FootComment == "" && v.FootComment != "" {
290     k.FootComment = v.FootComment
291     v.FootComment = ""
292     }
293     if p.peek() == yaml_TAIL_COMMENT_EVENT {
294     if k.FootComment == "" {
295     k.FootComment = string(p.event.foot_comment)
296     }
297     p.expect(yaml_TAIL_COMMENT_EVENT)
298     }
299     }
300     n.LineComment = string(p.event.line_comment)
301     n.FootComment = string(p.event.foot_comment)
302     if n.Style&FlowStyle == 0 && n.FootComment != "" && len(n.Content) > 1 {
303     n.Content[len(n.Content)-2].FootComment = n.FootComment
304     n.FootComment = ""
305     }
306     p.expect(yaml_MAPPING_END_EVENT)
307     return n
308     }
309    
310     // ----------------------------------------------------------------------------
311     // Decoder, unmarshals a node into a provided value.
312    
313     type decoder struct {
314     doc *Node
315     aliases map[*Node]bool
316     terrors []string
317    
318     stringMapType reflect.Type
319     generalMapType reflect.Type
320    
321     knownFields bool
322     uniqueKeys bool
323     decodeCount int
324     aliasCount int
325     aliasDepth int
326    
327     mergedFields map[interface{}]bool
328     }
329    
330     var (
331     nodeType = reflect.TypeOf(Node{})
332     durationType = reflect.TypeOf(time.Duration(0))
333     stringMapType = reflect.TypeOf(map[string]interface{}{})
334     generalMapType = reflect.TypeOf(map[interface{}]interface{}{})
335     ifaceType = generalMapType.Elem()
336     timeType = reflect.TypeOf(time.Time{})
337     ptrTimeType = reflect.TypeOf(&time.Time{})
338     )
339    
340     func newDecoder() *decoder {
341     d := &decoder{
342     stringMapType: stringMapType,
343     generalMapType: generalMapType,
344     uniqueKeys: true,
345     }
346     d.aliases = make(map[*Node]bool)
347     return d
348     }
349    
350     func (d *decoder) terror(n *Node, tag string, out reflect.Value) {
351     if n.Tag != "" {
352     tag = n.Tag
353     }
354     value := n.Value
355     if tag != seqTag && tag != mapTag {
356     if len(value) > 10 {
357     value = " `" + value[:7] + "...`"
358     } else {
359     value = " `" + value + "`"
360     }
361     }
362     d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.Line, shortTag(tag), value, out.Type()))
363     }
364    
365     func (d *decoder) callUnmarshaler(n *Node, u Unmarshaler) (good bool) {
366     err := u.UnmarshalYAML(n)
367     if e, ok := err.(*TypeError); ok {
368     d.terrors = append(d.terrors, e.Errors...)
369     return false
370     }
371     if err != nil {
372     fail(err)
373     }
374     return true
375     }
376    
377     func (d *decoder) callObsoleteUnmarshaler(n *Node, u obsoleteUnmarshaler) (good bool) {
378     terrlen := len(d.terrors)
379     err := u.UnmarshalYAML(func(v interface{}) (err error) {
380     defer handleErr(&err)
381     d.unmarshal(n, reflect.ValueOf(v))
382     if len(d.terrors) > terrlen {
383     issues := d.terrors[terrlen:]
384     d.terrors = d.terrors[:terrlen]
385     return &TypeError{issues}
386     }
387     return nil
388     })
389     if e, ok := err.(*TypeError); ok {
390     d.terrors = append(d.terrors, e.Errors...)
391     return false
392     }
393     if err != nil {
394     fail(err)
395     }
396     return true
397     }
398    
399     // d.prepare initializes and dereferences pointers and calls UnmarshalYAML
400     // if a value is found to implement it.
401     // It returns the initialized and dereferenced out value, whether
402     // unmarshalling was already done by UnmarshalYAML, and if so whether
403     // its types unmarshalled appropriately.
404     //
405     // If n holds a null value, prepare returns before doing anything.
406     func (d *decoder) prepare(n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
407     if n.ShortTag() == nullTag {
408     return out, false, false
409     }
410     again := true
411     for again {
412     again = false
413     if out.Kind() == reflect.Ptr {
414     if out.IsNil() {
415     out.Set(reflect.New(out.Type().Elem()))
416     }
417     out = out.Elem()
418     again = true
419     }
420     if out.CanAddr() {
421     outi := out.Addr().Interface()
422     if u, ok := outi.(Unmarshaler); ok {
423     good = d.callUnmarshaler(n, u)
424     return out, true, good
425     }
426     if u, ok := outi.(obsoleteUnmarshaler); ok {
427     good = d.callObsoleteUnmarshaler(n, u)
428     return out, true, good
429     }
430     }
431     }
432     return out, false, false
433     }
434    
435     func (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field reflect.Value) {
436     if n.ShortTag() == nullTag {
437     return reflect.Value{}
438     }
439     for _, num := range index {
440     for {
441     if v.Kind() == reflect.Ptr {
442     if v.IsNil() {
443     v.Set(reflect.New(v.Type().Elem()))
444     }
445     v = v.Elem()
446     continue
447     }
448     break
449     }
450     v = v.Field(num)
451     }
452     return v
453     }
454    
455     const (
456     // 400,000 decode operations is ~500kb of dense object declarations, or
457     // ~5kb of dense object declarations with 10000% alias expansion
458     alias_ratio_range_low = 400000
459    
460     // 4,000,000 decode operations is ~5MB of dense object declarations, or
461     // ~4.5MB of dense object declarations with 10% alias expansion
462     alias_ratio_range_high = 4000000
463    
464     // alias_ratio_range is the range over which we scale allowed alias ratios
465     alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low)
466     )
467    
468     func allowedAliasRatio(decodeCount int) float64 {
469     switch {
470     case decodeCount <= alias_ratio_range_low:
471     // allow 99% to come from alias expansion for small-to-medium documents
472     return 0.99
473     case decodeCount >= alias_ratio_range_high:
474     // allow 10% to come from alias expansion for very large documents
475     return 0.10
476     default:
477     // scale smoothly from 99% down to 10% over the range.
478     // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range.
479     // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps).
480     return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range)
481     }
482     }
483    
484     func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) {
485     d.decodeCount++
486     if d.aliasDepth > 0 {
487     d.aliasCount++
488     }
489     if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) {
490     failf("document contains excessive aliasing")
491     }
492     if out.Type() == nodeType {
493     out.Set(reflect.ValueOf(n).Elem())
494     return true
495     }
496     switch n.Kind {
497     case DocumentNode:
498     return d.document(n, out)
499     case AliasNode:
500     return d.alias(n, out)
501     }
502     out, unmarshaled, good := d.prepare(n, out)
503     if unmarshaled {
504     return good
505     }
506     switch n.Kind {
507     case ScalarNode:
508     good = d.scalar(n, out)
509     case MappingNode:
510     good = d.mapping(n, out)
511     case SequenceNode:
512     good = d.sequence(n, out)
513     case 0:
514     if n.IsZero() {
515     return d.null(out)
516     }
517     fallthrough
518     default:
519     failf("cannot decode node with unknown kind %d", n.Kind)
520     }
521     return good
522     }
523    
524     func (d *decoder) document(n *Node, out reflect.Value) (good bool) {
525     if len(n.Content) == 1 {
526     d.doc = n
527     d.unmarshal(n.Content[0], out)
528     return true
529     }
530     return false
531     }
532    
533     func (d *decoder) alias(n *Node, out reflect.Value) (good bool) {
534     if d.aliases[n] {
535     // TODO this could actually be allowed in some circumstances.
536     failf("anchor '%s' value contains itself", n.Value)
537     }
538     d.aliases[n] = true
539     d.aliasDepth++
540     good = d.unmarshal(n.Alias, out)
541     d.aliasDepth--
542     delete(d.aliases, n)
543     return good
544     }
545    
546     var zeroValue reflect.Value
547    
548     func resetMap(out reflect.Value) {
549     for _, k := range out.MapKeys() {
550     out.SetMapIndex(k, zeroValue)
551     }
552     }
553    
554     func (d *decoder) null(out reflect.Value) bool {
555     if out.CanAddr() {
556     switch out.Kind() {
557     case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
558     out.Set(reflect.Zero(out.Type()))
559     return true
560     }
561     }
562     return false
563     }
564    
565     func (d *decoder) scalar(n *Node, out reflect.Value) bool {
566     var tag string
567     var resolved interface{}
568     if n.indicatedString() {
569     tag = strTag
570     resolved = n.Value
571     } else {
572     tag, resolved = resolve(n.Tag, n.Value)
573     if tag == binaryTag {
574     data, err := base64.StdEncoding.DecodeString(resolved.(string))
575     if err != nil {
576     failf("!!binary value contains invalid base64 data")
577     }
578     resolved = string(data)
579     }
580     }
581     if resolved == nil {
582     return d.null(out)
583     }
584     if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
585     // We've resolved to exactly the type we want, so use that.
586     out.Set(resolvedv)
587     return true
588     }
589     // Perhaps we can use the value as a TextUnmarshaler to
590     // set its value.
591     if out.CanAddr() {
592     u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
593     if ok {
594     var text []byte
595     if tag == binaryTag {
596     text = []byte(resolved.(string))
597     } else {
598     // We let any value be unmarshaled into TextUnmarshaler.
599     // That might be more lax than we'd like, but the
600     // TextUnmarshaler itself should bowl out any dubious values.
601     text = []byte(n.Value)
602     }
603     err := u.UnmarshalText(text)
604     if err != nil {
605     fail(err)
606     }
607     return true
608     }
609     }
610     switch out.Kind() {
611     case reflect.String:
612     if tag == binaryTag {
613     out.SetString(resolved.(string))
614     return true
615     }
616     out.SetString(n.Value)
617     return true
618     case reflect.Interface:
619     out.Set(reflect.ValueOf(resolved))
620     return true
621     case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
622     // This used to work in v2, but it's very unfriendly.
623     isDuration := out.Type() == durationType
624    
625     switch resolved := resolved.(type) {
626     case int:
627     if !isDuration && !out.OverflowInt(int64(resolved)) {
628     out.SetInt(int64(resolved))
629     return true
630     }
631     case int64:
632     if !isDuration && !out.OverflowInt(resolved) {
633     out.SetInt(resolved)
634     return true
635     }
636     case uint64:
637     if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
638     out.SetInt(int64(resolved))
639     return true
640     }
641     case float64:
642     if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
643     out.SetInt(int64(resolved))
644     return true
645     }
646     case string:
647     if out.Type() == durationType {
648     d, err := time.ParseDuration(resolved)
649     if err == nil {
650     out.SetInt(int64(d))
651     return true
652     }
653     }
654     }
655     case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
656     switch resolved := resolved.(type) {
657     case int:
658     if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
659     out.SetUint(uint64(resolved))
660     return true
661     }
662     case int64:
663     if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
664     out.SetUint(uint64(resolved))
665     return true
666     }
667     case uint64:
668     if !out.OverflowUint(uint64(resolved)) {
669     out.SetUint(uint64(resolved))
670     return true
671     }
672     case float64:
673     if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
674     out.SetUint(uint64(resolved))
675     return true
676     }
677     }
678     case reflect.Bool:
679     switch resolved := resolved.(type) {
680     case bool:
681     out.SetBool(resolved)
682     return true
683     case string:
684     // This offers some compatibility with the 1.1 spec (https://yaml.org/type/bool.html).
685     // It only works if explicitly attempting to unmarshal into a typed bool value.
686     switch resolved {
687     case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON":
688     out.SetBool(true)
689     return true
690     case "n", "N", "no", "No", "NO", "off", "Off", "OFF":
691     out.SetBool(false)
692     return true
693     }
694     }
695     case reflect.Float32, reflect.Float64:
696     switch resolved := resolved.(type) {
697     case int:
698     out.SetFloat(float64(resolved))
699     return true
700     case int64:
701     out.SetFloat(float64(resolved))
702     return true
703     case uint64:
704     out.SetFloat(float64(resolved))
705     return true
706     case float64:
707     out.SetFloat(resolved)
708     return true
709     }
710     case reflect.Struct:
711     if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
712     out.Set(resolvedv)
713     return true
714     }
715     case reflect.Ptr:
716     panic("yaml internal error: please report the issue")
717     }
718     d.terror(n, tag, out)
719     return false
720     }
721    
722     func settableValueOf(i interface{}) reflect.Value {
723     v := reflect.ValueOf(i)
724     sv := reflect.New(v.Type()).Elem()
725     sv.Set(v)
726     return sv
727     }
728    
729     func (d *decoder) sequence(n *Node, out reflect.Value) (good bool) {
730     l := len(n.Content)
731    
732     var iface reflect.Value
733     switch out.Kind() {
734     case reflect.Slice:
735     out.Set(reflect.MakeSlice(out.Type(), l, l))
736     case reflect.Array:
737     if l != out.Len() {
738     failf("invalid array: want %d elements but got %d", out.Len(), l)
739     }
740     case reflect.Interface:
741     // No type hints. Will have to use a generic sequence.
742     iface = out
743     out = settableValueOf(make([]interface{}, l))
744     default:
745     d.terror(n, seqTag, out)
746     return false
747     }
748     et := out.Type().Elem()
749    
750     j := 0
751     for i := 0; i < l; i++ {
752     e := reflect.New(et).Elem()
753     if ok := d.unmarshal(n.Content[i], e); ok {
754     out.Index(j).Set(e)
755     j++
756     }
757     }
758     if out.Kind() != reflect.Array {
759     out.Set(out.Slice(0, j))
760     }
761     if iface.IsValid() {
762     iface.Set(out)
763     }
764     return true
765     }
766    
767     func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
768     l := len(n.Content)
769     if d.uniqueKeys {
770     nerrs := len(d.terrors)
771     for i := 0; i < l; i += 2 {
772     ni := n.Content[i]
773     for j := i + 2; j < l; j += 2 {
774     nj := n.Content[j]
775     if ni.Kind == nj.Kind && ni.Value == nj.Value {
776     d.terrors = append(d.terrors, fmt.Sprintf("line %d: mapping key %#v already defined at line %d", nj.Line, nj.Value, ni.Line))
777     }
778     }
779     }
780     if len(d.terrors) > nerrs {
781     return false
782     }
783     }
784     switch out.Kind() {
785     case reflect.Struct:
786     return d.mappingStruct(n, out)
787     case reflect.Map:
788     // okay
789     case reflect.Interface:
790     iface := out
791     if isStringMap(n) {
792     out = reflect.MakeMap(d.stringMapType)
793     } else {
794     out = reflect.MakeMap(d.generalMapType)
795     }
796     iface.Set(out)
797     default:
798     d.terror(n, mapTag, out)
799     return false
800     }
801    
802     outt := out.Type()
803     kt := outt.Key()
804     et := outt.Elem()
805    
806     stringMapType := d.stringMapType
807     generalMapType := d.generalMapType
808     if outt.Elem() == ifaceType {
809     if outt.Key().Kind() == reflect.String {
810     d.stringMapType = outt
811     } else if outt.Key() == ifaceType {
812     d.generalMapType = outt
813     }
814     }
815    
816     mergedFields := d.mergedFields
817     d.mergedFields = nil
818    
819     var mergeNode *Node
820    
821     mapIsNew := false
822     if out.IsNil() {
823     out.Set(reflect.MakeMap(outt))
824     mapIsNew = true
825     }
826     for i := 0; i < l; i += 2 {
827     if isMerge(n.Content[i]) {
828     mergeNode = n.Content[i+1]
829     continue
830     }
831     k := reflect.New(kt).Elem()
832     if d.unmarshal(n.Content[i], k) {
833     if mergedFields != nil {
834     ki := k.Interface()
835     if mergedFields[ki] {
836     continue
837     }
838     mergedFields[ki] = true
839     }
840     kkind := k.Kind()
841     if kkind == reflect.Interface {
842     kkind = k.Elem().Kind()
843     }
844     if kkind == reflect.Map || kkind == reflect.Slice {
845     failf("invalid map key: %#v", k.Interface())
846     }
847     e := reflect.New(et).Elem()
848     if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) {
849     out.SetMapIndex(k, e)
850     }
851     }
852     }
853    
854     d.mergedFields = mergedFields
855     if mergeNode != nil {
856     d.merge(n, mergeNode, out)
857     }
858    
859     d.stringMapType = stringMapType
860     d.generalMapType = generalMapType
861     return true
862     }
863    
864     func isStringMap(n *Node) bool {
865     if n.Kind != MappingNode {
866     return false
867     }
868     l := len(n.Content)
869     for i := 0; i < l; i += 2 {
870     shortTag := n.Content[i].ShortTag()
871     if shortTag != strTag && shortTag != mergeTag {
872     return false
873     }
874     }
875     return true
876     }
877    
878     func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
879     sinfo, err := getStructInfo(out.Type())
880     if err != nil {
881     panic(err)
882     }
883    
884     var inlineMap reflect.Value
885     var elemType reflect.Type
886     if sinfo.InlineMap != -1 {
887     inlineMap = out.Field(sinfo.InlineMap)
888     elemType = inlineMap.Type().Elem()
889     }
890    
891     for _, index := range sinfo.InlineUnmarshalers {
892     field := d.fieldByIndex(n, out, index)
893     d.prepare(n, field)
894     }
895    
896     mergedFields := d.mergedFields
897     d.mergedFields = nil
898     var mergeNode *Node
899     var doneFields []bool
900     if d.uniqueKeys {
901     doneFields = make([]bool, len(sinfo.FieldsList))
902     }
903     name := settableValueOf("")
904     l := len(n.Content)
905     for i := 0; i < l; i += 2 {
906     ni := n.Content[i]
907     if isMerge(ni) {
908     mergeNode = n.Content[i+1]
909     continue
910     }
911     if !d.unmarshal(ni, name) {
912     continue
913     }
914     sname := name.String()
915     if mergedFields != nil {
916     if mergedFields[sname] {
917     continue
918     }
919     mergedFields[sname] = true
920     }
921     if info, ok := sinfo.FieldsMap[sname]; ok {
922     if d.uniqueKeys {
923     if doneFields[info.Id] {
924     d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type()))
925     continue
926     }
927     doneFields[info.Id] = true
928     }
929     var field reflect.Value
930     if info.Inline == nil {
931     field = out.Field(info.Num)
932     } else {
933     field = d.fieldByIndex(n, out, info.Inline)
934     }
935     d.unmarshal(n.Content[i+1], field)
936     } else if sinfo.InlineMap != -1 {
937     if inlineMap.IsNil() {
938     inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
939     }
940     value := reflect.New(elemType).Elem()
941     d.unmarshal(n.Content[i+1], value)
942     inlineMap.SetMapIndex(name, value)
943     } else if d.knownFields {
944     d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type()))
945     }
946     }
947    
948     d.mergedFields = mergedFields
949     if mergeNode != nil {
950     d.merge(n, mergeNode, out)
951     }
952     return true
953     }
954    
955     func failWantMap() {
956     failf("map merge requires map or sequence of maps as the value")
957     }
958    
959     func (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) {
960     mergedFields := d.mergedFields
961     if mergedFields == nil {
962     d.mergedFields = make(map[interface{}]bool)
963     for i := 0; i < len(parent.Content); i += 2 {
964     k := reflect.New(ifaceType).Elem()
965     if d.unmarshal(parent.Content[i], k) {
966     d.mergedFields[k.Interface()] = true
967     }
968     }
969     }
970    
971     switch merge.Kind {
972     case MappingNode:
973     d.unmarshal(merge, out)
974     case AliasNode:
975     if merge.Alias != nil && merge.Alias.Kind != MappingNode {
976     failWantMap()
977     }
978     d.unmarshal(merge, out)
979     case SequenceNode:
980     for i := 0; i < len(merge.Content); i++ {
981     ni := merge.Content[i]
982     if ni.Kind == AliasNode {
983     if ni.Alias != nil && ni.Alias.Kind != MappingNode {
984     failWantMap()
985     }
986     } else if ni.Kind != MappingNode {
987     failWantMap()
988     }
989     d.unmarshal(ni, out)
990     }
991     default:
992     failWantMap()
993     }
994    
995     d.mergedFields = mergedFields
996     }
997    
998     func isMerge(n *Node) bool {
999     return n.Kind == ScalarNode && n.Value == "<<" && (n.Tag == "" || n.Tag == "!" || shortTag(n.Tag) == mergeTag)
1000     }