docmodel

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildDocumentSymbols

func BuildDocumentSymbols(root *UnifiedNode, totalLines int) []lsp.DocumentSymbol

BuildDocumentSymbols creates LSP document symbols from a UnifiedNode tree. This provides a format-agnostic symbol building implementation that works for both YAML and JSON documents.

func ExtractTypedPrefix

func ExtractTypedPrefix(
	position SyntacticPosition,
	style SyntacticStyle,
	textBefore string,
) string

ExtractTypedPrefix extracts the text being typed at the current position based on the syntactic position and style.

Types

type CompletionCapability

type CompletionCapability int

CompletionCapability represents the type of completion being provided. This is used to determine format compatibility.

const (
	// CapabilityKeyCompletion suggests field/key names (e.g., spec field names).
	// These are typically disabled for JSONC because editors handle JSON property completion.
	CapabilityKeyCompletion CompletionCapability = iota

	// CapabilityValueCompletion suggests values for a field (e.g., types, operators, references).
	// These work for both YAML and JSONC formats.
	CapabilityValueCompletion
)

type CompletionContext

type CompletionContext struct {
	Kind CompletionContextKind

	// Cursor context from position resolution (unified structural + syntactic context)
	CursorCtx *CursorContext

	// Extracted names when applicable
	ResourceName          string
	DataSourceName        string
	ChildName             string
	PotentialResourceName string // For standalone resource detection (needs blueprint validation)

	// Text analysis results
	TextBefore string
	IsInSub    bool
}

CompletionContext provides rich context for completion suggestions.

func DetermineCompletionContext

func DetermineCompletionContext(cursorCtx *CursorContext) *CompletionContext

DetermineCompletionContext analyzes the cursor context and text to determine what kind of completion should be provided.

type CompletionContextKind

type CompletionContextKind int

CompletionContextKind provides type-safe completion context classification. This replaces the string-based element type matching in completion.go.

const (
	CompletionContextUnknown CompletionContextKind = iota

	// Type fields
	CompletionContextResourceType
	CompletionContextDataSourceType
	CompletionContextVariableType
	CompletionContextValueType
	CompletionContextExportType
	CompletionContextDataSourceFieldType

	// Data source filter fields
	CompletionContextDataSourceFilterField
	CompletionContextDataSourceFilterOperator

	// Data source nested field contexts
	CompletionContextDataSourceFilterDefinitionField // Fields inside a filter definition (field, operator, search)
	CompletionContextDataSourceExportDefinitionField // Fields inside an export definition (type, aliasFor, description)
	CompletionContextDataSourceMetadataField         // Fields inside data source metadata (displayName, annotations, custom)

	// Data source export value contexts (aliasFor references data source fields)
	CompletionContextDataSourceExportAliasForValue // aliasFor: value field referencing data source spec fields
	CompletionContextDataSourceExportName          // Export name key (suggests data source spec fields)

	// Resource spec field (editing directly in YAML/JSONC definition)
	CompletionContextResourceSpecField
	// Resource spec field value (editing a value for a field with AllowedValues)
	CompletionContextResourceSpecFieldValue

	// Top-level blueprint fields with enum values
	CompletionContextVersionField   // version: field with known spec versions
	CompletionContextTransformField // transform: field with available transforms

	// Custom variable type options (default value for custom type variables)
	CompletionContextCustomVariableTypeValue

	// Resource metadata field (displayName, labels, annotations, custom)
	CompletionContextResourceMetadataField

	// Resource annotation key (inside metadata.annotations, suggests link annotation keys)
	CompletionContextResourceAnnotationKey

	// Resource annotation value (value for a resource annotation with AllowedValues)
	CompletionContextResourceAnnotationValue

	// Resource definition field (type, description, spec, metadata, etc.)
	CompletionContextResourceDefinitionField

	// Resource linkSelector field (byLabel, exclude)
	CompletionContextLinkSelectorField

	// Resource linkSelector exclude value (resource names)
	CompletionContextLinkSelectorExcludeValue

	// Definition field contexts for other sections
	CompletionContextVariableDefinitionField
	CompletionContextValueDefinitionField
	CompletionContextDataSourceDefinitionField
	CompletionContextIncludeDefinitionField
	CompletionContextExportDefinitionField
	CompletionContextBlueprintTopLevelField

	// Substitution references
	CompletionContextStringSub // Inside ${...} but no specific reference
	CompletionContextStringSubVariableRef
	CompletionContextStringSubResourceRef
	CompletionContextStringSubResourceProperty
	CompletionContextStringSubDataSourceRef
	CompletionContextStringSubDataSourceProperty
	CompletionContextStringSubValueRef
	CompletionContextStringSubChildRef
	CompletionContextStringSubElemRef
	CompletionContextStringSubChildProperty         // After children.{name}., suggest child exports
	CompletionContextStringSubValueProperty         // After values.{name}., suggest value fields/indices
	CompletionContextStringSubPartialPath           // Typing a partial path (no completions)
	CompletionContextStringSubPotentialResourceProp // Potential standalone resource property (needs blueprint validation)

	// Data source annotation contexts
	CompletionContextDataSourceAnnotationKey   // Inside data source metadata.annotations, suggest annotation keys
	CompletionContextDataSourceAnnotationValue // Value for a data source annotation

	// Resource label key context
	CompletionContextResourceLabelKey // Inside metadata.labels, suggest label keys from linked resources

	// Export field reference contexts (field property in blueprint exports)
	CompletionContextExportFieldTopLevel           // Empty field value, suggest namespaces
	CompletionContextExportFieldResourceRef        // After "resources.", suggest resource names
	CompletionContextExportFieldResourceProperty   // After "resources.{name}.", suggest spec/metadata/fields
	CompletionContextExportFieldVariableRef        // After "variables.", suggest variable names
	CompletionContextExportFieldValueRef           // After "values.", suggest value names
	CompletionContextExportFieldValueProperty      // After "values.{name}.", suggest value fields/indices
	CompletionContextExportFieldChildRef           // After "children.", suggest child names
	CompletionContextExportFieldChildProperty      // After "children.{name}.", suggest exports
	CompletionContextExportFieldDataSourceRef      // After "datasources.", suggest data source names
	CompletionContextExportFieldDataSourceProperty // After "datasources.{name}.", suggest exports
)

