Separate underlay acquisition from composition
This commit is contained in:
@@ -37,6 +37,16 @@ type loadInput struct {
|
||||
|
||||
type loadGroup struct{ inputs []loadInput }
|
||||
|
||||
type acquiredUnderlayGroup struct {
|
||||
index int
|
||||
scopes []acquisitionScope
|
||||
importGraph importInclusionGraph
|
||||
sources []SourceInfo
|
||||
contexts map[string]ResourceContext
|
||||
inputBytes int64
|
||||
inputNodes int
|
||||
}
|
||||
|
||||
func loadGroupedWithSecretLookup[T any](request loadRequest[T], secrets SecretBinding, lookup secretLookup) (*Loaded[T], error) {
|
||||
request.ordinary = false
|
||||
var diagnostics []Diagnostic
|
||||
@@ -84,9 +94,14 @@ func loadGroupedWithSecretLookup[T any](request loadRequest[T], secrets SecretBi
|
||||
func assembleLayeredInput[T any](request loadRequest[T], input assembledInput, accounting *importAccounting) (assembledInput, []Diagnostic) {
|
||||
groups := make([]*composedDocument, 0, len(request.underlays))
|
||||
for index, group := range request.underlays {
|
||||
composition, sources, contexts, diagnostics := acquireUnderlayGroupWithPolicyVersion(group, index+1, request.protectionVersion(), accounting, input.versionState, request.sequencePolicy)
|
||||
input.sources = append(input.sources, sources...)
|
||||
mergeResourceContexts(&input.contexts, contexts)
|
||||
acquired, diagnostics := acquireUnderlayGroupScopes(group, index+1, request.protectionVersion(), accounting, input.versionState, request.sequencePolicy)
|
||||
mergeResourceContexts(&input.contexts, acquired.contexts)
|
||||
if len(diagnostics) != 0 {
|
||||
input.sources = append(input.sources, acquired.sources...)
|
||||
return input, diagnostics
|
||||
}
|
||||
composition, diagnostics := composeUnderlayGroup(acquired, request.protectionVersion(), request.sequencePolicy, collectionPolicyScope{})
|
||||
input.sources = append(input.sources, acquired.sources...)
|
||||
if len(diagnostics) != 0 {
|
||||
return input, diagnostics
|
||||
}
|
||||
@@ -162,6 +177,15 @@ func acquireUnderlayGroupWithVersion(group loadGroup, index int, rule *VersionRu
|
||||
}
|
||||
|
||||
func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *VersionRule, accounting *importAccounting, versionState *sourceVersionState, policy sequencePolicy) (*composedDocument, []SourceInfo, map[string]ResourceContext, []Diagnostic) {
|
||||
acquired, diagnostics := acquireUnderlayGroupScopes(group, index, rule, accounting, versionState, policy)
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, acquired.sources, acquired.contexts, diagnostics
|
||||
}
|
||||
composition, diagnostics := composeUnderlayGroup(acquired, rule, policy, collectionPolicyScope{})
|
||||
return composition, acquired.sources, acquired.contexts, diagnostics
|
||||
}
|
||||
|
||||
func acquireUnderlayGroupScopes(group loadGroup, index int, rule *VersionRule, accounting *importAccounting, versionState *sourceVersionState, policy sequencePolicy) (*acquiredUnderlayGroup, []Diagnostic) {
|
||||
initialBytes, initialNodes := accounting.bytes, accounting.nodes
|
||||
visited := make(map[resourceIdentity]importRoute)
|
||||
hostToken := &namespaceToken{}
|
||||
@@ -173,10 +197,8 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
}
|
||||
}
|
||||
}
|
||||
var scopes []acquisitionScope
|
||||
acquiredGroup := &acquiredUnderlayGroup{index: index}
|
||||
inclusionGraph := newImportInclusionGraph()
|
||||
var sources []SourceInfo
|
||||
var contexts map[string]ResourceContext
|
||||
for inputIndex, contribution := range group.inputs {
|
||||
options := Options[struct{}]{
|
||||
Imports: contribution.imports, Filesystem: contribution.filesystem,
|
||||
@@ -193,11 +215,11 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
for _, source := range acquired.sources {
|
||||
source.Layer = LayerUnderlay
|
||||
source.UnderlayIndex = index
|
||||
sources = append(sources, source)
|
||||
acquiredGroup.sources = append(acquiredGroup.sources, source)
|
||||
}
|
||||
mergeResourceContexts(&contexts, acquired.contexts)
|
||||
mergeResourceContexts(&acquiredGroup.contexts, acquired.contexts)
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, sources, contexts, projectPriorInputDiagnosticPaths(diagnostics, scopes)
|
||||
return acquiredGroup, projectPriorInputDiagnosticPaths(diagnostics, acquiredGroup.scopes)
|
||||
}
|
||||
if acquired.document == nil && len(acquired.acquisition) == 0 {
|
||||
continue
|
||||
@@ -219,59 +241,66 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
for scopeIndex := range inputScopes {
|
||||
reanchorAcquisitionScope(&inputScopes[scopeIndex], keyMap, anchors)
|
||||
}
|
||||
scopes = append(scopes, inputScopes...)
|
||||
acquiredGroup.scopes = append(acquiredGroup.scopes, inputScopes...)
|
||||
mergeImportInclusionGraph(&inclusionGraph, inputGraph)
|
||||
}
|
||||
groupScope := scheduleAcquisitionGroup(scopes, inclusionGraph)
|
||||
traversal := importTraversal{accounting: accounting, limits: defaultImportLimits(), rule: rule, importGraph: inclusionGraph}
|
||||
if diagnostics := traversal.composePendingItems(&groupScope); len(diagnostics) != 0 {
|
||||
return nil, sources, contexts, diagnostics
|
||||
acquiredGroup.importGraph = inclusionGraph.clone()
|
||||
acquiredGroup.inputBytes = accounting.bytes - initialBytes
|
||||
acquiredGroup.inputNodes = accounting.nodes - initialNodes
|
||||
return acquiredGroup, nil
|
||||
}
|
||||
|
||||
func composeUnderlayGroup(acquired *acquiredUnderlayGroup, rule *VersionRule, policy sequencePolicy, lower collectionPolicyScope) (*composedDocument, []Diagnostic) {
|
||||
if acquired == nil {
|
||||
return nil, nil
|
||||
}
|
||||
groupScope := scheduleAcquisitionGroup(acquired.scopes, acquired.importGraph)
|
||||
if len(groupScope.contributions) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
groupScope.owner = importNodeKey{namespaceKind: "group", namespaceAnchor: explicitNamespaceAnchor(acquired.index, 0), resourceKind: "scope"}
|
||||
for contributionIndex := range groupScope.contributions {
|
||||
groupScope.contributions[contributionIndex].scopeOwner = groupScope.owner
|
||||
}
|
||||
accounting := &importAccounting{
|
||||
sources: len(acquired.sources), bytes: acquired.inputBytes, nodes: acquired.inputNodes,
|
||||
}
|
||||
composition, diagnostics := composeAcquiredScopeWithPolicy(
|
||||
&groupScope, lower, policy, acquired.importGraph, acquired.sources, nil, nil, accounting,
|
||||
)
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, diagnostics
|
||||
}
|
||||
var documents []*document.Node
|
||||
for _, contribution := range groupScope.contributions {
|
||||
documents = append(documents, contribution.document)
|
||||
}
|
||||
if len(documents) == 0 {
|
||||
return nil, sources, contexts, nil
|
||||
}
|
||||
composition, diagnostics := composeDocumentsWithPolicy(policy, documents...)
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, sources, contexts, diagnostics
|
||||
}
|
||||
if composition != nil && rule != nil {
|
||||
ranges := indexSequenceRanges(composition.sequenceRanges)
|
||||
for sourceIndex, document := range documents {
|
||||
for sourceIndex, input := range documents {
|
||||
if groupScope.contributions[sourceIndex].role == importRoleMain {
|
||||
continue
|
||||
}
|
||||
if node := fragmentVersionClaimWithIndex(document, rule, sourceIndex, ranges); node != nil {
|
||||
if node := fragmentVersionClaimWithIndex(input, rule, sourceIndex, ranges); node != nil {
|
||||
location := publicLocation(node.Location)
|
||||
return nil, sources, contexts, []Diagnostic{{
|
||||
return nil, []Diagnostic{{
|
||||
Code: CodeImportVersion, Severity: SeverityError, Path: rule.Path.clone(),
|
||||
Message: "imported fragments cannot contribute to the schema-version path", Primary: &location,
|
||||
}}
|
||||
}
|
||||
}
|
||||
for sourceIndex, document := range documents {
|
||||
if node := fragmentVersionClaimWithIndex(document, rule, sourceIndex, ranges); node != nil {
|
||||
for sourceIndex, input := range documents {
|
||||
if node := fragmentVersionClaimWithIndex(input, rule, sourceIndex, ranges); node != nil {
|
||||
location := publicLocation(node.Location)
|
||||
return nil, sources, contexts, []Diagnostic{{
|
||||
return nil, []Diagnostic{{
|
||||
Code: CodeUnderlayVersion, Severity: SeverityError, Path: rule.Path.clone(),
|
||||
Message: "underlay inputs cannot contribute to the schema-version path", Primary: &location,
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
composition.inputBytes = accounting.bytes - initialBytes
|
||||
composition.inputNodes = accounting.nodes - initialNodes
|
||||
groupScope.owner = importNodeKey{namespaceKind: "group", namespaceAnchor: explicitNamespaceAnchor(index, 0), resourceKind: "scope"}
|
||||
for contributionIndex := range groupScope.contributions {
|
||||
groupScope.contributions[contributionIndex].scopeOwner = groupScope.owner
|
||||
}
|
||||
composition.acquisition = []acquisitionScope{cloneAcquisitionScope(groupScope)}
|
||||
composition.importGraph = inclusionGraph.clone()
|
||||
projectNestedEvidence(composition, groupScope)
|
||||
projectAcquiredDestinations(composition, groupScope, sources)
|
||||
composition.inputBytes = acquired.inputBytes
|
||||
composition.inputNodes = acquired.inputNodes
|
||||
for pointer, origin := range composition.origins {
|
||||
origin.Layer = LayerUnderlay
|
||||
composition.origins[pointer] = origin
|
||||
@@ -279,7 +308,7 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
for index := range composition.applications {
|
||||
composition.applications[index].layer = LayerUnderlay
|
||||
}
|
||||
return composition, sources, contexts, nil
|
||||
return composition, nil
|
||||
}
|
||||
|
||||
func nativeTokenForLoadInput(input loadInput) *namespaceToken {
|
||||
|
||||
Reference in New Issue
Block a user