github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/Godeps/_workspace/src/gopkg.in/yaml.v2/decode.go (about)

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