Prepare collection policy transport through inheritance

This commit is contained in:
2026-10-23 20:04:06 +00:00
parent 80d8c1dc82
commit 9e75496664
8 changed files with 282 additions and 46 deletions

View File

@@ -7,14 +7,15 @@ import (
)
type inheritanceTemplate struct {
name string
entry document.Entry
path Path
parent int
hasParent bool
hasDirective bool
cancelled bool
directive document.Entry
name string
entry document.Entry
path Path
collectionPolicies collectionPolicyScope
parent int
hasParent bool
hasDirective bool
cancelled bool
directive document.Entry
}
type inheritanceGraph struct {
@@ -29,6 +30,10 @@ type inheritanceGraph struct {
// It validates declarations separately from applying their templates, leaving
// nested scopes for the existing destination-local walk.
func analyzeInheritanceGraph(scope *document.Node, scopePath Path) (*inheritanceGraph, []Diagnostic) {
return analyzeInheritanceGraphWithPolicies(scope, scopePath, collectionPolicyScope{})
}
func analyzeInheritanceGraphWithPolicies(scope *document.Node, scopePath Path, policies collectionPolicyScope) (*inheritanceGraph, []Diagnostic) {
if scope == nil || scope.Kind != document.Mapping {
return nil, []Diagnostic{{
Code: CodeInheritanceInvalid, Severity: SeverityError, Path: scopePath,
@@ -57,6 +62,7 @@ func analyzeInheritanceGraph(scope *document.Node, scopePath Path) (*inheritance
graph.byName[name] = index
graph.nodes = append(graph.nodes, inheritanceTemplate{
name: name, entry: entries[name], path: scopePath.Key(name),
collectionPolicies: inheritancePolicyScopeAtPath(policies, scopePath.Key(name)),
})
}
@@ -115,7 +121,11 @@ func (graph *inheritanceGraph) schedule() ([]int, []Diagnostic) {
}
func expandSiblingDefinitionsWithOrigins(scope *document.Node, scopePath Path, limits projectionLimits, inputOrigins map[string]Origin, budget ...*retainedNodeCounter) (*inheritanceScope, []Diagnostic) {
graph, diagnostics := analyzeInheritanceGraph(scope, scopePath)
return expandSiblingDefinitionsWithPolicies(scope, scopePath, limits, inputOrigins, collectionPolicyScope{}, budget...)
}
func expandSiblingDefinitionsWithPolicies(scope *document.Node, scopePath Path, limits projectionLimits, inputOrigins map[string]Origin, policies collectionPolicyScope, budget ...*retainedNodeCounter) (*inheritanceScope, []Diagnostic) {
graph, diagnostics := analyzeInheritanceGraphWithPolicies(scope, scopePath, policies)
if len(diagnostics) != 0 {
return nil, diagnostics
}
@@ -123,7 +133,12 @@ func expandSiblingDefinitionsWithOrigins(scope *document.Node, scopePath Path, l
if len(diagnostics) != 0 {
return nil, diagnostics
}
return applyInheritanceTemplates(graph, order, limits, inputOrigins, budget...)
result, diagnostics := applyInheritanceTemplates(graph, order, limits, inputOrigins, budget...)
if len(diagnostics) != 0 {
return nil, diagnostics
}
result.collectionPolicies = cloneCollectionPolicyScopeForInheritance(policies)
return result, nil
}
// applyInheritanceTemplates builds detached templates in the supplied
@@ -132,6 +147,7 @@ func expandSiblingDefinitionsWithOrigins(scope *document.Node, scopePath Path, l
func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits projectionLimits, inputOrigins map[string]Origin, budget ...*retainedNodeCounter) (*inheritanceScope, []Diagnostic) {
resolved := make([]*document.Node, len(graph.nodes))
resolvedOrigins := make([]map[string]Origin, len(graph.nodes))
resolvedPolicyTemplates := make([][]collectionPolicyScope, len(graph.nodes))
result := &inheritanceScope{}
counter := newRetainedNodeCounter(historyNodeLimit)
if len(budget) != 0 {
@@ -155,6 +171,7 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
for _, index := range order {
node := graph.nodes[index]
templatePolicies := cloneCollectionPolicyScopeForInheritance(node.collectionPolicies)
payload := withoutInheritanceDirective(node.entry.Value)
operationStart, replacementStart := len(result.operations), len(result.replacements)
childOrigins := directInheritanceOrigins(payload, node.path, inputOrigins)
@@ -183,11 +200,15 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
if node.hasParent {
parent := resolved[node.parent]
parentPolicies := cloneInheritancePolicyTemplates(resolvedPolicyTemplates[node.parent])
effectivePolicies := append(cloneInheritancePolicyTemplates(parentPolicies), cloneCollectionPolicyScopeForInheritance(templatePolicies))
merged := document.Clone(parent)
transfer := inheritanceTransfer{
from: graph.nodes[node.parent].path, to: node.path,
reference: node.path.Key(inheritanceKey),
locations: []Location{publicLocation(node.directive.Value.Location)},
reference: node.path.Key(inheritanceKey),
locations: []Location{publicLocation(node.directive.Value.Location)},
policyTemplates: parentPolicies, templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
projectedPolicies: projectInheritancePolicyTemplates(parentPolicies, node.path),
}
mergedOrigins := transferredInheritanceOrigins(resolvedOrigins[node.parent], transfer.from, node.path, transfer)
mergeInheritanceOrigin(mergedOrigins, node.path, childOrigins[node.path.String()])
@@ -214,10 +235,15 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
result.operations = append(result.operations, inheritanceOperation{
transfer: &transfer, parent: parent, effective: merged,
parentOrigins: resolvedOrigins[node.parent], effectiveOrigins: mergedOrigins,
parentPolicies: cloneInheritancePolicyTemplates(parentPolicies),
templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
effectivePolicies: cloneInheritancePolicyTemplates(effectivePolicies),
})
resolvedPolicyTemplates[index] = effectivePolicies
} else {
resolved[index] = document.Clone(payload)
resolvedOrigins[index] = childOrigins
resolvedPolicyTemplates[index] = []collectionPolicyScope{templatePolicies}
}
count, _ := inheritanceLowerBoundCount(resolved[index], limits.nodes)