87 lines
4.3 KiB
Go
87 lines
4.3 KiB
Go
|
|
package engine
|
||
|
|
|
||
|
|
import "go.maximumdirect.net/configkit/internal/document"
|
||
|
|
|
||
|
|
func acquireContextlessInput(input assembledInput, request inputAcquisitionRequest, processing *sourceVersionProcessingResult, policy acquisitionPolicy) (assembledInput, []Diagnostic) {
|
||
|
|
parsed := input.parsed
|
||
|
|
var body *document.Node
|
||
|
|
var declarations []importDeclarationSpec
|
||
|
|
var sequences []sequenceDeclarationSpec
|
||
|
|
var diagnostics []Diagnostic
|
||
|
|
if processing != nil {
|
||
|
|
body, declarations = processing.payload, processing.imports
|
||
|
|
sequences = cloneSequenceDeclarations(processing.sequences)
|
||
|
|
} else {
|
||
|
|
body, declarations, diagnostics = splitImportDirectives(parsed.document)
|
||
|
|
}
|
||
|
|
destination := request.input.destination
|
||
|
|
localDestination := destination
|
||
|
|
if request.input.placementMode == PlacementModeSequenceItem {
|
||
|
|
localDestination = Path{}
|
||
|
|
}
|
||
|
|
if len(diagnostics) == 0 {
|
||
|
|
var policies []resolvedImportPolicy
|
||
|
|
policies, diagnostics = prepareImportDeclarations(declarations, policy.importDefaults, localDestination)
|
||
|
|
if len(diagnostics) == 0 {
|
||
|
|
for i, spec := range declarations {
|
||
|
|
if !policies[i].required || spec.selector == importSelectorPath && len(spec.paths) == 0 {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
site := spec.fieldSites["path"]
|
||
|
|
if spec.selector == importSelectorPath && len(spec.selectorSites) != 0 {
|
||
|
|
site = spec.selectorSites[0]
|
||
|
|
}
|
||
|
|
if spec.selector == importSelectorDirectory {
|
||
|
|
site = spec.fieldSites["dir"]
|
||
|
|
}
|
||
|
|
if spec.selector == importSelectorGlob {
|
||
|
|
site = spec.fieldSites["glob"]
|
||
|
|
}
|
||
|
|
diagnostics = []Diagnostic{{Code: CodeImportMissing, Severity: SeverityError, Path: site.path.clone(), Message: "import cannot be selected because no filesystem base is available", Primary: cloneLocation(&site.location)}}
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if len(diagnostics) != 0 {
|
||
|
|
if request.input.placementMode == PlacementModeSequenceItem {
|
||
|
|
diagnostics = prependCompositionDiagnosticPaths(diagnostics, destination.Index(0))
|
||
|
|
}
|
||
|
|
return input, diagnostics
|
||
|
|
}
|
||
|
|
key := importKeyForMainSource(parsed.source)
|
||
|
|
info := cloneSourceInfo(*parsed.source)
|
||
|
|
accounting := input.accounting
|
||
|
|
accounting.sources++
|
||
|
|
accounting.bytes += parsed.bytes
|
||
|
|
accounting.nodes += countInputNodes(parsed.document)
|
||
|
|
limits := policy.importLimits
|
||
|
|
if accounting.sources > limits.sources || accounting.bytes > limits.bytes || accounting.nodes > limits.nodes {
|
||
|
|
return input, []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the aggregate input limit", nil)}
|
||
|
|
}
|
||
|
|
contribution := acquiredContribution{source: info, payload: body, identity: key, role: importRoleMain, scopeOwner: key, processing: processing, sequenceDeclarations: sequences}
|
||
|
|
var scope acquisitionScope
|
||
|
|
if request.input.placementMode == PlacementModeSequenceItem {
|
||
|
|
contribution.document = body
|
||
|
|
local := acquisitionScope{owner: key, contributions: []acquiredContribution{contribution}}
|
||
|
|
scope = acquisitionScope{owner: key, destination: destination.clone(), contributions: []acquiredContribution{{source: info, payload: body, identity: key, role: importRoleMain, scopeOwner: key, destination: destination.clone(), processing: processing, sequenceDeclarations: sequences, pendingItem: &local}}}
|
||
|
|
if diagnostic := reservePendingItemPlacements(&scope, limits, accounting); diagnostic != nil {
|
||
|
|
return input, []Diagnostic{*diagnostic}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
_, placed, err := placeDocument(body, destination, body.Location, maxDocumentDepth, maxDocumentNodes)
|
||
|
|
if err != nil {
|
||
|
|
return input, []Diagnostic{sourceDiagnostic(CodeSourceLimitExceeded, info.ID, "configuration exceeds the source depth or node limit after destination placement")}
|
||
|
|
}
|
||
|
|
accounting.nodes += destinationWrapperNodeCount(destination)
|
||
|
|
if accounting.nodes > limits.nodes {
|
||
|
|
return input, []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the aggregate node limit", nil)}
|
||
|
|
}
|
||
|
|
contribution.document, contribution.destination = placed, destination.clone()
|
||
|
|
scope = acquisitionScope{owner: key, destination: destination.clone(), contributions: []acquiredContribution{contribution}}
|
||
|
|
}
|
||
|
|
input.document = body
|
||
|
|
input.composition = &composedDocument{acquisition: []acquisitionScope{scope}, importGraph: newImportInclusionGraph(), inputBytes: accounting.bytes, inputNodes: accounting.nodes}
|
||
|
|
input.acquisition = cloneAcquisitionScopes(input.composition.acquisition)
|
||
|
|
return input, nil
|
||
|
|
}
|