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 }