func (CompletionContextKind) GetCompletionCapability

func (k CompletionContextKind) GetCompletionCapability() CompletionCapability

GetCompletionCapability returns the capability type for this completion context. Key completions suggest field names, value completions suggest field values.

func (CompletionContextKind) IsDataSourceFilter

func (k CompletionContextKind) IsDataSourceFilter() bool

IsDataSourceFilter returns true if this context is for a data source filter.

func (CompletionContextKind) IsEnabledForFormat

func (k CompletionContextKind) IsEnabledForFormat(format DocumentFormat) bool

IsEnabledForFormat returns true if this completion context is enabled for the given format. Key completions are disabled for JSONC because JSON editors typically handle property completion. Value completions work for both formats.

func (CompletionContextKind) IsExportFieldContext

func (k CompletionContextKind) IsExportFieldContext() bool

IsExportFieldContext returns true if this context is for an export field reference.

func (CompletionContextKind) IsSubstitution

func (k CompletionContextKind) IsSubstitution() bool

IsSubstitution returns true if this context is inside a substitution.

func (CompletionContextKind) IsSubstitutionContext

func (k CompletionContextKind) IsSubstitutionContext() bool

IsSubstitutionContext returns true if this context is for completions inside ${...} substitutions.

func (CompletionContextKind) IsTypeField

func (k CompletionContextKind) IsTypeField() bool

IsTypeField returns true if this context is for a type field.

func (CompletionContextKind) String

func (k CompletionContextKind) String() string

String returns a string representation of CompletionContextKind.

type CursorContext

type CursorContext struct {
	// Position is the cursor position in the document.
	Position source.Position

	// StructuralPath is the format-agnostic path from root to the current node.
	// Example: /resources/myResource/spec/tableName
	StructuralPath StructuredPath

	// UnifiedNode is the AST node at the cursor position.
	UnifiedNode *UnifiedNode

	// AncestorNodes contains nodes from root to the deepest node at the position.
	AncestorNodes []*UnifiedNode

	// Syntactic contains the syntactic editing context at the cursor.
	// This is format-aware but provides a unified interface.
	Syntactic *SyntacticContext

	// SchemaNode is the corresponding schema node if available.
	SchemaNode *schema.TreeNode

	// SchemaElement is the schema element at this position if available.
	SchemaElement any

	// DocumentCtx is a reference to the containing document context.
	DocumentCtx *DocumentContext

	// CurrentLine is the full current line of text.
	CurrentLine string

	// TextBefore is the text on the line before the cursor.
	TextBefore string

	// TextAfter is the text on the line after the cursor.
	TextAfter string

	// CurrentWord is the word at the cursor position.
	CurrentWord string

	// ExtractedFieldName is set during completion context determination
	// when the field name needs to be extracted from TextBefore.
	ExtractedFieldName string

	// IsStale is true if using last-known-good data due to parse errors.
	IsStale bool
}

CursorContext provides unified context information for a cursor position. It composes structural path information (format-agnostic) with syntactic editing context (format-aware but with a unified interface).

This is the preferred context type for new code. It provides cleaner separation between structural position ("where am I in the document tree") and syntactic position ("what kind of edit position is this").

func (*CursorContext) ElementKind

func (ctx *CursorContext) ElementKind() SchemaElementKind

ElementKind returns the kind of schema element at this context.

func (*CursorContext) GetASTPath

func (ctx *CursorContext) GetASTPath() StructuredPath

GetASTPath returns the structural path. Deprecated: Use StructuralPath field directly.

func (*CursorContext) GetDataSourceName

func (ctx *CursorContext) GetDataSourceName() (string, bool)

GetDataSourceName returns the data source name if under a data source.

func (*CursorContext) GetEnclosingQuoteType

func (ctx *CursorContext) GetEnclosingQuoteType() QuoteType

GetEnclosingQuoteType returns the quote type of the enclosing string.

func (*CursorContext) GetFieldName

func (ctx *CursorContext) GetFieldName() string

GetFieldName returns the field name if this is a map value.

func (*CursorContext) GetKeyRange

func (ctx *CursorContext) GetKeyRange() *source.Range

GetKeyRange returns the key range if this is a map value.

func (*CursorContext) GetRange

func (ctx *CursorContext) GetRange() *source.Range

GetRange returns the range of the current node.

func (*CursorContext) GetResourceName

func (ctx *CursorContext) GetResourceName() (string, bool)

GetResourceName returns the resource name if under a resource.

func (*CursorContext) GetSubstitutionText

func (ctx *CursorContext) GetSubstitutionText() string

GetSubstitutionText returns the text inside the current substitution.

func (*CursorContext) GetTypedPrefix

func (ctx *CursorContext) GetTypedPrefix() string

GetTypedPrefix returns the text being typed at the current position.

func (*CursorContext) GetValue

func (ctx *CursorContext) GetValue() string

GetValue returns the scalar value if this is a scalar node.

func (*CursorContext) GetValueName

func (ctx *CursorContext) GetValueName() (string, bool)

GetValueName returns the value name if under a value.

func (*CursorContext) GetVariableName

func (ctx *CursorContext) GetVariableName() (string, bool)

GetVariableName returns the variable name if under a variable.

func (*CursorContext) HasError

func (ctx *CursorContext) HasError() bool

HasError returns true if the position is in an error region.

func (*CursorContext) InSubstitution

func (ctx *CursorContext) InSubstitution() bool

InSubstitution returns true if the cursor is inside a ${...} substitution.

func (*CursorContext) IsAtDataSourceFilter

func (ctx *CursorContext) IsAtDataSourceFilter() bool

IsAtDataSourceFilter returns true if the position is in a data source filter.

