211 lines
5.9 KiB
Go
211 lines
5.9 KiB
Go
package configkit
|
|
|
|
// Layer identifies the precedence layer responsible for a configuration value.
|
|
type Layer string
|
|
|
|
const (
|
|
LayerDefault Layer = "default"
|
|
LayerBase Layer = "base"
|
|
LayerProfile Layer = "profile"
|
|
LayerCLI Layer = "cli"
|
|
LayerResolution Layer = "resolution"
|
|
)
|
|
|
|
// ChangeKind identifies an application resolution operation. The zero value is
|
|
// used for input and default origins.
|
|
type ChangeKind string
|
|
|
|
const (
|
|
ChangeDerivedDefault ChangeKind = "derived_default"
|
|
ChangeNormalization ChangeKind = "normalization"
|
|
)
|
|
|
|
// Severity classifies a diagnostic.
|
|
type Severity string
|
|
|
|
const (
|
|
SeverityError Severity = "error"
|
|
SeverityWarning Severity = "warning"
|
|
)
|
|
|
|
// Code is a stable, machine-readable diagnostic classification.
|
|
type Code string
|
|
|
|
const (
|
|
CodeSourceInvalid Code = "source.invalid"
|
|
CodeSourceMissing Code = "source.missing"
|
|
CodeSourcePermission Code = "source.permission"
|
|
CodeSourceRead Code = "source.read"
|
|
CodeSourceNotRegular Code = "source.not_regular"
|
|
CodeSourceLimitExceeded Code = "source.limit_exceeded"
|
|
CodeSourceReaderUsed Code = "source.reader_used"
|
|
|
|
CodeYAMLInvalid Code = "yaml.invalid"
|
|
CodeYAMLEmpty Code = "yaml.empty"
|
|
CodeYAMLMultipleDocuments Code = "yaml.multiple_documents"
|
|
CodeYAMLRootType Code = "yaml.root_type"
|
|
CodeYAMLDuplicateKey Code = "yaml.duplicate_key"
|
|
CodeYAMLTag Code = "yaml.tag"
|
|
CodeYAMLAnchor Code = "yaml.anchor"
|
|
CodeYAMLAlias Code = "yaml.alias"
|
|
CodeYAMLMergeKey Code = "yaml.merge_key"
|
|
CodeYAMLScalar Code = "yaml.scalar"
|
|
CodeYAMLDepthLimit Code = "yaml.depth_limit"
|
|
CodeYAMLNodeLimit Code = "yaml.node_limit"
|
|
|
|
CodeSchemaRoot Code = "schema.root"
|
|
CodeSchemaUnsupportedType Code = "schema.unsupported_type"
|
|
CodeSchemaAmbiguousField Code = "schema.ambiguous_field"
|
|
CodeSchemaTag Code = "schema.tag"
|
|
CodeSchemaTextCodec Code = "schema.text_codec"
|
|
CodeSchemaInline Code = "schema.inline"
|
|
CodeSchemaCycle Code = "schema.cycle"
|
|
CodeSchemaProjectionLimit Code = "schema.projection_limit"
|
|
CodeSchemaCodec Code = "schema.codec"
|
|
CodeSchemaNonFinite Code = "schema.non_finite"
|
|
CodeSchemaDynamicType Code = "schema.dynamic_type"
|
|
|
|
CodeDecodeType Code = "decode.type"
|
|
CodeDecodeNull Code = "decode.null"
|
|
CodeDecodeRange Code = "decode.range"
|
|
CodeDecodeDuration Code = "decode.duration"
|
|
CodeDecodeText Code = "decode.text"
|
|
CodeDecodeUnknownField Code = "decode.unknown_field"
|
|
CodeDecodeArrayLength Code = "decode.array_length"
|
|
)
|
|
|
|
// Location identifies a position in a configuration source. Zero line and column
|
|
// values mean that coordinates are unavailable or synthetic.
|
|
type Location struct {
|
|
SourceID string
|
|
Line int
|
|
Column int
|
|
}
|
|
|
|
// SourceInfo describes a source discovered during a load. Path is a canonical
|
|
// local path when one exists. ImportedFrom identifies the declaration that
|
|
// included this source.
|
|
type SourceInfo struct {
|
|
ID string
|
|
Label string
|
|
Path string
|
|
Layer Layer
|
|
ImportedFrom *Location
|
|
}
|
|
|
|
// Diagnostic is a safe structured problem report. Message and source labels must
|
|
// never contain configuration values or other secrets.
|
|
type Diagnostic struct {
|
|
Code Code
|
|
Severity Severity
|
|
Path Path
|
|
Message string
|
|
Primary *Location
|
|
Related []Location
|
|
}
|
|
|
|
// Origin describes where an effective definition came from. Multiple locations
|
|
// represent a composite origin.
|
|
type Origin struct {
|
|
Layer Layer
|
|
Locations []Location
|
|
Operation ChangeKind
|
|
}
|
|
|
|
// FieldInfo describes an effective configuration path.
|
|
type FieldInfo struct {
|
|
Explicit bool
|
|
Null bool
|
|
Origin Origin
|
|
}
|
|
|
|
// Change describes a definition or application-resolution operation. Historical
|
|
// values are intentionally not exposed by this record.
|
|
type Change struct {
|
|
Path Path
|
|
Origin Origin
|
|
Previous []Origin
|
|
Reasons []string
|
|
Dependencies []Path
|
|
}
|
|
|
|
func cloneLocation(location *Location) *Location {
|
|
if location == nil {
|
|
return nil
|
|
}
|
|
cloned := *location
|
|
return &cloned
|
|
}
|
|
|
|
func cloneLocations(locations []Location) []Location {
|
|
if locations == nil {
|
|
return nil
|
|
}
|
|
return append([]Location(nil), locations...)
|
|
}
|
|
|
|
func cloneSourceInfo(source SourceInfo) SourceInfo {
|
|
source.ImportedFrom = cloneLocation(source.ImportedFrom)
|
|
return source
|
|
}
|
|
|
|
func cloneSourceInfos(sources []SourceInfo) []SourceInfo {
|
|
if sources == nil {
|
|
return nil
|
|
}
|
|
cloned := make([]SourceInfo, len(sources))
|
|
for i, source := range sources {
|
|
cloned[i] = cloneSourceInfo(source)
|
|
}
|
|
return cloned
|
|
}
|
|
|
|
func cloneOrigin(origin Origin) Origin {
|
|
origin.Locations = cloneLocations(origin.Locations)
|
|
return origin
|
|
}
|
|
|
|
func cloneFieldInfo(info FieldInfo) FieldInfo {
|
|
info.Origin = cloneOrigin(info.Origin)
|
|
return info
|
|
}
|
|
|
|
func cloneChange(change Change) Change {
|
|
change.Path = change.Path.clone()
|
|
change.Origin = cloneOrigin(change.Origin)
|
|
if change.Previous != nil {
|
|
previous := make([]Origin, len(change.Previous))
|
|
for i, origin := range change.Previous {
|
|
previous[i] = cloneOrigin(origin)
|
|
}
|
|
change.Previous = previous
|
|
}
|
|
change.Reasons = append([]string(nil), change.Reasons...)
|
|
if change.Dependencies != nil {
|
|
dependencies := make([]Path, len(change.Dependencies))
|
|
for i, path := range change.Dependencies {
|
|
dependencies[i] = path.clone()
|
|
}
|
|
change.Dependencies = dependencies
|
|
}
|
|
return change
|
|
}
|
|
|
|
func cloneDiagnostic(diagnostic Diagnostic) Diagnostic {
|
|
diagnostic.Path = diagnostic.Path.clone()
|
|
diagnostic.Primary = cloneLocation(diagnostic.Primary)
|
|
diagnostic.Related = cloneLocations(diagnostic.Related)
|
|
return diagnostic
|
|
}
|
|
|
|
func cloneDiagnostics(diagnostics []Diagnostic) []Diagnostic {
|
|
if diagnostics == nil {
|
|
return nil
|
|
}
|
|
cloned := make([]Diagnostic, len(diagnostics))
|
|
for i, diagnostic := range diagnostics {
|
|
cloned[i] = cloneDiagnostic(diagnostic)
|
|
}
|
|
return cloned
|
|
}
|