2026-10-25 12:55:04 +00:00
package engine
import "strconv"
type acquisitionPolicy struct {
2026-10-26 00:10:07 +00:00
importDefaults ImportDefaults
2026-10-25 12:55:04 +00:00
sequencePolicy sequencePolicy
importLimits importLimits
}
type acquisitionState struct {
accounting * importAccounting
versionState * sourceVersionState
}
type tierAcquisitionState struct {
visited map [ resourceIdentity ] importRoute
hostToken * namespaceToken
}
type inputAcquisitionRequest struct {
input loadInput
role sourceVersionRole
directiveContext rootDirectiveContext
protectionRule * VersionRule
ordinaryOverlay string
}
type importAcquisitionRequest struct {
input inputAcquisitionRequest
main parsedSource
processing * sourceVersionProcessingResult
}
func acquireInput ( request inputAcquisitionRequest , policy acquisitionPolicy , state * acquisitionState , tier * tierAcquisitionState ) ( assembledInput , [ ] Diagnostic ) {
source := request . input . source
destination := request . input . destination
accounting := state . accounting
versionState := state . versionState
sourceID := "source-" + strconv . Itoa ( accounting . sources + 1 )
selectedSource := source
if source . kind == sourceSearch {
resolved , failedSource , diagnostics := resolveSearchInput ( source , sourceID , defaultDiscoveryDirectoryHelpers ( ) , defaultDiscoveryHostProbe ( ) )
if len ( diagnostics ) != 0 {
if failedSource != nil {
failedSource . Destination = destination . clone ( )
failedSource . placementMode = request . input . placementMode
}
return assembledInput { source : resolved , sources : sourceInfos ( failedSource ) , versionState : versionState , accounting : accounting } , diagnostics
}
selectedSource = resolved
if request . input . filesystem != nil {
if diagnostics := filesystemOptionDiagnostics ( selectedSource , request . input . filesystem ) ; len ( diagnostics ) != 0 {
return assembledInput { source : selectedSource , versionState : versionState , accounting : accounting } , diagnostics
}
}
if selectedSource . kind == sourceNone && activeOverlay ( request . ordinaryOverlay ) && request . input . filesystem == nil {
return assembledInput { source : selectedSource , versionState : versionState , accounting : accounting } , [ ] Diagnostic { optionDiagnostic ( CodeOptionsInvalid , "NoSource overlays require explicit filesystem context" ) }
}
}
limits := policy . importLimits
parseLimits := defaultParseLimits ( )
parseLimits . source . remaining = limits . bytes - accounting . bytes
parsed , diagnostics := parseSource ( selectedSource , sourceID , parseLimits )
if parsed . source != nil {
parsed . source . Destination = destination . clone ( )
parsed . source . placementMode = request . input . placementMode
}
input := assembledInput { source : selectedSource , parsed : parsed , document : parsed . document , sources : sourceInfos ( parsed . source ) , versionState : versionState , accounting : accounting }
if len ( diagnostics ) != 0 {
input . sources = sourceInfos ( parsed . source )
// Mapping value issues already identify application content. Other early
// failures describe source syntax or access, not a placed value.
if selectedSource . kind == sourceMapping && selectedSource . mapIssue != nil && len ( destination . segments ) != 0 {
for index := range diagnostics {
relative := diagnostics [ index ] . Path
segments := clonePathSegments ( destination . segments , len ( relative . segments ) )
diagnostics [ index ] . Path = Path { segments : append ( segments , relative . segments ... ) }
}
}
return input , diagnostics
}
directiveContext := request . directiveContext
if directiveContext == 0 {
directiveContext = rootDirectiveContextImportsOnly
}
if ! request . input . imports && parsed . document != nil {
var directiveDiagnostics [ ] Diagnostic
if directiveContext == rootDirectiveContextSource || directiveContext == rootDirectiveContextLayered {
directiveDiagnostics = disabledRootImportDiagnostics ( parsed . document )
} else {
directiveDiagnostics = disabledDirectiveDiagnostics ( parsed . document , Path { } )
}
if len ( directiveDiagnostics ) != 0 {
return input , directiveDiagnostics
}
}
2026-10-25 22:30:46 +00:00
request . directiveContext = directiveContext
versionProcessing , diagnostics := processAcquiredInputVersion ( parsed , request , versionState )
if len ( diagnostics ) != 0 {
return input , diagnostics
2026-10-25 12:55:04 +00:00
}
2026-10-25 13:07:16 +00:00
request . input . source = selectedSource
2026-10-25 12:55:04 +00:00
if request . input . imports && selectedSource . kind != sourceNone {
2026-10-25 13:02:46 +00:00
importRequest := importAcquisitionRequest { input : request , main : parsed , processing : versionProcessing }
2026-10-25 13:13:47 +00:00
input . composition , input . sources , input . resolvedFilesystem , diagnostics = acquireImportedInput ( importRequest , & policy , state , tier )
2026-10-25 12:55:04 +00:00
if len ( diagnostics ) != 0 {
return input , diagnostics
}
if input . composition != nil {
input . acquisition = cloneAcquisitionScopes ( input . composition . acquisition )
input . document = input . composition . root
}
} else {
2026-10-25 22:32:52 +00:00
input , diagnostics = acquireStandaloneInput ( input , request , versionProcessing , policy , tier )
if len ( diagnostics ) != 0 {
return input , diagnostics
2026-10-25 12:55:04 +00:00
}
}
2026-10-25 22:32:52 +00:00
return completeAcquisitionContexts ( input , request , tier )
}
func acquireStandaloneInput ( input assembledInput , request inputAcquisitionRequest , processing * sourceVersionProcessingResult , policy acquisitionPolicy , tier * tierAcquisitionState ) ( assembledInput , [ ] Diagnostic ) {
parsed := input . parsed
input . sources = sourceInfos ( parsed . source )
if processing != nil {
input . document = processing . payload
}
if request . input . filesystem != nil && ( input . source . kind == sourceNone || ! activeOverlay ( request . ordinaryOverlay ) ) {
resolved , diagnostic := validateFilesystemContext ( input . source , request . input . filesystem , parsed , tier . hostToken )
if diagnostic != nil {
2026-10-25 12:55:04 +00:00
return input , [ ] Diagnostic { * diagnostic }
}
2026-10-25 22:32:52 +00:00
input . resolvedFilesystem = & resolved
}
if request . input . imports || input . document == nil {
return input , nil
}
limits := policy . importLimits
placement := request . input . destination
documentLimits := defaultParseLimits ( ) . document
_ , placed , err := placeDocumentWithMode ( input . document , placement , request . input . placementMode , input . document . Location , documentLimits . Depth , documentLimits . Nodes )
if err != nil {
return input , [ ] Diagnostic { sourceDiagnostic ( CodeSourceLimitExceeded , parsed . source . ID , "configuration exceeds the source depth or node limit after destination placement" ) }
}
localPayload := input . document
input . document = placed
identity := importKeyForMainSource ( parsed . source )
var sequenceDeclarations [ ] sequenceDeclarationSpec
if processing != nil {
sequenceDeclarations = cloneSequenceDeclarations ( processing . sequences )
}
input . acquisition = [ ] acquisitionScope { {
owner : identity ,
destination : placement . clone ( ) ,
contributions : [ ] acquiredContribution { {
source : cloneSourceInfo ( * parsed . source ) , payload : localPayload ,
identity : identity , role : importRoleMain , scopeOwner : identity ,
document : placed , destination : placement . clone ( ) , processing : processing ,
sequenceDeclarations : sequenceDeclarations ,
} } ,
} }
rawNodes := countInputNodes ( parsed . document )
placementNodes := destinationWrapperNodeCountForMode ( placement , request . input . placementMode )
accounting := input . accounting
if accounting . sources + 1 > limits . sources || accounting . bytes + parsed . bytes > limits . bytes || accounting . nodes + rawNodes + placementNodes > limits . nodes {
return input , [ ] Diagnostic { sourceDiagnostic ( CodeSourceLimitExceeded , parsed . source . ID , "configuration exceeds the aggregate input limit" ) }
}
if diagnostic := registerAcquiredSource ( input . source , request . input . filesystem , parsed . source , tier . visited , tier . hostToken ) ; diagnostic != nil {
return input , [ ] Diagnostic { * diagnostic }
}
accounting . sources ++
accounting . bytes += parsed . bytes
accounting . nodes += rawNodes + placementNodes
return input , nil
}
func completeAcquisitionContexts ( input assembledInput , request inputAcquisitionRequest , tier * tierAcquisitionState ) ( assembledInput , [ ] Diagnostic ) {
if activeOverlay ( request . ordinaryOverlay ) && ! request . input . imports {
return input , nil
}
if input . resolvedFilesystem == nil && len ( input . sources ) != 0 && ( input . source . kind == sourceFile || request . input . filesystem != nil || nativeContext ( input . source , request . input . filesystem ) ) {
resolved , diagnostic := resolveFilesystemContext ( input . source , request . input . filesystem , input . parsed , tier . hostToken )
2026-10-25 12:55:04 +00:00
if diagnostic != nil {
return input , [ ] Diagnostic { * diagnostic }
}
2026-10-25 22:32:52 +00:00
input . resolvedFilesystem = & resolved
}
contexts , diagnostic := contextsForResolvedSources ( input . resolvedFilesystem , input . sources )
if diagnostic != nil {
return input , [ ] Diagnostic { * diagnostic }
2026-10-25 12:55:04 +00:00
}
2026-10-25 22:32:52 +00:00
input . contexts = contexts
2026-10-25 12:55:04 +00:00
return input , nil
}
2026-10-25 13:07:16 +00:00
2026-10-25 22:30:46 +00:00
func processAcquiredInputVersion ( parsed parsedSource , request inputAcquisitionRequest , state * sourceVersionState ) ( * sourceVersionProcessingResult , [ ] Diagnostic ) {
sourceID := ""
if parsed . source != nil {
sourceID = parsed . source . ID
}
var result sourceVersionProcessingResult
hasResult := false
updateMainProcessing := false
switch request . directiveContext {
case rootDirectiveContextSource :
if state != nil {
processed , diagnostics := state . processWithDirectiveContext (
parsed . document , request . role , request . input . destination , sourceID ,
request . input . placementMode , request . directiveContext ,
)
if len ( diagnostics ) != 0 {
return nil , diagnostics
}
result = processed
updateMainProcessing = request . role == sourceVersionMain
} else {
result = processSourceVersionWithDirectiveContext (
parsed . document , request . protectionRule , request . role ,
request . input . destination , sourceVersionModeDefault , request . directiveContext ,
)
if len ( result . diagnostics ) != 0 {
return nil , result . diagnostics
}
}
hasResult = true
case rootDirectiveContextLayered :
extracted , diagnostics := extractRootDirectives ( parsed . document , request . directiveContext )
if len ( diagnostics ) != 0 {
return nil , diagnostics
}
result = sourceVersionProcessingResult {
payload : extracted . body , imports : extracted . imports , sequences : extracted . sequences ,
directiveContext : request . directiveContext ,
}
hasResult = true
if state != nil && state . mode != sourceVersionModeDefault {
processed , diagnostics := state . process (
extracted . body , request . role , request . input . destination ,
sourceID , request . input . placementMode ,
)
if len ( diagnostics ) != 0 {
return nil , diagnostics
}
processed . imports = extracted . imports
processed . sequences = append ( cloneSequenceDeclarations ( extracted . sequences ) , processed . sequences ... )
processed . directiveContext = request . directiveContext
result = processed
updateMainProcessing = request . role == sourceVersionMain
}
default :
if state != nil && state . mode != sourceVersionModeDefault {
processed , diagnostics := state . process (
parsed . document , request . role , request . input . destination ,
sourceID , request . input . placementMode ,
)
if len ( diagnostics ) != 0 {
return nil , diagnostics
}
result = processed
hasResult = true
updateMainProcessing = request . role == sourceVersionMain
}
}
if ! hasResult {
return nil , nil
}
if updateMainProcessing {
completed := result
state . mainProcessing = & completed
}
return & result , nil
}
2026-10-25 13:07:16 +00:00
func registerAcquiredSource ( source Source , context * FilesystemContext , info * SourceInfo , visited map [ resourceIdentity ] importRoute , hostToken * namespaceToken ) * Diagnostic {
if visited == nil || info == nil || info . Path == "" {
return nil
}
identity := resourceIdentity { namespace : hostToken , path : info . Path }
if source . kind == sourceFilesystem {
identity . namespace = source . namespace . token
} else if context != nil && context . FS != nil {
identity . namespace = context . FS . namespace . token
}
if previous , repeated := visited [ identity ] ; repeated {
value := importRepeatedDiagnostic ( Location { SourceID : info . ID } , previous , importRoute { } )
return & value
}
visited [ identity ] = importRoute { canonical : info . Path }
return nil
}