github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/Godeps/_workspace/src/gopkg.in/yaml.v1/decode.go (about)

     1  package yaml
     2  
     3  import (
     4  	"reflect"
     5  	"strconv"
     6  	"time"
     7  )
     8  
     9  const (
    10  	documentNode = 1 << iota
    11  	mappingNode
    12  	sequenceNode
    13  	scalarNode
    14  	aliasNode
    15  )
    16  
    17  type node struct {
    18  	kind         int
    19  	line, column int
    20  	tag          string
    21  	value        string
    22  	implicit     bool
    23  	children     []*node
    24  	anchors      map[string]*node
    25  }
    26  
    27  // ----------------------------------------------------------------------------
    28  // Parser, produces a node tree out of a libyaml event stream.
    29  
    30  type parser struct {
    31  	parser yaml_parser_t
    32  	event  yaml_event_t
    33  	doc    *node
    34  }
    35  
    36  func newParser(b []byte) *parser {
    37  	p := parser{}
    38  	if !yaml_parser_initialize(&p.parser) {
    39  		panic("Failed to initialize YAML emitter")
    40  	}
    41  
    42  	if len(b) == 0 {
    43  		b = []byte{'\n'}
    44  	}
    45  
    46  	yaml_parser_set_input_string(&p.parser, b)
    47  
    48  	p.skip()
    49  	if p.event.typ != yaml_STREAM_START_EVENT {
    50  		panic("Expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
    51  	}
    52  	p.skip()
    53  	return &p
    54  }
    55  
    56  func (p *parser) destroy() {
    57  	if p.event.typ != yaml_NO_EVENT {
    58  		yaml_event_delete(&p.event)
    59  	}
    60  	yaml_parser_delete(&p.parser)
    61  }
    62  
    63  func (p *parser) skip() {
    64  	if p.event.typ != yaml_NO_EVENT {
    65  		if p.event.typ == yaml_STREAM_END_EVENT {
    66  			panic("Attempted to go past the end of stream. Corrupted value?")
    67  		}
    68  		yaml_event_delete(&p.event)
    69  	}
    70  	if !yaml_parser_parse(&p.parser, &p.event) {
    71  		p.fail()
    72  	}
    73  }
    74  
    75  func (p *parser) fail() {
    76  	var where string
    77  	var line int
    78  	if p.parser.problem_mark.line != 0 {
    79  		line = p.parser.problem_mark.line
    80  	} else if p.parser.context_mark.line != 0 {
    81  		line = p.parser.context_mark.line
    82  	}
    83  	if line != 0 {
    84  		where = "line " + strconv.Itoa(line) + ": "
    85  	}
    86  	var msg string
    87  	if len(p.parser.problem) > 0 {
    88  		msg = p.parser.problem
    89  	} else {
    90  		msg = "Unknown problem parsing YAML content"
    91  	}
    92  	panic(where + msg)
    93  }
    94  
    95  func (p *parser) anchor(n *node, anchor []byte) {
    96  	if anchor != nil {
    97  		p.doc.anchors[string(anchor)] = n
    98  	}
    99  }
   100  
   101  func (p *parser) parse() *node {
   102  	switch p.event.typ {
   103  	case yaml_SCALAR_EVENT:
   104  		return p.scalar()
   105  	case yaml_ALIAS_EVENT:
   106  		return p.alias()
   107  	case yaml_MAPPING_START_EVENT:
   108  		return p.mapping()
   109  	case yaml_SEQUENCE_START_EVENT:
   110  		return p.sequence()
   111  	case yaml_DOCUMENT_START_EVENT:
   112  		return p.document()
   113  	case yaml_STREAM_END_EVENT:
   114  		// Happens when attempting to decode an empty buffer.
   115  		return nil
   116  	default:
   117  		panic("Attempted to parse unknown event: " +
   118  			strconv.Itoa(int(p.event.typ)))
   119  	}
   120  	panic("Unreachable")
   121  }
   122  
   123  func (p *parser) node(kind int) *node {
   124  	return &node{
   125  		kind:   kind,
   126  		line:   p.event.start_mark.line,
   127  		column: p.event.start_mark.column,
   128  	}
   129  }
   130  
   131  func (p *parser) document() *node {
   132  	n := p.node(documentNode)
   133  	n.anchors = make(map[string]*node)
   134  	p.doc = n
   135  	p.skip()
   136  	n.children = append(n.children, p.parse())
   137  	if p.event.typ != yaml_DOCUMENT_END_EVENT {
   138  		panic("Expected end of document event but got " +
   139  			strconv.Itoa(int(p.event.typ)))
   140  	}
   141  	p.skip()
   142  	return n
   143  }
   144  
   145  func (p *parser) alias() *node {
   146  	n := p.node(aliasNode)
   147  	n.value = string(p.event.anchor)
   148  	p.skip()
   149  	return n
   150  }
   151  
   152  func (p *parser) scalar() *node {
   153  	n := p.node(scalarNode)
   154  	n.value = string(p.event.value)
   155  	n.tag = string(p.event.tag)
   156  	n.implicit = p.event.implicit
   157  	p.anchor(n, p.event.anchor)
   158  	p.skip()
   159  	return n
   160  }
   161  
   162  func (p *parser) sequence() *node {
   163  	n := p.node(sequenceNode)
   164  	p.anchor(n, p.event.anchor)
   165  	p.skip()
   166  	for p.event.typ != yaml_SEQUENCE_END_EVENT {
   167  		n.children = append(n.children, p.parse())
   168  	}
   169  	p.skip()
   170  	return n
   171  }
   172  
   173  func (p *parser) mapping() *node {
   174  	n := p.node(mappingNode)
   175  	p.anchor(n, p.event.anchor)
   176  	p.skip()
   177  	for p.event.typ != yaml_MAPPING_END_EVENT {
   178  		n.children = append(n.children, p.parse(), p.parse())
   179  	}
   180  	p.skip()
   181  	return n
   182  }
   183  
   184  // ----------------------------------------------------------------------------
   185  // Decoder, unmarshals a node into a provided value.
   186  
   187  type decoder struct {
   188  	doc     *node
   189  	aliases map[string]bool
   190  }
   191  
   192  func newDecoder() *decoder {
   193  	d := &decoder{}
   194  	d.aliases = make(map[string]bool)
   195  	return d
   196  }
   197  
   198  // d.setter deals with setters and pointer dereferencing and initialization.
   199  //
   200  // It's a slightly convoluted case to handle properly:
   201  //
   202  // - nil pointers should be initialized, unless being set to nil
   203  // - we don't know at this point yet what's the value to SetYAML() with.
   204  // - we can't separate pointer deref/init and setter checking, because
   205  //   a setter may be found while going down a pointer chain.
   206  //
   207  // Thus, here is how it takes care of it:
   208  //
   209  // - out is provided as a pointer, so that it can be replaced.
   210  // - when looking at a non-setter ptr, *out=ptr.Elem(), unless tag=!!null
   211  // - when a setter is found, *out=interface{}, and a set() function is
   212  //   returned to call SetYAML() with the value of *out once it's defined.
   213  //
   214  func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()) {
   215  	if (*out).Kind() != reflect.Ptr && (*out).CanAddr() {
   216  		setter, _ := (*out).Addr().Interface().(Setter)
   217  		if setter != nil {
   218  			var arg interface{}
   219  			*out = reflect.ValueOf(&arg).Elem()
   220  			return func() {
   221  				*good = setter.SetYAML(tag, arg)
   222  			}
   223  		}
   224  	}
   225  	again := true
   226  	for again {
   227  		again = false
   228  		setter, _ := (*out).Interface().(Setter)
   229  		if tag != "!!null" || setter != nil {
   230  			if pv := (*out); pv.Kind() == reflect.Ptr {
   231  				if pv.IsNil() {
   232  					*out = reflect.New(pv.Type().Elem()).Elem()
   233  					pv.Set((*out).Addr())
   234  				} else {
   235  					*out = pv.Elem()
   236  				}
   237  				setter, _ = pv.Interface().(Setter)
   238  				again = true
   239  			}
   240  		}
   241  		if setter != nil {
   242  			var arg interface{}
   243  			*out = reflect.ValueOf(&arg).Elem()
   244  			return func() {
   245  				*good = setter.SetYAML(tag, arg)
   246  			}
   247  		}
   248  	}
   249  	return nil
   250  }
   251  
   252  func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
   253  	switch n.kind {
   254  	case documentNode:
   255  		good = d.document(n, out)
   256  	case scalarNode:
   257  		good = d.scalar(n, out)
   258  	case aliasNode:
   259  		good = d.alias(n, out)
   260  	case mappingNode:
   261  		good = d.mapping(n, out)
   262  	case sequenceNode:
   263  		good = d.sequence(n, out)
   264  	default:
   265  		panic("Internal error: unknown node kind: " + strconv.Itoa(n.kind))
   266  	}
   267  	return
   268  }
   269  
   270  func (d *decoder) document(n *node, out reflect.Value) (good bool) {
   271  	if len(n.children) == 1 {
   272  		d.doc = n
   273  		d.unmarshal(n.children[0], out)
   274  		return true
   275  	}
   276  	return false
   277  }
   278  
   279  func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
   280  	an, ok := d.doc.anchors[n.value]
   281  	if !ok {
   282  		panic("Unknown anchor '" + n.value + "' referenced")
   283  	}
   284  	if d.aliases[n.value] {
   285  		panic("Anchor '" + n.value + "' value contains itself")
   286  	}
   287  	d.aliases[n.value] = true
   288  	good = d.unmarshal(an, out)
   289  	delete(d.aliases, n.value)
   290  	return good
   291  }
   292  
   293  var durationType = reflect.TypeOf(time.Duration(0))
   294  
   295  func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
   296  	var tag string
   297  	var resolved interface{}
   298  	if n.tag == "" && !n.implicit {
   299  		tag = "!!str"
   300  		resolved = n.value
   301  	} else {
   302  		tag, resolved = resolve(n.tag, n.value)
   303  	}
   304  	if set := d.setter(tag, &out, &good); set != nil {
   305  		defer set()
   306  	}
   307  	switch out.Kind() {
   308  	case reflect.String:
   309  		if resolved != nil {
   310  			out.SetString(n.value)
   311  			good = true
   312  		}
   313  	case reflect.Interface:
   314  		if resolved == nil {
   315  			out.Set(reflect.Zero(out.Type()))
   316  		} else {
   317  			out.Set(reflect.ValueOf(resolved))
   318  		}
   319  		good = true
   320  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   321  		switch resolved := resolved.(type) {
   322  		case int:
   323  			if !out.OverflowInt(int64(resolved)) {
   324  				out.SetInt(int64(resolved))
   325  				good = true
   326  			}
   327  		case int64:
   328  			if !out.OverflowInt(resolved) {
   329  				out.SetInt(resolved)
   330  				good = true
   331  			}
   332  		case float64:
   333  			if resolved < 1<<63-1 && !out.OverflowInt(int64(resolved)) {
   334  				out.SetInt(int64(resolved))
   335  				good = true
   336  			}
   337  		case string:
   338  			if out.Type() == durationType {
   339  				d, err := time.ParseDuration(resolved)
   340  				if err == nil {
   341  					out.SetInt(int64(d))
   342  					good = true
   343  				}
   344  			}
   345  		}
   346  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   347  		switch resolved := resolved.(type) {
   348  		case int:
   349  			if resolved >= 0 {
   350  				out.SetUint(uint64(resolved))
   351  				good = true
   352  			}
   353  		case int64:
   354  			if resolved >= 0 {
   355  				out.SetUint(uint64(resolved))
   356  				good = true
   357  			}
   358  		case float64:
   359  			if resolved < 1<<64-1 && !out.OverflowUint(uint64(resolved)) {
   360  				out.SetUint(uint64(resolved))
   361  				good = true
   362  			}
   363  		}
   364  	case reflect.Bool:
   365  		switch resolved := resolved.(type) {
   366  		case bool:
   367  			out.SetBool(resolved)
   368  			good = true
   369  		}
   370  	case reflect.Float32, reflect.Float64:
   371  		switch resolved := resolved.(type) {
   372  		case int:
   373  			out.SetFloat(float64(resolved))
   374  			good = true
   375  		case int64:
   376  			out.SetFloat(float64(resolved))
   377  			good = true
   378  		case float64:
   379  			out.SetFloat(resolved)
   380  			good = true
   381  		}
   382  	case reflect.Ptr:
   383  		switch resolved.(type) {
   384  		case nil:
   385  			out.Set(reflect.Zero(out.Type()))
   386  			good = true
   387  		default:
   388  			if out.Type().Elem() == reflect.TypeOf(resolved) {
   389  				elem := reflect.New(out.Type().Elem())
   390  				elem.Elem().Set(reflect.ValueOf(resolved))
   391  				out.Set(elem)
   392  				good = true
   393  			}
   394  		}
   395  	}
   396  	return good
   397  }
   398  
   399  func settableValueOf(i interface{}) reflect.Value {
   400  	v := reflect.ValueOf(i)
   401  	sv := reflect.New(v.Type()).Elem()
   402  	sv.Set(v)
   403  	return sv
   404  }
   405  
   406  func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
   407  	if set := d.setter("!!seq", &out, &good); set != nil {
   408  		defer set()
   409  	}
   410  	var iface reflect.Value
   411  	if out.Kind() == reflect.Interface {
   412  		// No type hints. Will have to use a generic sequence.
   413  		iface = out
   414  		out = settableValueOf(make([]interface{}, 0))
   415  	}
   416  
   417  	if out.Kind() != reflect.Slice {
   418  		return false
   419  	}
   420  	et := out.Type().Elem()
   421  
   422  	l := len(n.children)
   423  	for i := 0; i < l; i++ {
   424  		e := reflect.New(et).Elem()
   425  		if ok := d.unmarshal(n.children[i], e); ok {
   426  			out.Set(reflect.Append(out, e))
   427  		}
   428  	}
   429  	if iface.IsValid() {
   430  		iface.Set(out)
   431  	}
   432  	return true
   433  }
   434  
   435  func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
   436  	if set := d.setter("!!map", &out, &good); set != nil {
   437  		defer set()
   438  	}
   439  	if out.Kind() == reflect.Struct {
   440  		return d.mappingStruct(n, out)
   441  	}
   442  
   443  	if out.Kind() == reflect.Interface {
   444  		// No type hints. Will have to use a generic map.
   445  		iface := out
   446  		out = settableValueOf(make(map[interface{}]interface{}))
   447  		iface.Set(out)
   448  	}
   449  
   450  	if out.Kind() != reflect.Map {
   451  		return false
   452  	}
   453  	outt := out.Type()
   454  	kt := outt.Key()
   455  	et := outt.Elem()
   456  
   457  	if out.IsNil() {
   458  		out.Set(reflect.MakeMap(outt))
   459  	}
   460  	l := len(n.children)
   461  	for i := 0; i < l; i += 2 {
   462  		if isMerge(n.children[i]) {
   463  			d.merge(n.children[i+1], out)
   464  			continue
   465  		}
   466  		k := reflect.New(kt).Elem()
   467  		if d.unmarshal(n.children[i], k) {
   468  			e := reflect.New(et).Elem()
   469  			if d.unmarshal(n.children[i+1], e) {
   470  				out.SetMapIndex(k, e)
   471  			}
   472  		}
   473  	}
   474  	return true
   475  }
   476  
   477  func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
   478  	sinfo, err := getStructInfo(out.Type())
   479  	if err != nil {
   480  		panic(err)
   481  	}
   482  	name := settableValueOf("")
   483  	l := len(n.children)
   484  	for i := 0; i < l; i += 2 {
   485  		ni := n.children[i]
   486  		if isMerge(ni) {
   487  			d.merge(n.children[i+1], out)
   488  			continue
   489  		}
   490  		if !d.unmarshal(ni, name) {
   491  			continue
   492  		}
   493  		if info, ok := sinfo.FieldsMap[name.String()]; ok {
   494  			var field reflect.Value
   495  			if info.Inline == nil {
   496  				field = out.Field(info.Num)
   497  			} else {
   498  				field = out.FieldByIndex(info.Inline)
   499  			}
   500  			d.unmarshal(n.children[i+1], field)
   501  		}
   502  	}
   503  	return true
   504  }
   505  
   506  func (d *decoder) merge(n *node, out reflect.Value) {
   507  	const wantMap = "map merge requires map or sequence of maps as the value"
   508  	switch n.kind {
   509  	case mappingNode:
   510  		d.unmarshal(n, out)
   511  	case aliasNode:
   512  		an, ok := d.doc.anchors[n.value]
   513  		if ok && an.kind != mappingNode {
   514  			panic(wantMap)
   515  		}
   516  		d.unmarshal(n, out)
   517  	case sequenceNode:
   518  		// Step backwards as earlier nodes take precedence.
   519  		for i := len(n.children)-1; i >= 0; i-- {
   520  			ni := n.children[i]
   521  			if ni.kind == aliasNode {
   522  				an, ok := d.doc.anchors[ni.value]
   523  				if ok && an.kind != mappingNode {
   524  					panic(wantMap)
   525  				}
   526  			} else if ni.kind != mappingNode {
   527  				panic(wantMap)
   528  			}
   529  			d.unmarshal(ni, out)
   530  		}
   531  	default:
   532  		panic(wantMap)
   533  	}
   534  }
   535  
   536  func isMerge(n *node) bool {
   537  	return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == "!!merge" || n.tag == "tag:yaml.org,2002:merge")
   538  }