Skip to content

Compilation Pipeline

The IonPath compiler processes .ion files through a multi-stage pipeline. Each stage validates or transforms the schema, and errors are collected across all stages (the compiler does not stop at the first error).

Pipeline Stages

Stages execute in this order:

1

Parse

Lexes and parses all .ion files into an AST (Abstract Syntax Tree). The parser has error recovery — it continues parsing after syntax errors to report as many issues as possible in one pass.

2

ImportCycleDetectionStage

Detects circular #use imports. If module A imports B and B imports A, reports ION0001.

3

DuplicateSymbolValidationStage

Checks for duplicate type, message, service, or enum names within and across modules. Reports ION0002.

4

TransformStage

Converts the syntax AST into runtime IR (Internal Representation). Compiles messages, services, enums, flags, unions, and attributes into their typed objects. Performs first pass of type resolution — forward references are allowed.

5

StreamParameterValidationStage

Validates that each service method has at most one stream parameter. Reports ION0013 on violation.

6

RestoreUnresolvedTypeStage

Second pass of type resolution. Resolves all forward references. If a type cannot be resolved, suggests similar names using Levenshtein distance matching. Reports ION0009.

7

CircularTypeReferenceStage

DFS-based cycle detection in the type graph. If message A has a field of type B, and B has a field of type A, reports ION0030 with the full cycle path.

8

SchemaLockValidationStage

Compares the current schema against ion.lock.json. Detects breaking changes: removed fields, reordered fields, changed types, removed methods, etc. Reports ION0020–ION0029. Skipped with --no-lock.

9

Code Generation

Generates target code (C#, TypeScript) from the validated IR. Only runs if there are no errors. See C# Code Generation and TypeScript Code Generation.

Error Collection

The compiler collects all errors across stages rather than stopping at the first one. Each stage can set StopOnError to halt the pipeline after critical failures (e.g., circular imports make further resolution meaningless).

Diagnostics have three severity levels:

Severity Behavior
Error Blocks code generation. Must be fixed.
Warning Compilation succeeds, but potential issues (e.g., non-nullable field added).
Info Informational only — no action required.

Verbose Output

Use --verbose to see timing for each stage:

$ ionc compile --verbose
[  2ms] Parse (3 modules)
[  0ms] ImportCycleDetection
[  1ms] DuplicateSymbolValidation
[  3ms] Transform
[  0ms] StreamParameterValidation
[  1ms] RestoreUnresolvedType
[  0ms] CircularTypeReference
[  1ms] SchemaLockValidation
[  5ms] CodeGeneration (dotnet, browser)
 Done in 13ms