2026-09-12 15:58:06 +00:00
package engine
import (
"bytes"
"errors"
"io/fs"
"strconv"
"strings"
"gitea.maximumdirect.net/eric/ConfigKit/internal/document"
yamladapter "gitea.maximumdirect.net/eric/ConfigKit/internal/yaml"
)
const (
maxImportDepth = 64
maxImportSources = 1024
maxGlobEntries = 1_000_000
)
type importLimits struct {
depth int
sources int
bytes int64
nodes int
entries int
}
func defaultImportLimits ( ) importLimits {
return importLimits {
depth : maxImportDepth , sources : maxImportSources ,
bytes : maxTotalBytes , nodes : maxDocumentNodes , entries : maxGlobEntries ,
}
}
type importRoute struct {
canonical string
locations [ ] Location
2026-10-19 17:34:21 +00:00
key importNodeKey
2026-09-12 15:58:06 +00:00
}
2026-09-29 17:29:01 +00:00
type importAccounting struct {
sources int
bytes int64
nodes int
entries int
}
2026-09-12 15:58:06 +00:00
type importTraversal struct {
2026-10-15 15:33:40 +00:00
access * filesystemAccess
accounting * importAccounting
limits importLimits
rule * VersionRule
versionState * sourceVersionState
2026-09-12 15:58:06 +00:00
2026-10-16 19:23:43 +00:00
scope acquisitionScope
itemScope bool
itemPrefix Path
itemFallback Path
sources [ ] SourceInfo
active map [ resourceIdentity ] int
visited map [ resourceIdentity ] importRoute
stack [ ] importRoute
2026-10-19 17:34:21 +00:00
importGraph importInclusionGraph
2026-09-12 15:58:06 +00:00
}
func loadImportedDocuments ( source Source , context * FilesystemContext , main parsedSource , rule * VersionRule , limits importLimits ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-14 13:19:31 +00:00
return loadImportedDocumentsTracked ( source , context , main , Path { } , rule , limits , & importAccounting { } , nil , nil )
2026-09-29 17:52:20 +00:00
}
2026-10-14 13:19:31 +00:00
func loadImportedDocumentsTracked ( source Source , context * FilesystemContext , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute , hostToken * namespaceToken ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-15 15:33:40 +00:00
return loadImportedDocumentsTrackedWithVersion ( source , context , main , destination , rule , limits , accounting , visited , hostToken , nil )
}
func loadImportedDocumentsTrackedWithVersion ( source Source , context * FilesystemContext , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute , hostToken * namespaceToken , versionState * sourceVersionState ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-15 15:40:11 +00:00
var processing * sourceVersionProcessingResult
if versionState != nil && versionState . mode != sourceVersionModeDefault {
processing = versionState . mainProcessing
}
2026-10-16 18:59:52 +00:00
return loadImportedDocumentsTrackedWithProcessing ( source , context , main , destination , rule , limits , accounting , visited , hostToken , versionState , processing , sequencePolicy { } )
2026-10-15 15:40:11 +00:00
}
2026-10-16 18:59:52 +00:00
func loadImportedDocumentsTrackedWithProcessing ( source Source , context * FilesystemContext , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute , hostToken * namespaceToken , versionState * sourceVersionState , processing * sourceVersionProcessingResult , policy sequencePolicy ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-09-29 17:36:20 +00:00
if nativeContext ( source , context ) {
access , basePath , mainPath , diagnostic := nativeFilesystemAccess ( source , context )
if diagnostic != nil {
return nil , sourceInfos ( main . source ) , [ ] Diagnostic { * diagnostic }
}
2026-10-16 18:59:52 +00:00
return loadImportedWithAccessTrackedAndProcessingPolicy ( access , basePath , mainPath , main , destination , rule , limits , accounting , visited , versionState , processing , policy )
2026-09-29 17:29:01 +00:00
}
2026-09-12 15:58:06 +00:00
rootPath , basePath , mainPath , diagnostic := importFilesystem ( source , context , main )
if diagnostic != nil {
return nil , sourceInfos ( main . source ) , [ ] Diagnostic { * diagnostic }
}
2026-09-29 17:29:01 +00:00
access , err := openHostAccess ( rootPath )
2026-09-12 15:58:06 +00:00
if err != nil {
diagnostic := globFilesystemDiagnostic ( err , "configuration root could not be opened" , Location { } )
diagnostic . Primary = nil
return nil , sourceInfos ( main . source ) , [ ] Diagnostic { diagnostic }
}
2026-09-29 17:52:20 +00:00
if hostToken != nil {
access . token = hostToken
}
2026-10-16 18:59:52 +00:00
return loadImportedWithAccessTrackedAndProcessingPolicy ( access , basePath , mainPath , main , destination , rule , limits , accounting , visited , versionState , processing , policy )
2026-09-29 17:29:01 +00:00
}
2026-09-12 15:58:06 +00:00
2026-09-29 17:29:01 +00:00
func loadImportedWithAccess ( access * filesystemAccess , basePath , mainPath string , main parsedSource , rule * VersionRule , limits importLimits , accounting * importAccounting ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-14 13:19:31 +00:00
return loadImportedWithAccessTracked ( access , basePath , mainPath , main , Path { } , rule , limits , accounting , nil )
2026-09-29 17:52:20 +00:00
}
2026-10-14 13:19:31 +00:00
func loadImportedWithAccessTracked ( access * filesystemAccess , basePath , mainPath string , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-15 15:33:40 +00:00
return loadImportedWithAccessTrackedWithVersion ( access , basePath , mainPath , main , destination , rule , limits , accounting , visited , nil )
}
func loadImportedWithAccessTrackedWithVersion ( access * filesystemAccess , basePath , mainPath string , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute , versionState * sourceVersionState ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-15 15:40:11 +00:00
var processing * sourceVersionProcessingResult
if versionState != nil && versionState . mode != sourceVersionModeDefault {
processing = versionState . mainProcessing
}
return loadImportedWithAccessTrackedAndProcessing ( access , basePath , mainPath , main , destination , rule , limits , accounting , visited , versionState , processing )
}
func loadImportedWithAccessTrackedAndProcessing ( access * filesystemAccess , basePath , mainPath string , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute , versionState * sourceVersionState , processing * sourceVersionProcessingResult ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-10-16 18:59:52 +00:00
return loadImportedWithAccessTrackedAndProcessingPolicy ( access , basePath , mainPath , main , destination , rule , limits , accounting , visited , versionState , processing , sequencePolicy { } )
}
func loadImportedWithAccessTrackedAndProcessingPolicy ( access * filesystemAccess , basePath , mainPath string , main parsedSource , destination Path , rule * VersionRule , limits importLimits , accounting * importAccounting , visited map [ resourceIdentity ] importRoute , versionState * sourceVersionState , processing * sourceVersionProcessingResult , policy sequencePolicy ) ( * composedDocument , [ ] SourceInfo , [ ] Diagnostic ) {
2026-09-29 17:29:01 +00:00
if ! access . contains ( basePath ) || ( mainPath != "" && ! access . contains ( mainPath ) ) {
_ = access . close ( )
return nil , sourceInfos ( main . source ) , [ ] Diagnostic { importDiagnostic ( CodeImportOutsideRoot , "selected source and import base must stay inside the configuration root" , nil ) }
}
for _ , directory := range [ ] string { access . rootPath , basePath } {
info , err := access . stat ( directory )
if err != nil || ! info . IsDir ( ) {
_ = access . close ( )
return nil , sourceInfos ( main . source ) , [ ] Diagnostic { importDiagnostic ( CodeImportInvalid , "configuration root and import base must be directories" , nil ) }
}
}
2026-09-12 15:58:06 +00:00
mainInfo := cloneSourceInfo ( * main . source )
2026-10-14 13:19:31 +00:00
mainInfo . Destination = destination . clone ( )
2026-10-16 16:20:14 +00:00
mainIsItem := main . source . placementMode == placementModeSequenceItem
2026-09-12 15:58:06 +00:00
if mainPath != "" {
mainInfo . Path = mainPath
}
2026-10-19 17:34:21 +00:00
mainResource := access . identity ( mainPath )
mainNodeKey := importKeyFor ( access , mainPath , mainPath == "" )
2026-09-29 17:52:20 +00:00
if mainPath == "" {
2026-10-19 17:34:21 +00:00
mainResource = access . syntheticIdentity ( )
2026-09-29 17:52:20 +00:00
}
2026-10-19 17:34:21 +00:00
if previous , repeated := visited [ mainResource ] ; repeated {
2026-09-29 17:52:20 +00:00
_ = access . close ( )
return nil , sourceInfos ( main . source ) , [ ] Diagnostic { importRepeatedDiagnostic ( Location { SourceID : main . source . ID } , previous , importRoute { } ) }
}
2026-09-29 17:29:01 +00:00
accounting . sources ++
accounting . bytes += main . bytes
accounting . nodes += countInputNodes ( main . document )
2026-09-12 15:58:06 +00:00
state := importTraversal {
2026-10-15 15:33:40 +00:00
access : access , accounting : accounting , limits : limits , rule : rule , versionState : versionState ,
2026-10-19 17:34:21 +00:00
scope : acquisitionScope { owner : mainNodeKey , destination : destination . clone ( ) } ,
2026-10-16 15:48:36 +00:00
sources : [ ] SourceInfo { mainInfo } ,
active : make ( map [ resourceIdentity ] int ) , visited : visited ,
2026-10-19 17:34:21 +00:00
importGraph : newImportInclusionGraph ( ) ,
2026-09-29 17:52:20 +00:00
}
2026-10-16 16:20:14 +00:00
if mainIsItem {
state . itemScope = true
state . itemPrefix = destination . clone ( )
2026-10-16 19:23:43 +00:00
state . itemFallback = destination . clone ( )
2026-10-16 16:20:14 +00:00
state . scope . destination = Path { }
state . sources [ 0 ] = cloneSourceInfo ( mainInfo )
}
2026-09-29 17:52:20 +00:00
if state . visited == nil {
state . visited = make ( map [ resourceIdentity ] importRoute )
2026-09-12 15:58:06 +00:00
}
if diagnostic := state . checkInitialLimits ( ) ; diagnostic != nil {
2026-09-29 17:29:01 +00:00
_ = access . close ( )
2026-09-12 15:58:06 +00:00
return nil , cloneSourceInfos ( state . sources ) , [ ] Diagnostic { * diagnostic }
}
mainIdentity := mainPath
if mainIdentity == "" {
mainIdentity = "<selected-source>"
}
mainRoute := importRoute { canonical : mainIdentity }
2026-10-19 17:34:21 +00:00
state . importGraph . addNode ( importGraphNode { key : mainNodeKey , canonical : mainIdentity , sourceID : mainInfo . ID , role : importRoleMain } )
mainRoute . key = mainNodeKey
state . active [ mainResource ] = 0
state . visited [ mainResource ] = mainRoute
2026-09-12 15:58:06 +00:00
state . stack = append ( state . stack , mainRoute )
2026-10-15 15:33:40 +00:00
var body * document . Node
var declarations [ ] importDeclaration
var diagnostics [ ] Diagnostic
2026-10-15 15:40:11 +00:00
if processing != nil {
body = processing . payload
declarations = processing . imports
2026-10-15 15:33:40 +00:00
} else {
body , declarations , diagnostics = splitImportDirectives ( main . document )
}
2026-09-12 15:58:06 +00:00
if len ( diagnostics ) == 0 {
2026-10-16 16:20:14 +00:00
if mainIsItem {
2026-10-16 15:48:36 +00:00
state . scope . contributions = append ( state . scope . contributions , acquiredContribution {
2026-10-19 17:34:21 +00:00
source : cloneSourceInfo ( mainInfo ) , identity : mainNodeKey , role : importRoleMain ,
scopeOwner : mainNodeKey , payload : body , document : body , processing : processing ,
2026-10-16 15:48:36 +00:00
} )
2026-10-16 16:20:14 +00:00
diagnostics = state . walkDeclarations ( basePath , declarations , 0 , Path { } )
} else {
_ , placed , err := placeDocument ( body , destination , body . Location , maxDocumentDepth , maxDocumentNodes )
placementNodes := destinationWrapperNodeCount ( destination )
if err != nil {
diagnostics = [ ] Diagnostic { sourceDiagnostic ( CodeSourceLimitExceeded , main . source . ID , "configuration exceeds the source depth or node limit after destination placement" ) }
} else if accounting . nodes + placementNodes > limits . nodes {
diagnostics = [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate node limit" , nil ) }
} else {
accounting . nodes += placementNodes
state . scope . contributions = append ( state . scope . contributions , acquiredContribution {
source : cloneSourceInfo ( mainInfo ) , payload : body , document : placed ,
2026-10-19 17:34:21 +00:00
identity : mainNodeKey , role : importRoleMain , scopeOwner : mainNodeKey ,
2026-10-16 16:20:14 +00:00
destination : destination . clone ( ) , processing : processing ,
} )
diagnostics = state . walkDeclarations ( basePath , declarations , 0 , destination )
}
2026-10-14 13:19:31 +00:00
}
2026-09-12 15:58:06 +00:00
}
2026-10-19 17:34:21 +00:00
if len ( diagnostics ) == 0 {
2026-10-19 19:39:19 +00:00
state . scheduleAcquisitionScopes ( & state . scope )
2026-10-19 17:34:21 +00:00
diagnostics = state . composePendingItems ( & state . scope )
}
2026-09-12 15:58:06 +00:00
2026-09-29 17:29:01 +00:00
closeErr := access . close ( )
2026-09-12 15:58:06 +00:00
if len ( diagnostics ) != 0 {
2026-10-17 04:54:01 +00:00
if mainIsItem {
diagnostics = prependCompositionDiagnosticPaths ( diagnostics , destination . Index ( 0 ) )
}
2026-09-12 15:58:06 +00:00
return nil , cloneSourceInfos ( state . sources ) , diagnostics
}
if closeErr != nil {
return nil , cloneSourceInfos ( state . sources ) , [ ] Diagnostic { importDiagnostic ( CodeImportRead , "configuration root could not be closed" , nil ) }
}
2026-10-16 16:20:14 +00:00
if mainIsItem {
localScope := state . scope
documents := make ( [ ] * document . Node , 0 , len ( localScope . contributions ) )
for _ , contribution := range localScope . contributions {
documents = append ( documents , contribution . document )
}
completed , failures := composeDocuments ( documents ... )
if len ( failures ) != 0 {
2026-10-17 04:54:01 +00:00
return nil , cloneSourceInfos ( state . sources ) , prependCompositionDiagnosticPaths ( failures , destination . Index ( 0 ) )
2026-10-16 16:20:14 +00:00
}
2026-10-16 19:11:08 +00:00
if versionState != nil {
2026-10-17 04:48:25 +00:00
protectionRule := versionState . localRule
if versionState . mode == sourceVersionModeDefault && protectionRule != nil {
prefix := destination . Index ( 0 )
relative , inside := relativeHistoryPath ( prefix , protectionRule . Path )
if ! inside || ! matchesPathShape ( Path { segments : protectionRule . Path . segments [ : len ( prefix . segments ) ] } , prefix ) {
protectionRule = nil
} else {
scoped := * protectionRule
scoped . Path = relative
protectionRule = & scoped
}
}
2026-10-19 19:29:35 +00:00
if diagnostic := importedVersionClaim ( documents , localScope , completed , protectionRule ) ; diagnostic != nil {
2026-10-17 04:48:25 +00:00
if rule != nil {
diagnostic . Path = rule . Path . clone ( )
}
2026-10-16 19:11:08 +00:00
return nil , cloneSourceInfos ( state . sources ) , [ ] Diagnostic { * diagnostic }
}
}
2026-10-16 16:20:14 +00:00
completed . acquisition = [ ] acquisitionScope { cloneAcquisitionScope ( localScope ) }
projectNestedEvidence ( completed , localScope )
_ , placed , err := placeDocumentWithMode ( completed . root , destination , placementModeSequenceItem , body . Location , maxDocumentDepth , maxDocumentNodes )
if err != nil {
return nil , cloneSourceInfos ( state . sources ) , [ ] Diagnostic { sourceDiagnostic ( CodeSourceLimitExceeded , main . source . ID , "configuration exceeds the source depth or node limit after destination placement" ) }
}
placementNodes := destinationWrapperNodeCountForMode ( destination , placementModeSequenceItem )
if accounting . nodes + placementNodes > limits . nodes {
return nil , cloneSourceInfos ( state . sources ) , [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate node limit" , nil ) }
}
accounting . nodes += placementNodes
2026-10-16 18:59:52 +00:00
composed , failures := composeDocumentsWithPolicy ( policy , placed )
2026-10-16 16:20:14 +00:00
if composed != nil {
synthetic := acquisitionScope { contributions : [ ] acquiredContribution { {
source : cloneSourceInfo ( mainInfo ) , payload : completed . root , document : placed ,
2026-10-19 17:34:21 +00:00
identity : mainNodeKey , role : importRoleMain , scopeOwner : mainNodeKey ,
2026-10-16 16:20:14 +00:00
destination : destination . clone ( ) , processing : processing , nested : completed ,
} } }
2026-10-19 17:34:21 +00:00
synthetic . owner = mainNodeKey
2026-10-16 16:20:14 +00:00
projectNestedEvidence ( composed , synthetic )
projectAcquiredDestinations ( composed , synthetic , state . sources )
composed . acquisition = [ ] acquisitionScope { cloneAcquisitionScope ( synthetic ) }
composed . inputBytes = accounting . bytes
composed . inputNodes = accounting . nodes
2026-10-19 17:34:21 +00:00
composed . importGraph = state . importGraph . clone ( )
2026-10-16 16:20:14 +00:00
}
return composed , cloneSourceInfos ( state . sources ) , failures
}
2026-10-16 15:48:36 +00:00
documents := make ( [ ] * document . Node , 0 , len ( state . scope . contributions ) )
for _ , contribution := range state . scope . contributions {
documents = append ( documents , contribution . document )
}
2026-10-16 18:59:52 +00:00
composed , diagnostics := composeDocumentsWithPolicy ( policy , documents ... )
2026-10-16 19:11:08 +00:00
if composed != nil {
2026-10-19 19:29:35 +00:00
if diagnostic := importedVersionClaim ( documents , state . scope , composed , rule ) ; diagnostic != nil {
2026-10-16 19:11:08 +00:00
return nil , cloneSourceInfos ( state . sources ) , [ ] Diagnostic { * diagnostic }
}
}
2026-09-12 15:58:06 +00:00
if composed != nil {
2026-10-16 16:20:14 +00:00
projectNestedEvidence ( composed , state . scope )
projectAcquiredDestinations ( composed , state . scope , state . sources )
2026-10-16 15:48:36 +00:00
composed . acquisition = [ ] acquisitionScope { cloneAcquisitionScope ( state . scope ) }
2026-09-29 17:29:01 +00:00
composed . inputBytes = accounting . bytes
composed . inputNodes = accounting . nodes
2026-10-19 17:34:21 +00:00
composed . importGraph = state . importGraph . clone ( )
2026-09-12 15:58:06 +00:00
}
return composed , cloneSourceInfos ( state . sources ) , diagnostics
}
func ( s * importTraversal ) checkInitialLimits ( ) * Diagnostic {
2026-09-29 17:29:01 +00:00
if s . accounting . sources > s . limits . sources {
2026-09-12 15:58:06 +00:00
value := importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the source-count limit" , nil )
return & value
}
2026-09-29 17:29:01 +00:00
if s . accounting . bytes > s . limits . bytes {
2026-09-12 15:58:06 +00:00
value := importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate byte limit" , nil )
return & value
}
2026-09-29 17:29:01 +00:00
if s . accounting . nodes > s . limits . nodes {
2026-09-12 15:58:06 +00:00
value := importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate node limit" , nil )
return & value
}
return nil
}
2026-10-14 17:21:07 +00:00
func ( s * importTraversal ) walkDeclarations ( basePath string , declarations [ ] importDeclaration , depth int , parentDestination Path ) [ ] Diagnostic {
2026-09-12 15:58:06 +00:00
for _ , declaration := range declarations {
2026-10-14 17:21:07 +00:00
childDestination := appendDestination ( parentDestination , declaration . destination )
2026-09-12 15:58:06 +00:00
if declaration . glob != "" {
matches , diagnostics := s . expandImportGlob ( basePath , declaration )
if len ( diagnostics ) != 0 {
return diagnostics
}
if len ( matches ) == 0 {
if declaration . optional {
continue
}
location := declaration . location
return [ ] Diagnostic { importDiagnostic ( CodeImportMissing , "required import glob matched no files" , & location ) }
}
for _ , match := range matches {
matched := declaration
matched . path = match
matched . glob = ""
2026-10-16 15:48:36 +00:00
if diagnostics := s . visitPath ( basePath , matched , childDestination , declaration . destination , depth + 1 ) ; len ( diagnostics ) != 0 {
2026-09-12 15:58:06 +00:00
return diagnostics
}
}
continue
}
2026-10-16 15:48:36 +00:00
if diagnostics := s . visitPath ( basePath , declaration , childDestination , declaration . destination , depth + 1 ) ; len ( diagnostics ) != 0 {
2026-09-12 15:58:06 +00:00
return diagnostics
}
}
return nil
}
2026-10-16 15:48:36 +00:00
func ( s * importTraversal ) visitPath ( basePath string , declaration importDeclaration , destination , relativeDestination Path , depth int ) [ ] Diagnostic {
2026-09-12 15:58:06 +00:00
location := declaration . location
2026-10-16 16:20:14 +00:00
if declaration . placement == placementModeSequenceItem && len ( destination . segments ) == 0 {
return [ ] Diagnostic { {
Code : CodeImportInvalid , Severity : SeverityError ,
Path : declaration . placementPath . clone ( ) ,
Message : "sequence-item placement requires a nonempty destination" ,
Primary : cloneLocation ( declaration . placementLocation ) ,
} }
}
2026-09-12 15:58:06 +00:00
if depth > s . limits . depth {
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the active import-depth limit" , & location ) }
}
if ! validImportPath ( declaration . path ) {
return [ ] Diagnostic { importDiagnostic ( CodeImportInvalid , "import path must be a nonempty slash-relative path without a network scheme" , & location ) }
}
2026-09-29 17:29:01 +00:00
candidate := s . access . join ( basePath , declaration . path )
if ! s . access . contains ( candidate ) {
2026-09-12 15:58:06 +00:00
return [ ] Diagnostic { importDiagnostic ( CodeImportOutsideRoot , "import target is outside the configuration root" , & location ) }
}
2026-09-29 17:29:01 +00:00
canonical , err := s . access . canonical ( candidate )
2026-09-12 15:58:06 +00:00
if err != nil {
if declaration . optional && errors . Is ( err , fs . ErrNotExist ) {
return nil
}
code := CodeImportInvalid
message := "import target could not be canonicalized"
if errors . Is ( err , fs . ErrNotExist ) {
code , message = CodeImportMissing , "required import target does not exist"
} else if errors . Is ( err , fs . ErrPermission ) {
message = "import target cannot be accessed"
}
return [ ] Diagnostic { importDiagnostic ( code , message , & location ) }
}
2026-09-29 17:29:01 +00:00
if ! s . access . contains ( canonical ) {
2026-09-12 15:58:06 +00:00
return [ ] Diagnostic { importDiagnostic ( CodeImportOutsideRoot , "import target resolves outside the configuration root" , & location ) }
}
currentRoute := s . currentRoute ( location )
2026-09-29 17:29:01 +00:00
identity := s . access . identity ( canonical )
2026-10-19 17:34:21 +00:00
nodeKey := importKeyFor ( s . access , canonical , false )
importerKey := s . currentImportNode ( )
2026-09-29 17:29:01 +00:00
if activeIndex , ok := s . active [ identity ] ; ok {
2026-10-19 17:34:21 +00:00
closingEdge := s . importGraph . addEdge ( importerKey , nodeKey , location )
if diagnostic , ok := s . importGraph . scheduleCycle ( closingEdge , location ) ; ok {
return [ ] Diagnostic { diagnostic }
}
2026-09-12 15:58:06 +00:00
cycle := append ( [ ] importRoute ( nil ) , s . stack [ activeIndex : ] ... )
return [ ] Diagnostic { importCycleDiagnostic ( canonical , location , cycle ) }
}
2026-09-29 17:29:01 +00:00
if previous , ok := s . visited [ identity ] ; ok {
2026-10-19 17:34:21 +00:00
s . importGraph . addEdge ( importerKey , nodeKey , location )
2026-09-12 15:58:06 +00:00
return [ ] Diagnostic { importRepeatedDiagnostic ( location , previous , currentRoute ) }
}
2026-09-29 17:29:01 +00:00
if s . accounting . sources + 1 > s . limits . sources {
2026-09-12 15:58:06 +00:00
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the source-count limit" , & location ) }
}
2026-09-29 17:29:01 +00:00
if _ , err := s . access . relative ( canonical ) ; err != nil {
2026-09-12 15:58:06 +00:00
return [ ] Diagnostic { importDiagnostic ( CodeImportOutsideRoot , "import target could not be addressed inside the configuration root" , & location ) }
}
2026-09-29 17:29:01 +00:00
sourceID := "source-" + strconv . Itoa ( s . accounting . sources + 1 )
2026-09-29 17:36:20 +00:00
kind := SourceKindFile
label := declaration . path
if s . access . native != nil {
kind = SourceKindFilesystem
label = s . access . label + "/" + canonical
}
2026-10-16 16:20:14 +00:00
info := SourceInfo { ID : sourceID , Label : label , Path : canonical , Destination : s . sourceDestination ( destination ) , Layer : LayerBase , Kind : kind , ImportedFrom : & location }
if declaration . placement == placementModeSequenceItem {
info . placementMode = placementModeSequenceItem
}
2026-10-16 19:23:43 +00:00
// A source's own item placement still has an exact sequence-container
// destination. Only an unresolved enclosing item index makes the path a
// fallback container for this snapshot.
info . destinationUnresolved = s . itemScope
2026-09-29 17:58:15 +00:00
if kind == SourceKindFilesystem {
info . namespace = s . access . token
}
2026-09-12 15:58:06 +00:00
s . sources = append ( s . sources , info )
2026-09-29 17:29:01 +00:00
data , skipped , diagnostic := s . readImport ( canonical , sourceID , declaration . optional )
2026-09-12 15:58:06 +00:00
if diagnostic != nil {
return [ ] Diagnostic { * diagnostic }
}
if skipped {
s . sources = s . sources [ : len ( s . sources ) - 1 ]
return nil
}
2026-09-29 17:29:01 +00:00
s . accounting . sources ++
2026-09-12 15:58:06 +00:00
root , issues := yamladapter . Parse ( bytes . NewReader ( data ) , sourceID , yamladapter . Limits {
Depth : maxDocumentDepth , Nodes : maxDocumentNodes ,
} )
if len ( issues ) != 0 {
return parserDiagnostics ( sourceID , issues )
}
nodeCount := countInputNodes ( root )
2026-09-29 17:29:01 +00:00
if s . accounting . nodes + nodeCount > s . limits . nodes {
2026-09-12 15:58:06 +00:00
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate node limit" , & location ) }
}
2026-09-29 17:29:01 +00:00
s . accounting . nodes += nodeCount
2026-09-12 15:58:06 +00:00
2026-10-15 15:33:40 +00:00
var body * document . Node
var declarations [ ] importDeclaration
var diagnostics [ ] Diagnostic
2026-10-16 15:48:36 +00:00
var processing * sourceVersionProcessingResult
2026-10-15 15:33:40 +00:00
if s . versionState != nil && s . versionState . mode != sourceVersionModeDefault {
2026-10-16 19:11:08 +00:00
versionDestination := destination
if s . itemScope {
versionDestination = appendDestination ( s . itemPrefix . Index ( 0 ) , destination )
}
processed , failures := s . versionState . process ( root , sourceVersionContribution , versionDestination , sourceID , declaration . placement )
2026-10-15 15:33:40 +00:00
if len ( failures ) != 0 {
return failures
}
2026-10-16 15:48:36 +00:00
processing = & processed
2026-10-15 15:33:40 +00:00
body , declarations = processed . payload , processed . imports
} else {
body , declarations , diagnostics = splitImportDirectives ( root )
if len ( diagnostics ) != 0 {
return diagnostics
}
2026-09-12 15:58:06 +00:00
}
2026-10-16 16:20:14 +00:00
placementDestination := destination
mode := placementModeMapping
if declaration . placement == placementModeSequenceItem {
mode = placementModeSequenceItem
}
2026-10-19 17:34:21 +00:00
role := importRoleMapping
if mode == placementModeSequenceItem {
role = importRoleItem
}
s . importGraph . addNode ( importGraphNode { key : nodeKey , canonical : canonical , sourceID : sourceID , role : role } )
s . importGraph . addEdge ( importerKey , nodeKey , location )
2026-10-16 16:20:14 +00:00
if mode == placementModeSequenceItem {
2026-10-19 17:34:21 +00:00
route := importRoute { canonical : canonical , locations : currentRoute . locations , key : nodeKey }
2026-10-16 16:20:14 +00:00
s . active [ identity ] = len ( s . stack )
s . visited [ identity ] = route
s . stack = append ( s . stack , route )
2026-10-19 17:34:21 +00:00
diagnostics := s . visitItemSource ( canonical , nodeKey , declaration , destination , relativeDestination , depth , info , body , declarations , processing )
2026-10-16 16:20:14 +00:00
delete ( s . active , identity )
s . stack = s . stack [ : len ( s . stack ) - 1 ]
return diagnostics
}
_ , placed , err := placeDocument ( body , placementDestination , body . Location , maxDocumentDepth , maxDocumentNodes )
2026-10-14 13:19:31 +00:00
if err != nil {
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the source depth or node limit after destination placement" , & location ) }
}
2026-10-16 16:20:14 +00:00
placementNodes := destinationWrapperNodeCount ( placementDestination )
2026-10-14 13:31:32 +00:00
if s . accounting . nodes + placementNodes > s . limits . nodes {
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate node limit" , & location ) }
}
s . accounting . nodes += placementNodes
2026-10-19 17:34:21 +00:00
route := importRoute { canonical : canonical , locations : currentRoute . locations , key : nodeKey }
2026-10-16 15:48:36 +00:00
s . scope . contributions = append ( s . scope . contributions , acquiredContribution {
source : cloneSourceInfo ( info ) , payload : body , document : placed ,
2026-10-19 17:34:21 +00:00
identity : nodeKey , role : role , scopeOwner : s . scope . owner ,
2026-10-16 16:20:14 +00:00
destination : placementDestination . clone ( ) , relativeDestination : relativeDestination . clone ( ) , processing : processing ,
2026-10-16 15:48:36 +00:00
} )
2026-09-29 17:29:01 +00:00
s . active [ identity ] = len ( s . stack )
s . visited [ identity ] = route
2026-09-12 15:58:06 +00:00
s . stack = append ( s . stack , route )
2026-10-14 17:21:07 +00:00
diagnostics = s . walkDeclarations ( s . access . dir ( canonical ) , declarations , depth , destination )
2026-09-29 17:29:01 +00:00
delete ( s . active , identity )
2026-09-12 15:58:06 +00:00
s . stack = s . stack [ : len ( s . stack ) - 1 ]
return diagnostics
}
2026-10-19 17:34:21 +00:00
func ( s * importTraversal ) currentImportNode ( ) importNodeKey {
if len ( s . stack ) != 0 {
return s . stack [ len ( s . stack ) - 1 ] . key
}
key := s . scope . owner
if _ , exists := s . importGraph . index [ key ] ; ! exists {
s . importGraph . addNode ( importGraphNode { key : key , canonical : "<selected-source>" , role : importRoleMain } )
}
return key
}
2026-10-16 16:20:14 +00:00
func ( s * importTraversal ) sourceDestination ( destination Path ) Path {
if ! s . itemScope {
return destination . clone ( )
}
2026-10-16 19:23:43 +00:00
// Until the enclosing item receives its assigned index, only the collection
// container is exact. Keep the local suffix in the acquisition projection.
return s . itemFallback . clone ( )
2026-10-16 16:20:14 +00:00
}
2026-10-19 17:34:21 +00:00
func ( s * importTraversal ) visitItemSource ( canonical string , identity importNodeKey , declaration importDeclaration , destination , relativeDestination Path , depth int , info SourceInfo , body * document . Node , declarations [ ] importDeclaration , processing * sourceVersionProcessingResult ) [ ] Diagnostic {
2026-10-16 16:20:14 +00:00
parentScope := s . scope
2026-10-16 19:23:43 +00:00
parentItemScope , parentPrefix , parentFallback := s . itemScope , s . itemPrefix , s . itemFallback
2026-10-19 17:34:21 +00:00
s . scope = acquisitionScope { owner : identity }
2026-10-16 16:20:14 +00:00
s . itemScope = true
if parentItemScope {
s . itemPrefix = appendDestination ( parentPrefix , destination )
} else {
s . itemPrefix = destination . clone ( )
2026-10-16 19:23:43 +00:00
s . itemFallback = destination . clone ( )
2026-10-16 16:20:14 +00:00
}
s . scope . contributions = append ( s . scope . contributions , acquiredContribution {
source : cloneSourceInfo ( info ) , payload : body , document : body ,
2026-10-19 17:34:21 +00:00
identity : identity , role : importRoleItem , scopeOwner : identity ,
2026-10-16 16:20:14 +00:00
processing : processing ,
} )
diagnostics := s . walkDeclarations ( s . access . dir ( canonical ) , declarations , depth , Path { } )
itemScope := s . scope
2026-10-16 19:23:43 +00:00
s . scope , s . itemScope , s . itemPrefix , s . itemFallback = parentScope , parentItemScope , parentPrefix , parentFallback
2026-10-16 16:20:14 +00:00
if len ( diagnostics ) != 0 {
2026-10-19 19:39:19 +00:00
return diagnostics
2026-10-16 16:20:14 +00:00
}
itemScope . destination = Path { }
s . scope . contributions = append ( s . scope . contributions , acquiredContribution {
2026-10-19 17:34:21 +00:00
source : cloneSourceInfo ( info ) , payload : body ,
identity : identity , role : importRoleItem , scopeOwner : parentScope . owner ,
destination : destination . clone ( ) , relativeDestination : relativeDestination . clone ( ) , processing : processing ,
pendingItem : & itemScope ,
2026-10-16 16:20:14 +00:00
} )
return nil
}
2026-10-19 19:39:19 +00:00
func ( s * importTraversal ) scheduleAcquisitionScopes ( scope * acquisitionScope ) {
* scope = scheduleAcquisitionScope ( * scope , s . importGraph )
for index := range scope . contributions {
if pending := scope . contributions [ index ] . pendingItem ; pending != nil {
s . scheduleAcquisitionScopes ( pending )
}
}
}
2026-10-19 17:34:21 +00:00
func ( s * importTraversal ) composePendingItems ( scope * acquisitionScope ) [ ] Diagnostic {
for index := range scope . contributions {
contribution := & scope . contributions [ index ]
if contribution . pendingItem == nil {
continue
}
itemScope := contribution . pendingItem
if diagnostics := s . composePendingItems ( itemScope ) ; len ( diagnostics ) != 0 {
2026-10-19 19:39:19 +00:00
return projectItemDiagnosticPaths ( diagnostics , * scope , contribution . destination , index )
2026-10-19 17:34:21 +00:00
}
documents := make ( [ ] * document . Node , 0 , len ( itemScope . contributions ) )
for _ , nested := range itemScope . contributions {
documents = append ( documents , nested . document )
}
completed , diagnostics := composeDocuments ( documents ... )
if len ( diagnostics ) != 0 {
2026-10-19 19:39:19 +00:00
return projectItemDiagnosticPaths ( diagnostics , * scope , contribution . destination , index )
2026-10-19 17:34:21 +00:00
}
completed . acquisition = [ ] acquisitionScope { cloneAcquisitionScope ( * itemScope ) }
projectNestedEvidence ( completed , * itemScope )
_ , placed , err := placeDocumentWithMode ( completed . root , contribution . destination , placementModeSequenceItem , contribution . payload . Location , maxDocumentDepth , maxDocumentNodes )
if err != nil {
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the source depth or node limit after destination placement" , contribution . source . ImportedFrom ) }
}
placementNodes := destinationWrapperNodeCountForMode ( contribution . destination , placementModeSequenceItem )
if s . accounting . nodes + placementNodes > s . limits . nodes {
return [ ] Diagnostic { importDiagnostic ( CodeImportLimitExceeded , "configuration exceeds the aggregate node limit" , contribution . source . ImportedFrom ) }
}
s . accounting . nodes += placementNodes
contribution . payload = completed . root
contribution . document = placed
contribution . nested = completed
contribution . pendingItem = nil
}
return nil
}
2026-10-19 19:29:35 +00:00
func importedVersionClaim ( documents [ ] * document . Node , scope acquisitionScope , composed * composedDocument , rule * VersionRule ) * Diagnostic {
2026-10-16 19:11:08 +00:00
if composed == nil || rule == nil {
return nil
}
2026-10-19 19:29:35 +00:00
mainIndex := - 1
for index , contribution := range scope . contributions {
if contribution . role == importRoleMain {
mainIndex = index
break
}
}
2026-10-17 04:52:20 +00:00
ranges := indexSequenceRanges ( composed . sequenceRanges )
2026-10-16 19:11:08 +00:00
for index , contribution := range documents {
if index == mainIndex {
continue
}
2026-10-17 04:52:20 +00:00
if node := fragmentVersionClaimWithIndex ( contribution , rule , index , ranges ) ; node != nil {
2026-10-16 19:11:08 +00:00
location := publicLocation ( node . Location )
return & Diagnostic {
Code : CodeImportVersion , Severity : SeverityError , Path : rule . Path . clone ( ) ,
Message : "imported fragments cannot contribute to the schema-version path" , Primary : & location ,
}
}
}
return nil
}
2026-10-17 04:54:01 +00:00
func prependCompositionDiagnosticPaths ( diagnostics [ ] Diagnostic , prefix Path ) [ ] Diagnostic {
2026-10-16 16:20:14 +00:00
cloned := append ( [ ] Diagnostic ( nil ) , diagnostics ... )
for index := range cloned {
2026-10-17 04:54:01 +00:00
if ! isCompositionDiagnostic ( cloned [ index ] ) {
continue
}
2026-10-16 16:20:14 +00:00
cloned [ index ] . Path = appendDestination ( prefix , cloned [ index ] . Path )
cloned [ index ] . Primary = cloneLocation ( cloned [ index ] . Primary )
cloned [ index ] . Related = cloneLocations ( cloned [ index ] . Related )
}
return cloned
}
2026-10-17 04:54:01 +00:00
func isCompositionDiagnostic ( diagnostic Diagnostic ) bool {
return diagnostic . Code == CodeComposeConflict || diagnostic . Code == CodeComposeInvalid
}
// On a composition failure only the earlier contributions are needed to locate
// this item. Project one enclosing scope at a time as traversal unwinds; syntax
// and access diagnostics keep their original source-local coordinates.
2026-10-19 19:39:19 +00:00
func projectItemDiagnosticPaths ( diagnostics [ ] Diagnostic , parent acquisitionScope , destination Path , beforeContribution int ) [ ] Diagnostic {
2026-10-17 04:54:01 +00:00
for _ , diagnostic := range diagnostics {
if isCompositionDiagnostic ( diagnostic ) {
2026-10-19 19:39:19 +00:00
prefix := parent
prefix . contributions = parent . contributions [ : beforeContribution ]
index := priorSequenceLength ( [ ] acquisitionScope { prefix } , destination )
2026-10-17 04:54:01 +00:00
return prependCompositionDiagnosticPaths ( diagnostics , destination . Index ( index ) )
}
}
return diagnostics
}
// This scan is confined to failed loads, not the successful construction path.
func priorSequenceLength ( scopes [ ] acquisitionScope , path Path ) int {
length := 0
for _ , scope := range scopes {
for _ , contribution := range scope . contributions {
if node , present := documentAtPath ( contribution . document , path ) ; present && node . Kind == document . Sequence {
length += len ( node . Sequence )
}
}
}
return length
}
func projectPriorInputDiagnosticPaths ( diagnostics [ ] Diagnostic , scopes [ ] acquisitionScope ) [ ] Diagnostic {
cloned := cloneDiagnostics ( diagnostics )
for index := range cloned {
if ! isCompositionDiagnostic ( cloned [ index ] ) {
continue
}
for position , segment := range cloned [ index ] . Path . segments {
if segment . kind != pathSegmentIndex {
continue
}
container := Path { segments : cloned [ index ] . Path . segments [ : position ] }
cloned [ index ] . Path . segments [ position ] . index += priorSequenceLength ( scopes , container )
// Registration does not address paths through item indexes. A prior
// input shifts the outer collection, not its item-local sequences.
break
}
}
return cloned
}
2026-10-16 16:20:14 +00:00
func projectNestedEvidence ( composed * composedDocument , scope acquisitionScope ) {
if composed == nil {
return
}
2026-10-17 04:44:29 +00:00
applications := composed . applications
projectedApplications := make ( [ ] historyApplication , 0 , len ( applications ) )
2026-10-17 04:52:20 +00:00
ranges := indexSequenceRanges ( composed . sequenceRanges )
2026-10-16 16:20:14 +00:00
for sourceIndex , contribution := range scope . contributions {
if contribution . nested == nil {
2026-10-17 04:44:29 +00:00
projectedApplications = append ( projectedApplications , applications [ sourceIndex ] )
2026-10-16 16:20:14 +00:00
continue
}
2026-10-17 04:52:20 +00:00
start := ranges [ sequenceRangeKey { sourceIndex : sourceIndex , path : contribution . destination . String ( ) } ] . start
2026-10-16 16:20:14 +00:00
prefix := contribution . destination . Index ( start )
2026-10-17 04:44:29 +00:00
if sourceIndex < len ( applications ) {
outer := applications [ sourceIndex ]
2026-10-16 16:20:14 +00:00
structural := document . Clone ( outer . value )
2026-10-17 04:44:29 +00:00
if node , found := documentAtPath ( structural , contribution . destination ) ; found && node . Kind == document . Sequence && len ( node . Sequence ) > 0 {
// The retained fragment is still a local singleton. Its assigned
// outer index belongs to the projection, not this source tree.
node . Sequence [ 0 ] = & document . Node { Kind : document . Mapping , Location : node . Sequence [ 0 ] . Location }
2026-10-16 16:20:14 +00:00
}
outer . value = structural
2026-10-17 04:44:29 +00:00
projectedApplications = append ( projectedApplications , outer )
2026-10-16 16:20:14 +00:00
for _ , nested := range contribution . nested . applications {
projected := nested
projected . path = appendDestination ( prefix , nested . path )
projected . sequences = cloneSequenceHistoryContributions ( nested . sequences )
2026-10-17 04:52:20 +00:00
projected . sequencesByPath = indexSequenceHistoryContributions ( projected . sequences )
2026-10-17 04:44:29 +00:00
projectedApplications = append ( projectedApplications , projected )
2026-10-16 16:20:14 +00:00
}
}
projectNestedOrigins ( composed . origins , contribution . nested . root , contribution . nested . origins , prefix )
}
2026-10-17 04:44:29 +00:00
composed . applications = projectedApplications
2026-10-16 16:20:14 +00:00
}
func projectNestedOrigins ( target map [ string ] Origin , root * document . Node , origins map [ string ] Origin , prefix Path ) {
var visit func ( * document . Node , Path )
visit = func ( node * document . Node , path Path ) {
if node == nil {
return
}
if origin , ok := origins [ path . String ( ) ] ; ok {
target [ appendDestination ( prefix , path ) . String ( ) ] = cloneOrigin ( origin )
}
for _ , entry := range node . Mapping {
visit ( entry . Value , path . Key ( entry . Key ) )
}
for index , child := range node . Sequence {
visit ( child , path . Index ( index ) )
}
}
visit ( root , Path { } )
}
func projectAcquiredDestinations ( composed * composedDocument , scope acquisitionScope , sources [ ] SourceInfo ) {
byID := make ( map [ string ] int , len ( sources ) )
for index := range sources {
byID [ sources [ index ] . ID ] = index
}
var projectScope func ( * composedDocument , acquisitionScope , Path , bool , string )
projectScope = func ( currentComposition * composedDocument , current acquisitionScope , prefix Path , insideItem bool , parentSourceID string ) {
2026-10-17 04:52:20 +00:00
ranges := indexSequenceRanges ( currentComposition . sequenceRanges )
2026-10-16 16:20:14 +00:00
for sourceIndex , contribution := range current . contributions {
if contribution . source . ID == parentSourceID {
continue
}
contributionPrefix := prefix
contributionInsideItem := insideItem
2026-10-17 04:52:20 +00:00
start := ranges [ sequenceRangeKey { sourceIndex : sourceIndex , path : contribution . destination . String ( ) } ] . start
2026-10-16 16:20:14 +00:00
if contribution . source . placementMode == placementModeSequenceItem {
container := appendDestination ( contributionPrefix , contribution . destination )
contribution . source . Destination = container . clone ( )
contribution . source . destinationUnresolved = false
current . contributions [ sourceIndex ] . source = cloneSourceInfo ( contribution . source )
if position , ok := byID [ contribution . source . ID ] ; ok {
sources [ position ] . Destination = container
sources [ position ] . destinationUnresolved = false
}
contributionPrefix = appendDestination ( container , Path { } . Index ( start ) )
contributionInsideItem = true
2026-10-17 04:42:23 +00:00
projectSourceVersionEvidence ( contribution . processing , contributionPrefix , nil , sourceIndex )
2026-10-16 16:20:14 +00:00
} else if contributionInsideItem {
exactDestination := appendDestination ( contributionPrefix , contribution . destination )
contribution . source . Destination = exactDestination . clone ( )
contribution . source . destinationUnresolved = false
current . contributions [ sourceIndex ] . source = cloneSourceInfo ( contribution . source )
if position , ok := byID [ contribution . source . ID ] ; ok {
sources [ position ] . Destination = exactDestination
sources [ position ] . destinationUnresolved = false
}
2026-10-17 04:42:23 +00:00
projectSourceVersionEvidence ( contribution . processing , exactDestination , nil , sourceIndex )
} else {
2026-10-17 04:52:20 +00:00
projectSourceVersionEvidence ( contribution . processing , contribution . destination , ranges , sourceIndex )
2026-10-16 16:20:14 +00:00
}
if contribution . nested != nil && contribution . nested . acquisition != nil {
for _ , nestedScope := range contribution . nested . acquisition {
projectScope ( contribution . nested , nestedScope , contributionPrefix , contributionInsideItem , contribution . source . ID )
}
}
}
}
projectScope ( composed , scope , Path { } , false , "" )
}
2026-10-17 04:52:20 +00:00
func projectSourceVersionEvidence ( processing * sourceVersionProcessingResult , destination Path , ranges sequenceRangeIndex , sourceIndex int ) {
2026-10-16 19:11:08 +00:00
if processing != nil && processing . evidence != nil {
2026-10-17 04:42:23 +00:00
evidence := processing . evidence
evidence . destination = destination . clone ( )
// Rebuild from source-local paths on each handoff: an input can be
// composed first on its own and then at a different offset in its tier.
evidence . projectedPaths = nil
paths := evidence . sensitivityPaths ( )
for index , path := range paths {
2026-10-17 04:52:20 +00:00
for position := range path . segments {
prefix := Path { segments : path . segments [ : position ] }
assigned , found := ranges [ sequenceRangeKey { sourceIndex : sourceIndex , path : prefix . String ( ) } ]
if ! found {
2026-10-17 04:42:23 +00:00
continue
}
item , ok := schemaIndex ( path . segments [ position ] )
if ok && path . segments [ position ] . kind != pathSegmentKey {
path . segments [ position ] = pathSegment { kind : pathSegmentIndex , index : assigned . start + item }
}
}
paths [ index ] = path
}
evidence . projectedPaths = paths
2026-10-16 19:11:08 +00:00
}
}
2026-09-29 17:29:01 +00:00
func ( s * importTraversal ) readImport ( name , sourceID string , optional bool ) ( [ ] byte , bool , * Diagnostic ) {
remaining := s . limits . bytes - s . accounting . bytes
2026-09-12 15:58:06 +00:00
limit := min ( int64 ( maxSourceBytes ) , remaining )
if limit < 0 {
limit = 0
}
2026-09-29 17:29:01 +00:00
data , failure := readRegularFile ( name , s . access . stat , s . access . open , limit )
2026-09-12 15:58:06 +00:00
if failure != nil {
if optional && failure . missingTarget {
return nil , true , nil
}
value := sourceReadDiagnostic ( failure , sourceID , CodeImportLimitExceeded , "configuration exceeds a source or aggregate byte limit" )
return nil , false , & value
}
2026-09-29 17:29:01 +00:00
s . accounting . bytes += int64 ( len ( data ) )
2026-09-12 15:58:06 +00:00
return data , false , nil
}
func ( s * importTraversal ) currentRoute ( location Location ) importRoute {
locations := make ( [ ] Location , 0 , len ( s . stack ) + 1 )
for _ , route := range s . stack {
if len ( route . locations ) != 0 {
locations = append ( locations , route . locations [ len ( route . locations ) - 1 ] )
}
}
locations = append ( locations , location )
return importRoute { locations : locations }
}
func sourceInfos ( source * SourceInfo ) [ ] SourceInfo {
if source == nil {
return nil
}
return [ ] SourceInfo { cloneSourceInfo ( * source ) }
}
func importDiagnostic ( code Code , message string , location * Location ) Diagnostic {
return Diagnostic { Code : code , Severity : SeverityError , Message : message , Primary : cloneLocation ( location ) }
}
func importCycleDiagnostic ( target string , location Location , cycle [ ] importRoute ) Diagnostic {
paths := make ( [ ] string , 0 , len ( cycle ) + 1 )
related := make ( [ ] Location , 0 , len ( cycle ) )
for _ , route := range cycle {
paths = append ( paths , route . canonical )
if len ( route . locations ) != 0 {
related = append ( related , route . locations [ len ( route . locations ) - 1 ] )
}
}
paths = append ( paths , target )
return Diagnostic {
Code : CodeImportCycle , Severity : SeverityError ,
Message : "import cycle detected: " + strings . Join ( paths , " -> " ) ,
Primary : & location , Related : related ,
}
}
func importRepeatedDiagnostic ( location Location , previous , current importRoute ) Diagnostic {
related := append ( [ ] Location ( nil ) , previous . locations ... )
if len ( current . locations ) > 1 {
related = append ( related , current . locations [ : len ( current . locations ) - 1 ] ... )
}
return Diagnostic {
Code : CodeImportRepeated , Severity : SeverityError ,
Message : "configuration source is included by more than one import route" ,
Primary : & location , Related : related ,
}
}