2017-05-20 02:33:14 +00:00
|
|
|
package json
|
|
|
|
|
|
|
|
import (
|
2018-02-17 18:26:58 +00:00
|
|
|
"fmt"
|
2017-05-20 02:33:14 +00:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type navigation struct {
|
2018-02-17 18:26:58 +00:00
|
|
|
root node
|
2017-05-20 02:33:14 +00:00
|
|
|
}
|
|
|
|
|
2018-01-27 18:51:26 +00:00
|
|
|
// Implementation of hcled.ContextString
|
2017-05-20 02:33:14 +00:00
|
|
|
func (n navigation) ContextString(offset int) string {
|
|
|
|
steps := navigationStepsRev(n.root, offset)
|
|
|
|
if steps == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// We built our slice backwards, so we'll reverse it in-place now.
|
|
|
|
half := len(steps) / 2 // integer division
|
|
|
|
for i := 0; i < half; i++ {
|
|
|
|
steps[i], steps[len(steps)-1-i] = steps[len(steps)-1-i], steps[i]
|
|
|
|
}
|
|
|
|
|
2018-02-17 18:26:58 +00:00
|
|
|
ret := strings.Join(steps, "")
|
|
|
|
if len(ret) > 0 && ret[0] == '.' {
|
|
|
|
ret = ret[1:]
|
|
|
|
}
|
|
|
|
return ret
|
2017-05-20 02:33:14 +00:00
|
|
|
}
|
|
|
|
|
2018-02-17 18:26:58 +00:00
|
|
|
func navigationStepsRev(v node, offset int) []string {
|
|
|
|
switch tv := v.(type) {
|
|
|
|
case *objectVal:
|
|
|
|
// Do any of our properties have an object that contains the target
|
|
|
|
// offset?
|
|
|
|
for _, attr := range tv.Attrs {
|
|
|
|
k := attr.Name
|
|
|
|
av := attr.Value
|
|
|
|
|
|
|
|
switch av.(type) {
|
|
|
|
case *objectVal, *arrayVal:
|
|
|
|
// okay
|
|
|
|
default:
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if av.Range().ContainsOffset(offset) {
|
|
|
|
return append(navigationStepsRev(av, offset), "."+k)
|
|
|
|
}
|
2017-05-20 02:33:14 +00:00
|
|
|
}
|
2018-02-17 18:26:58 +00:00
|
|
|
case *arrayVal:
|
|
|
|
// Do any of our elements contain the target offset?
|
|
|
|
for i, elem := range tv.Values {
|
2017-05-20 02:33:14 +00:00
|
|
|
|
2018-02-17 18:26:58 +00:00
|
|
|
switch elem.(type) {
|
|
|
|
case *objectVal, *arrayVal:
|
|
|
|
// okay
|
|
|
|
default:
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if elem.Range().ContainsOffset(offset) {
|
|
|
|
return append(navigationStepsRev(elem, offset), fmt.Sprintf("[%d]", i))
|
|
|
|
}
|
2017-05-20 02:33:14 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-17 18:26:58 +00:00
|
|
|
|
2017-05-20 02:33:14 +00:00
|
|
|
return nil
|
|
|
|
}
|