decode.go 20 KB

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