func (*CursorContext) IsAtKeyPosition

func (ctx *CursorContext) IsAtKeyPosition() bool

IsAtKeyPosition returns true if the cursor is at a key/field name position.

func (*CursorContext) IsAtResourceSpec

func (ctx *CursorContext) IsAtResourceSpec() bool

IsAtResourceSpec returns true if the position is in a resource spec.

func (*CursorContext) IsAtResourceType

func (ctx *CursorContext) IsAtResourceType() bool

IsAtResourceType returns true if the position is at a resource type field.

func (*CursorContext) IsAtSequenceItemPosition

func (ctx *CursorContext) IsAtSequenceItemPosition() bool

IsAtSequenceItemPosition returns true if the cursor is at a sequence item position.

func (*CursorContext) IsAtTypeField

func (ctx *CursorContext) IsAtTypeField() bool

IsAtTypeField returns true if the position is at a type field.

func (*CursorContext) IsAtValuePosition

func (ctx *CursorContext) IsAtValuePosition() bool

IsAtValuePosition returns true if the cursor is at a value position.

func (*CursorContext) IsBlockStyle

func (ctx *CursorContext) IsBlockStyle() bool

IsBlockStyle returns true if the context is in block-style YAML.

func (*CursorContext) IsEmpty

func (ctx *CursorContext) IsEmpty() bool

IsEmpty returns true if no node was found at the position.

func (*CursorContext) IsFlowStyle

func (ctx *CursorContext) IsFlowStyle() bool

IsFlowStyle returns true if the context is in flow-style YAML or JSONC.

func (*CursorContext) IsInDataSources

func (ctx *CursorContext) IsInDataSources() bool

IsInDataSources returns true if the position is under the datasources section.

func (*CursorContext) IsInResources

func (ctx *CursorContext) IsInResources() bool

IsInResources returns true if the position is under the resources section.

func (*CursorContext) IsPrecededByOperatorField

func (ctx *CursorContext) IsPrecededByOperatorField() bool

IsPrecededByOperatorField returns true if the cursor is right after "operator:".

type DocumentContext

type DocumentContext struct {
	URI     string
	Format  DocumentFormat
	Content string
	Version int

	// Current state (may be invalid)
	CurrentAST *UnifiedNode
	ParseError error
	Status     DocumentStatus

	// Last-known-good state (always valid when available)
	LastValidAST     *UnifiedNode
	LastValidSchema  *schema.Blueprint
	LastValidTree    *schema.TreeNode
	LastValidVersion int

	// Position index for efficient lookups
	PositionIndex *PositionIndex

	// Schema information (only available when document validates)
	Blueprint  *schema.Blueprint
	SchemaTree *schema.TreeNode

	// Syntax errors detected during parsing (e.g., duplicate keys)
	DuplicateKeys *DuplicateKeyResult
	// contains filtered or unexported fields
}

DocumentContext provides unified access to document information for language features. It maintains both current and last-known-good state for robustness during editing.

func NewDocumentContext

func NewDocumentContext(
	uri string,
	content string,
	format DocumentFormat,
	logger *zap.Logger,
) *DocumentContext

NewDocumentContext creates a new document context from content.

func NewDocumentContextFromSchema

func NewDocumentContextFromSchema(
	uri string,
	blueprint *schema.Blueprint,
	tree *schema.TreeNode,
) *DocumentContext

NewDocumentContextFromSchema creates a DocumentContext from existing schema information. This is useful for transitioning from the old state management approach where schema and tree are already available.

func (*DocumentContext) CollectSchemaNodesAtPosition

func (ctx *DocumentContext) CollectSchemaNodesAtPosition(pos source.Position, leeway int) []*schema.TreeNode

CollectSchemaNodesAtPosition collects all schema tree nodes containing the position. This is used for hover to find the hoverable element in the ancestor chain.

func (*DocumentContext) FindFunctionAtPosition

func (ctx *DocumentContext) FindFunctionAtPosition(pos source.Position) *substitutions.SubstitutionFunctionExpr

FindFunctionAtPosition finds the deepest function expression at the given position. This traverses the schema tree to find nested function calls.

func (*DocumentContext) GetCursorContext

func (ctx *DocumentContext) GetCursorContext(pos source.Position, leeway int) *CursorContext

GetCursorContext returns unified context information for a cursor position. This is the preferred method for getting position context.

func (*DocumentContext) GetEffectiveAST

func (ctx *DocumentContext) GetEffectiveAST() *UnifiedNode

GetEffectiveAST returns the current AST or falls back to last-known-good.

func (*DocumentContext) GetEffectiveSchema

func (ctx *DocumentContext) GetEffectiveSchema() *schema.Blueprint

GetEffectiveSchema returns the current schema or falls back to last-known-good.

func (*DocumentContext) HasSchema

func (ctx *DocumentContext) HasSchema() bool

HasSchema returns true if schema information is available.

func (*DocumentContext) HasValidAST

func (ctx *DocumentContext) HasValidAST() bool

HasValidAST returns true if a valid AST is available (current or last-known-good).

func (*DocumentContext) NewCursorContext

func (ctx *DocumentContext) NewCursorContext(pos source.Position, leeway int) *CursorContext

NewCursorContext creates a CursorContext for a given position in a document. It resolves the structural path, detects the syntactic context, and correlates with schema information if available.

func (*DocumentContext) UpdateContent

func (ctx *DocumentContext) UpdateContent(content string, version int)

UpdateContent updates the document content and re-parses.

func (*DocumentContext) UpdateSchema

func (ctx *DocumentContext) UpdateSchema(blueprint *schema.Blueprint, tree *schema.TreeNode)

UpdateSchema sets the schema information after successful validation.

type DocumentFormat

type DocumentFormat int

DocumentFormat identifies the document format.

const (
	FormatYAML DocumentFormat = iota
	FormatJSONC
)

func (DocumentFormat) String

func (f DocumentFormat) String() string

String returns a string representation of DocumentFormat.

type DocumentStatus

type DocumentStatus int

