Skip to content

ADR-001: Langium as Parser and LSP Framework

Context

Weltenwanderer needs a parser generator that produces typed ASTs and an LSP server for IDE integration. The .ddd DSL defines approximately 28 AST node types across constructs such as Decider, Command, Event, State, evolve, decide, require, and ensure.

Options evaluated:

OptionAST TypingLSPError RecoveryTS Native
Hand-written parserManualNoneManualYes
tree-sitterNoPartialYesNo
ANTLR 4Java codegenAdapter neededYesNo
Langium 4.xYes (generated)FullYesYes

Decision

Use Langium 4.x (Eclipse Foundation). A single grammar file (packages/language/src/weltenwanderer.langium) drives:

  • Parser generation with error recovery
  • Typed TypeScript AST interfaces
  • Scope resolution and cross-reference linking
  • A complete LSP server (hover, go-to-definition, diagnostics)
  • A validation framework with location-aware error reporting

The grammar file is the canonical source of truth for all AST structure. Parser artifacts are regenerated via bun run langium:generate.

Consequences

Positive

  • Typed AST eliminates a class of null-reference errors in validation passes.
  • LSP server is produced without additional code; VS Code extension is a thin wrapper.
  • TypeScript-native output integrates directly with the Bun/TS stack.
  • Grammar-driven DI system (module.ts) separates language services cleanly.

Negative

  • All validation and generation code couples to Langium’s AST node shapes.
  • Grammar modifications require a langium:generate step before compilation.
  • Langium’s expression grammar support required a dedicated workaround (ExpressionFragment → operator-precedence grammar, resolved in ADR-013).
  • The Langium DI container (module.ts) is a singleton file; parallel agents must not modify it concurrently (see file ownership matrix in CLAUDE.md).