WSO2 MI Language Server
/ Component Reference
Deep Dive

Component Reference

A file-by-file map: what each module owns, what it exposes, and who depends on it.

Entry & routing

src/server.ts entry point

Creates the LSP connection and wires the whole lifecycle.

  • onInitialize — reads workspaceFolders and initializationOptions.schemas, registers pattern mappings to bundled 430/440 schemas, advertises capabilities.
  • onInitialized — pulls xmlLanguageServer.schemas config, applies it, then validates open docs. Sets initialConfigurationLoaded.
  • onDidChangeConfiguration — invalidate caches → dispose validators → clear user associations → re-register init-option mappings → apply workspace schemas → re-validate.
  • onDidChangeContent — schedule validation for the changed document, debounced 300 ms per URI: each edit cancels the previous timer, so a burst of keystrokes produces one validation after the user pauses (deferred until initial config is loaded).
  • onDidClose — cancel any pending debounce timer for the closed document.
  • onShutdown — dispose diagnostics + service.

Also defines registerSchemas() for the init-options {pattern, schema} shape and SCHEMA_FOLDER_MAP (430/440 → bundled folder).

src/requestHandlers.ts

Registers one handler per LSP request: completion, hover, documentSymbol, foldingRange, rename, definition, references, formatting (full + range). Maintains a parsed-document cache keyed by URI + version so repeated requests don't re-parse. The hover handler calls diagnosticsHandler.hasErrorAt() to suppress hover where a diagnostic already exists.

src/xmlLanguageService.ts façade

getLanguageService() returns a single object aggregating every capability and owning the one SchemaProvider instance. This is the seam everything else depends on — parseXMLDocument, doComplete, doHover, validate, registerSchema, addUserAssociation, clearUserAssociations, invalidateAutoSchemas, dispose, etc.

src/configuration.ts

applySchemaSettings() takes workspace {pattern, xsdPath} entries, resolves each xsdPath (absolute, or relative to a workspace root), and registers it as a user association. Warns and skips unresolvable paths. Heavily unit-tested.

Schema subsystem

src/schema/schemaAssociator.ts

Owns findSchema(file, xmlns, path): user/init pattern matches first, then built-in namespace matches. Includes a small glob→RegExp engine (*, **, ?) and resolveSchemaRoot() which locates bundled schemas in both the production bundle and the test tree. Exposes addUserAssociation / clearUserAssociations.

src/schema/schemaProvider.ts

The registry. registerSchema() creates one XsdValidatorService wrapper per unique xsdKey (it stores the XSD text — no compilation here) and builds a completion provider from the fully-inlined XSD (via inlineIncludes()). validate() routes to the right validator or falls back to the parser's syntax errors. invalidateAutoSchemas() drops all auto:// entries; dispose() tears everything down. Holds the three maps described in Caches & keys.

src/schema/xsdCompletionProvider.ts engine 2

Hand-written XSD reader. Parses element/attribute/type declarations from XSD text and answers completion + hover queries (getAllElements, getElement, …). This is the completion "brain" — independent of Xerces.

src/schema/xsdValidator.ts engine 1

Thin wrapper over the WASM validate(). Extracts the targetNamespace via regex (Xerces needs it), runs validation, and maps raw Xerces errors to ranges — including clever remapping of mismatched-tag and content-model errors back onto the offending open tag.

Diagnostics

src/diagnosticsHandler.ts orchestrator

The busiest file. validateAndSend() drives the whole diagnostics flow. It captures document.version on entry and re-checks it before publishing (version guard): if the document changed while the async validation ran, the stale result is discarded instead of overwriting diagnostics from a newer run. Beyond that it owns the schema-graph loading used by both engines:

  • getOrCreateValidator() — cached ProjectValidator per xsdPath.
  • buildFilesMap() — recursively reads every .xsd/.dtd in the schema folder (feeds Xerces).
  • loadReferencedXsds() — follows xs:include/import/redefine + DTD references with depth/size/count guards (feeds the completion provider).
  • filterDiagnostics() — collapses noisy cascades (e.g. drops "attribute not declared" when the element itself is unknown) and de-duplicates.

Parser

FileRole
parser/xmlParser.tsRuns @xml-tools/parser (CST) and builds the AST.
parser/xmlNode.tsAST node types (XMLDocument, elements, attributes).
parser/xmlDocument.tsDocument wrapper: text, AST tree construction, syntax errors.

Feature providers services/

Each is a stateless function over the AST (and, where relevant, a completion provider). They contain no transport or schema-resolution logic.

xmlHover

Schema-aware hover content for elements/attributes.

xmlCompletion

Context-aware element/attribute completion.

xmlFolding

Folding ranges from element nesting.

xmlSymbols

Document outline / symbols.

xmlReferences

Find references across the document.

xmlRename

Rename with matching edits.

xmlDefinition

Go-to-definition.

xmlFormatter

Full-document & range formatting.