aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/mitchellh/reflectwalk
diff options
context:
space:
mode:
authorJake Champlin <jake.champlin.27@gmail.com>2017-06-06 12:40:07 -0400
committerJake Champlin <jake.champlin.27@gmail.com>2017-06-06 12:40:07 -0400
commitbae9f6d2fd5eb5bc80929bd393932b23f14d7c93 (patch)
treeca9ab12a7d78b1fc27a8f734729081357ce6d252 /vendor/github.com/mitchellh/reflectwalk
parent254c495b6bebab3fb72a243c4bce858d79e6ee99 (diff)
downloadterraform-provider-statuscake-bae9f6d2fd5eb5bc80929bd393932b23f14d7c93.tar.gz
terraform-provider-statuscake-bae9f6d2fd5eb5bc80929bd393932b23f14d7c93.tar.zst
terraform-provider-statuscake-bae9f6d2fd5eb5bc80929bd393932b23f14d7c93.zip
Initial transfer of provider code
Diffstat (limited to 'vendor/github.com/mitchellh/reflectwalk')
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/LICENSE21
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/README.md6
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/location.go17
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/location_string.go16
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/reflectwalk.go339
5 files changed, 399 insertions, 0 deletions
diff --git a/vendor/github.com/mitchellh/reflectwalk/LICENSE b/vendor/github.com/mitchellh/reflectwalk/LICENSE
new file mode 100644
index 0000000..f9c841a
--- /dev/null
+++ b/vendor/github.com/mitchellh/reflectwalk/LICENSE
@@ -0,0 +1,21 @@
1The MIT License (MIT)
2
3Copyright (c) 2013 Mitchell Hashimoto
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/reflectwalk/README.md b/vendor/github.com/mitchellh/reflectwalk/README.md
new file mode 100644
index 0000000..ac82cd2
--- /dev/null
+++ b/vendor/github.com/mitchellh/reflectwalk/README.md
@@ -0,0 +1,6 @@
1# reflectwalk
2
3reflectwalk is a Go library for "walking" a value in Go using reflection,
4in the same way a directory tree can be "walked" on the filesystem. Walking
5a complex structure can allow you to do manipulations on unknown structures
6such as those decoded from JSON.
diff --git a/vendor/github.com/mitchellh/reflectwalk/location.go b/vendor/github.com/mitchellh/reflectwalk/location.go
new file mode 100644
index 0000000..7c59d76
--- /dev/null
+++ b/vendor/github.com/mitchellh/reflectwalk/location.go
@@ -0,0 +1,17 @@
1package reflectwalk
2
3//go:generate stringer -type=Location location.go
4
5type Location uint
6
7const (
8 None Location = iota
9 Map
10 MapKey
11 MapValue
12 Slice
13 SliceElem
14 Struct
15 StructField
16 WalkLoc
17)
diff --git a/vendor/github.com/mitchellh/reflectwalk/location_string.go b/vendor/github.com/mitchellh/reflectwalk/location_string.go
new file mode 100644
index 0000000..d3cfe85
--- /dev/null
+++ b/vendor/github.com/mitchellh/reflectwalk/location_string.go
@@ -0,0 +1,16 @@
1// generated by stringer -type=Location location.go; DO NOT EDIT
2
3package reflectwalk
4
5import "fmt"
6
7const _Location_name = "NoneMapMapKeyMapValueSliceSliceElemStructStructFieldWalkLoc"
8
9var _Location_index = [...]uint8{0, 4, 7, 13, 21, 26, 35, 41, 52, 59}
10
11func (i Location) String() string {
12 if i+1 >= Location(len(_Location_index)) {
13 return fmt.Sprintf("Location(%d)", i)
14 }
15 return _Location_name[_Location_index[i]:_Location_index[i+1]]
16}
diff --git a/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go
new file mode 100644
index 0000000..ec0a623
--- /dev/null
+++ b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go
@@ -0,0 +1,339 @@
1// reflectwalk is a package that allows you to "walk" complex structures
2// similar to how you may "walk" a filesystem: visiting every element one
3// by one and calling callback functions allowing you to handle and manipulate
4// those elements.
5package reflectwalk
6
7import (
8 "errors"
9 "reflect"
10)
11
12// PrimitiveWalker implementations are able to handle primitive values
13// within complex structures. Primitive values are numbers, strings,
14// booleans, funcs, chans.
15//
16// These primitive values are often members of more complex
17// structures (slices, maps, etc.) that are walkable by other interfaces.
18type PrimitiveWalker interface {
19 Primitive(reflect.Value) error
20}
21
22// InterfaceWalker implementations are able to handle interface values as they
23// are encountered during the walk.
24type InterfaceWalker interface {
25 Interface(reflect.Value) error
26}
27
28// MapWalker implementations are able to handle individual elements
29// found within a map structure.
30type MapWalker interface {
31 Map(m reflect.Value) error
32 MapElem(m, k, v reflect.Value) error
33}
34
35// SliceWalker implementations are able to handle slice elements found
36// within complex structures.
37type SliceWalker interface {
38 Slice(reflect.Value) error
39 SliceElem(int, reflect.Value) error
40}
41
42// StructWalker is an interface that has methods that are called for
43// structs when a Walk is done.
44type StructWalker interface {
45 Struct(reflect.Value) error
46 StructField(reflect.StructField, reflect.Value) error
47}
48
49// EnterExitWalker implementations are notified before and after
50// they walk deeper into complex structures (into struct fields,
51// into slice elements, etc.)
52type EnterExitWalker interface {
53 Enter(Location) error
54 Exit(Location) error
55}
56
57// PointerWalker implementations are notified when the value they're
58// walking is a pointer or not. Pointer is called for _every_ value whether
59// it is a pointer or not.
60type PointerWalker interface {
61 PointerEnter(bool) error
62 PointerExit(bool) error
63}
64
65// SkipEntry can be returned from walk functions to skip walking
66// the value of this field. This is only valid in the following functions:
67//
68// - StructField: skips walking the struct value
69//
70var SkipEntry = errors.New("skip this entry")
71
72// Walk takes an arbitrary value and an interface and traverses the
73// value, calling callbacks on the interface if they are supported.
74// The interface should implement one or more of the walker interfaces
75// in this package, such as PrimitiveWalker, StructWalker, etc.
76func Walk(data, walker interface{}) (err error) {
77 v := reflect.ValueOf(data)
78 ew, ok := walker.(EnterExitWalker)
79 if ok {
80 err = ew.Enter(WalkLoc)
81 }
82
83 if err == nil {
84 err = walk(v, walker)
85 }
86
87 if ok && err == nil {
88 err = ew.Exit(WalkLoc)
89 }
90
91 return
92}
93
94func walk(v reflect.Value, w interface{}) (err error) {
95 // Determine if we're receiving a pointer and if so notify the walker.
96 // The logic here is convoluted but very important (tests will fail if
97 // almost any part is changed). I will try to explain here.
98 //
99 // First, we check if the value is an interface, if so, we really need
100 // to check the interface's VALUE to see whether it is a pointer.
101 //
102 // Check whether the value is then a pointer. If so, then set pointer
103 // to true to notify the user.
104 //
105 // If we still have a pointer or an interface after the indirections, then
106 // we unwrap another level
107 //
108 // At this time, we also set "v" to be the dereferenced value. This is
109 // because once we've unwrapped the pointer we want to use that value.
110 pointer := false
111 pointerV := v
112
113 for {
114 if pointerV.Kind() == reflect.Interface {
115 if iw, ok := w.(InterfaceWalker); ok {
116 if err = iw.Interface(pointerV); err != nil {
117 return
118 }
119 }
120
121 pointerV = pointerV.Elem()
122 }
123
124 if pointerV.Kind() == reflect.Ptr {
125 pointer = true
126 v = reflect.Indirect(pointerV)
127 }
128 if pw, ok := w.(PointerWalker); ok {
129 if err = pw.PointerEnter(pointer); err != nil {
130 return
131 }
132
133 defer func(pointer bool) {
134 if err != nil {
135 return
136 }
137
138 err = pw.PointerExit(pointer)
139 }(pointer)
140 }
141
142 if pointer {
143 pointerV = v
144 }
145 pointer = false
146
147 // If we still have a pointer or interface we have to indirect another level.
148 switch pointerV.Kind() {
149 case reflect.Ptr, reflect.Interface:
150 continue
151 }
152 break
153 }
154
155 // We preserve the original value here because if it is an interface
156 // type, we want to pass that directly into the walkPrimitive, so that
157 // we can set it.
158 originalV := v
159 if v.Kind() == reflect.Interface {
160 v = v.Elem()
161 }
162
163 k := v.Kind()
164 if k >= reflect.Int && k <= reflect.Complex128 {
165 k = reflect.Int
166 }
167
168 switch k {
169 // Primitives
170 case reflect.Bool, reflect.Chan, reflect.Func, reflect.Int, reflect.String, reflect.Invalid:
171 err = walkPrimitive(originalV, w)
172 return
173 case reflect.Map:
174 err = walkMap(v, w)
175 return
176 case reflect.Slice:
177 err = walkSlice(v, w)
178 return
179 case reflect.Struct:
180 err = walkStruct(v, w)
181 return
182 default:
183 panic("unsupported type: " + k.String())
184 }
185}
186
187func walkMap(v reflect.Value, w interface{}) error {
188 ew, ewok := w.(EnterExitWalker)
189 if ewok {
190 ew.Enter(Map)
191 }
192
193 if mw, ok := w.(MapWalker); ok {
194 if err := mw.Map(v); err != nil {
195 return err
196 }
197 }
198
199 for _, k := range v.MapKeys() {
200 kv := v.MapIndex(k)
201
202 if mw, ok := w.(MapWalker); ok {
203 if err := mw.MapElem(v, k, kv); err != nil {
204 return err
205 }
206 }
207
208 ew, ok := w.(EnterExitWalker)
209 if ok {
210 ew.Enter(MapKey)
211 }
212
213 if err := walk(k, w); err != nil {
214 return err
215 }
216
217 if ok {
218 ew.Exit(MapKey)
219 ew.Enter(MapValue)
220 }
221
222 if err := walk(kv, w); err != nil {
223 return err
224 }
225
226 if ok {
227 ew.Exit(MapValue)
228 }
229 }
230
231 if ewok {
232 ew.Exit(Map)
233 }
234
235 return nil
236}
237
238func walkPrimitive(v reflect.Value, w interface{}) error {
239 if pw, ok := w.(PrimitiveWalker); ok {
240 return pw.Primitive(v)
241 }
242
243 return nil
244}
245
246func walkSlice(v reflect.Value, w interface{}) (err error) {
247 ew, ok := w.(EnterExitWalker)
248 if ok {
249 ew.Enter(Slice)
250 }
251
252 if sw, ok := w.(SliceWalker); ok {
253 if err := sw.Slice(v); err != nil {
254 return err
255 }
256 }
257
258 for i := 0; i < v.Len(); i++ {
259 elem := v.Index(i)
260
261 if sw, ok := w.(SliceWalker); ok {
262 if err := sw.SliceElem(i, elem); err != nil {
263 return err
264 }
265 }
266
267 ew, ok := w.(EnterExitWalker)
268 if ok {
269 ew.Enter(SliceElem)
270 }
271
272 if err := walk(elem, w); err != nil {
273 return err
274 }
275
276 if ok {
277 ew.Exit(SliceElem)
278 }
279 }
280
281 ew, ok = w.(EnterExitWalker)
282 if ok {
283 ew.Exit(Slice)
284 }
285
286 return nil
287}
288
289func walkStruct(v reflect.Value, w interface{}) (err error) {
290 ew, ewok := w.(EnterExitWalker)
291 if ewok {
292 ew.Enter(Struct)
293 }
294
295 if sw, ok := w.(StructWalker); ok {
296 if err = sw.Struct(v); err != nil {
297 return
298 }
299 }
300
301 vt := v.Type()
302 for i := 0; i < vt.NumField(); i++ {
303 sf := vt.Field(i)
304 f := v.FieldByIndex([]int{i})
305
306 if sw, ok := w.(StructWalker); ok {
307 err = sw.StructField(sf, f)
308
309 // SkipEntry just pretends this field doesn't even exist
310 if err == SkipEntry {
311 continue
312 }
313
314 if err != nil {
315 return
316 }
317 }
318
319 ew, ok := w.(EnterExitWalker)
320 if ok {
321 ew.Enter(StructField)
322 }
323
324 err = walk(f, w)
325 if err != nil {
326 return
327 }
328
329 if ok {
330 ew.Exit(StructField)
331 }
332 }
333
334 if ewok {
335 ew.Exit(Struct)
336 }
337
338 return nil
339}