decode.go 20 KB

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