Prepare reusable inheritance scope execution
This commit is contained in:
@@ -155,40 +155,45 @@ func expandSiblingDefinitionsWithCollectionRules(scope *document.Node, scopePath
|
||||
// dependency-ready order while retaining the existing origins, merge history,
|
||||
// and node-accounting evidence. The root keeps its authored mapping order.
|
||||
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))
|
||||
resolvedPolicies := make([]collectionPolicyScope, len(graph.nodes))
|
||||
return applyInheritanceScopeTemplates(mappingInheritanceScope{graph: graph}, order, limits, inputOrigins, budget...)
|
||||
}
|
||||
|
||||
func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int, limits projectionLimits, inputOrigins map[string]Origin, budget ...*retainedNodeCounter) (*inheritanceScope, []Diagnostic) {
|
||||
templates := adapter.templates()
|
||||
resolved := make([]*document.Node, len(templates))
|
||||
resolvedOrigins := make([]map[string]Origin, len(templates))
|
||||
resolvedPolicyTemplates := make([][]collectionPolicyScope, len(templates))
|
||||
resolvedPolicies := make([]collectionPolicyScope, len(templates))
|
||||
result := &inheritanceScope{}
|
||||
counter := newRetainedNodeCounter(historyNodeLimit)
|
||||
if len(budget) != 0 {
|
||||
counter = budget[0]
|
||||
}
|
||||
retained := 1 // scope mapping node
|
||||
for _, entry := range graph.scope.Mapping {
|
||||
if entry.Value.Kind == document.Mapping {
|
||||
retained := 1 // scope container node
|
||||
for _, slot := range adapter.slots() {
|
||||
if slot.hasTemplate || slot.value.Kind == document.Mapping {
|
||||
continue
|
||||
}
|
||||
remaining := limits.nodes - retained - 1
|
||||
if limits.nodes >= 0 && remaining < 0 {
|
||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(graph.scopePath.Key(entry.Key), entry.Value.Location)}
|
||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(slot.path, slot.value.Location)}
|
||||
}
|
||||
count, within := inheritanceLowerBoundCount(entry.Value, remaining)
|
||||
count, within := inheritanceLowerBoundCount(slot.value, remaining)
|
||||
if !within {
|
||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(graph.scopePath.Key(entry.Key), entry.Value.Location)}
|
||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(slot.path, slot.value.Location)}
|
||||
}
|
||||
retained += 1 + count
|
||||
}
|
||||
|
||||
for _, index := range order {
|
||||
node := graph.nodes[index]
|
||||
node := templates[index]
|
||||
templatePolicies := cloneCollectionPolicyScopeForInheritance(node.collectionPolicies)
|
||||
payload := withoutInheritanceDirective(node.entry.Value)
|
||||
operationStart, replacementStart := len(result.operations), len(result.replacements)
|
||||
childOrigins := directInheritanceOrigins(payload, node.path, inputOrigins)
|
||||
if node.hasDirective {
|
||||
control := inheritanceControl{
|
||||
path: node.path.Key(inheritanceKey),
|
||||
path: node.directivePath,
|
||||
locations: []Location{publicLocation(node.directive.Value.Location)},
|
||||
cancelled: node.cancelled,
|
||||
}
|
||||
@@ -199,7 +204,7 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
|
||||
})
|
||||
}
|
||||
if limits.nodes >= 0 {
|
||||
remaining := limits.nodes - retained - 1 // the sibling key
|
||||
remaining := limits.nodes - retained - adapter.slotOverhead()
|
||||
within := inheritanceLowerBoundWithin(payload, remaining)
|
||||
if node.hasParent {
|
||||
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], payload, remaining)
|
||||
@@ -217,14 +222,14 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
|
||||
childPolicyScope := projectCurrentInheritanceCollectionPolicies(templatePolicies, node.path)
|
||||
merged := document.Clone(parent)
|
||||
mergedPolicyScope, policyDiagnostics := mergeInheritanceCollectionPolicies(
|
||||
parentPolicyScope, childPolicyScope, node.path, parent, graph.applicationPolicy,
|
||||
parentPolicyScope, childPolicyScope, node.path, parent, adapter.applicationPolicy(),
|
||||
)
|
||||
if len(policyDiagnostics) != 0 {
|
||||
return nil, policyDiagnostics
|
||||
}
|
||||
transfer := inheritanceTransfer{
|
||||
from: graph.nodes[node.parent].path, to: node.path,
|
||||
reference: node.path.Key(inheritanceKey),
|
||||
from: templates[node.parent].path, to: node.path,
|
||||
reference: node.directivePath,
|
||||
locations: []Location{publicLocation(node.directive.Value.Location)},
|
||||
policyTemplates: parentPolicies, templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
|
||||
projectedPolicies: projectInheritancePolicyTemplates(
|
||||
@@ -253,7 +258,7 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
|
||||
},
|
||||
merge: func(childPath Path, existing, incoming *document.Node) (*document.Node, bool) {
|
||||
resolution, _, _, active, issues := inheritanceCollectionResolution(
|
||||
childPath, parentPolicyScope, childPolicyScope, graph.applicationPolicy,
|
||||
childPath, parentPolicyScope, childPolicyScope, adapter.applicationPolicy(),
|
||||
)
|
||||
if len(issues) != 0 {
|
||||
combinationDiagnostics = append(combinationDiagnostics, issues...)
|
||||
@@ -293,10 +298,11 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
|
||||
return combined.value, true
|
||||
},
|
||||
})
|
||||
preserveInheritanceIdentityFields(merged, payload, node.identityFields)
|
||||
if len(combinationDiagnostics) != 0 {
|
||||
return nil, canonicalDiagnostics(combinationDiagnostics)
|
||||
}
|
||||
if problems := validateRegisteredInheritanceSequences(merged, node.path, graph.applicationPolicy); len(problems) != 0 {
|
||||
if problems := validateRegisteredInheritanceSequences(merged, node.path, adapter.applicationPolicy()); len(problems) != 0 {
|
||||
return nil, problems
|
||||
}
|
||||
merged.Location = node.entry.Value.Location
|
||||
@@ -320,7 +326,7 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
|
||||
}
|
||||
|
||||
count, _ := inheritanceLowerBoundCount(resolved[index], limits.nodes)
|
||||
retained += 1 + count
|
||||
retained += adapter.slotOverhead() + count
|
||||
for _, operation := range result.operations[operationStart:] {
|
||||
if !counter.add(operation.parent) || !counter.add(operation.effective) {
|
||||
return nil, []Diagnostic{inheritanceHistoryBudgetDiagnostic(node.path, node.entry.Value.Location)}
|
||||
@@ -333,30 +339,27 @@ func applyInheritanceTemplates(graph *inheritanceGraph, order []int, limits proj
|
||||
}
|
||||
}
|
||||
|
||||
root := *graph.scope
|
||||
root.Mapping = make([]document.Entry, len(graph.scope.Mapping))
|
||||
root := adapter.rebuild(resolved)
|
||||
result.collectionPolicies = collectionPolicyScope{}
|
||||
result.origins = directInheritanceOrigins(&document.Node{Kind: document.Mapping, Location: graph.scope.Location}, graph.scopePath, inputOrigins)
|
||||
for i, entry := range graph.scope.Mapping {
|
||||
root.Mapping[i] = entry
|
||||
if index, found := graph.byName[entry.Key]; found {
|
||||
root.Mapping[i].Value = resolved[index]
|
||||
projectInheritancePolicyRoots(&result.collectionPolicies, resolvedPolicies[index], graph.nodes[index].path)
|
||||
result.origins = directInheritanceOrigins(&document.Node{Kind: root.Kind, Location: root.Location}, adapter.scopePath(), inputOrigins)
|
||||
for _, slot := range adapter.slots() {
|
||||
if slot.hasTemplate {
|
||||
index := slot.template
|
||||
projectInheritancePolicyRoots(&result.collectionPolicies, resolvedPolicies[index], templates[index].path)
|
||||
for pointer, origin := range resolvedOrigins[index] {
|
||||
result.origins[pointer] = origin
|
||||
}
|
||||
continue
|
||||
}
|
||||
root.Mapping[i].Value = document.Clone(entry.Value)
|
||||
localPolicies := inheritancePolicyScopeAtPath(graph.collectionPolicies, graph.scopePath.Key(entry.Key))
|
||||
projectInheritancePolicyRoots(&result.collectionPolicies, localPolicies, graph.scopePath.Key(entry.Key))
|
||||
for pointer, origin := range directInheritanceOrigins(entry.Value, graph.scopePath.Key(entry.Key), inputOrigins) {
|
||||
localPolicies := inheritancePolicyScopeAtPath(adapter.collectionPolicies(), slot.path)
|
||||
projectInheritancePolicyRoots(&result.collectionPolicies, localPolicies, slot.path)
|
||||
for pointer, origin := range directInheritanceOrigins(slot.value, slot.path, inputOrigins) {
|
||||
result.origins[pointer] = origin
|
||||
}
|
||||
}
|
||||
result.root = &root
|
||||
result.root = root
|
||||
if !inheritanceLowerBoundWithin(result.root, limits.nodes) {
|
||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(graph.scopePath, graph.scope.Location)}
|
||||
return nil, []Diagnostic{inheritanceBudgetDiagnostic(adapter.scopePath(), adapter.scope().Location)}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user