Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / github.com / !burnt!sushi / toml@v0.3.1 / decode.go
1 package toml
2
3 import (
4         "fmt"
5         "io"
6         "io/ioutil"
7         "math"
8         "reflect"
9         "strings"
10         "time"
11 )
12
13 func e(format string, args ...interface{}) error {
14         return fmt.Errorf("toml: "+format, args...)
15 }
16
17 // Unmarshaler is the interface implemented by objects that can unmarshal a
18 // TOML description of themselves.
19 type Unmarshaler interface {
20         UnmarshalTOML(interface{}) error
21 }
22
23 // Unmarshal decodes the contents of `p` in TOML format into a pointer `v`.
24 func Unmarshal(p []byte, v interface{}) error {
25         _, err := Decode(string(p), v)
26         return err
27 }
28
29 // Primitive is a TOML value that hasn't been decoded into a Go value.
30 // When using the various `Decode*` functions, the type `Primitive` may
31 // be given to any value, and its decoding will be delayed.
32 //
33 // A `Primitive` value can be decoded using the `PrimitiveDecode` function.
34 //
35 // The underlying representation of a `Primitive` value is subject to change.
36 // Do not rely on it.
37 //
38 // N.B. Primitive values are still parsed, so using them will only avoid
39 // the overhead of reflection. They can be useful when you don't know the
40 // exact type of TOML data until run time.
41 type Primitive struct {
42         undecoded interface{}
43         context   Key
44 }
45
46 // DEPRECATED!
47 //
48 // Use MetaData.PrimitiveDecode instead.
49 func PrimitiveDecode(primValue Primitive, v interface{}) error {
50         md := MetaData{decoded: make(map[string]bool)}
51         return md.unify(primValue.undecoded, rvalue(v))
52 }
53
54 // PrimitiveDecode is just like the other `Decode*` functions, except it
55 // decodes a TOML value that has already been parsed. Valid primitive values
56 // can *only* be obtained from values filled by the decoder functions,
57 // including this method. (i.e., `v` may contain more `Primitive`
58 // values.)
59 //
60 // Meta data for primitive values is included in the meta data returned by
61 // the `Decode*` functions with one exception: keys returned by the Undecoded
62 // method will only reflect keys that were decoded. Namely, any keys hidden
63 // behind a Primitive will be considered undecoded. Executing this method will
64 // update the undecoded keys in the meta data. (See the example.)
65 func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error {
66         md.context = primValue.context
67         defer func() { md.context = nil }()
68         return md.unify(primValue.undecoded, rvalue(v))
69 }
70
71 // Decode will decode the contents of `data` in TOML format into a pointer
72 // `v`.
73 //
74 // TOML hashes correspond to Go structs or maps. (Dealer's choice. They can be
75 // used interchangeably.)
76 //
77 // TOML arrays of tables correspond to either a slice of structs or a slice
78 // of maps.
79 //
80 // TOML datetimes correspond to Go `time.Time` values.
81 //
82 // All other TOML types (float, string, int, bool and array) correspond
83 // to the obvious Go types.
84 //
85 // An exception to the above rules is if a type implements the
86 // encoding.TextUnmarshaler interface. In this case, any primitive TOML value
87 // (floats, strings, integers, booleans and datetimes) will be converted to
88 // a byte string and given to the value's UnmarshalText method. See the
89 // Unmarshaler example for a demonstration with time duration strings.
90 //
91 // Key mapping
92 //
93 // TOML keys can map to either keys in a Go map or field names in a Go
94 // struct. The special `toml` struct tag may be used to map TOML keys to
95 // struct fields that don't match the key name exactly. (See the example.)
96 // A case insensitive match to struct names will be tried if an exact match
97 // can't be found.
98 //
99 // The mapping between TOML values and Go values is loose. That is, there
100 // may exist TOML values that cannot be placed into your representation, and
101 // there may be parts of your representation that do not correspond to
102 // TOML values. This loose mapping can be made stricter by using the IsDefined
103 // and/or Undecoded methods on the MetaData returned.
104 //
105 // This decoder will not handle cyclic types. If a cyclic type is passed,
106 // `Decode` will not terminate.
107 func Decode(data string, v interface{}) (MetaData, error) {
108         rv := reflect.ValueOf(v)
109         if rv.Kind() != reflect.Ptr {
110                 return MetaData{}, e("Decode of non-pointer %s", reflect.TypeOf(v))
111         }
112         if rv.IsNil() {
113                 return MetaData{}, e("Decode of nil %s", reflect.TypeOf(v))
114         }
115         p, err := parse(data)
116         if err != nil {
117                 return MetaData{}, err
118         }
119         md := MetaData{
120                 p.mapping, p.types, p.ordered,
121                 make(map[string]bool, len(p.ordered)), nil,
122         }
123         return md, md.unify(p.mapping, indirect(rv))
124 }
125
126 // DecodeFile is just like Decode, except it will automatically read the
127 // contents of the file at `fpath` and decode it for you.
128 func DecodeFile(fpath string, v interface{}) (MetaData, error) {
129         bs, err := ioutil.ReadFile(fpath)
130         if err != nil {
131                 return MetaData{}, err
132         }
133         return Decode(string(bs), v)
134 }
135
136 // DecodeReader is just like Decode, except it will consume all bytes
137 // from the reader and decode it for you.
138 func DecodeReader(r io.Reader, v interface{}) (MetaData, error) {
139         bs, err := ioutil.ReadAll(r)
140         if err != nil {
141                 return MetaData{}, err
142         }
143         return Decode(string(bs), v)
144 }
145
146 // unify performs a sort of type unification based on the structure of `rv`,
147 // which is the client representation.
148 //
149 // Any type mismatch produces an error. Finding a type that we don't know
150 // how to handle produces an unsupported type error.
151 func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
152
153         // Special case. Look for a `Primitive` value.
154         if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() {
155                 // Save the undecoded data and the key context into the primitive
156                 // value.
157                 context := make(Key, len(md.context))
158                 copy(context, md.context)
159                 rv.Set(reflect.ValueOf(Primitive{
160                         undecoded: data,
161                         context:   context,
162                 }))
163                 return nil
164         }
165
166         // Special case. Unmarshaler Interface support.
167         if rv.CanAddr() {
168                 if v, ok := rv.Addr().Interface().(Unmarshaler); ok {
169                         return v.UnmarshalTOML(data)
170                 }
171         }
172
173         // Special case. Handle time.Time values specifically.
174         // TODO: Remove this code when we decide to drop support for Go 1.1.
175         // This isn't necessary in Go 1.2 because time.Time satisfies the encoding
176         // interfaces.
177         if rv.Type().AssignableTo(rvalue(time.Time{}).Type()) {
178                 return md.unifyDatetime(data, rv)
179         }
180
181         // Special case. Look for a value satisfying the TextUnmarshaler interface.
182         if v, ok := rv.Interface().(TextUnmarshaler); ok {
183                 return md.unifyText(data, v)
184         }
185         // BUG(burntsushi)
186         // The behavior here is incorrect whenever a Go type satisfies the
187         // encoding.TextUnmarshaler interface but also corresponds to a TOML
188         // hash or array. In particular, the unmarshaler should only be applied
189         // to primitive TOML values. But at this point, it will be applied to
190         // all kinds of values and produce an incorrect error whenever those values
191         // are hashes or arrays (including arrays of tables).
192
193         k := rv.Kind()
194
195         // laziness
196         if k >= reflect.Int && k <= reflect.Uint64 {
197                 return md.unifyInt(data, rv)
198         }
199         switch k {
200         case reflect.Ptr:
201                 elem := reflect.New(rv.Type().Elem())
202                 err := md.unify(data, reflect.Indirect(elem))
203                 if err != nil {
204                         return err
205                 }
206                 rv.Set(elem)
207                 return nil
208         case reflect.Struct:
209                 return md.unifyStruct(data, rv)
210         case reflect.Map:
211                 return md.unifyMap(data, rv)
212         case reflect.Array:
213                 return md.unifyArray(data, rv)
214         case reflect.Slice:
215                 return md.unifySlice(data, rv)
216         case reflect.String:
217                 return md.unifyString(data, rv)
218         case reflect.Bool:
219                 return md.unifyBool(data, rv)
220         case reflect.Interface:
221                 // we only support empty interfaces.
222                 if rv.NumMethod() > 0 {
223                         return e("unsupported type %s", rv.Type())
224                 }
225                 return md.unifyAnything(data, rv)
226         case reflect.Float32:
227                 fallthrough
228         case reflect.Float64:
229                 return md.unifyFloat64(data, rv)
230         }
231         return e("unsupported type %s", rv.Kind())
232 }
233
234 func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
235         tmap, ok := mapping.(map[string]interface{})
236         if !ok {
237                 if mapping == nil {
238                         return nil
239                 }
240                 return e("type mismatch for %s: expected table but found %T",
241                         rv.Type().String(), mapping)
242         }
243
244         for key, datum := range tmap {
245                 var f *field
246                 fields := cachedTypeFields(rv.Type())
247                 for i := range fields {
248                         ff := &fields[i]
249                         if ff.name == key {
250                                 f = ff
251                                 break
252                         }
253                         if f == nil && strings.EqualFold(ff.name, key) {
254                                 f = ff
255                         }
256                 }
257                 if f != nil {
258                         subv := rv
259                         for _, i := range f.index {
260                                 subv = indirect(subv.Field(i))
261                         }
262                         if isUnifiable(subv) {
263                                 md.decoded[md.context.add(key).String()] = true
264                                 md.context = append(md.context, key)
265                                 if err := md.unify(datum, subv); err != nil {
266                                         return err
267                                 }
268                                 md.context = md.context[0 : len(md.context)-1]
269                         } else if f.name != "" {
270                                 // Bad user! No soup for you!
271                                 return e("cannot write unexported field %s.%s",
272                                         rv.Type().String(), f.name)
273                         }
274                 }
275         }
276         return nil
277 }
278
279 func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
280         tmap, ok := mapping.(map[string]interface{})
281         if !ok {
282                 if tmap == nil {
283                         return nil
284                 }
285                 return badtype("map", mapping)
286         }
287         if rv.IsNil() {
288                 rv.Set(reflect.MakeMap(rv.Type()))
289         }
290         for k, v := range tmap {
291                 md.decoded[md.context.add(k).String()] = true
292                 md.context = append(md.context, k)
293
294                 rvkey := indirect(reflect.New(rv.Type().Key()))
295                 rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
296                 if err := md.unify(v, rvval); err != nil {
297                         return err
298                 }
299                 md.context = md.context[0 : len(md.context)-1]
300
301                 rvkey.SetString(k)
302                 rv.SetMapIndex(rvkey, rvval)
303         }
304         return nil
305 }
306
307 func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
308         datav := reflect.ValueOf(data)
309         if datav.Kind() != reflect.Slice {
310                 if !datav.IsValid() {
311                         return nil
312                 }
313                 return badtype("slice", data)
314         }
315         sliceLen := datav.Len()
316         if sliceLen != rv.Len() {
317                 return e("expected array length %d; got TOML array of length %d",
318                         rv.Len(), sliceLen)
319         }
320         return md.unifySliceArray(datav, rv)
321 }
322
323 func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error {
324         datav := reflect.ValueOf(data)
325         if datav.Kind() != reflect.Slice {
326                 if !datav.IsValid() {
327                         return nil
328                 }
329                 return badtype("slice", data)
330         }
331         n := datav.Len()
332         if rv.IsNil() || rv.Cap() < n {
333                 rv.Set(reflect.MakeSlice(rv.Type(), n, n))
334         }
335         rv.SetLen(n)
336         return md.unifySliceArray(datav, rv)
337 }
338
339 func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
340         sliceLen := data.Len()
341         for i := 0; i < sliceLen; i++ {
342                 v := data.Index(i).Interface()
343                 sliceval := indirect(rv.Index(i))
344                 if err := md.unify(v, sliceval); err != nil {
345                         return err
346                 }
347         }
348         return nil
349 }
350
351 func (md *MetaData) unifyDatetime(data interface{}, rv reflect.Value) error {
352         if _, ok := data.(time.Time); ok {
353                 rv.Set(reflect.ValueOf(data))
354                 return nil
355         }
356         return badtype("time.Time", data)
357 }
358
359 func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
360         if s, ok := data.(string); ok {
361                 rv.SetString(s)
362                 return nil
363         }
364         return badtype("string", data)
365 }
366
367 func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
368         if num, ok := data.(float64); ok {
369                 switch rv.Kind() {
370                 case reflect.Float32:
371                         fallthrough
372                 case reflect.Float64:
373                         rv.SetFloat(num)
374                 default:
375                         panic("bug")
376                 }
377                 return nil
378         }
379         return badtype("float", data)
380 }
381
382 func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
383         if num, ok := data.(int64); ok {
384                 if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 {
385                         switch rv.Kind() {
386                         case reflect.Int, reflect.Int64:
387                                 // No bounds checking necessary.
388                         case reflect.Int8:
389                                 if num < math.MinInt8 || num > math.MaxInt8 {
390                                         return e("value %d is out of range for int8", num)
391                                 }
392                         case reflect.Int16:
393                                 if num < math.MinInt16 || num > math.MaxInt16 {
394                                         return e("value %d is out of range for int16", num)
395                                 }
396                         case reflect.Int32:
397                                 if num < math.MinInt32 || num > math.MaxInt32 {
398                                         return e("value %d is out of range for int32", num)
399                                 }
400                         }
401                         rv.SetInt(num)
402                 } else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 {
403                         unum := uint64(num)
404                         switch rv.Kind() {
405                         case reflect.Uint, reflect.Uint64:
406                                 // No bounds checking necessary.
407                         case reflect.Uint8:
408                                 if num < 0 || unum > math.MaxUint8 {
409                                         return e("value %d is out of range for uint8", num)
410                                 }
411                         case reflect.Uint16:
412                                 if num < 0 || unum > math.MaxUint16 {
413                                         return e("value %d is out of range for uint16", num)
414                                 }
415                         case reflect.Uint32:
416                                 if num < 0 || unum > math.MaxUint32 {
417                                         return e("value %d is out of range for uint32", num)
418                                 }
419                         }
420                         rv.SetUint(unum)
421                 } else {
422                         panic("unreachable")
423                 }
424                 return nil
425         }
426         return badtype("integer", data)
427 }
428
429 func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
430         if b, ok := data.(bool); ok {
431                 rv.SetBool(b)
432                 return nil
433         }
434         return badtype("boolean", data)
435 }
436
437 func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {
438         rv.Set(reflect.ValueOf(data))
439         return nil
440 }
441
442 func (md *MetaData) unifyText(data interface{}, v TextUnmarshaler) error {
443         var s string
444         switch sdata := data.(type) {
445         case TextMarshaler:
446                 text, err := sdata.MarshalText()
447                 if err != nil {
448                         return err
449                 }
450                 s = string(text)
451         case fmt.Stringer:
452                 s = sdata.String()
453         case string:
454                 s = sdata
455         case bool:
456                 s = fmt.Sprintf("%v", sdata)
457         case int64:
458                 s = fmt.Sprintf("%d", sdata)
459         case float64:
460                 s = fmt.Sprintf("%f", sdata)
461         default:
462                 return badtype("primitive (string-like)", data)
463         }
464         if err := v.UnmarshalText([]byte(s)); err != nil {
465                 return err
466         }
467         return nil
468 }
469
470 // rvalue returns a reflect.Value of `v`. All pointers are resolved.
471 func rvalue(v interface{}) reflect.Value {
472         return indirect(reflect.ValueOf(v))
473 }
474
475 // indirect returns the value pointed to by a pointer.
476 // Pointers are followed until the value is not a pointer.
477 // New values are allocated for each nil pointer.
478 //
479 // An exception to this rule is if the value satisfies an interface of
480 // interest to us (like encoding.TextUnmarshaler).
481 func indirect(v reflect.Value) reflect.Value {
482         if v.Kind() != reflect.Ptr {
483                 if v.CanSet() {
484                         pv := v.Addr()
485                         if _, ok := pv.Interface().(TextUnmarshaler); ok {
486                                 return pv
487                         }
488                 }
489                 return v
490         }
491         if v.IsNil() {
492                 v.Set(reflect.New(v.Type().Elem()))
493         }
494         return indirect(reflect.Indirect(v))
495 }
496
497 func isUnifiable(rv reflect.Value) bool {
498         if rv.CanSet() {
499                 return true
500         }
501         if _, ok := rv.Interface().(TextUnmarshaler); ok {
502                 return true
503         }
504         return false
505 }
506
507 func badtype(expected string, data interface{}) error {
508         return e("cannot load TOML value of type %T into a Go %s", data, expected)
509 }