github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/gopkg.in/v2/yaml/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  	panic("unreachable")
   124  }
   125  
   126  func (p *parser) node(kind int) *node {
   127  	return &node{
   128  		kind:   kind,
   129  		line:   p.event.start_mark.line,
   130  		column: p.event.start_mark.column,
   131  	}
   132  }
   133  
   134  func (p *parser) document() *node {
   135  	n := p.node(documentNode)
   136  	n.anchors = make(map[string]*node)
   137  	p.doc = n
   138  	p.skip()
   139  	n.children = append(n.children, p.parse())
   140  	if p.event.typ != yaml_DOCUMENT_END_EVENT {
   141  		panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
   142  	}
   143  	p.skip()
   144  	return n
   145  }
   146  
   147  func (p *parser) alias() *node {
   148  	n := p.node(aliasNode)
   149  	n.value = string(p.event.anchor)
   150  	p.skip()
   151  	return n
   152  }
   153  
   154  func (p *parser) scalar() *node {
   155  	n := p.node(scalarNode)
   156  	n.value = string(p.event.value)
   157  	n.tag = string(p.event.tag)
   158  	n.implicit = p.event.implicit
   159  	p.anchor(n, p.event.anchor)
   160  	p.skip()
   161  	return n
   162  }
   163  
   164  func (p *parser) sequence() *node {
   165  	n := p.node(sequenceNode)
   166  	p.anchor(n, p.event.anchor)
   167  	p.skip()
   168  	for p.event.typ != yaml_SEQUENCE_END_EVENT {
   169  		n.children = append(n.children, p.parse())
   170  	}
   171  	p.skip()
   172  	return n
   173  }
   174  
   175  func (p *parser) mapping() *node {
   176  	n := p.node(mappingNode)
   177  	p.anchor(n, p.event.anchor)
   178  	p.skip()
   179  	for p.event.typ != yaml_MAPPING_END_EVENT {
   180  		n.children = append(n.children, p.parse(), p.parse())
   181  	}
   182  	p.skip()
   183  	return n
   184  }
   185  
   186  // ----------------------------------------------------------------------------
   187  // Decoder, unmarshals a node into a provided value.
   188  
   189  type decoder struct {
   190  	doc     *node
   191  	aliases map[string]bool
   192  	mapType reflect.Type
   193  	terrors []string
   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() *decoder {
   204  	d := &decoder{mapType: defaultMapType}
   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 == "") {
   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  	var iface reflect.Value
   480  	switch out.Kind() {
   481  	case reflect.Slice:
   482  		// okay
   483  	case reflect.Interface:
   484  		// No type hints. Will have to use a generic sequence.
   485  		iface = out
   486  		out = settableValueOf(make([]interface{}, 0))
   487  	default:
   488  		d.terror(n, yaml_SEQ_TAG, out)
   489  		return false
   490  	}
   491  	et := out.Type().Elem()
   492  
   493  	l := len(n.children)
   494  	for i := 0; i < l; i++ {
   495  		e := reflect.New(et).Elem()
   496  		if ok := d.unmarshal(n.children[i], e); ok {
   497  			out.Set(reflect.Append(out, e))
   498  		}
   499  	}
   500  	if iface.IsValid() {
   501  		iface.Set(out)
   502  	}
   503  	return true
   504  }
   505  
   506  
   507  
   508  func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
   509  	switch out.Kind() {
   510  	case reflect.Struct:
   511  		return d.mappingStruct(n, out)
   512  	case reflect.Slice:
   513  		return d.mappingSlice(n, out)
   514  	case reflect.Map:
   515  		// okay
   516  	case reflect.Interface:
   517  		if d.mapType.Kind() == reflect.Map {
   518  			iface := out
   519  			out = reflect.MakeMap(d.mapType)
   520  			iface.Set(out)
   521  		} else {
   522  			slicev := reflect.New(d.mapType).Elem()
   523  			if !d.mappingSlice(n, slicev) {
   524  				return false
   525  			}
   526  			out.Set(slicev)
   527  			return true
   528  		}
   529  	default:
   530  		d.terror(n, yaml_MAP_TAG, out)
   531  		return false
   532  	}
   533  	outt := out.Type()
   534  	kt := outt.Key()
   535  	et := outt.Elem()
   536  
   537  	mapType := d.mapType
   538  	if outt.Key() == ifaceType && outt.Elem() == ifaceType {
   539  		d.mapType = outt
   540  	}
   541  
   542  	if out.IsNil() {
   543  		out.Set(reflect.MakeMap(outt))
   544  	}
   545  	l := len(n.children)
   546  	for i := 0; i < l; i += 2 {
   547  		if isMerge(n.children[i]) {
   548  			d.merge(n.children[i+1], out)
   549  			continue
   550  		}
   551  		k := reflect.New(kt).Elem()
   552  		if d.unmarshal(n.children[i], k) {
   553  			kkind := k.Kind()
   554  			if kkind == reflect.Interface {
   555  				kkind = k.Elem().Kind()
   556  			}
   557  			if kkind == reflect.Map || kkind == reflect.Slice {
   558  				failf("invalid map key: %#v", k.Interface())
   559  			}
   560  			e := reflect.New(et).Elem()
   561  			if d.unmarshal(n.children[i+1], e) {
   562  				out.SetMapIndex(k, e)
   563  			}
   564  		}
   565  	}
   566  	d.mapType = mapType
   567  	return true
   568  }
   569  
   570  func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
   571  	outt := out.Type()
   572  	if outt.Elem() != mapItemType {
   573  		d.terror(n, yaml_MAP_TAG, out)
   574  		return false
   575  	}
   576  
   577  	mapType := d.mapType
   578  	d.mapType = outt
   579  
   580  	var slice []MapItem
   581  	var l = len(n.children)
   582  	for i := 0; i < l; i += 2 {
   583  		if isMerge(n.children[i]) {
   584  			d.merge(n.children[i+1], out)
   585  			continue
   586  		}
   587  		item := MapItem{}
   588  		k := reflect.ValueOf(&item.Key).Elem()
   589  		if d.unmarshal(n.children[i], k) {
   590  			v := reflect.ValueOf(&item.Value).Elem()
   591  			if d.unmarshal(n.children[i+1], v) {
   592  				slice = append(slice, item)
   593  			}
   594  		}
   595  	}
   596  	out.Set(reflect.ValueOf(slice))
   597  	d.mapType = mapType
   598  	return true
   599  }
   600  
   601  func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
   602  	sinfo, err := getStructInfo(out.Type())
   603  	if err != nil {
   604  		panic(err)
   605  	}
   606  	name := settableValueOf("")
   607  	l := len(n.children)
   608  	for i := 0; i < l; i += 2 {
   609  		ni := n.children[i]
   610  		if isMerge(ni) {
   611  			d.merge(n.children[i+1], out)
   612  			continue
   613  		}
   614  		if !d.unmarshal(ni, name) {
   615  			continue
   616  		}
   617  		if info, ok := sinfo.FieldsMap[name.String()]; ok {
   618  			var field reflect.Value
   619  			if info.Inline == nil {
   620  				field = out.Field(info.Num)
   621  			} else {
   622  				field = out.FieldByIndex(info.Inline)
   623  			}
   624  			d.unmarshal(n.children[i+1], field)
   625  		}
   626  	}
   627  	return true
   628  }
   629  
   630  func failWantMap() {
   631  	failf("map merge requires map or sequence of maps as the value")
   632  }
   633  
   634  func (d *decoder) merge(n *node, out reflect.Value) {
   635  	switch n.kind {
   636  	case mappingNode:
   637  		d.unmarshal(n, out)
   638  	case aliasNode:
   639  		an, ok := d.doc.anchors[n.value]
   640  		if ok && an.kind != mappingNode {
   641  			failWantMap()
   642  		}
   643  		d.unmarshal(n, out)
   644  	case sequenceNode:
   645  		// Step backwards as earlier nodes take precedence.
   646  		for i := len(n.children) - 1; i >= 0; i-- {
   647  			ni := n.children[i]
   648  			if ni.kind == aliasNode {
   649  				an, ok := d.doc.anchors[ni.value]
   650  				if ok && an.kind != mappingNode {
   651  					failWantMap()
   652  				}
   653  			} else if ni.kind != mappingNode {
   654  				failWantMap()
   655  			}
   656  			d.unmarshal(ni, out)
   657  		}
   658  	default:
   659  		failWantMap()
   660  	}
   661  }
   662  
   663  func isMerge(n *node) bool {
   664  	return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
   665  }