Compose grouped underlays in shared load lifecycle

This commit is contained in:
2026-09-29 17:52:20 +00:00
parent 90c6e8ed7e
commit 1cdf90d831
7 changed files with 494 additions and 25 deletions

View File

@@ -1,6 +1,10 @@
package engine
import "gitea.maximumdirect.net/eric/ConfigKit/internal/document"
import (
"strconv"
"gitea.maximumdirect.net/eric/ConfigKit/internal/document"
)
// assembledInput is the source/document handoff across schema and version checks.
type assembledInput struct {
@@ -11,14 +15,21 @@ type assembledInput struct {
}
func assembleBaseInput[T any](source Source, options Options[T]) (assembledInput, []Diagnostic) {
parsed, diagnostics := parseSource(source, "source-1", defaultParseLimits())
return assembleBaseInputTracked(source, options, &importAccounting{}, nil, nil)
}
func assembleBaseInputTracked[T any](source Source, options Options[T], accounting *importAccounting, visited map[resourceIdentity]importRoute, hostToken *namespaceToken) (assembledInput, []Diagnostic) {
limits := defaultImportLimits()
parseLimits := defaultParseLimits()
parseLimits.source.remaining = limits.bytes - accounting.bytes
parsed, diagnostics := parseSource(source, "source-"+strconv.Itoa(accounting.sources+1), parseLimits)
input := assembledInput{parsed: parsed, document: parsed.document}
if len(diagnostics) != 0 {
input.sources = sourceInfos(parsed.source)
return input, diagnostics
}
if options.Imports {
input.composition, input.sources, diagnostics = loadImportedDocuments(source, options.Filesystem, parsed, options.Definition.Version, defaultImportLimits())
input.composition, input.sources, diagnostics = loadImportedDocumentsTracked(source, options.Filesystem, parsed, options.Definition.Version, limits, accounting, visited, hostToken)
if len(diagnostics) != 0 {
return input, diagnostics
}
@@ -35,10 +46,37 @@ func assembleBaseInput[T any](source Source, options Options[T]) (assembledInput
if diagnostics := disabledDirectiveDiagnostics(input.document, Path{}); len(diagnostics) != 0 {
return input, diagnostics
}
if accounting.sources+1 > limits.sources || accounting.bytes+parsed.bytes > limits.bytes || accounting.nodes+countInputNodes(input.document) > limits.nodes {
return input, []Diagnostic{sourceDiagnostic(CodeSourceLimitExceeded, parsed.source.ID, "configuration exceeds the aggregate input limit")}
}
if diagnostic := registerAcquiredSource(source, options.Filesystem, parsed.source, visited, hostToken); diagnostic != nil {
return input, []Diagnostic{*diagnostic}
}
accounting.sources++
accounting.bytes += parsed.bytes
accounting.nodes += countInputNodes(input.document)
}
return input, nil
}
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
}
func applyInputLayers[T any](source Source, options Options[T], input assembledInput) (assembledInput, []Diagnostic) {
if !activeOverlay(options.Overlay) && len(options.Overrides) == 0 {
return input, nil