Extract inheritance input preparation

This commit is contained in:
2026-10-25 13:32:01 +00:00
parent 729c6fb5d5
commit f404168900
3 changed files with 133 additions and 71 deletions

View File

@@ -188,27 +188,19 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
for _, index := range order {
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.directivePath,
locations: []Location{publicLocation(node.directive.Value.Location)},
cancelled: node.cancelled,
}
result.controls = append(result.controls, control)
controlOrigins := directInheritanceOrigins(node.directive.Value, control.path, inputOrigins)
child := prepareInheritanceChild(node, inputOrigins)
if child.control != nil {
result.controls = append(result.controls, *child.control)
result.operations = append(result.operations, inheritanceOperation{
control: &control, controlOrigin: controlOrigins[control.path.String()],
control: child.control, controlOrigin: child.controlOrigin,
})
}
if limits.nodes >= 0 {
remaining := limits.nodes - retained - adapter.slotOverhead()
within := inheritanceLowerBoundWithin(payload, remaining)
within := inheritanceLowerBoundWithin(child.payload, remaining)
if node.hasParent {
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], payload, remaining)
within = inheritanceOverlayLowerBoundWithin(resolved[node.parent], child.payload, remaining)
}
if !within {
return nil, []Diagnostic{inheritanceBudgetDiagnostic(node.path, node.entry.Value.Location)}
@@ -217,65 +209,41 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
if node.hasParent {
parent := resolved[node.parent]
parentPolicies := cloneInheritancePolicyTemplates(resolvedPolicyTemplates[node.parent])
effectivePolicies := append(cloneInheritancePolicyTemplates(parentPolicies), cloneCollectionPolicyScopeForInheritance(templatePolicies))
parentPolicyScope := projectInheritanceCollectionPolicies(resolvedPolicies[node.parent], node.path)
childPolicyScope := projectCurrentInheritanceCollectionPolicies(templatePolicies, node.path)
var replaced collectionReplacementPaths
if len(parentPolicyScope.collections) != 0 || len(childPolicyScope.collections) != 0 {
claims := compositionClaims{byPath: make(map[string][]compositionClaim)}
claims.append(payload, node.path, 0)
declarations := make(map[string][]sequenceDeclarationSpec, len(childPolicyScope.collections))
for key, entry := range childPolicyScope.collections {
declarations[key] = inheritanceDeclarationsAt(entry.destination, entry.policy)
}
parentPolicyScope, replaced = lowerCollectionPoliciesForClaims(parentPolicyScope, claims.ordered, declarations, adapter.applicationPolicy())
}
merged := inheritanceParentPayload(parent, node.identityFields)
historyParent := parent
if len(node.identityFields) != 0 {
// The retained parent snapshot is the inherited payload, before
// child fields are applied, with parent identity excluded.
historyParent = document.Clone(merged)
}
preparedParent := prepareInheritanceParent(
node, templates[node.parent].path, parent, resolvedPolicyTemplates[node.parent],
resolvedPolicies[node.parent], child, adapter.applicationPolicy(),
)
mergedPolicyScope, policyDiagnostics := mergeInheritanceCollectionPolicies(
parentPolicyScope, childPolicyScope, node.path, parent, payload, adapter.applicationPolicy(), replaced,
preparedParent.parentPolicyScope, preparedParent.childPolicyScope,
node.path, preparedParent.payload, child.payload,
adapter.applicationPolicy(), preparedParent.replaced,
)
if len(policyDiagnostics) != 0 {
return nil, policyDiagnostics
}
transfer := inheritanceTransfer{
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(
[]collectionPolicyScope{resolvedPolicies[node.parent]}, node.path,
),
}
mergedOrigins := transferredInheritanceOrigins(resolvedOrigins[node.parent], transfer.from, node.path, transfer)
mergeInheritanceOrigin(mergedOrigins, node.path, childOrigins[node.path.String()])
mergedOrigins := transferredInheritanceOrigins(resolvedOrigins[node.parent], preparedParent.transfer.from, node.path, preparedParent.transfer)
mergeInheritanceOrigin(mergedOrigins, node.path, child.origins[node.path.String()])
var sequenceContributions []sequenceHistoryContribution
var combinationDiagnostics []Diagnostic
mergeRecursiveMappings(merged, payload, node.path, new(mappingIndex), recursiveMergeHooks{
mergeRecursiveMappings(preparedParent.payload, child.payload, node.path, new(mappingIndex), recursiveMergeHooks{
added: func(childPath Path, incoming *document.Node) {
copyInheritanceSubtree(mergedOrigins, childOrigins, incoming, childPath)
copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath)
},
combined: func(childPath Path, _ *document.Node) {
mergeInheritanceOrigin(mergedOrigins, childPath, childOrigins[childPath.String()])
mergeInheritanceOrigin(mergedOrigins, childPath, child.origins[childPath.String()])
},
replaced: func(childPath Path, existing, incoming *document.Node) {
previous := displacedOrigins(existing, mergedOrigins, childPath)
result.replacements = append(result.replacements, inheritanceReplacement{
path: childPath.clone(), before: existing, after: incoming,
previous: previous, effective: cloneOrigin(childOrigins[childPath.String()]),
previous: previous, effective: cloneOrigin(child.origins[childPath.String()]),
})
deleteOriginSubtree(mergedOrigins, childPath, existing)
copyInheritanceSubtree(mergedOrigins, childOrigins, incoming, childPath)
copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath)
},
merge: func(childPath Path, existing, incoming *document.Node) (*document.Node, bool) {
resolution, _, _, active, issues := inheritanceCollectionResolution(
childPath, parentPolicyScope, childPolicyScope, adapter.applicationPolicy(), incoming,
childPath, preparedParent.parentPolicyScope, preparedParent.childPolicyScope, adapter.applicationPolicy(), incoming,
)
if len(issues) != 0 {
combinationDiagnostics = append(combinationDiagnostics, issues...)
@@ -291,11 +259,11 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
return existing, false
}
policy := applyInheritanceSequencePolicy(
childPath, combined, resolution, parentPolicyScope, childPolicyScope,
childPath, combined, resolution, preparedParent.parentPolicyScope, preparedParent.childPolicyScope,
)
mergedPolicyScope.set(childPath, policy)
applyInheritanceSequenceOrigins(
result, mergedOrigins, childOrigins, childPath, lowerValue, incoming, combined, resolution.operation,
result, mergedOrigins, child.origins, childPath, lowerValue, incoming, combined, resolution.operation,
)
history := sequenceHistoryContribution{path: childPath.clone(), mode: sequenceHistoryMapped}
if resolution.operation == sequenceModeReplace {
@@ -311,32 +279,32 @@ func applyInheritanceScopeTemplates(adapter inheritanceScopeAdapter, order []int
return combined.value, true
},
})
preserveInheritanceIdentityFields(merged, payload, node.identityFields)
preserveInheritanceIdentityFields(preparedParent.payload, child.payload, node.identityFields)
if len(combinationDiagnostics) != 0 {
return nil, canonicalDiagnostics(combinationDiagnostics)
}
if problems := validateRegisteredInheritanceSequences(merged, node.path, adapter.applicationPolicy()); len(problems) != 0 {
if problems := validateRegisteredInheritanceSequences(preparedParent.payload, node.path, adapter.applicationPolicy()); len(problems) != 0 {
return nil, problems
}
merged.Location = node.entry.Value.Location
resolved[index], resolvedOrigins[index] = merged, mergedOrigins
preparedParent.payload.Location = node.entry.Value.Location
resolved[index], resolvedOrigins[index] = preparedParent.payload, mergedOrigins
resolvedPolicies[index] = inheritancePolicyScopeAtPath(mergedPolicyScope, node.path)
result.transfers = append(result.transfers, transfer)
result.transfers = append(result.transfers, preparedParent.transfer)
result.operations = append(result.operations, inheritanceOperation{
transfer: &transfer, parent: historyParent, effective: merged,
transfer: &preparedParent.transfer, parent: preparedParent.historyParent, effective: preparedParent.payload,
parentOrigins: resolvedOrigins[node.parent], effectiveOrigins: mergedOrigins,
parentPolicies: cloneInheritancePolicyTemplates(parentPolicies),
templatePolicies: cloneCollectionPolicyScopeForInheritance(templatePolicies),
effectivePolicies: cloneInheritancePolicyTemplates(effectivePolicies),
parentPolicies: cloneInheritancePolicyTemplates(preparedParent.policyTemplates),
templatePolicies: cloneCollectionPolicyScopeForInheritance(child.policyTemplates),
effectivePolicies: cloneInheritancePolicyTemplates(preparedParent.effectivePolicyTemplates),
sequences: cloneSequenceHistoryContributions(sequenceContributions),
identityFields: cloneStrings(node.identityFields),
})
resolvedPolicyTemplates[index] = effectivePolicies
resolvedPolicyTemplates[index] = preparedParent.effectivePolicyTemplates
} else {
resolved[index] = document.Clone(payload)
resolvedOrigins[index] = childOrigins
resolvedPolicyTemplates[index] = []collectionPolicyScope{templatePolicies}
resolvedPolicies[index] = cloneCollectionPolicyScopeForInheritance(templatePolicies)
resolved[index] = document.Clone(child.payload)
resolvedOrigins[index] = child.origins
resolvedPolicyTemplates[index] = []collectionPolicyScope{child.policyTemplates}
resolvedPolicies[index] = cloneCollectionPolicyScopeForInheritance(child.policyTemplates)
}
count, _ := inheritanceLowerBoundCount(resolved[index], limits.nodes)