diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go index 349d38d61..8122bfb77 100644 --- a/vendor/github.com/mitchellh/copystructure/copystructure.go +++ b/vendor/github.com/mitchellh/copystructure/copystructure.go @@ -28,6 +28,18 @@ type CopierFunc func(interface{}) (interface{}, error) // this map as well as to Copy in a mutex. var Copiers map[reflect.Type]CopierFunc = make(map[reflect.Type]CopierFunc) +// Must is a helper that wraps a call to a function returning +// (interface{}, error) and panics if the error is non-nil. It is intended +// for use in variable initializations and should only be used when a copy +// error should be a crashing case. +func Must(v interface{}, err error) interface{} { + if err != nil { + panic("copy error: " + err.Error()) + } + + return v +} + var errPointerRequired = errors.New("Copy argument must be a pointer when Lock is true") type Config struct { @@ -77,7 +89,7 @@ type walker struct { ignoreDepth int vals []reflect.Value cs []reflect.Value - ps []bool + ps []int // any locks we've taken, indexed by depth locks []sync.Locker @@ -93,6 +105,10 @@ func (w *walker) Enter(l reflectwalk.Location) error { w.locks = append(w.locks, nil) } + for len(w.ps) < w.depth+1 { + w.ps = append(w.ps, 0) + } + return nil } @@ -103,6 +119,7 @@ func (w *walker) Exit(l reflectwalk.Location) error { defer locker.Unlock() } + w.ps[w.depth] = 0 w.depth-- if w.ignoreDepth > w.depth { w.ignoreDepth = 0 @@ -154,6 +171,7 @@ func (w *walker) Exit(l reflectwalk.Location) error { if v.IsValid() { s := w.cs[len(w.cs)-1] sf := reflect.Indirect(s).FieldByName(f.Name) + if sf.CanSet() { sf.Set(v) } @@ -191,20 +209,16 @@ func (w *walker) MapElem(m, k, v reflect.Value) error { } func (w *walker) PointerEnter(v bool) error { - if w.ignoring() { - return nil + if v { + w.ps[w.depth]++ } - - w.ps = append(w.ps, v) return nil } -func (w *walker) PointerExit(bool) error { - if w.ignoring() { - return nil +func (w *walker) PointerExit(v bool) error { + if v { + w.ps[w.depth]-- } - - w.ps = w.ps[:len(w.ps)-1] return nil } @@ -219,7 +233,7 @@ func (w *walker) Primitive(v reflect.Value) error { var newV reflect.Value if v.IsValid() && v.CanInterface() { newV = reflect.New(v.Type()) - reflect.Indirect(newV).Set(v) + newV.Elem().Set(v) } w.valPush(newV) @@ -318,7 +332,7 @@ func (w *walker) ignoring() bool { } func (w *walker) pointerPeek() bool { - return w.ps[len(w.ps)-1] + return w.ps[w.depth] > 0 } func (w *walker) valPop() reflect.Value { @@ -350,7 +364,17 @@ func (w *walker) replacePointerMaybe() { // we need to push that onto the stack. if !w.pointerPeek() { w.valPush(reflect.Indirect(w.valPop())) + return } + + v := w.valPop() + for i := 1; i < w.ps[w.depth]; i++ { + p := reflect.New(v.Type()) + p.Elem().Set(v) + v = p + } + + w.valPush(v) } // if this value is a Locker, lock it and add it to the locks slice diff --git a/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go index ecce023e1..3a6da9737 100644 --- a/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go +++ b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go @@ -81,35 +81,52 @@ func walk(v reflect.Value, w interface{}) (err error) { // almost any part is changed). I will try to explain here. // // First, we check if the value is an interface, if so, we really need - // to check the interface's VALUE to see whether it is a pointer (pointers - // to interfaces are not allowed). + // to check the interface's VALUE to see whether it is a pointer. // - // Check whether the value is then an interface. If so, then set pointer + // Check whether the value is then a pointer. If so, then set pointer // to true to notify the user. // + // If we still have a pointer or an interface after the indirections, then + // we unwrap another level + // // At this time, we also set "v" to be the dereferenced value. This is // because once we've unwrapped the pointer we want to use that value. pointer := false pointerV := v - if pointerV.Kind() == reflect.Interface { - pointerV = pointerV.Elem() - } - if pointerV.Kind() == reflect.Ptr { - pointer = true - v = reflect.Indirect(pointerV) - } - if pw, ok := w.(PointerWalker); ok { - if err = pw.PointerEnter(pointer); err != nil { - return - } - defer func() { - if err != nil { + for { + if pointerV.Kind() == reflect.Interface { + pointerV = pointerV.Elem() + } + if pointerV.Kind() == reflect.Ptr { + pointer = true + v = reflect.Indirect(pointerV) + } + if pw, ok := w.(PointerWalker); ok { + if err = pw.PointerEnter(pointer); err != nil { return } - err = pw.PointerExit(pointer) - }() + defer func(pointer bool) { + if err != nil { + return + } + + err = pw.PointerExit(pointer) + }(pointer) + } + + if pointer { + pointerV = v + } + pointer = false + + // If we still have a pointer or interface we have to indirect another level. + switch pointerV.Kind() { + case reflect.Ptr, reflect.Interface: + continue + } + break } // We preserve the original value here because if it is an interface diff --git a/vendor/vendor.json b/vendor/vendor.json index d315bcbcc..c5871e5c7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1464,10 +1464,10 @@ "revision": "8631ce90f28644f54aeedcb3e389a85174e067d1" }, { - "checksumSHA1": "EDAtec3XSbTjw6gWG+NNScows9M=", + "checksumSHA1": "gsIaLhXE/YZahSg33edGHvzVQ1o=", "path": "github.com/mitchellh/copystructure", - "revision": "49a4444999946bce1882f9db0eb3ba0a44ed1fbb", - "revisionTime": "2016-09-28T02:49:35Z" + "revision": "c740739b7b69de009385f52933769c1c037705df", + "revisionTime": "2016-10-03T06:35:14Z" }, { "path": "github.com/mitchellh/go-homedir", @@ -1499,10 +1499,10 @@ "revision": "6e6954073784f7ee67b28f2d22749d6479151ed7" }, { - "checksumSHA1": "kXh6sdGViiRK0REpIWydJvpsyY0=", + "checksumSHA1": "u+sHUhd/XXvjiVPAJ/h8yvLbSj4=", "path": "github.com/mitchellh/reflectwalk", - "revision": "0c9480f65513be815a88d6076a3d8d95d4274236", - "revisionTime": "2016-09-28T02:49:03Z" + "revision": "4a18c295388e8482403483c88469392f9e6556d7", + "revisionTime": "2016-10-02T04:32:56Z" }, { "checksumSHA1": "/iig5lYSPCL3C8J7e4nTAevYNDE=",