DocumentStatus indicates the validity state of a document.

const (
	StatusValid         DocumentStatus = iota // Document parses and validates successfully
	StatusParsingErrors                       // Has parse errors but some features work
	StatusDegraded                            // Using stale data from last valid parse
	StatusUnavailable                         // No AST available
)

func (DocumentStatus) String

func (s DocumentStatus) String() string

String returns a string representation of DocumentStatus.

type DuplicateKeyError

type DuplicateKeyError struct {
	Key      string
	Range    source.Range
	KeyRange *source.Range
	IsFirst  bool
}

DuplicateKeyError represents a duplicate key found in a mapping.

type DuplicateKeyResult

type DuplicateKeyResult struct {
	Errors []*DuplicateKeyError
}

DuplicateKeyResult holds all duplicate key errors found in a document.

func DetectDuplicateKeys

func DetectDuplicateKeys(root *UnifiedNode) *DuplicateKeyResult

DetectDuplicateKeys analyzes a UnifiedNode tree and returns all duplicate key errors.

type HoverContext

type HoverContext struct {
	// ElementKind is the type-safe classification of the schema element
	ElementKind SchemaElementKind

	// SchemaElement is the raw schema element (for type assertions)
	SchemaElement any

	// TreeNode is the schema tree node containing position information
	TreeNode *schema.TreeNode

	// AncestorNodes are the ancestor tree nodes from root to the target node
	AncestorNodes []*schema.TreeNode

	// DescendantNodes are tree nodes deeper than the target node
	// that were collected at the hover position but are not themselves hoverable.
	DescendantNodes []*schema.TreeNode

	// CursorPosition is the 1-based cursor position used for hover.
	// This is set by the caller after DetermineHoverContext returns.
	CursorPosition source.Position
}

HoverContext provides context for hover information at a position.

func DetermineHoverContext

func DetermineHoverContext(collected []*schema.TreeNode) *HoverContext

DetermineHoverContext analyzes collected tree nodes to find the hover target. It works backwards through the collected elements to find the first element that supports hover content.

type JSONParser

type JSONParser struct {
	// contains filtered or unexported fields
}

JSONParser wraps tree-sitter for parsing JSON/JSONC documents. Must call Close() when done to free C memory.

func NewJSONParser

func NewJSONParser() (*JSONParser, error)

NewJSONParser creates a new JSON parser using tree-sitter.

func (*JSONParser) Close

func (p *JSONParser) Close()

Close releases the parser resources.

func (*JSONParser) Parse

func (p *JSONParser) Parse(content []byte) *tree_sitter.Tree

Parse parses JSON content and returns the tree-sitter tree.

func (*JSONParser) ParseIncremental

func (p *JSONParser) ParseIncremental(content []byte, oldTree *tree_sitter.Tree) *tree_sitter.Tree

ParseIncremental parses JSON content with an existing tree for incremental updates.

type NodeKind

type NodeKind int

NodeKind represents the structural type of a unified AST node.

const (
	NodeKindDocument NodeKind = iota
	NodeKindMapping
	NodeKindSequence
	NodeKindScalar
	NodeKindKey
	NodeKindError // Marks invalid/error regions from tree-sitter
)

func (NodeKind) String

func (k NodeKind) String() string

String returns a string representation of NodeKind for debugging.

type PathSegment

type PathSegment struct {
	Kind      PathSegmentKind
	FieldName string // Set when Kind == PathSegmentField
	Index     int    // Set when Kind == PathSegmentIndex
}

PathSegment represents a single segment in a node path.

func (PathSegment) String

func (s PathSegment) String() string

String returns a string representation of the segment.

type PathSegmentKind

type PathSegmentKind int

PathSegmentKind identifies the type of path segment.

const (
	PathSegmentField PathSegmentKind = iota
	PathSegmentIndex
)

type PositionIndex

type PositionIndex struct {
	// contains filtered or unexported fields
}

PositionIndex provides efficient lookup of nodes at a given position. It indexes nodes by line number for O(1) line lookup, then filters by column.

func NewPositionIndex

func NewPositionIndex(root *UnifiedNode) *PositionIndex

NewPositionIndex builds an index from a unified node tree.

func (*PositionIndex) AllNodes

func (idx *PositionIndex) AllNodes() []*UnifiedNode

AllNodes returns all indexed nodes.

func (*PositionIndex) DeepestNodeAtPosition

func (idx *PositionIndex) DeepestNodeAtPosition(pos source.Position, leeway int) *UnifiedNode

DeepestNodeAtPosition returns the most specific node at the position.

func (*PositionIndex) FindNodeByPath

func (idx *PositionIndex) FindNodeByPath(path string) *UnifiedNode

FindNodeByPath finds a node by its path string.

func (*PositionIndex) MaxLine

func (idx *PositionIndex) MaxLine() int

MaxLine returns the maximum line number in the index.

func (*PositionIndex) NodesAtPosition

func (idx *PositionIndex) NodesAtPosition(pos source.Position, leeway int) []*UnifiedNode

NodesAtPosition returns all nodes containing the given position, ordered from root to most specific (deepest).

func (*PositionIndex) NodesOnLine

func (idx *PositionIndex) NodesOnLine(line int) []*UnifiedNode

NodesOnLine returns all nodes that intersect with the given line.

func (*PositionIndex) Root

func (idx *PositionIndex) Root() *UnifiedNode

Root returns the root node of the indexed tree.

type QuoteType

type QuoteType int

QuoteType indicates the type of quotes enclosing a string value.

const (
	// QuoteTypeNone indicates no quotes or unknown quote type.
	QuoteTypeNone QuoteType = iota

	// QuoteTypeSingle indicates single quotes ('value').
	QuoteTypeSingle

	// QuoteTypeDouble indicates double quotes ("value").
	QuoteTypeDouble
)

type SchemaElementKind

type SchemaElementKind int

SchemaElementKind provides type-safe schema element classification.

