Files
ConfigKit/internal/engine/document_lookup.go

55 lines
1.3 KiB
Go

package engine
import "gitea.maximumdirect.net/eric/ConfigKit/internal/document"
// documentLookup contains read-only mapping positions for a completed document.
type documentLookup struct {
byNode map[*document.Node]map[string]int
}
func buildDocumentLookup(roots ...*document.Node) *documentLookup {
lookup := &documentLookup{byNode: make(map[*document.Node]map[string]int)}
visited := make(map[*document.Node]struct{})
var visit func(*document.Node)
visit = func(node *document.Node) {
if node == nil {
return
}
if _, ok := visited[node]; ok {
return
}
visited[node] = struct{}{}
switch node.Kind {
case document.Mapping:
entries := make(map[string]int, len(node.Mapping))
for index, entry := range node.Mapping {
if _, exists := entries[entry.Key]; !exists {
entries[entry.Key] = index
}
visit(entry.Value)
}
lookup.byNode[node] = entries
case document.Sequence:
for _, child := range node.Sequence {
visit(child)
}
}
}
for _, root := range roots {
visit(root)
}
return lookup
}
func (lookup *documentLookup) find(node *document.Node, key string) int {
if lookup == nil {
return -1
}
if entries := lookup.byNode[node]; entries != nil {
if index, ok := entries[key]; ok {
return index
}
}
return -1
}