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