const (
	SchemaElementUnknown SchemaElementKind = iota

	// Top-level sections
	SchemaElementVariables
	SchemaElementValues
	SchemaElementResources
	SchemaElementDataSources
	SchemaElementIncludes
	SchemaElementExports

	// Named elements
	SchemaElementVariable
	SchemaElementValue
	SchemaElementResource
	SchemaElementDataSource
	SchemaElementInclude
	SchemaElementExport

	// Field types
	SchemaElementResourceType
	SchemaElementDataSourceType
	SchemaElementVariableType
	SchemaElementValueType
	SchemaElementExportType
	SchemaElementDataSourceFieldType
	SchemaElementDataSourceFilterField
	SchemaElementDataSourceFilterOperator

	// Substitution elements
	SchemaElementSubstitution
	SchemaElementFunctionCall
	SchemaElementVariableRef
	SchemaElementValueRef
	SchemaElementResourceRef
	SchemaElementDataSourceRef
	SchemaElementChildRef
	SchemaElementElemRef
	SchemaElementElemIndexRef
	SchemaElementPathItem

	// Structural elements
	SchemaElementMappingNode
	SchemaElementDataSourceFieldExport
	SchemaElementDataSourceFieldExportMap
	SchemaElementDataSourceFilters
	SchemaElementDataSourceFilter
	SchemaElementDataSourceFilterSearch
	SchemaElementMetadata
	SchemaElementDataSourceMetadata
	SchemaElementLinkSelector
	SchemaElementStringMap
	SchemaElementStringOrSubstitutionsMap
	SchemaElementStringList

	// Value nodes
	SchemaElementScalar
	SchemaElementMapping
	SchemaElementSequence
)

func KindFromSchemaElement

func KindFromSchemaElement(elem any) SchemaElementKind

KindFromSchemaElement determines the kind from a schema element interface.

func (SchemaElementKind) IsReference

func (k SchemaElementKind) IsReference() bool

IsReference returns true if this is a reference kind.

func (SchemaElementKind) IsSubstitution

func (k SchemaElementKind) IsSubstitution() bool

IsSubstitution returns true if this is a substitution kind.

func (SchemaElementKind) IsTypeField

func (k SchemaElementKind) IsTypeField() bool

IsTypeField returns true if this is a type field kind.

func (SchemaElementKind) String

func (k SchemaElementKind) String() string

String returns a string representation of SchemaElementKind.

func (SchemaElementKind) SupportsHover

func (k SchemaElementKind) SupportsHover() bool

SupportsHover returns true if this kind supports hover content.

type StructuredPath

type StructuredPath []PathSegment

StructuredPath wraps a slice of path segments with helper methods for type-safe path matching without string parsing.

func (StructuredPath) At

func (p StructuredPath) At(index int) PathSegment

At returns the segment at the given index, or an empty segment if out of bounds.

func (StructuredPath) GetAnnotationKey

func (p StructuredPath) GetAnnotationKey() (string, bool)

GetAnnotationKey returns the annotation key name if path is at an annotation value position. Pattern: /resources/{name}/metadata/annotations/{annotationKey}

func (StructuredPath) GetDataSourceAnnotationKey

func (p StructuredPath) GetDataSourceAnnotationKey() (string, bool)

GetDataSourceAnnotationKey returns the annotation key from a data source annotation value path. Pattern: /datasources/{name}/metadata/annotations/{key}

func (StructuredPath) GetDataSourceExportName

func (p StructuredPath) GetDataSourceExportName() (string, bool)

GetDataSourceExportName returns the export name if path is under a data source export. Pattern: /datasources/{name}/exports/{exportName}/...

func (StructuredPath) GetDataSourceName

func (p StructuredPath) GetDataSourceName() (string, bool)

GetDataSourceName returns the data source name if path is under a data source.

func (StructuredPath) GetExportName

func (p StructuredPath) GetExportName() (string, bool)

GetExportName returns the export name if path is under an export.

func (StructuredPath) GetIncludeName

func (p StructuredPath) GetIncludeName() (string, bool)

GetIncludeName returns the include name if path is under an include.

func (StructuredPath) GetResourceName

func (p StructuredPath) GetResourceName() (string, bool)

GetResourceName returns the resource name if path is under a resource.

func (StructuredPath) GetSpecPath

func (p StructuredPath) GetSpecPath() []PathSegment

GetSpecPath returns the path segments after /resources/{name}/spec/. Returns an empty slice when at the root of spec (path length == 3), or nil if not in a resource spec path.

func (StructuredPath) GetValueName

func (p StructuredPath) GetValueName() (string, bool)

GetValueName returns the value name if path is under a value.

func (StructuredPath) GetVariableName

func (p StructuredPath) GetVariableName() (string, bool)

GetVariableName returns the variable name if path is under a variable.

func (StructuredPath) IsBlueprintMetadata

func (p StructuredPath) IsBlueprintMetadata() bool

IsBlueprintMetadata returns true if path is in blueprint-level metadata. Pattern: /metadata or /metadata/...

func (StructuredPath) IsBlueprintTopLevel

func (p StructuredPath) IsBlueprintTopLevel() bool

IsBlueprintTopLevel returns true if path is at the blueprint root level. Pattern: /{field} (single segment that is a known top-level field) Note: Empty paths are not considered top-level as they indicate no parsed structure.

func (StructuredPath) IsDataSourceDefinition

func (p StructuredPath) IsDataSourceDefinition() bool

IsDataSourceDefinition returns true if path is directly inside a data source definition, but not in a nested field like metadata, filter, or exports. Pattern: /datasources/{name} (exactly 2 segments)

func (StructuredPath) IsDataSourceExportAliasFor

func (p StructuredPath) IsDataSourceExportAliasFor() bool

IsDataSourceExportAliasFor returns true if path points to a data source export aliasFor field. Pattern: /datasources/{name}/exports/{exportName}/aliasFor (5 segments)

func (StructuredPath) IsDataSourceExportDefinition

func (p StructuredPath) IsDataSourceExportDefinition() bool

