This document contains an overview of how Intellisense works, as well as a general view of the architecture of the code.
Providers in the VS Code API are extension points that let you plug specific language or editor features into the editor’s pipeline (e.g., completions, hovers, formatting). Providers are implemented and then registered in the code, which then gets called depending on the situation in which the provider activates.
Many providers exist. Relevant ones that are used extensively in the code about IntelliSense functionality include completionItemProvider, which provides code suggestions, and hoverProvider, which provides hover information. For more information, visit https://code.visualstudio.com/api/references/vscode-api.
After a provider has its functionality implemented, it can then be registered into the extension so that its functionality can be utilized in the IntelliSense functionality pipeline. Relevant registration calls include registerCompletionItemProvider and registerHoverProvider.
This section focuses on the dfdl Intellisense implementation.
This section provides a high-level view of the architecture of all relevant code items about the dfdl IntelliSense functionality.
src/language/dfdl.ts is the starting point. It wires up the extension’s language features by calling VS Code registration APIs (e.g., registerCompletionItemProvider, registerHoverProvider, and similar) that are then customized as functions that provide customized provider functionality.
In other words, dfdl.ts connects the provider implementations to VS Code for the DFDL language.
Autocompletion logic is split into multiple provider modules under src/language/providers/, each handling different completion scenarios.
elementCompletion.ts -- suggests child elements/element tags.attributeCompletion.ts -- suggests attribute names when inside an element.attributeValueCompletion.ts -- provides completion suggestions for attribute values (e.g., enumerated values).closeElement.ts, closeElementSlash.ts -- completions for closing tags and slash completions.attributeHover.ts -- hover provider that shows attribute documentation/available attributes.It should be noted that there are many registerCompletionItemProvider calls. The implemented completionItemProviders each contain logic to determine whether or not the provider is relevant to a given situation.
src/language/providers/utils.ts contains shared helpers for constructing CompletionItem objects, and context parsing utilities used by many providers. It also contains utilities used for root-level completion logic (common completion primitives).
Providers do lightweight parsing of the current document and cursor context (often using a small tokenizer/utility functions) to determine whether the cursor is:
This context detection guides which provider runs and how it filters suggestions.
The code can determine the current element's namespace, and the suggestions can insert the correct namespace or omit the namespace accordingly for attribute and element suggestions.
Providers build vscode.CompletionItem objects populated with:
Some items use resolveCompletionItem logic if additional data must be computed after selection.
attributeHover.ts forms hover messages (Markdown strings) describing attributes available on a tag, DFDL property documentation, etc. Hover resolves the current element context, then gathers attribute docs and returns a vscode.Hover object.
Hover tooltips can be found under attributeHoverValues() in attributeHoverItems.ts.
src/tests/suite/language/items.test.ts contains unit-style checks that assert which items should be available in certain contexts -- useful to confirm the expected behavior of completion providers.
Purpose: Attribute name completion provider for XML elements in DFDL schemas and TDML test files.
Key Functionality:
Key Functions:
getAttributeCompletionProvider(): DFDL document providergetTDMLAttributeCompletionProvider(): TDML document providergetDefinedTypes(): Scans for xs:simpleType and xs:complexType declarationsprunedDuplicateAttributes(): Removes attributes already present on the elementTrigger: Space ( ) or newline (\n)
Purpose: Hover provider that displays documentation tooltips when users hover over DFDL/XSD attribute names. The attribute's tooltips are obtained from attributeItems.ts
Key Functionality:
Documentation Categories:
Provider Registered:
getAttributeHoverProvider(): For DFDL documentsPurpose: Attribute value completion provider for DFDL schemas and TDML test files.
Key Functionality:
Key Functions:
getAttributeValueCompletionProvider(): DFDL document providergetTDMLAttributeValueCompletionProvider(): TDML document providergetAttributeDetails(): Extracts attribute name and value range for completion contextTrigger: Space ( )
Purpose: Completion provider that handles auto-completion of XML element structures when the user types a > character. Unlike closeElementSlash.ts which handles closing tags with /, this provider completes the element opening and provides the corresponding closing tag structure.
Key Functionality:
> is typed>: Standard trigger for multi-line completion with indentation>>: Inline completion without extra whitespace.=>: Alternative trigger pattern for special casesschema tag: Gets unique multi-line formatting with proper XML document structuredefineVariable, setVariable): Multi-line snippets with newlines for readabilityassert, discriminator): Inline snippets with tab stops for test expressionsKey Functions:
getCloseElementProvider(): Main DFDL completion provider registrationgetTDMLCloseElementProvider(): TDML-specific completion provider registrationcheckItemsOnLine(): Core logic determining what to insert based on item count and contextcheckNearestTagNotClosed(): Handles tag-specific snippet patterns for single-item linescheckTriggerText(): Manages insertion for complex multi-tag linesTrigger: Greater-than sign (>)
Architecture Notes:
closeElementSlash.ts)insertSnippet) instead of completion listsDependencies:
closeUtils.checkMissingCloseTag(): Determines which tag needs closingutils.insertSnippet(): Performs the actual text insertion with tab stopscheckBraceOpen(), cursorWithinBraces(), cursorWithinQuotes(), cursorAfterEquals(), isInXPath(), isNotTriggerChar()getNsPrefix(), getItemPrefix(), getItemsOnLineCount()Flow:
> at cursor position> is the trigger charcheckMissingCloseTag() scans document to find the nearest unclosed tag>, >>, or .=>) and items on linecheckItemsOnLine() delegates to specialized handlers:checkNearestTagNotClosed() for single-item lines (tag-specific formatting)checkTriggerText() for multi-tag lines (ensures no duplicate closing tags)Comparison with closeElementSlash.ts:
| Feature | closeElement.ts (This File) | closeElementSlash.ts |
|---|---|---|
| Trigger | > character | / character |
| Primary Action | Completes element opening with closing structure | Closes element (self-closing or full closing) |
| Snippet Complexity | Multi-tab-stop ($0, $1) for progressive workflow | Single tab-stop ($0) only |
| Special Patterns | >, >>, .=> triggers | / only |
| Schema Handling | Special multi-line formatting with indentation | Standard completion |
| Content Insertion | Yes (between opening and closing tags) | No (cursor after closing) |
| Use Case | Creating new elements with content | Closing existing elements |
Purpose: Completion provider that handles auto-closing XML/DFDL elements when the user types a forward slash ‘/’ character, determining whether to insert self-closing tags (/>) or full closing tags (</tag>).
Key Functionality:
/>$0) or full closing tags (</ns:tag>$0) based on contextdefineVariable, setVariable) with added newlines for readabilityKey Functions:
getCloseElementSlashProvider(): Main DFDL completion provider registrationgetTDMLCloseElementSlashProvider(): TDML-specific completion provider registrationcheckItemsOnLine(): Core logic determining what to insert based on tag count, namespace, and contextTrigger: Forward slash (/)
Architecture Notes:
insertSnippet) instead of completion listscheckItemsOnLine()Dependencies:
closeUtils.checkMissingCloseTag(): Determines if a tag needs closingutils.insertSnippet(): Performs the actual text insertioncheckBraceOpen(), cursorWithinBraces(), cursorWithinQuotes(), cursorAfterEquals(), isInXPath(), isNotTriggerChar()getNsPrefix(), getItemPrefix(), getItemsOnLineCount()Flow:
checkMissingCloseTag() scans document to find nearest unclosed tagcheckItemsOnLine() decides: self-closing tag, full closing tag, or nothingPurpose: Element name completion provider for XML elements in DFDL schemas and TDML test files. Suggests valid child elements when the user presses newline inside an XML element.
Key Functionality:
sequence suggests element, choice, etc.)dfdl:setVariable completion choicesKey Functions:
getElementCompletionProvider(): Main DFDL document provider registrationgetTDMLElementCompletionProvider(): TDML document provider registrationgetElementCompletionItems(): Creates completion items from elementItems.ts data based on contextgetDefinedVariables(): Scans document for dfdl:defineVariable declarations to extract variable namesnearestOpenTagChildElements(): Core logic determining which child elements are valid for a given parent (main DFDL hierarchy switch statement)getAnnotationParent(): Finds the parent element of an annotation to provide correct DFDL format elements in appinfo contextgetTagNearestTrigger(): Complex algorithm to find the nearest tag to cursor position, handling single-line and multi-line scenariosTrigger: Newline (\n)
Architecture Notes:
dfdl:setVariable suggestions$1, $2, $0 for guided element constructionDependencies:
closeUtils: checkMissingCloseTag() for determining tag closure stateutils: Extensive use including checkBraceOpen(), cursorWithinBraces(), cursorWithinQuotes(), cursorAfterEquals(), isInXPath(), isTagEndTrigger(), nearestOpen(), nearestTag(), getAttributeNames(), getItemsOnLineCount(), getNsPrefix(), createCompletionItem()intellisense/elementItems: elementCompletion() factory function for completion dataXmlItem class from utils for encapsulating parsed element dataDFDL Hierarchy Rules (from nearestOpenTagChildElements()):
The function implements the complete DFDL Schema hierarchy through a large switch statement:
element → complexType, simpleType, annotationsequence → element, sequence, choice, annotationchoice → element, sequence, group, annotationgroup → sequence, annotationcomplexType → sequence, group, choice, annotationsimpleType → annotation, restrictionannotation → appinfoappinfo → DFDL elements based on annotation parent (dfdl:format, dfdl:element, dfdl:sequence, etc.)assert/discriminator → CDATA, {}schema root → sequence, element, choice, group, complexType, simpleType, annotation, include, import, defineVariableemptySchema → xml version declarationFlow:
nearestOpen() finds the parent element at cursor positiongetTagNearestTrigger() determines which tag should trigger completion (handles multi-item lines)nearestOpenTagChildElements() uses switch statement to determine valid child elements for parentgetElementCompletionItems() filters elementItems.ts data for valid elements onlyPurpose: Core utility module providing tag state analysis functions for the auto-completion system. Determines whether XML/DFDL tags are properly closed and identifies unclosed tags that need completion.
Key Functionality:
checkMissingCloseTag() is the primary function that scans documents to find opened-but-unclosed tagsgetItemsForLineGT1(): Array-based position tracking for complex multi-tag scenariosgetItemsForLineLT2(): Bidirectional document scanning for simpler single-tag situationsgetCloseTag() finds exact positions of closing tags for document structure analysiscursorInsideCloseTag() prevents interference when user is manually typing closing tagsKey Functions:
checkMissingCloseTag(): Main entry point - returns name of unclosed tag or ‘none’checkItemsForLineGT1(): Multi-tag line analysis using opening/closing position arrayscheckItemsForLineLT2(): Single-tag line analysis with forward/backward scanninggetCloseTag(): Locates closing tag positions with nested tag trackingcursorInsideCloseTag(): Checks if cursor is positioned inside a closing taggetItemsForLineGT1(): Complex multi-tag line parsergetItemsForLineLT2(): Simple single-tag line parserAlgorithm Details:
getItemsForLineGT1() (Multi-tag lines):
getItemsForLineLT2() (Single-tag lines):
>getCloseTag() (Closing tag locator):
nestedTagCount for proper nested element handling<!-- -->) to avoid false positivesDependencies:
utils.getItemsOnLineCount(): Counts XML items on a lineutils.getItemPrefix(): Determines correct namespace prefix for tagsutils.getItems(): Gets list of all DFDL/XSD tag namesIntegration:
closeElementSlash.ts providersPerformance Considerations:
indexOf, lastIndexOf)Purpose: Static completion data for XML schema attributes used in DFDL/XSD documents.
Data Structure:
item: Attribute namesnippetString: VS Code snippet with placeholders and default valuesmarkdownString: Documentation shown in completion tooltipSnippet Features:
Attribute Categories:
Key Export:
attributeCompletion(additionalItems, nsPrefix, dfdlPrefix, spacingChar, afterChar): Returns object with completion itemsPurpose: Completion logic for attribute values (as opposed to attribute names).
Data Structures:
noChoiceAttributes: Array of free-text attributes that should not show completion choicesattributeValues(): Function that generates value snippets based on attribute nameSnippet Patterns:
${1|option1,option2|}: Dropdown with predefined choices"$1": Simple placeholder for user input"{$1}": Placeholder for DFDL expressions with curly braces$0: Final cursor positionAttribute Categories Handled:
Key Exports:
noChoiceAttributes: List of attributes without predefined choicesattributeValues(attributeName, startPos, additionalTypes): Inserts appropriate snippet at cursorPurpose: Static completion data for XML elements used in DFDL/XSD documents. Provides a complete catalog of XML/DFDL elements that can be suggested in different schema contexts, along with their snippet templates and documentation.
Data Structure:
elementCompletion(definedVariables, nsPrefix) that returns an object with an items arrayitem: Element name (can include namespace prefix)snippetString: VS Code snippet with tab stops, placeholders, and default valuesmarkdownString: Documentation shown in completion tooltipSnippet Features:
$1, $2, $0 for progressive navigation${1|option1,option2|} for dropdown selectionsdefinedVariables parameter to populate dfdl:setVariable ref attribute choicesnsPrefix parameter to customize snippets with correct namespace (xs:, xsd:, etc.)Element Categories:
xml version - XML prolog with UTF-8 encodingschema, element (name/ref variants), complexType, simpleType, sequence, choice, group, annotation, appinfo, restriction, include, importdfdl:format, dfdl:property, dfdl:assert, dfdl:discriminator, dfdl:escapeSchemedfdl:defineVariable, dfdl:setVariable, dfdl:newVariableInstancedfdl:defineFormat, dfdl:defineEscapeSchemedfdl:element, dfdl:sequence, dfdl:choice, dfdl:groupminInclusive, minExclusive, maxInclusive, maxExclusive, pattern, totalDigits, fractionDigits, enumerationCDATA, {} DFDL expression wrapperKey Export:
elementCompletion(definedVariables, nsPrefix): Factory function that generates completion data dynamically based on:definedVariables: Comma-separated string of variable names for dfdl:setVariable dropdownnsPrefix: Namespace prefix to use for XSD elements (typically “xs:” or “xsd:”)Dynamic Behavior:
Unlike static attribute files, elementItems.ts is a factory function that constructs completion data at runtime. This enables:
Example Usage:
// In elementCompletion.ts const definedVariables = getDefinedVariables(document) // "var1,var2,var3" const nsPrefix = getNsPrefix(document, position) // "xs:" const elementData = elementCompletion(definedVariables, nsPrefix) // elementData.items now contains customized snippets with proper vars and prefixes
Purpose: The central registration file for all DFDL language features.
Key Functionality:
<, :, ", =, /, whitespace).Purpose: Central utility module providing common functions used across all completion and hover providers.
Key Functionality:
Key Classes:
XmlItem: Encapsulates parsed XML element information (name, namespace, attributes)Key Functions:
nearestOpen(): Finds the nearest unclosed XML element at the cursor positioncheckTagOpen(): Determines if a tag is open at a given position with attribute discoverycursorWithinQuotes(): Detects if the cursor is inside attribute value quotesgetNsPrefix(): Retrieves namespace prefix for schema elementscreateCompletionItem(): Creates VS Code completion items from intellisense dataProvider Checks:
If you look at the structure of the dfdl.ts, it registers multiple providers. There are checks to determine whether or not a certain provider‘s autocomplete suggestions apply to the situation. This file’s helper functions provide a check criterion.
This section focuses on the tdml Intellisense implementation. It should be noted that the functionality is currently unused.