databricks-cli/bundle/schema/tracker.go

58 lines
1.4 KiB
Go
Raw Normal View History

package schema
import (
"container/list"
"fmt"
"reflect"
)
type tracker struct {
2023-01-19 17:58:31 +00:00
// Types encountered in current path during the recursive traversal. Used to
// check for cycles
seenTypes map[reflect.Type]struct{}
2023-01-19 17:58:31 +00:00
// List of field names encountered in current path during the recursive traversal.
// Used to hydrate errors with path to the exact node where error occured.
//
// The field names here are the first tag in the json tags of struct field.
debugTrace *list.List
}
func newTracker() *tracker {
return &tracker{
seenTypes: map[reflect.Type]struct{}{},
debugTrace: list.New(),
}
}
func (t *tracker) errWithTrace(prefix string) error {
traceString := "root"
curr := t.debugTrace.Front()
for curr != nil {
if curr.Value.(string) != "" {
traceString += " -> " + curr.Value.(string)
}
curr = curr.Next()
}
return fmt.Errorf("[ERROR] " + prefix + ". traversal trace: " + traceString)
}
func (t *tracker) hasCycle(golangType reflect.Type) bool {
_, ok := t.seenTypes[golangType]
if ok {
fmt.Println("[DEBUG] traceSet for cycle: ", t.seenTypes)
}
return ok
}
func (t *tracker) step(nodeType reflect.Type, jsonName string) {
t.seenTypes[nodeType] = struct{}{}
t.debugTrace.PushBack(jsonName)
}
func (t *tracker) undoStep(nodeType reflect.Type) {
back := t.debugTrace.Back()
t.debugTrace.Remove(back)
delete(t.seenTypes, nodeType)
}