IsDataSourceExportDefinition returns true if path is at a specific export definition. Pattern: /datasources/{name}/exports/{exportName} (exactly 4 segments)

func (StructuredPath) IsDataSourceExports

func (p StructuredPath) IsDataSourceExports() bool

IsDataSourceExports returns true if path is inside a data source exports field. Pattern: /datasources/{name}/exports/...

func (StructuredPath) IsDataSourceFilter

func (p StructuredPath) IsDataSourceFilter() bool

IsDataSourceFilter returns true if path is in a data source filter. Pattern: /datasources/{name}/filters/... (note: "filters" plural in schema tree)

func (StructuredPath) IsDataSourceFilterDefinition

func (p StructuredPath) IsDataSourceFilterDefinition() bool

IsDataSourceFilterDefinition returns true if path is at a filter definition level. Pattern: /datasources/{name}/filter or /datasources/{name}/filter/{index} Note: The singular "filter" is used in the schema tree.

func (StructuredPath) IsDataSourceFilterField

func (p StructuredPath) IsDataSourceFilterField() bool

IsDataSourceFilterField returns true if path points to a filter field. Pattern 1: /datasources/{name}/filter/field (4 segments, singular filter) Pattern 2: /datasources/{name}/filters/{index}/filter/field (6 segments, plural filters with index)

func (StructuredPath) IsDataSourceFilterOperator

func (p StructuredPath) IsDataSourceFilterOperator() bool

IsDataSourceFilterOperator returns true if path points to a filter operator. Pattern 1: /datasources/{name}/filter/operator (4 segments, singular filter) Pattern 2: /datasources/{name}/filters/{index}/filter/operator (6 segments, plural filters with index)

func (StructuredPath) IsDataSourceMetadata

func (p StructuredPath) IsDataSourceMetadata() bool

IsDataSourceMetadata returns true if path is inside a data source metadata field. Pattern: /datasources/{name}/metadata/...

func (StructuredPath) IsDataSourceMetadataAnnotationValue

func (p StructuredPath) IsDataSourceMetadataAnnotationValue() bool

IsDataSourceMetadataAnnotationValue returns true if path is at a data source annotation value position. Pattern: /datasources/{name}/metadata/annotations/{key} (exactly 5 segments)

func (StructuredPath) IsDataSourceMetadataAnnotations

func (p StructuredPath) IsDataSourceMetadataAnnotations() bool

IsDataSourceMetadataAnnotations returns true if path is inside data source metadata annotations. Pattern: /datasources/{name}/metadata/annotations or deeper

func (StructuredPath) IsDataSourceType

func (p StructuredPath) IsDataSourceType() bool

IsDataSourceType returns true if path points to a data source type field. Pattern: /datasources/{name}/type

func (StructuredPath) IsEmpty

func (p StructuredPath) IsEmpty() bool

IsEmpty returns true if the path has no segments.

func (StructuredPath) IsExportDefinition

func (p StructuredPath) IsExportDefinition() bool

IsExportDefinition returns true if path is directly inside an export definition. Pattern: /exports/{name} (exactly 2 segments)

func (StructuredPath) IsExportField

func (p StructuredPath) IsExportField() bool

IsExportField returns true if path points to an export field value. Pattern: /exports/{name}/field

func (StructuredPath) IsExportType

func (p StructuredPath) IsExportType() bool

IsExportType returns true if path points to an export type field. Pattern: /exports/{name}/type

func (StructuredPath) IsInDataSources

func (p StructuredPath) IsInDataSources() bool

IsInDataSources returns true if the path is under /datasources.

func (StructuredPath) IsInExports

func (p StructuredPath) IsInExports() bool

IsInExports returns true if the path is under /exports.

func (StructuredPath) IsInIncludes

func (p StructuredPath) IsInIncludes() bool

IsInIncludes returns true if the path is under /include.

func (StructuredPath) IsInResources

func (p StructuredPath) IsInResources() bool

IsInResources returns true if the path is under /resources.

func (StructuredPath) IsInValues

func (p StructuredPath) IsInValues() bool

IsInValues returns true if the path is under /values.

func (StructuredPath) IsInVariables

func (p StructuredPath) IsInVariables() bool

IsInVariables returns true if the path is under /variables.

func (StructuredPath) IsIncludeDefinition

func (p StructuredPath) IsIncludeDefinition() bool

IsIncludeDefinition returns true if path is directly inside an include definition. Pattern: /include/{name} (exactly 2 segments)

func (StructuredPath) IsResourceDefinition

func (p StructuredPath) IsResourceDefinition() bool

IsResourceDefinition returns true if path is directly inside a resource definition, but not in a nested field like spec or metadata. Pattern: /resources/{name} (exactly 2 segments)

func (StructuredPath) IsResourceLinkSelector

func (p StructuredPath) IsResourceLinkSelector() bool

IsResourceLinkSelector returns true if path points to a resource linkSelector field. Pattern: /resources/{name}/linkSelector (exactly 3 segments)

func (StructuredPath) IsResourceLinkSelectorExclude

func (p StructuredPath) IsResourceLinkSelectorExclude() bool

IsResourceLinkSelectorExclude returns true if path is inside a linkSelector exclude list. Pattern: /resources/{name}/linkSelector/exclude or /resources/{name}/linkSelector/exclude/{index}

func (StructuredPath) IsResourceMetadata

func (p StructuredPath) IsResourceMetadata() bool

IsResourceMetadata returns true if path points to a resource metadata field. Pattern: /resources/{name}/metadata/...

func (StructuredPath) IsResourceMetadataAnnotationValue

func (p StructuredPath) IsResourceMetadataAnnotationValue() bool

IsResourceMetadataAnnotationValue returns true if path is at an annotation value position. Pattern: /resources/{name}/metadata/annotations/{annotationKey} (exactly 5 segments)

func (StructuredPath) IsResourceMetadataAnnotations

func (p StructuredPath) IsResourceMetadataAnnotations() bool

