decode.go 20 KB

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