github.com/go-xe2/third@v1.0.3/gopkg.in/yaml.v2/decode.go (about)

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