IsResourceMetadataAnnotations returns true if path is inside resource metadata annotations. Pattern: /resources/{name}/metadata/annotations or /resources/{name}/metadata/annotations/{key}

func (StructuredPath) IsResourceMetadataLabels

func (p StructuredPath) IsResourceMetadataLabels() bool

IsResourceMetadataLabels returns true if path is inside resource metadata labels. Pattern: /resources/{name}/metadata/labels or deeper

func (StructuredPath) IsResourceSpec

func (p StructuredPath) IsResourceSpec() bool

IsResourceSpec returns true if path points to a resource spec field. Pattern: /resources/{name}/spec/...

func (StructuredPath) IsResourceType

func (p StructuredPath) IsResourceType() bool

IsResourceType returns true if path points to a resource type field. Pattern: /resources/{name}/type

func (StructuredPath) IsValueDefinition

func (p StructuredPath) IsValueDefinition() bool

IsValueDefinition returns true if path is directly inside a value definition. Pattern: /values/{name} (exactly 2 segments)

func (StructuredPath) IsValueType

func (p StructuredPath) IsValueType() bool

IsValueType returns true if path points to a value type field. Pattern: /values/{name}/type

func (StructuredPath) IsVariableDefinition

func (p StructuredPath) IsVariableDefinition() bool

IsVariableDefinition returns true if path is directly inside a variable definition. Pattern: /variables/{name} (exactly 2 segments)

func (StructuredPath) IsVariableType

func (p StructuredPath) IsVariableType() bool

IsVariableType returns true if path points to a variable type field. Pattern: /variables/{name}/type

func (StructuredPath) Last

func (p StructuredPath) Last() PathSegment

Last returns the last segment in the path, or an empty segment if empty.

func (StructuredPath) Len

func (p StructuredPath) Len() int

Len returns the number of segments in the path.

func (StructuredPath) String

func (p StructuredPath) String() string

String returns the full path as a string.

type SyntacticContext

type SyntacticContext struct {
	// Position indicates what kind of syntactic position the cursor is at.
	Position SyntacticPosition

	// Style indicates the syntactic style (block YAML, flow YAML, or JSONC).
	Style SyntacticStyle

	// TypedPrefix is the text being typed at the current position.
	// This is used for filtering completion suggestions.
	TypedPrefix string

	// QuoteType indicates the enclosing quote style if inside a string.
	QuoteType QuoteType

	// InSubstitution is true if the cursor is inside a ${...} substitution.
	InSubstitution bool

	// SubstitutionText is the text inside the current substitution, if any.
	SubstitutionText string
}

SyntacticContext captures the syntactic editing context at a cursor position. It provides a unified interface for completion generation regardless of the underlying document format.

func (*SyntacticContext) IsAtEmptyContainer

func (ctx *SyntacticContext) IsAtEmptyContainer() bool

IsAtEmptyContainer returns true if the cursor is inside an empty container.

func (*SyntacticContext) IsAtKeyPosition

func (ctx *SyntacticContext) IsAtKeyPosition() bool

IsAtKeyPosition returns true if the cursor is at a key/field name position.

func (*SyntacticContext) IsAtSequenceItemPosition

func (ctx *SyntacticContext) IsAtSequenceItemPosition() bool

IsAtSequenceItemPosition returns true if the cursor is at a sequence item position.

func (*SyntacticContext) IsAtStringContent

func (ctx *SyntacticContext) IsAtStringContent() bool

IsAtStringContent returns true if the cursor is inside a string value.

func (*SyntacticContext) IsAtValuePosition

func (ctx *SyntacticContext) IsAtValuePosition() bool

IsAtValuePosition returns true if the cursor is at a value position.

type SyntacticPosition

type SyntacticPosition int

SyntacticPosition represents where the cursor is syntactically within the document structure. This is independent of the document format (YAML vs JSONC) and represents the semantic editing position.

const (
	// SyntacticPositionUnknown indicates the position could not be determined.
	SyntacticPositionUnknown SyntacticPosition = iota

	// SyntacticPositionKeyField indicates the cursor is at a position where
	// a mapping key (field name) should be entered.
	// Examples:
	//   YAML block: "  |" (indented empty line under a mapping)
	//   YAML flow:  "{|" or "{key: value, |"
	//   JSONC:      "{|" or '{"key": "value", |'
	SyntacticPositionKeyField

	// SyntacticPositionValueField indicates the cursor is at a position where
	// a value should be entered (after a colon).
	// Examples:
	//   YAML block: "key: |"
	//   YAML flow:  "{key: |"
	//   JSONC:      '{"key": |'
	SyntacticPositionValueField

	// SyntacticPositionSequenceItem indicates the cursor is at a position where
	// a sequence/array item should be entered.
	// Examples:
	//   YAML block: "- |" (after sequence marker)
	//   YAML flow:  "[|" or "[item, |"
	//   JSONC:      "[|" or '["item", |'
	SyntacticPositionSequenceItem

	// SyntacticPositionStringContent indicates the cursor is inside a string value.
	// This is relevant for substitution completions and array item completions.
	// Examples:
	//   YAML: '"${resources.|}"'
	//   JSONC: '["partial|"]'
	SyntacticPositionStringContent

	// SyntacticPositionEmptyContainer indicates the cursor is inside an empty
	// container (array or object) with no content yet.
	// Examples:
	//   YAML flow: "[]" with cursor between brackets
	//   JSONC:     "[]" or "{}" with cursor between brackets
	SyntacticPositionEmptyContainer
)

func DetectSyntacticPosition

func DetectSyntacticPosition(
	style SyntacticStyle,
	node *UnifiedNode,
	ancestors []*UnifiedNode,
	pos source.Position,
	textBefore string,
) SyntacticPosition

DetectSyntacticPosition determines the syntactic position at the cursor based on the detected style and text context.

