diff options
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hcl/json/navigation.go')
-rw-r--r-- | vendor/github.com/hashicorp/hcl2/hcl/json/navigation.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hcl/json/navigation.go b/vendor/github.com/hashicorp/hcl2/hcl/json/navigation.go new file mode 100644 index 0000000..bc8a97f --- /dev/null +++ b/vendor/github.com/hashicorp/hcl2/hcl/json/navigation.go | |||
@@ -0,0 +1,70 @@ | |||
1 | package json | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "strings" | ||
6 | ) | ||
7 | |||
8 | type navigation struct { | ||
9 | root node | ||
10 | } | ||
11 | |||
12 | // Implementation of hcled.ContextString | ||
13 | func (n navigation) ContextString(offset int) string { | ||
14 | steps := navigationStepsRev(n.root, offset) | ||
15 | if steps == nil { | ||
16 | return "" | ||
17 | } | ||
18 | |||
19 | // We built our slice backwards, so we'll reverse it in-place now. | ||
20 | half := len(steps) / 2 // integer division | ||
21 | for i := 0; i < half; i++ { | ||
22 | steps[i], steps[len(steps)-1-i] = steps[len(steps)-1-i], steps[i] | ||
23 | } | ||
24 | |||
25 | ret := strings.Join(steps, "") | ||
26 | if len(ret) > 0 && ret[0] == '.' { | ||
27 | ret = ret[1:] | ||
28 | } | ||
29 | return ret | ||
30 | } | ||
31 | |||
32 | func navigationStepsRev(v node, offset int) []string { | ||
33 | switch tv := v.(type) { | ||
34 | case *objectVal: | ||
35 | // Do any of our properties have an object that contains the target | ||
36 | // offset? | ||
37 | for _, attr := range tv.Attrs { | ||
38 | k := attr.Name | ||
39 | av := attr.Value | ||
40 | |||
41 | switch av.(type) { | ||
42 | case *objectVal, *arrayVal: | ||
43 | // okay | ||
44 | default: | ||
45 | continue | ||
46 | } | ||
47 | |||
48 | if av.Range().ContainsOffset(offset) { | ||
49 | return append(navigationStepsRev(av, offset), "."+k) | ||
50 | } | ||
51 | } | ||
52 | case *arrayVal: | ||
53 | // Do any of our elements contain the target offset? | ||
54 | for i, elem := range tv.Values { | ||
55 | |||
56 | switch elem.(type) { | ||
57 | case *objectVal, *arrayVal: | ||
58 | // okay | ||
59 | default: | ||
60 | continue | ||
61 | } | ||
62 | |||
63 | if elem.Range().ContainsOffset(offset) { | ||
64 | return append(navigationStepsRev(elem, offset), fmt.Sprintf("[%d]", i)) | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | return nil | ||
70 | } | ||