This delegates to style-specific detection logic: - Block YAML uses indentation and "- " marker heuristics - Flow YAML and JSONC share delimiter-based detection ({, [, ,, :)

func (SyntacticPosition) String

func (p SyntacticPosition) String() string

String returns a human-readable name for the syntactic position.

type SyntacticStyle

type SyntacticStyle int

SyntacticStyle represents the syntactic style being used at the cursor position. This distinguishes between indentation-based YAML (block style), delimiter-based YAML (flow style), and JSON/JSONC syntax.

Key insight: JSON is a subset of YAML 1.2. Flow-style YAML uses the same delimiter syntax as JSON ({}, [], commas), so they can share detection logic.

const (
	// SyntacticStyleUnknown indicates the style could not be determined.
	SyntacticStyleUnknown SyntacticStyle = iota

	// SyntacticStyleBlockYAML indicates indentation-based YAML syntax.
	// Structure is determined by indentation levels and markers like "- ".
	// Examples:
	//   resources:
	//     myResource:
	//       type: aws/lambda/function
	SyntacticStyleBlockYAML

	// SyntacticStyleFlowYAML indicates inline/flow-style YAML syntax.
	// Structure is determined by delimiters: {}, [], commas.
	// Examples:
	//   resources: {myResource: {type: "aws/lambda/function"}}
	//   exclude: [item1, item2]
	SyntacticStyleFlowYAML

	// SyntacticStyleJSONC indicates JSON or JSONC syntax.
	// Like flow YAML, structure is determined by delimiters.
	// Examples:
	//   {"resources": {"myResource": {"type": "aws/lambda/function"}}}
	SyntacticStyleJSONC
)

func DetectSyntacticStyle

func DetectSyntacticStyle(ancestors []*UnifiedNode, format DocumentFormat) SyntacticStyle

DetectSyntacticStyle determines the syntactic style at a position based on the document format and the tree-sitter node types (TSKind) in the ancestry.

For YAML documents, it examines ancestors to find the nearest flow or block container. For JSONC documents, it always returns JSONC style.

func (SyntacticStyle) IsBlockStyle

func (s SyntacticStyle) IsBlockStyle() bool

IsBlockStyle returns true if the style uses indentation-based syntax (block YAML).

func (SyntacticStyle) IsFlowStyle

func (s SyntacticStyle) IsFlowStyle() bool

IsFlowStyle returns true if the style uses delimiter-based syntax (flow YAML or JSONC). This is useful because flow YAML and JSONC share the same structural delimiters ({}, [], commas) and can use the same position detection logic.

func (SyntacticStyle) String

func (s SyntacticStyle) String() string

String returns a human-readable name for the syntactic style.

type UnifiedNode

type UnifiedNode struct {
	Kind      NodeKind
	Range     source.Range
	KeyRange  *source.Range  // Range of the key if this is a map value
	Value     string         // Scalar value if NodeKindScalar
	Tag       string         // Type tag (e.g., "string", "integer")
	Children  []*UnifiedNode // Child nodes
	Parent    *UnifiedNode   // Parent reference for upward traversal
	FieldName string         // Field name if child of a mapping
	Index     int            // Index if child of a sequence (-1 if not applicable)
	IsError   bool           // True if this node represents an error region
	TSKind    string         // Original tree-sitter node kind for debugging
}

UnifiedNode provides a format-agnostic representation of an AST node with accurate position information. It abstracts over YAML and JSON AST differences to provide consistent position-based lookups.

func ParseJSONCToUnified

func ParseJSONCToUnified(content string) (*UnifiedNode, error)

ParseJSONCToUnified parses JSONC content and converts to a UnifiedNode tree. It uses hujson to strip comments, then tree-sitter for error-recovering parsing.

func ParseYAMLToUnified

func ParseYAMLToUnified(content string) (*UnifiedNode, error)

ParseYAMLToUnified parses YAML content and converts to a UnifiedNode tree. This is a convenience function that handles parser lifecycle.

func (*UnifiedNode) AncestorPath

func (n *UnifiedNode) AncestorPath() []PathSegment

AncestorPath returns the path segments from root to this node. Only segments with meaningful field names or indices are included.

func (*UnifiedNode) CollectAncestors

func (n *UnifiedNode) CollectAncestors() []*UnifiedNode

CollectAncestors returns all ancestor nodes from root to this node (inclusive).

func (*UnifiedNode) ContainsPosition

func (n *UnifiedNode) ContainsPosition(pos source.Position) bool

ContainsPosition returns true if the node's range contains the given position.

func (*UnifiedNode) ContainsPositionWithLeeway

func (n *UnifiedNode) ContainsPositionWithLeeway(pos source.Position, leeway int) bool

ContainsPositionWithLeeway returns true if the node's range contains the given position with configurable column leeway for fuzzy matching.

func (*UnifiedNode) DeepestChildAt

func (n *UnifiedNode) DeepestChildAt(pos source.Position, leeway int) *UnifiedNode

DeepestChildAt returns the deepest child node containing the position. Returns the node itself if no children contain the position.

func (*UnifiedNode) IsLeaf

func (n *UnifiedNode) IsLeaf() bool

IsLeaf returns true if this node has no children.

func (*UnifiedNode) Path

func (n *UnifiedNode) Path() string

Path returns the structural path to this node (e.g., "/resources/myResource/type"). Uses "/" as separator since "." can appear in element names.

type YAMLParser

type YAMLParser struct {
	// contains filtered or unexported fields
}

YAMLParser wraps tree-sitter for parsing YAML documents. Must call Close() when done to free C memory.

func NewYAMLParser

func NewYAMLParser() (*YAMLParser, error)

NewYAMLParser creates a new YAML parser using tree-sitter.

func (*YAMLParser) Close

func (p *YAMLParser) Close()

Close releases the parser resources.

func (*YAMLParser) Parse

func (p *YAMLParser) Parse(content []byte) *tree_sitter.Tree

Parse parses YAML content and returns the tree-sitter tree.

func (*YAMLParser) ParseIncremental

func (p *YAMLParser) ParseIncremental(content []byte, oldTree *tree_sitter.Tree) *tree_sitter.Tree

ParseIncremental parses YAML content with an existing tree for incremental updates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL