Skip to main content

sysml_v2_parser/
ast.rs

1//! Abstract syntax tree types for SysML v2 textual notation.
2
3/// Source location: byte offset, line, column, and length in the source file.
4/// Line and column are **1-based**. Use [`Span::to_lsp_range`] for 0-based LSP ranges.
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Span {
7    pub offset: usize,
8    pub line: u32,
9    pub column: usize,
10    pub len: usize,
11}
12
13impl Span {
14    /// Dummy span for tests or synthetic nodes (offset 0, line 1, column 1, len 0).
15    pub fn dummy() -> Self {
16        Self {
17            offset: 0,
18            line: 1,
19            column: 1,
20            len: 0,
21        }
22    }
23
24    /// LSP uses 0-based line and 0-based character. Returns (start_line, start_character, end_line, end_character).
25    pub fn to_lsp_range(&self) -> (u32, u32, u32, u32) {
26        let start_line = self.line.saturating_sub(1);
27        let start_char = self.column.saturating_sub(1);
28        let end_char = start_char.saturating_add(self.len);
29        (start_line, start_char as u32, start_line, end_char as u32)
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::Span;
36
37    #[test]
38    fn span_dummy() {
39        let s = Span::dummy();
40        assert_eq!(s.offset, 0);
41        assert_eq!(s.line, 1);
42        assert_eq!(s.column, 1);
43        assert_eq!(s.len, 0);
44    }
45}
46
47#[derive(Debug, Clone)]
48pub struct Node<T> {
49    pub span: Span,
50    pub value: T,
51}
52
53impl<T: PartialEq> PartialEq for Node<T> {
54    fn eq(&self, other: &Self) -> bool {
55        self.value == other.value
56    }
57}
58
59impl<T: Eq> Eq for Node<T> {}
60
61impl<T> Node<T> {
62    pub fn new(span: Span, value: T) -> Self {
63        Self { span, value }
64    }
65}
66
67impl<T> std::ops::Deref for Node<T> {
68    type Target = T;
69    fn deref(&self) -> &T {
70        &self.value
71    }
72}
73
74/// Trait for generic access to node source span (e.g. visitors).
75pub trait AstNode {
76    fn span(&self) -> Span;
77}
78
79impl<T> AstNode for Node<T> {
80    fn span(&self) -> Span {
81        self.span.clone()
82    }
83}
84
85/// Expression: literals, feature refs, member access, index, bracket/unit, etc.
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub enum Expression {
88    LiteralInteger(i64),
89    LiteralReal(String),
90    LiteralString(String),
91    LiteralBoolean(bool),
92    /// Single name or qualified name.
93    FeatureRef(String),
94    /// base.member (e.g. engine.fuelCmdPort).
95    MemberAccess(Box<Node<Expression>>, String),
96    /// base#(index) e.g. frontWheel#(1).
97    Index {
98        base: Box<Node<Expression>>,
99        index: Box<Node<Expression>>,
100    },
101    /// [unit] e.g. [kg].
102    Bracket(Box<Node<Expression>>),
103    /// value [unit] e.g. 1750 [kg].
104    LiteralWithUnit {
105        value: Box<Node<Expression>>,
106        unit: Box<Node<Expression>>,
107    },
108    /// Binary infix operation e.g. `a >= b * c`, `x / y`.
109    BinaryOp {
110        op: String,
111        left: Box<Node<Expression>>,
112        right: Box<Node<Expression>>,
113    },
114    /// Unary prefix: + - ~ not
115    UnaryOp {
116        op: String,
117        operand: Box<Node<Expression>>,
118    },
119    /// KerML null or empty sequence ().
120    Null,
121}
122
123/// KerML top-level element: package, namespace, import, or library package (BNF RootNamespace = PackageBodyElement*).
124#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum RootElement {
126    Package(Node<Package>),
127    LibraryPackage(Node<LibraryPackage>),
128    Namespace(Node<NamespaceDecl>),
129    Import(Node<Import>),
130}
131
132/// KerML NamespaceDeclaration: `namespace` Identification NamespaceBody (same body structure as Package).
133#[derive(Debug, Clone, PartialEq, Eq)]
134pub struct NamespaceDecl {
135    pub identification: Identification,
136    pub body: PackageBody,
137}
138
139/// Root of a SysML/KerML document: a sequence of top-level package or namespace elements.
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct RootNamespace {
142    pub elements: Vec<Node<RootElement>>,
143}
144
145/// KerML ElementFilterMember: MemberPrefix? 'filter' condition ';'
146#[derive(Debug, Clone, PartialEq, Eq)]
147pub struct FilterMember {
148    pub visibility: Option<Visibility>,
149    pub condition: Node<Expression>,
150}
151
152/// Placeholder node inserted when resilient parsing skips malformed input.
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct ParseErrorNode {
155    pub message: String,
156    pub code: String,
157    pub expected: Option<String>,
158    pub found: Option<String>,
159    pub suggestion: Option<String>,
160}
161
162/// Modeled KerML semantic declaration captured as package-level syntax.
163#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct KermlSemanticDecl {
165    pub bnf_production: String,
166    pub text: String,
167}
168
169/// Modeled KerML feature declaration family (occurrence/expr/predicate/succession).
170#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct KermlFeatureDecl {
172    pub bnf_production: String,
173    pub text: String,
174}
175
176/// Package-level KerML feature declaration captured as an explicit dedicated node.
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct FeatureDecl {
179    pub keyword: String,
180    pub text: String,
181}
182
183/// Package-level KerML classifier declaration captured as an explicit dedicated node.
184#[derive(Debug, Clone, PartialEq, Eq)]
185pub struct ClassifierDecl {
186    pub keyword: String,
187    pub text: String,
188}
189
190/// Modeled extended SysML/KerML declaration family not yet represented by
191/// dedicated concrete nodes (e.g. concern/message style library declarations).
192#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct ExtendedLibraryDecl {
194    pub bnf_production: String,
195    pub text: String,
196}
197
198/// Top-level element inside a namespace or package body.
199#[derive(Debug, Clone, PartialEq, Eq)]
200pub enum PackageBodyElement {
201    Error(Node<ParseErrorNode>),
202    Doc(Node<DocComment>),
203    Comment(Node<CommentAnnotation>),
204    TextualRep(Node<TextualRepresentation>),
205    Filter(Node<FilterMember>),
206    Package(Node<Package>),
207    LibraryPackage(Node<LibraryPackage>),
208    Import(Node<Import>),
209    PartDef(Node<PartDef>),
210    PartUsage(Node<PartUsage>),
211    PortDef(Node<PortDef>),
212    InterfaceDef(Node<InterfaceDef>),
213    AliasDef(Node<AliasDef>),
214    AttributeDef(Node<AttributeDef>),
215    ActionDef(Node<ActionDef>),
216    ActionUsage(Node<ActionUsage>),
217    RequirementDef(Node<RequirementDef>),
218    RequirementUsage(Node<RequirementUsage>),
219    Satisfy(Node<Satisfy>),
220    UseCaseDef(Node<UseCaseDef>),
221    Actor(Node<ActorDecl>),
222    StateDef(Node<StateDef>),
223    StateUsage(Node<StateUsage>),
224    ItemDef(Node<ItemDef>),
225    IndividualDef(Node<IndividualDef>),
226    ConstraintDef(Node<ConstraintDef>),
227    CalcDef(Node<CalcDef>),
228    ViewDef(Node<ViewDef>),
229    ViewpointDef(Node<ViewpointDef>),
230    RenderingDef(Node<RenderingDef>),
231    ViewUsage(Node<ViewUsage>),
232    ViewpointUsage(Node<ViewpointUsage>),
233    RenderingUsage(Node<RenderingUsage>),
234    ConnectionDef(Node<ConnectionDef>),
235    MetadataDef(Node<MetadataDef>),
236    EnumDef(Node<EnumDef>),
237    OccurrenceDef(Node<OccurrenceDef>),
238    OccurrenceUsage(Node<OccurrenceUsage>),
239    Dependency(Node<Dependency>),
240    AllocationDef(Node<AllocationDef>),
241    AllocationUsage(Node<AllocationUsage>),
242    FlowDef(Node<FlowDef>),
243    FlowUsage(Node<FlowUsage>),
244    ConcernUsage(Node<ConcernUsage>),
245    CaseDef(Node<CaseDef>),
246    CaseUsage(Node<CaseUsage>),
247    AnalysisCaseDef(Node<AnalysisCaseDef>),
248    AnalysisCaseUsage(Node<AnalysisCaseUsage>),
249    VerificationCaseDef(Node<VerificationCaseDef>),
250    VerificationCaseUsage(Node<VerificationCaseUsage>),
251    UseCaseUsage(Node<UseCaseUsage>),
252    FeatureDecl(Node<FeatureDecl>),
253    ClassifierDecl(Node<ClassifierDecl>),
254    KermlSemanticDecl(Node<KermlSemanticDecl>),
255    KermlFeatureDecl(Node<KermlFeatureDecl>),
256    ExtendedLibraryDecl(Node<ExtendedLibraryDecl>),
257}
258
259/// A package declaration: `package` Identification PackageBody
260#[derive(Debug, Clone, PartialEq, Eq)]
261pub struct Package {
262    pub identification: Identification,
263    pub body: PackageBody,
264}
265
266/// Identification: optional short name in `< >`, optional name.
267/// BNF: ( '<' declaredShortName = NAME '>' )? ( declaredName = NAME )?
268#[derive(Debug, Clone, PartialEq, Eq)]
269pub struct Identification {
270    /// Short name inside `< ... >`, if present.
271    pub short_name: Option<String>,
272    /// Main declared name (may be quoted, e.g. '1a-Parts Tree').
273    pub name: Option<String>,
274}
275
276/// Package body: either `;` or `{` PackageBodyElement* `}`
277#[derive(Debug, Clone, PartialEq, Eq)]
278pub enum PackageBody {
279    /// Semicolon form: no body elements.
280    Semicolon,
281    /// Brace form: list of body elements (may be empty).
282    Brace {
283        elements: Vec<Node<PackageBodyElement>>,
284    },
285}
286
287/// Visibility for imports and members.
288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
289pub enum Visibility {
290    Public,
291    Private,
292    Protected,
293}
294
295/// KerML FilterPackageMember: `[` OwnedExpression `]`.
296#[derive(Debug, Clone, PartialEq, Eq)]
297pub struct FilterPackageMember {
298    pub expression: Node<Expression>,
299}
300
301/// Import: `private`? `import` `all`? QualifiedName (`::` `*`)? or FilterPackage form.
302#[derive(Debug, Clone, PartialEq, Eq)]
303pub struct Import {
304    pub visibility: Option<Visibility>,
305    /// Whether this is a namespace import (QualifiedName::* or FilterPackage) or membership import (single QualifiedName).
306    pub is_import_all: bool,
307    /// Import target, e.g. "SI::kg" or "Definitions::*".
308    pub target: String,
309    /// KerML: optional recursive import after :: (e.g. QualifiedName::** or QualifiedName::*::**).
310    pub is_recursive: bool,
311    /// KerML FilterPackage form: one or more `[ expr ]` members. When present, this is a namespace import of a filter package.
312    pub filter_members: Option<Vec<Node<FilterPackageMember>>>,
313}
314
315/// Part definition: `part def` Identification (`:>` specializes)? Body.
316#[derive(Debug, Clone, PartialEq, Eq)]
317pub struct PartDef {
318    /// Optional `abstract` or `variation` prefix (BNF BasicDefinitionPrefix).
319    pub definition_prefix: Option<DefinitionPrefix>,
320    /// Whether this is an `individual part def`.
321    pub is_individual: bool,
322    pub identification: Identification,
323    /// Supertype after `:>`, e.g. Some("Axle") for `part def FrontAxle :> Axle`.
324    pub specializes: Option<String>,
325    /// Span of the `:> <type>` fragment (for semantic tokens), when present.
326    pub specializes_span: Option<Span>,
327    pub body: PartDefBody,
328}
329
330/// BNF BasicDefinitionPrefix: `abstract` | `variation`.
331#[derive(Debug, Clone, PartialEq, Eq)]
332pub enum DefinitionPrefix {
333    Abstract,
334    Variation,
335}
336
337/// Body of a part definition: `;` or `{` PartDefBodyElement* `}`.
338#[derive(Debug, Clone, PartialEq, Eq)]
339pub enum PartDefBody {
340    Semicolon,
341    Brace {
342        elements: Vec<Node<PartDefBodyElement>>,
343    },
344}
345
346/// Element inside a part definition body.
347#[derive(Debug, Clone, PartialEq, Eq)]
348pub enum PartDefBodyElement {
349    Error(Node<ParseErrorNode>),
350    Doc(Node<DocComment>),
351    Annotation(Node<Annotation>),
352    Other(String),
353    AttributeDef(Node<AttributeDef>),
354    AttributeUsage(Node<AttributeUsage>),
355    RequirementUsage(Node<RequirementUsage>),
356    Ref(Node<RefDecl>),
357    PortUsage(Node<PortUsage>),
358    PartUsage(Box<Node<PartUsage>>),
359    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
360    InterfaceUsage(Node<InterfaceUsage>),
361    Connect(Node<Connect>),
362    Perform(Node<Perform>),
363    Allocate(Node<Allocate>),
364    OpaqueMember(Node<OpaqueMemberDecl>),
365    /// `exhibit state` name `:` type (`;` or body).
366    ExhibitState(Node<ExhibitState>),
367}
368
369/// Library-tolerant part member preserved without forcing it into an unrelated node shape.
370#[derive(Debug, Clone, PartialEq, Eq)]
371pub struct OpaqueMemberDecl {
372    pub keyword: String,
373    pub name: String,
374    pub text: String,
375    pub body: AttributeBody,
376}
377
378/// Exhibit state usage: `exhibit state` name `:` type (`;` or body).
379#[derive(Debug, Clone, PartialEq, Eq)]
380pub struct ExhibitState {
381    pub name: String,
382    pub type_name: Option<String>,
383    pub redefines: Option<String>,
384    pub body: StateDefBody,
385}
386
387/// Attribute definition: `attribute` name (`:>` type)? body.
388#[derive(Debug, Clone, PartialEq, Eq)]
389pub struct AttributeDef {
390    pub name: String,
391    /// Type after `:>`, e.g. Some("ISQ::mass").
392    pub typing: Option<String>,
393    pub body: AttributeBody,
394    /// Span of the defined name (for semantic tokens).
395    pub name_span: Option<Span>,
396    /// Span of the type after `:>`, if present (for semantic tokens).
397    pub typing_span: Option<Span>,
398}
399
400/// Body of an attribute (def or usage): `;` or `{` ... `}`.
401#[derive(Debug, Clone, PartialEq, Eq)]
402pub enum AttributeBody {
403    Semicolon,
404    Brace,
405}
406
407/// Item definition: `item def` Identification body (for events, etc.).
408#[derive(Debug, Clone, PartialEq, Eq)]
409pub struct ItemDef {
410    pub identification: Identification,
411    pub body: AttributeBody,
412}
413
414/// Individual definition: `individual def` Identification `:>` type body.
415#[derive(Debug, Clone, PartialEq, Eq)]
416pub struct IndividualDef {
417    pub identification: Identification,
418    pub specializes: Option<String>,
419    pub body: AttributeBody,
420}
421
422/// Part usage: `part` name `:` type multiplicity? `ordered`? (`redefines`|`:>>`)? value? body.
423#[derive(Debug, Clone, PartialEq, Eq)]
424pub struct PartUsage {
425    pub is_individual: bool,
426    pub name: String,
427    /// Type after `:`, e.g. "Vehicle", "AxleAssembly".
428    pub type_name: String,
429    /// Multiplicity, e.g. Some("[2]").
430    pub multiplicity: Option<String>,
431    pub ordered: bool,
432    /// Optional `subsets` feature and value expression.
433    pub subsets: Option<(String, Option<Node<Expression>>)>,
434    /// Redefines target, e.g. Some("frontAxleAssembly") or Some("vehicle1::mass").
435    pub redefines: Option<String>,
436    /// Value expression (= expr, default = expr, := expr).
437    pub value: Option<Node<Expression>>,
438    pub body: PartUsageBody,
439    /// Span of the usage name (for semantic tokens).
440    pub name_span: Option<Span>,
441    /// Span of the type reference after `:` (for semantic tokens).
442    pub type_ref_span: Option<Span>,
443}
444
445/// Body of a part usage: `;` or `{` PartUsageBodyElement* `}`.
446#[derive(Debug, Clone, PartialEq, Eq)]
447pub enum PartUsageBody {
448    Semicolon,
449    Brace {
450        elements: Vec<Node<PartUsageBodyElement>>,
451    },
452}
453
454/// Metadata annotation on usage: `@` Name (`:` Type)? MetadataBody (e.g. `@Security;` or `@Safety{isMandatory = true;}`).
455#[derive(Debug, Clone, PartialEq, Eq)]
456pub struct MetadataAnnotation {
457    pub name: String,
458    pub type_name: Option<String>,
459    pub body: ConnectBody,
460}
461
462/// Generic annotation or metadata usage captured in body scopes.
463#[derive(Debug, Clone, PartialEq, Eq)]
464pub struct Annotation {
465    pub sigil: String,
466    pub head: String,
467    pub type_name: Option<String>,
468    pub body: ConnectBody,
469}
470
471/// Element inside a part usage body.
472#[derive(Debug, Clone, PartialEq, Eq)]
473pub enum PartUsageBodyElement {
474    Error(Node<ParseErrorNode>),
475    Doc(Node<DocComment>),
476    Annotation(Node<Annotation>),
477    AttributeUsage(Node<AttributeUsage>),
478    PartUsage(Box<Node<PartUsage>>),
479    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
480    PortUsage(Node<PortUsage>),
481    Bind(Node<Bind>),
482    /// `ref` name `:` type body (reference binding in part usage).
483    Ref(Node<RefDecl>),
484    InterfaceUsage(Node<InterfaceUsage>),
485    Connect(Node<Connect>),
486    Perform(Node<Perform>),
487    Allocate(Node<Allocate>),
488    Satisfy(Node<Satisfy>),
489    StateUsage(Node<StateUsage>),
490    MetadataAnnotation(Node<MetadataAnnotation>),
491}
492
493/// Enacted performance: `perform` action_path `{` body `}` inside a part usage.
494#[derive(Debug, Clone, PartialEq, Eq)]
495pub struct Perform {
496    /// Qualified action name (e.g. "provide power" or "provide power.generate torque").
497    pub action_name: String,
498    /// Type after `:` in "perform action name : Type" form.
499    pub type_name: Option<String>,
500    pub body: PerformBody,
501}
502
503/// Body of a perform: `;` or `{` PerformBodyElement* `}`.
504#[derive(Debug, Clone, PartialEq, Eq)]
505pub enum PerformBody {
506    Semicolon,
507    Brace {
508        elements: Vec<Node<PerformBodyElement>>,
509    },
510}
511
512/// Element inside a perform body: doc comment or in/out binding.
513#[derive(Debug, Clone, PartialEq, Eq)]
514pub enum PerformBodyElement {
515    Doc(Node<DocComment>),
516    InOut(Node<PerformInOutBinding>),
517}
518
519/// In/out binding inside a perform body: `in` name `=` expr `;` or `out` name `=` expr `;`.
520#[derive(Debug, Clone, PartialEq, Eq)]
521pub struct PerformInOutBinding {
522    pub direction: InOut,
523    pub name: String,
524    pub value: Node<Expression>,
525}
526
527/// Attribute usage: `attribute` name `redefines`? value? body.
528#[derive(Debug, Clone, PartialEq, Eq)]
529pub struct AttributeUsage {
530    pub name: String,
531    /// Redefines target, e.g. Some("Vehicle::mass").
532    pub redefines: Option<String>,
533    /// Value expression.
534    pub value: Option<Node<Expression>>,
535    pub body: AttributeBody,
536    /// Span of the usage name (for semantic tokens).
537    pub name_span: Option<Span>,
538    /// Span of the redefines target after `redefines`, if present (for semantic tokens).
539    pub redefines_span: Option<Span>,
540}
541
542// ---------------------------------------------------------------------------
543// Port
544// ---------------------------------------------------------------------------
545
546/// Port definition: `port def` Identification body.
547#[derive(Debug, Clone, PartialEq, Eq)]
548pub struct PortDef {
549    pub identification: Identification,
550    /// Supertype after `:>`, e.g. Some("ClutchPort") for `port def ManualClutchPort :> ClutchPort`.
551    pub specializes: Option<String>,
552    pub body: PortDefBody,
553}
554
555/// Body of a port definition: `;` or `{` PortDefBodyElement* `}`.
556#[derive(Debug, Clone, PartialEq, Eq)]
557pub enum PortDefBody {
558    Semicolon,
559    Brace {
560        elements: Vec<Node<PortDefBodyElement>>,
561    },
562}
563
564/// Element inside a port definition body (in/out declarations or nested port usages).
565#[derive(Debug, Clone, PartialEq, Eq)]
566pub enum PortDefBodyElement {
567    InOutDecl(Node<InOutDecl>),
568    Doc(Node<DocComment>),
569    AttributeDef(Node<AttributeDef>),
570    AttributeUsage(Node<AttributeUsage>),
571    PortUsage(Node<PortUsage>),
572}
573
574/// Port usage: `port` name `:` type multiplicity? `:>` subsets? `redefines`? body.
575#[derive(Debug, Clone, PartialEq, Eq)]
576pub struct PortUsage {
577    pub name: String,
578    pub type_name: Option<String>,
579    pub multiplicity: Option<String>,
580    /// Subsets feature and optional value expression.
581    pub subsets: Option<(String, Option<Node<Expression>>)>,
582    pub redefines: Option<String>,
583    pub body: PortBody,
584    /// Span of the usage name (for semantic tokens).
585    pub name_span: Option<Span>,
586    /// Span of the type reference after `:`, if present (for semantic tokens).
587    pub type_ref_span: Option<Span>,
588}
589
590/// Body of a port usage: `;` or `{` PortUsage* `}` (nested ports).
591#[derive(Debug, Clone, PartialEq, Eq)]
592pub enum PortBody {
593    Semicolon,
594    Brace,
595    /// Brace with nested port usages (e.g. port vehicleToRoadPort redefines ... { port left...; port right...; }).
596    BraceWithPorts {
597        elements: Vec<Node<PortUsage>>,
598    },
599}
600
601// ---------------------------------------------------------------------------
602// Interface
603// ---------------------------------------------------------------------------
604
605/// Interface definition: `interface def` Identification body.
606#[derive(Debug, Clone, PartialEq, Eq)]
607pub struct InterfaceDef {
608    pub identification: Identification,
609    pub body: InterfaceDefBody,
610}
611
612/// Body of an interface definition: `;` or `{` InterfaceDefBodyElement* `}`.
613#[derive(Debug, Clone, PartialEq, Eq)]
614pub enum InterfaceDefBody {
615    Semicolon,
616    Brace {
617        elements: Vec<Node<InterfaceDefBodyElement>>,
618    },
619}
620
621/// Element inside an interface definition body.
622#[derive(Debug, Clone, PartialEq, Eq)]
623pub enum InterfaceDefBodyElement {
624    Doc(Node<DocComment>),
625    EndDecl(Node<EndDecl>),
626    RefDecl(Node<RefDecl>),
627    ConnectStmt(Node<ConnectStmt>),
628}
629
630/// End declaration in interface def: `end` name `:` type `;`.
631#[derive(Debug, Clone, PartialEq, Eq)]
632pub struct EndDecl {
633    pub name: String,
634    pub type_name: String,
635    /// Span of the name (for semantic tokens).
636    pub name_span: Option<Span>,
637    /// Span of the type after `:` (for semantic tokens).
638    pub type_ref_span: Option<Span>,
639}
640
641/// Ref declaration in interface def: `ref` name `:` type body.
642#[derive(Debug, Clone, PartialEq, Eq)]
643pub struct RefDecl {
644    pub name: String,
645    pub type_name: String,
646    /// Optional binding value: `= expr` (SysML shorthand binding for references).
647    pub value: Option<Node<Expression>>,
648    pub body: RefBody,
649    /// Span of the name (for semantic tokens).
650    pub name_span: Option<Span>,
651    /// Span of the type after `:` (for semantic tokens).
652    pub type_ref_span: Option<Span>,
653}
654
655/// Body of a ref declaration: `;` or `{` ... `}`.
656#[derive(Debug, Clone, PartialEq, Eq)]
657pub enum RefBody {
658    Semicolon,
659    Brace,
660}
661
662// ---------------------------------------------------------------------------
663// Connection (Phase 2)
664// ---------------------------------------------------------------------------
665
666/// Connection definition: `connection def` Identification body (BNF ConnectionDefinition).
667#[derive(Debug, Clone, PartialEq, Eq)]
668pub struct ConnectionDef {
669    pub identification: Identification,
670    pub body: ConnectionDefBody,
671}
672
673/// Body of a connection definition: `;` or `{` end/ref/connect* `}`.
674#[derive(Debug, Clone, PartialEq, Eq)]
675pub enum ConnectionDefBody {
676    Semicolon,
677    Brace {
678        elements: Vec<Node<ConnectionDefBodyElement>>,
679    },
680}
681
682#[derive(Debug, Clone, PartialEq, Eq)]
683pub enum ConnectionDefBodyElement {
684    EndDecl(Node<EndDecl>),
685    RefDecl(Node<RefDecl>),
686    ConnectStmt(Node<ConnectStmt>),
687}
688
689// ---------------------------------------------------------------------------
690// Metadata (Phase 2)
691// ---------------------------------------------------------------------------
692
693/// Metadata definition: `metadata def` Identification body (BNF MetadataDefinition).
694#[derive(Debug, Clone, PartialEq, Eq)]
695pub struct MetadataDef {
696    pub is_abstract: bool,
697    pub identification: Identification,
698    pub body: DefinitionBody,
699}
700
701// ---------------------------------------------------------------------------
702// Enumeration (Phase 2)
703// ---------------------------------------------------------------------------
704
705/// Enumeration definition: `enum def` Identification EnumerationBody (BNF EnumerationDefinition).
706#[derive(Debug, Clone, PartialEq, Eq)]
707pub struct EnumDef {
708    pub identification: Identification,
709    pub body: EnumerationBody,
710}
711
712#[derive(Debug, Clone, PartialEq, Eq)]
713pub enum EnumerationBody {
714    Semicolon,
715    Brace { values: Vec<String> },
716}
717
718// ---------------------------------------------------------------------------
719// Occurrence (Phase 2)
720// ---------------------------------------------------------------------------
721
722/// Occurrence definition: `occurrence def` Identification body (BNF OccurrenceDefinition).
723#[derive(Debug, Clone, PartialEq, Eq)]
724pub struct OccurrenceDef {
725    pub is_abstract: bool,
726    pub identification: Identification,
727    pub body: DefinitionBody,
728}
729
730/// Occurrence usage: `occurrence` name (`:` type)? body, with optional individual/portion modifiers.
731#[derive(Debug, Clone, PartialEq, Eq)]
732pub struct OccurrenceUsage {
733    pub is_individual: bool,
734    pub is_then: bool,
735    pub portion_kind: Option<String>,
736    pub name: String,
737    pub type_name: Option<String>,
738    pub subsets: Option<String>,
739    pub redefines: Option<String>,
740    pub body: OccurrenceUsageBody,
741}
742
743#[derive(Debug, Clone, PartialEq, Eq)]
744pub enum OccurrenceUsageBody {
745    Semicolon,
746    Brace {
747        elements: Vec<Node<OccurrenceBodyElement>>,
748    },
749}
750
751#[derive(Debug, Clone, PartialEq, Eq)]
752pub enum OccurrenceBodyElement {
753    Error(Node<ParseErrorNode>),
754    Doc(Node<DocComment>),
755    Annotation(Node<Annotation>),
756    Other(String),
757    AttributeUsage(Node<AttributeUsage>),
758    PartUsage(Box<Node<PartUsage>>),
759    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
760}
761
762// ---------------------------------------------------------------------------
763// Library Package (Phase 2)
764// ---------------------------------------------------------------------------
765
766/// Library package: `library` (optional `standard`) `package` Identification PackageBody (BNF LibraryPackage).
767#[derive(Debug, Clone, PartialEq, Eq)]
768pub struct LibraryPackage {
769    pub is_standard: bool,
770    pub identification: Identification,
771    pub body: PackageBody,
772}
773
774/// Generic definition body: `;` or `{` ... `}` (skip content for metadata/occurrence).
775#[derive(Debug, Clone, PartialEq, Eq)]
776pub enum DefinitionBody {
777    Semicolon,
778    Brace,
779}
780
781/// Connect statement in interface def or usage: `connect` from `to` to body.
782#[derive(Debug, Clone, PartialEq, Eq)]
783pub struct ConnectStmt {
784    pub from: Node<Expression>,
785    pub to: Node<Expression>,
786    pub body: ConnectBody,
787}
788
789/// Body of a connect statement: `;` or `{` ... `}`.
790#[derive(Debug, Clone, PartialEq, Eq)]
791pub enum ConnectBody {
792    Semicolon,
793    Brace,
794}
795
796// ---------------------------------------------------------------------------
797// Part usage body: bind, interface usage, connect
798// ---------------------------------------------------------------------------
799
800/// Bind: `bind` left `=` right (`;` or `{ }`).
801#[derive(Debug, Clone, PartialEq, Eq)]
802pub struct Bind {
803    pub left: Node<Expression>,
804    pub right: Node<Expression>,
805    /// Optional body after the bind (semicolon or brace); 3a fixture uses `bind x = y { }`.
806    pub body: Option<ConnectBody>,
807}
808
809/// Interface usage: typed+connect or connection form.
810#[derive(Debug, Clone, PartialEq, Eq)]
811pub enum InterfaceUsage {
812    /// `interface` `:Type`? `connect` from `to` to body; optional body with ref redefs.
813    TypedConnect {
814        interface_type: Option<String>,
815        from: Node<Expression>,
816        to: Node<Expression>,
817        body: ConnectBody,
818        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
819    },
820    /// `interface` from `to` to body.
821    Connection {
822        from: Node<Expression>,
823        to: Node<Expression>,
824        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
825    },
826}
827
828/// Element in interface usage body (e.g. ref redefinition).
829#[derive(Debug, Clone, PartialEq, Eq)]
830pub enum InterfaceUsageBodyElement {
831    /// `ref` `:>>` name `=` value body.
832    RefRedef {
833        name: String,
834        value: Node<Expression>,
835        body: RefBody,
836    },
837}
838
839/// Connect at part usage level: `connect` from `to` to body.
840#[derive(Debug, Clone, PartialEq, Eq)]
841pub struct Connect {
842    pub from: Node<Expression>,
843    pub to: Node<Expression>,
844    pub body: ConnectBody,
845}
846
847// ---------------------------------------------------------------------------
848// Alias
849// ---------------------------------------------------------------------------
850
851/// Alias definition: `alias` Identification `for` qualified_name body.
852#[derive(Debug, Clone, PartialEq, Eq)]
853pub struct AliasDef {
854    pub identification: Identification,
855    pub target: String,
856    pub body: AliasBody,
857}
858
859/// Body of an alias definition: `;` or `{` ... `}`.
860#[derive(Debug, Clone, PartialEq, Eq)]
861pub enum AliasBody {
862    Semicolon,
863    Brace,
864}
865
866// ---------------------------------------------------------------------------
867// Action (function-based behavior)
868// ---------------------------------------------------------------------------
869
870/// Action definition: `action def` Identification body (in/out params).
871#[derive(Debug, Clone, PartialEq, Eq)]
872pub struct ActionDef {
873    pub identification: Identification,
874    pub body: ActionDefBody,
875}
876
877/// Body of an action definition: `;` or `{` ActionDefBodyElement* `}`.
878#[derive(Debug, Clone, PartialEq, Eq)]
879pub enum ActionDefBody {
880    Semicolon,
881    Brace {
882        elements: Vec<Node<ActionDefBodyElement>>,
883    },
884}
885
886/// Element inside an action definition body.
887#[derive(Debug, Clone, PartialEq, Eq)]
888pub enum ActionDefBodyElement {
889    Error(Node<ParseErrorNode>),
890    InOutDecl(Node<InOutDecl>),
891    Doc(Node<DocComment>),
892    Annotation(Node<Annotation>),
893    RefDecl(Node<RefDecl>),
894    Perform(Node<Perform>),
895    Bind(Node<Bind>),
896    Flow(Node<Flow>),
897    FirstStmt(Node<FirstStmt>),
898    MergeStmt(Node<MergeStmt>),
899    StateUsage(Node<StateUsage>),
900    ActionUsage(Box<Node<ActionUsage>>),
901    Assign(Node<AssignStmt>),
902    ForLoop(Node<ForLoop>),
903    ThenAction(Node<ThenAction>),
904    Decl(Node<ActionBodyDecl>),
905}
906
907/// Assignment statement (SysML v2 AssignmentNode/AssignmentActionUsage).
908///
909/// Examples:
910/// - `assign x := y;`
911/// - `then assign position := dynamics.x_out;`
912#[derive(Debug, Clone, PartialEq, Eq)]
913pub struct AssignStmt {
914    pub is_then: bool,
915    pub lhs: String,
916    pub rhs: String,
917}
918
919/// For-loop node (SysML v2 ForLoopNode) - modeled minimally.
920#[derive(Debug, Clone, PartialEq, Eq)]
921pub struct ForLoop {
922    pub var: String,
923    pub range: String,
924    pub body: ActionDefBody,
925}
926
927/// Succession to an action usage: `then action ...`.
928#[derive(Debug, Clone, PartialEq, Eq)]
929pub struct ThenAction {
930    pub action: Node<ActionUsage>,
931}
932
933/// In/out parameter in action def: `in` name `:` type `;` or `out` name `:` type `;`.
934#[derive(Debug, Clone, PartialEq, Eq)]
935pub struct InOutDecl {
936    pub direction: InOut,
937    pub name: String,
938    pub type_name: String,
939}
940
941#[derive(Debug, Clone, Copy, PartialEq, Eq)]
942pub enum InOut {
943    In,
944    Out,
945    InOut,
946}
947
948/// Action usage: `action` name `:` type_name (`accept` param_name `:` param_type)? body.
949#[derive(Debug, Clone, PartialEq, Eq)]
950pub struct ActionUsage {
951    pub name: String,
952    pub type_name: String,
953    /// For accept form: (param_name, param_type).
954    pub accept: Option<(String, String)>,
955    pub body: ActionUsageBody,
956    /// Span of the usage name (for semantic tokens).
957    pub name_span: Option<Span>,
958    /// Span of the type reference after `:` (for semantic tokens).
959    pub type_ref_span: Option<Span>,
960}
961
962/// Body of an action usage: `;` or `{` ActionUsageBodyElement* `}`.
963#[derive(Debug, Clone, PartialEq, Eq)]
964pub enum ActionUsageBody {
965    Semicolon,
966    Brace {
967        elements: Vec<Node<ActionUsageBodyElement>>,
968    },
969}
970
971/// Element inside an action usage body.
972#[derive(Debug, Clone, PartialEq, Eq)]
973pub enum ActionUsageBodyElement {
974    Error(Node<ParseErrorNode>),
975    Doc(Node<DocComment>),
976    Annotation(Node<Annotation>),
977    InOutDecl(Node<InOutDecl>),
978    RefDecl(Node<RefDecl>),
979    Bind(Node<Bind>),
980    Flow(Node<Flow>),
981    FirstStmt(Node<FirstStmt>),
982    MergeStmt(Node<MergeStmt>),
983    StateUsage(Node<StateUsage>),
984    ActionUsage(Box<Node<ActionUsage>>),
985    Assign(Node<AssignStmt>),
986    ForLoop(Node<ForLoop>),
987    ThenAction(Node<ThenAction>),
988    Decl(Node<ActionBodyDecl>),
989}
990
991/// A minimally-modeled declaration inside an action/behavior body (e.g. `attribute ...;`, `calc ...;`).
992#[derive(Debug, Clone, PartialEq, Eq)]
993pub struct ActionBodyDecl {
994    pub keyword: String,
995    pub text: String,
996}
997
998/// Flow: `flow` from `to` to body.
999#[derive(Debug, Clone, PartialEq, Eq)]
1000pub struct Flow {
1001    pub from: Node<Expression>,
1002    pub to: Node<Expression>,
1003    pub body: ConnectBody,
1004}
1005
1006/// Flow definition: `flow def` Identification body.
1007#[derive(Debug, Clone, PartialEq, Eq)]
1008pub struct FlowDef {
1009    pub identification: Identification,
1010    pub body: DefinitionBody,
1011}
1012
1013/// Flow usage: `flow` name (`:` type)? [`from` expr `to` expr]? body.
1014#[derive(Debug, Clone, PartialEq, Eq)]
1015pub struct FlowUsage {
1016    pub name: String,
1017    pub type_name: Option<String>,
1018    pub from: Option<Node<Expression>>,
1019    pub to: Option<Node<Expression>>,
1020    pub body: DefinitionBody,
1021}
1022
1023/// First/then control flow: `first` expr `then` expr body.
1024#[derive(Debug, Clone, PartialEq, Eq)]
1025pub struct FirstStmt {
1026    pub first: Node<Expression>,
1027    pub then: Node<Expression>,
1028    pub body: FirstMergeBody,
1029}
1030
1031/// Merge: `merge` expr body.
1032#[derive(Debug, Clone, PartialEq, Eq)]
1033pub struct MergeStmt {
1034    pub merge: Node<Expression>,
1035    pub body: FirstMergeBody,
1036}
1037
1038/// Body of first/merge: `;` or `{` ... `}`.
1039#[derive(Debug, Clone, PartialEq, Eq)]
1040pub enum FirstMergeBody {
1041    Semicolon,
1042    Brace,
1043}
1044
1045// ---------------------------------------------------------------------------
1046// Allocation
1047// ---------------------------------------------------------------------------
1048
1049/// Allocate statement at part usage level: `allocate` from `to` to body.
1050#[derive(Debug, Clone, PartialEq, Eq)]
1051pub struct Allocate {
1052    pub source: Node<Expression>,
1053    pub target: Node<Expression>,
1054    pub body: ConnectBody,
1055}
1056
1057/// Allocation definition: `allocation def` Identification body.
1058#[derive(Debug, Clone, PartialEq, Eq)]
1059pub struct AllocationDef {
1060    pub identification: Identification,
1061    pub body: DefinitionBody,
1062}
1063
1064/// Allocation usage: `allocation` name (`:` type)? [`allocate` source `to` target]? body.
1065#[derive(Debug, Clone, PartialEq, Eq)]
1066pub struct AllocationUsage {
1067    pub name: String,
1068    pub type_name: Option<String>,
1069    pub source: Option<Node<Expression>>,
1070    pub target: Option<Node<Expression>>,
1071    pub body: DefinitionBody,
1072}
1073
1074// ---------------------------------------------------------------------------
1075// Requirements
1076// ---------------------------------------------------------------------------
1077
1078/// Requirement definition: `requirement def` Identification body.
1079#[derive(Debug, Clone, PartialEq, Eq)]
1080pub struct RequirementDef {
1081    pub identification: Identification,
1082    pub body: RequirementDefBody,
1083}
1084
1085/// Body of an requirement definition: `;` or `{` RequirementDefBodyElement* `}`.
1086#[derive(Debug, Clone, PartialEq, Eq)]
1087pub enum RequirementDefBody {
1088    Semicolon,
1089    Brace {
1090        elements: Vec<Node<RequirementDefBodyElement>>,
1091    },
1092}
1093
1094#[derive(Debug, Clone, PartialEq, Eq)]
1095pub enum RequirementDefBodyElement {
1096    Error(Node<ParseErrorNode>),
1097    /// Unmodeled requirement-body element captured as raw text (used for library parsing).
1098    Other(String),
1099    Annotation(Node<Annotation>),
1100    Import(Node<Import>),
1101    SubjectDecl(Node<SubjectDecl>),
1102    AttributeDef(Node<AttributeDef>),
1103    AttributeUsage(Node<AttributeUsage>),
1104    RequireConstraint(Node<RequireConstraint>),
1105    Frame(Node<FrameMember>),
1106    Doc(Node<DocComment>),
1107}
1108
1109/// Subject declaration: `subject` name `:` type `;`.
1110#[derive(Debug, Clone, PartialEq, Eq)]
1111pub struct SubjectDecl {
1112    pub name: String,
1113    pub type_name: String,
1114}
1115
1116/// Require constraint: `require constraint { ... }`.
1117#[derive(Debug, Clone, PartialEq, Eq)]
1118pub struct RequireConstraint {
1119    pub body: RequireConstraintBody,
1120}
1121
1122/// Require constraint body: `;` or `{` ConstraintDefBodyElement* `}`.
1123#[derive(Debug, Clone, PartialEq, Eq)]
1124pub enum RequireConstraintBody {
1125    Semicolon,
1126    Brace {
1127        elements: Vec<Node<ConstraintDefBodyElement>>,
1128    },
1129}
1130
1131/// Requirement usage / Satisfy. Example: `satisfy EnduranceReq by droneInstance;`
1132#[derive(Debug, Clone, PartialEq, Eq)]
1133pub struct Satisfy {
1134    pub source: Node<Expression>,
1135    pub target: Node<Expression>,
1136    pub body: ConnectBody,
1137}
1138
1139/// Bare requirement Usage.
1140#[derive(Debug, Clone, PartialEq, Eq)]
1141pub struct RequirementUsage {
1142    pub name: String,
1143    pub type_name: Option<String>,
1144    pub subsets: Option<String>,
1145    pub body: RequirementDefBody,
1146}
1147
1148/// Dependency: `dependency` (Identification `from`)? client(s) `to` supplier(s) RelationshipBody.
1149#[derive(Debug, Clone, PartialEq, Eq)]
1150pub struct Dependency {
1151    pub identification: Option<Identification>,
1152    pub clients: Vec<String>,
1153    pub suppliers: Vec<String>,
1154    pub body: ConnectBody,
1155}
1156
1157/// Framed concern member in requirement body: `frame` name (`;` or body).
1158#[derive(Debug, Clone, PartialEq, Eq)]
1159pub struct FrameMember {
1160    pub name: String,
1161    pub body: RequirementDefBody,
1162}
1163
1164/// Concern usage at package level: `concern` name (`:` type)? RequirementBody.
1165#[derive(Debug, Clone, PartialEq, Eq)]
1166pub struct ConcernUsage {
1167    pub name: String,
1168    pub type_name: Option<String>,
1169    pub body: RequirementDefBody,
1170}
1171
1172/// Case definition: `case def` Identification body.
1173#[derive(Debug, Clone, PartialEq, Eq)]
1174pub struct CaseDef {
1175    pub identification: Identification,
1176    pub body: UseCaseDefBody,
1177}
1178
1179/// Case usage: `case` name (`:` type)? body.
1180#[derive(Debug, Clone, PartialEq, Eq)]
1181pub struct CaseUsage {
1182    pub name: String,
1183    pub type_name: Option<String>,
1184    pub body: UseCaseDefBody,
1185}
1186
1187/// Analysis case definition: `analysis def` Identification body.
1188#[derive(Debug, Clone, PartialEq, Eq)]
1189pub struct AnalysisCaseDef {
1190    pub identification: Identification,
1191    pub body: UseCaseDefBody,
1192}
1193
1194/// Analysis case usage: `analysis` name (`:` type)? body.
1195#[derive(Debug, Clone, PartialEq, Eq)]
1196pub struct AnalysisCaseUsage {
1197    pub name: String,
1198    pub type_name: Option<String>,
1199    pub body: UseCaseDefBody,
1200}
1201
1202/// Verification case definition: `verification def` Identification body.
1203#[derive(Debug, Clone, PartialEq, Eq)]
1204pub struct VerificationCaseDef {
1205    pub identification: Identification,
1206    pub body: UseCaseDefBody,
1207}
1208
1209/// Verification case usage: `verification` name (`:` type)? body.
1210#[derive(Debug, Clone, PartialEq, Eq)]
1211pub struct VerificationCaseUsage {
1212    pub name: String,
1213    pub type_name: Option<String>,
1214    pub body: UseCaseDefBody,
1215}
1216
1217/// Use case usage at package level: `use case` name (`:` type)? CaseBody.
1218#[derive(Debug, Clone, PartialEq, Eq)]
1219pub struct UseCaseUsage {
1220    pub name: String,
1221    pub type_name: Option<String>,
1222    pub body: UseCaseDefBody,
1223}
1224
1225// ---------------------------------------------------------------------------
1226// Use Cases
1227// ---------------------------------------------------------------------------
1228
1229/// Actor declaration: `actor` Identification `;`.
1230#[derive(Debug, Clone, PartialEq, Eq)]
1231pub struct ActorDecl {
1232    pub identification: Identification,
1233}
1234
1235/// Use Case definition: `use case def` Identification body.
1236#[derive(Debug, Clone, PartialEq, Eq)]
1237pub struct UseCaseDef {
1238    pub identification: Identification,
1239    pub body: UseCaseDefBody,
1240}
1241
1242#[derive(Debug, Clone, PartialEq, Eq)]
1243pub enum UseCaseDefBody {
1244    Semicolon,
1245    Brace {
1246        elements: Vec<Node<UseCaseDefBodyElement>>,
1247    },
1248}
1249
1250/// `first <name>;` inside a case/use-case body (used in SysML v2 release fixtures).
1251#[derive(Debug, Clone, PartialEq, Eq)]
1252pub struct FirstSuccession {
1253    pub target: String,
1254}
1255
1256/// `then done;` inside a case/use-case body.
1257#[derive(Debug, Clone, PartialEq, Eq)]
1258pub struct ThenDone {}
1259
1260/// `include <usecase> ...` inside a case/use-case body.
1261#[derive(Debug, Clone, PartialEq, Eq)]
1262pub struct IncludeUseCase {
1263    pub name: String,
1264    /// Optional multiplicity suffix like `[0..*]` captured as raw text including brackets.
1265    pub multiplicity: Option<String>,
1266    pub body: UseCaseDefBody,
1267}
1268
1269/// `then include <usecase> ...` inside a case/use-case body.
1270#[derive(Debug, Clone, PartialEq, Eq)]
1271pub struct ThenIncludeUseCase {
1272    pub include: Node<IncludeUseCase>,
1273}
1274
1275/// `then use case <name> ...` inside a case/use-case body.
1276#[derive(Debug, Clone, PartialEq, Eq)]
1277pub struct ThenUseCaseUsage {
1278    pub use_case: Node<UseCaseUsage>,
1279}
1280
1281/// `subject;` shorthand used in SysML v2 release fixtures (subject of an enclosing case/use case).
1282#[derive(Debug, Clone, PartialEq, Eq)]
1283pub struct SubjectRef {}
1284
1285/// `actor :>> <name> = <expr>;` redefinition/assignment used in SysML v2 release fixtures.
1286#[derive(Debug, Clone, PartialEq, Eq)]
1287pub struct ActorRedefinitionAssignment {
1288    pub name: String,
1289    /// Raw RHS expression text up to `;` (we don't model the expression grammar here yet).
1290    pub rhs: String,
1291}
1292
1293/// `ref :>> <name> { ... }` redefinition used in SysML v2 release fixtures.
1294#[derive(Debug, Clone, PartialEq, Eq)]
1295pub struct RefRedefinition {
1296    pub name: String,
1297    /// Raw body text for now (balanced `{ ... }` including nested braces).
1298    pub body: String,
1299}
1300
1301/// `return ref <name><multiplicity?> { ... }` used in SysML v2 release libraries.
1302#[derive(Debug, Clone, PartialEq, Eq)]
1303pub struct ReturnRef {
1304    pub name: String,
1305    pub multiplicity: Option<String>,
1306    /// Raw body text for now (balanced `{ ... }` including nested braces).
1307    pub body: String,
1308}
1309
1310#[derive(Debug, Clone, PartialEq, Eq)]
1311pub enum UseCaseDefBodyElement {
1312    Error(Node<ParseErrorNode>),
1313    /// Unmodeled use-case / analysis-case body element captured as raw text (used for library parsing).
1314    Other(String),
1315    Doc(Node<DocComment>),
1316    SubjectDecl(Node<SubjectDecl>),
1317    /// `subject;` shorthand.
1318    SubjectRef(Node<SubjectRef>),
1319    ActorUsage(Node<ActorUsage>),
1320    ActorRedefinitionAssignment(Node<ActorRedefinitionAssignment>),
1321    Objective(Node<Objective>),
1322    FirstSuccession(Node<FirstSuccession>),
1323    ThenIncludeUseCase(Node<ThenIncludeUseCase>),
1324    ThenUseCaseUsage(Node<ThenUseCaseUsage>),
1325    ThenDone(Node<ThenDone>),
1326    IncludeUseCase(Node<IncludeUseCase>),
1327    RefRedefinition(Node<RefRedefinition>),
1328    ReturnRef(Node<ReturnRef>),
1329    Assign(Node<AssignStmt>),
1330    ForLoop(Node<ForLoop>),
1331    ThenAction(Node<ThenAction>),
1332}
1333
1334/// actor usage `actor pilot : Operator;`
1335#[derive(Debug, Clone, PartialEq, Eq)]
1336pub struct ActorUsage {
1337    pub name: String,
1338    pub type_name: String,
1339}
1340
1341/// Objective `objective { doc ... }`
1342#[derive(Debug, Clone, PartialEq, Eq)]
1343pub struct Objective {
1344    pub body: ConstraintBody,
1345}
1346
1347// ---------------------------------------------------------------------------
1348// State Machine
1349// ---------------------------------------------------------------------------
1350
1351/// State definition: `state def` Identification body.
1352#[derive(Debug, Clone, PartialEq, Eq)]
1353pub struct StateDef {
1354    pub identification: Identification,
1355    pub body: StateDefBody,
1356}
1357
1358#[derive(Debug, Clone, PartialEq, Eq)]
1359pub enum StateDefBody {
1360    Semicolon,
1361    Brace {
1362        elements: Vec<Node<StateDefBodyElement>>,
1363    },
1364}
1365
1366#[derive(Debug, Clone, PartialEq, Eq)]
1367pub enum StateDefBodyElement {
1368    Error(Node<ParseErrorNode>),
1369    Doc(Node<DocComment>),
1370    Annotation(Node<Annotation>),
1371    Other(String),
1372    /// `entry` (`;` or body) - entry action.
1373    Entry(Node<EntryAction>),
1374    /// `then` name `;` - initial state.
1375    Then(Node<ThenStmt>),
1376    /// `ref` name `:` type body – reference binding in state.
1377    Ref(Node<RefDecl>),
1378    RequirementUsage(Node<RequirementUsage>),
1379    StateUsage(Node<StateUsage>),
1380    Transition(Node<Transition>),
1381}
1382
1383/// Entry action: `entry` (`;` or body).
1384#[derive(Debug, Clone, PartialEq, Eq)]
1385pub struct EntryAction {
1386    /// For `entry action name body` form; None for plain `entry` body.
1387    pub action_name: Option<String>,
1388    pub body: StateDefBody,
1389}
1390
1391/// Then (initial state): `then` name `;`
1392#[derive(Debug, Clone, PartialEq, Eq)]
1393pub struct ThenStmt {
1394    pub state_name: String,
1395}
1396
1397/// State usage: `state` name (`:` type)? body.
1398#[derive(Debug, Clone, PartialEq, Eq)]
1399pub struct StateUsage {
1400    pub name: String,
1401    pub type_name: Option<String>,
1402    pub body: StateDefBody,
1403}
1404
1405/// Transition: `transition` name [`first` source] [`if` guard] [`do` effect] `then` target body.
1406#[derive(Debug, Clone, PartialEq, Eq)]
1407pub struct Transition {
1408    pub name: Option<String>,
1409    /// If omitted, form is `transition name then target;`.
1410    pub source: Option<Node<Expression>>,
1411    pub guard: Option<Node<Expression>>,
1412    pub effect: Option<Node<Expression>>,
1413    pub target: Node<Expression>,
1414    pub body: ConnectBody,
1415}
1416
1417// ---------------------------------------------------------------------------
1418// Constraints & Calculations
1419// ---------------------------------------------------------------------------
1420
1421/// Constraint definition: `constraint def` Identification body.
1422#[derive(Debug, Clone, PartialEq, Eq)]
1423pub struct ConstraintDef {
1424    pub identification: Identification,
1425    pub body: ConstraintDefBody,
1426}
1427
1428#[derive(Debug, Clone, PartialEq, Eq)]
1429pub enum ConstraintDefBody {
1430    Semicolon,
1431    Brace {
1432        elements: Vec<Node<ConstraintDefBodyElement>>,
1433    },
1434}
1435
1436#[derive(Debug, Clone, PartialEq, Eq)]
1437pub enum ConstraintDefBodyElement {
1438    Error(Node<ParseErrorNode>),
1439    Doc(Node<DocComment>),
1440    InOutDecl(Node<InOutDecl>),
1441    Expression(Node<Expression>), // e.g. totalThrust >= totalWeight * margin
1442    /// Unmodeled constraint-body element captured as raw text (used for library parsing).
1443    Other(String),
1444}
1445
1446/// constraint body {}
1447#[derive(Debug, Clone, PartialEq, Eq)]
1448pub enum ConstraintBody {
1449    Semicolon,
1450    Brace, // Often contains docs or block of expressions
1451}
1452
1453/// KerML Documentation: 'doc' Identification? ( 'locale' STRING_VALUE )? body = REGULAR_COMMENT.
1454#[derive(Debug, Clone, PartialEq, Eq)]
1455pub struct DocComment {
1456    /// Optional identification after 'doc'.
1457    pub identification: Option<Identification>,
1458    /// Optional locale string (e.g. "en").
1459    pub locale: Option<String>,
1460    /// Body text (content between /* and */).
1461    pub text: String,
1462}
1463
1464/// KerML Comment: ( 'comment' Identification? )? ( 'locale' STRING_VALUE )? body = REGULAR_COMMENT.
1465#[derive(Debug, Clone, PartialEq, Eq)]
1466pub struct CommentAnnotation {
1467    pub identification: Option<Identification>,
1468    pub locale: Option<String>,
1469    pub text: String,
1470}
1471
1472/// KerML TextualRepresentation: ( 'rep' Identification )? 'language' STRING_VALUE body.
1473#[derive(Debug, Clone, PartialEq, Eq)]
1474pub struct TextualRepresentation {
1475    pub rep_identification: Option<Identification>,
1476    pub language: String,
1477    pub text: String,
1478}
1479
1480/// Calc definition: `calc def` Identification body.
1481#[derive(Debug, Clone, PartialEq, Eq)]
1482pub struct CalcDef {
1483    pub identification: Identification,
1484    pub body: CalcDefBody,
1485}
1486
1487#[derive(Debug, Clone, PartialEq, Eq)]
1488pub enum CalcDefBody {
1489    Semicolon,
1490    Brace {
1491        elements: Vec<Node<CalcDefBodyElement>>,
1492    },
1493}
1494
1495#[derive(Debug, Clone, PartialEq, Eq)]
1496pub enum CalcDefBodyElement {
1497    Error(Node<ParseErrorNode>),
1498    Doc(Node<DocComment>),
1499    InOutDecl(Node<InOutDecl>),
1500    ReturnDecl(Node<ReturnDecl>),
1501    Expression(Node<Expression>), // formula
1502    /// Unmodeled calc-body element captured as raw text (used for library parsing).
1503    Other(String),
1504}
1505
1506/// Return declaration: `return` name `:` type `;`.
1507#[derive(Debug, Clone, PartialEq, Eq)]
1508pub struct ReturnDecl {
1509    pub name: String,
1510    pub type_name: String,
1511}
1512
1513// ---------------------------------------------------------------------------
1514// Views and Viewpoints (SysML v2 Clause 8.2.2.26)
1515// ---------------------------------------------------------------------------
1516
1517/// View definition: `view def` Identification ViewDefinitionBody.
1518#[derive(Debug, Clone, PartialEq, Eq)]
1519pub struct ViewDef {
1520    pub identification: Identification,
1521    pub body: ViewDefBody,
1522}
1523
1524#[derive(Debug, Clone, PartialEq, Eq)]
1525pub enum ViewDefBody {
1526    Semicolon,
1527    Brace {
1528        elements: Vec<Node<ViewDefBodyElement>>,
1529    },
1530}
1531
1532#[derive(Debug, Clone, PartialEq, Eq)]
1533pub enum ViewDefBodyElement {
1534    Error(Node<ParseErrorNode>),
1535    /// Unmodeled view-definition body element captured as raw text (used for library parsing).
1536    Other(String),
1537    Doc(Node<DocComment>),
1538    Filter(Node<FilterMember>),
1539    ViewRendering(Node<ViewRenderingUsage>),
1540}
1541
1542/// View rendering usage: `render` name `:` type (`;` or body).
1543#[derive(Debug, Clone, PartialEq, Eq)]
1544pub struct ViewRenderingUsage {
1545    pub name: String,
1546    pub type_name: Option<String>,
1547    pub body: ConnectBody,
1548}
1549
1550/// Viewpoint definition: `viewpoint def` Identification RequirementBody.
1551#[derive(Debug, Clone, PartialEq, Eq)]
1552pub struct ViewpointDef {
1553    pub identification: Identification,
1554    pub body: RequirementDefBody,
1555}
1556
1557/// Rendering definition: `rendering def` Definition.
1558#[derive(Debug, Clone, PartialEq, Eq)]
1559pub struct RenderingDef {
1560    pub identification: Identification,
1561    pub body: RenderingDefBody,
1562}
1563
1564#[derive(Debug, Clone, PartialEq, Eq)]
1565pub enum RenderingDefBody {
1566    Semicolon,
1567    Brace,
1568}
1569
1570/// View usage: `view` name `:` type? ViewBody.
1571#[derive(Debug, Clone, PartialEq, Eq)]
1572pub struct ViewUsage {
1573    pub name: String,
1574    pub type_name: Option<String>,
1575    pub body: ViewBody,
1576}
1577
1578#[derive(Debug, Clone, PartialEq, Eq)]
1579pub enum ViewBody {
1580    Semicolon,
1581    Brace {
1582        elements: Vec<Node<ViewBodyElement>>,
1583    },
1584}
1585
1586#[derive(Debug, Clone, PartialEq, Eq)]
1587pub enum ViewBodyElement {
1588    Error(Node<ParseErrorNode>),
1589    /// Unmodeled view body element captured as raw text (used for library parsing).
1590    Other(String),
1591    Doc(Node<DocComment>),
1592    Filter(Node<FilterMember>),
1593    ViewRendering(Node<ViewRenderingUsage>),
1594    Expose(Node<ExposeMember>),
1595    Satisfy(Node<SatisfyViewMember>),
1596}
1597
1598/// Expose in view body: `expose` (MembershipImport | NamespaceImport) RelationshipBody.
1599#[derive(Debug, Clone, PartialEq, Eq)]
1600pub struct ExposeMember {
1601    /// Full target path (e.g. vehicle, vehicle::*, vehicle::*::**, SystemModel::vehicle::**).
1602    pub target: String,
1603    pub body: ConnectBody,
1604}
1605
1606/// Satisfy in view body: `satisfy` QualifiedName RelationshipBody.
1607#[derive(Debug, Clone, PartialEq, Eq)]
1608pub struct SatisfyViewMember {
1609    pub viewpoint_ref: String,
1610    pub body: ConnectBody,
1611}
1612
1613/// Viewpoint usage: `viewpoint` ConstraintUsageDeclaration RequirementBody.
1614#[derive(Debug, Clone, PartialEq, Eq)]
1615pub struct ViewpointUsage {
1616    pub name: String,
1617    pub type_name: String,
1618    pub body: RequirementDefBody,
1619}
1620
1621/// Rendering usage: `rendering` Usage.
1622#[derive(Debug, Clone, PartialEq, Eq)]
1623pub struct RenderingUsage {
1624    pub name: String,
1625    pub type_name: Option<String>,
1626    pub body: ConnectBody,
1627}
1628
1629// ---------------------------------------------------------------------------
1630// Normalization for test comparison (strips optional spans so parsed == expected)
1631// ---------------------------------------------------------------------------
1632
1633impl RootNamespace {
1634    /// Returns a copy with all optional source spans set to `None` and all `Node` spans set to
1635    /// `Span::dummy()`. Use when comparing parser output to hand-built expected AST in tests.
1636    pub fn normalize_for_test_comparison(&self) -> Self {
1637        RootNamespace {
1638            elements: self
1639                .elements
1640                .iter()
1641                .map(normalize_root_element_node)
1642                .collect(),
1643        }
1644    }
1645}
1646
1647fn dummy_node<T: Clone>(_n: &Node<T>, value: T) -> Node<T> {
1648    Node::new(Span::dummy(), value)
1649}
1650
1651fn normalize_root_element_node(el: &Node<RootElement>) -> Node<RootElement> {
1652    let value = match &el.value {
1653        RootElement::Package(p) => RootElement::Package(dummy_node(p, normalize_package(&p.value))),
1654        RootElement::LibraryPackage(lp) => {
1655            RootElement::LibraryPackage(dummy_node(lp, normalize_library_package(&lp.value)))
1656        }
1657        RootElement::Namespace(n) => {
1658            RootElement::Namespace(dummy_node(n, normalize_namespace_decl(&n.value)))
1659        }
1660        RootElement::Import(n) => RootElement::Import(dummy_node(n, n.value.clone())),
1661    };
1662    dummy_node(el, value)
1663}
1664
1665fn normalize_library_package(lp: &LibraryPackage) -> LibraryPackage {
1666    LibraryPackage {
1667        is_standard: lp.is_standard,
1668        identification: lp.identification.clone(),
1669        body: normalize_package_body(&lp.body),
1670    }
1671}
1672
1673fn normalize_namespace_decl(n: &NamespaceDecl) -> NamespaceDecl {
1674    NamespaceDecl {
1675        identification: n.identification.clone(),
1676        body: normalize_package_body(&n.body),
1677    }
1678}
1679
1680fn normalize_package(p: &Package) -> Package {
1681    Package {
1682        identification: p.identification.clone(),
1683        body: normalize_package_body(&p.body),
1684    }
1685}
1686
1687fn normalize_package_body(b: &PackageBody) -> PackageBody {
1688    match b {
1689        PackageBody::Semicolon => PackageBody::Semicolon,
1690        PackageBody::Brace { elements } => PackageBody::Brace {
1691            elements: elements
1692                .iter()
1693                .map(normalize_package_body_element_node)
1694                .collect(),
1695        },
1696    }
1697}
1698
1699fn normalize_package_body_element_node(el: &Node<PackageBodyElement>) -> Node<PackageBodyElement> {
1700    let value = match &el.value {
1701        PackageBodyElement::Error(n) => PackageBodyElement::Error(dummy_node(n, n.value.clone())),
1702        PackageBodyElement::Doc(n) => PackageBodyElement::Doc(dummy_node(n, n.value.clone())),
1703        PackageBodyElement::Comment(n) => {
1704            PackageBodyElement::Comment(dummy_node(n, n.value.clone()))
1705        }
1706        PackageBodyElement::TextualRep(n) => {
1707            PackageBodyElement::TextualRep(dummy_node(n, n.value.clone()))
1708        }
1709        PackageBodyElement::Filter(n) => PackageBodyElement::Filter(dummy_node(n, n.value.clone())),
1710        PackageBodyElement::Package(n) => {
1711            PackageBodyElement::Package(dummy_node(n, normalize_package(&n.value)))
1712        }
1713        PackageBodyElement::LibraryPackage(n) => {
1714            PackageBodyElement::LibraryPackage(dummy_node(n, normalize_library_package(&n.value)))
1715        }
1716        PackageBodyElement::Import(n) => PackageBodyElement::Import(dummy_node(n, n.value.clone())),
1717        PackageBodyElement::PartDef(n) => {
1718            PackageBodyElement::PartDef(dummy_node(n, normalize_part_def(&n.value)))
1719        }
1720        PackageBodyElement::PartUsage(n) => {
1721            PackageBodyElement::PartUsage(dummy_node(n, normalize_part_usage(&n.value)))
1722        }
1723        PackageBodyElement::PortDef(n) => {
1724            PackageBodyElement::PortDef(dummy_node(n, normalize_port_def(&n.value)))
1725        }
1726        PackageBodyElement::InterfaceDef(n) => {
1727            PackageBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
1728        }
1729        PackageBodyElement::ConnectionDef(n) => {
1730            PackageBodyElement::ConnectionDef(dummy_node(n, normalize_connection_def(&n.value)))
1731        }
1732        PackageBodyElement::MetadataDef(n) => {
1733            PackageBodyElement::MetadataDef(dummy_node(n, normalize_metadata_def(&n.value)))
1734        }
1735        PackageBodyElement::EnumDef(n) => {
1736            PackageBodyElement::EnumDef(dummy_node(n, normalize_enum_def(&n.value)))
1737        }
1738        PackageBodyElement::OccurrenceDef(n) => {
1739            PackageBodyElement::OccurrenceDef(dummy_node(n, normalize_occurrence_def(&n.value)))
1740        }
1741        PackageBodyElement::OccurrenceUsage(n) => {
1742            PackageBodyElement::OccurrenceUsage(dummy_node(n, n.value.clone()))
1743        }
1744        PackageBodyElement::AliasDef(n) => {
1745            PackageBodyElement::AliasDef(dummy_node(n, n.value.clone()))
1746        }
1747        PackageBodyElement::AttributeDef(n) => {
1748            PackageBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
1749        }
1750        PackageBodyElement::ActionDef(n) => {
1751            PackageBodyElement::ActionDef(dummy_node(n, normalize_action_def(&n.value)))
1752        }
1753        PackageBodyElement::ActionUsage(n) => {
1754            PackageBodyElement::ActionUsage(dummy_node(n, normalize_action_usage(&n.value)))
1755        }
1756        PackageBodyElement::RequirementDef(n) => {
1757            PackageBodyElement::RequirementDef(dummy_node(n, n.value.clone()))
1758        }
1759        PackageBodyElement::RequirementUsage(n) => {
1760            PackageBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
1761        }
1762        PackageBodyElement::Satisfy(n) => {
1763            PackageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
1764        }
1765        PackageBodyElement::UseCaseDef(n) => {
1766            PackageBodyElement::UseCaseDef(dummy_node(n, n.value.clone()))
1767        }
1768        PackageBodyElement::Actor(n) => PackageBodyElement::Actor(dummy_node(n, n.value.clone())),
1769        PackageBodyElement::StateDef(n) => {
1770            PackageBodyElement::StateDef(dummy_node(n, n.value.clone()))
1771        }
1772        PackageBodyElement::StateUsage(n) => {
1773            PackageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
1774        }
1775        PackageBodyElement::ItemDef(n) => {
1776            PackageBodyElement::ItemDef(dummy_node(n, n.value.clone()))
1777        }
1778        PackageBodyElement::IndividualDef(n) => {
1779            PackageBodyElement::IndividualDef(dummy_node(n, n.value.clone()))
1780        }
1781        PackageBodyElement::ConstraintDef(n) => {
1782            PackageBodyElement::ConstraintDef(dummy_node(n, n.value.clone()))
1783        }
1784        PackageBodyElement::CalcDef(n) => {
1785            PackageBodyElement::CalcDef(dummy_node(n, n.value.clone()))
1786        }
1787        PackageBodyElement::ViewDef(n) => {
1788            PackageBodyElement::ViewDef(dummy_node(n, n.value.clone()))
1789        }
1790        PackageBodyElement::ViewpointDef(n) => {
1791            PackageBodyElement::ViewpointDef(dummy_node(n, n.value.clone()))
1792        }
1793        PackageBodyElement::RenderingDef(n) => {
1794            PackageBodyElement::RenderingDef(dummy_node(n, n.value.clone()))
1795        }
1796        PackageBodyElement::ViewUsage(n) => {
1797            PackageBodyElement::ViewUsage(dummy_node(n, n.value.clone()))
1798        }
1799        PackageBodyElement::ViewpointUsage(n) => {
1800            PackageBodyElement::ViewpointUsage(dummy_node(n, n.value.clone()))
1801        }
1802        PackageBodyElement::RenderingUsage(n) => {
1803            PackageBodyElement::RenderingUsage(dummy_node(n, n.value.clone()))
1804        }
1805        PackageBodyElement::Dependency(n) => {
1806            PackageBodyElement::Dependency(dummy_node(n, n.value.clone()))
1807        }
1808        PackageBodyElement::AllocationDef(n) => {
1809            PackageBodyElement::AllocationDef(dummy_node(n, n.value.clone()))
1810        }
1811        PackageBodyElement::AllocationUsage(n) => {
1812            PackageBodyElement::AllocationUsage(dummy_node(n, n.value.clone()))
1813        }
1814        PackageBodyElement::FlowDef(n) => {
1815            PackageBodyElement::FlowDef(dummy_node(n, n.value.clone()))
1816        }
1817        PackageBodyElement::FlowUsage(n) => {
1818            PackageBodyElement::FlowUsage(dummy_node(n, n.value.clone()))
1819        }
1820        PackageBodyElement::ConcernUsage(n) => {
1821            PackageBodyElement::ConcernUsage(dummy_node(n, n.value.clone()))
1822        }
1823        PackageBodyElement::CaseDef(n) => {
1824            PackageBodyElement::CaseDef(dummy_node(n, n.value.clone()))
1825        }
1826        PackageBodyElement::CaseUsage(n) => {
1827            PackageBodyElement::CaseUsage(dummy_node(n, n.value.clone()))
1828        }
1829        PackageBodyElement::AnalysisCaseDef(n) => {
1830            PackageBodyElement::AnalysisCaseDef(dummy_node(n, n.value.clone()))
1831        }
1832        PackageBodyElement::AnalysisCaseUsage(n) => {
1833            PackageBodyElement::AnalysisCaseUsage(dummy_node(n, n.value.clone()))
1834        }
1835        PackageBodyElement::VerificationCaseDef(n) => {
1836            PackageBodyElement::VerificationCaseDef(dummy_node(n, n.value.clone()))
1837        }
1838        PackageBodyElement::VerificationCaseUsage(n) => {
1839            PackageBodyElement::VerificationCaseUsage(dummy_node(n, n.value.clone()))
1840        }
1841        PackageBodyElement::UseCaseUsage(n) => {
1842            PackageBodyElement::UseCaseUsage(dummy_node(n, n.value.clone()))
1843        }
1844        PackageBodyElement::FeatureDecl(n) => {
1845            PackageBodyElement::FeatureDecl(dummy_node(n, n.value.clone()))
1846        }
1847        PackageBodyElement::ClassifierDecl(n) => {
1848            PackageBodyElement::ClassifierDecl(dummy_node(n, n.value.clone()))
1849        }
1850        PackageBodyElement::KermlSemanticDecl(n) => {
1851            PackageBodyElement::KermlSemanticDecl(dummy_node(n, n.value.clone()))
1852        }
1853        PackageBodyElement::KermlFeatureDecl(n) => {
1854            PackageBodyElement::KermlFeatureDecl(dummy_node(n, n.value.clone()))
1855        }
1856        PackageBodyElement::ExtendedLibraryDecl(n) => {
1857            PackageBodyElement::ExtendedLibraryDecl(dummy_node(n, n.value.clone()))
1858        }
1859    };
1860    dummy_node(el, value)
1861}
1862
1863fn normalize_attribute_def(a: &AttributeDef) -> AttributeDef {
1864    AttributeDef {
1865        name: a.name.clone(),
1866        typing: a.typing.clone(),
1867        body: a.body.clone(),
1868        name_span: None,
1869        typing_span: None,
1870    }
1871}
1872
1873fn normalize_part_def(p: &PartDef) -> PartDef {
1874    PartDef {
1875        definition_prefix: p.definition_prefix.clone(),
1876        is_individual: p.is_individual,
1877        identification: p.identification.clone(),
1878        specializes: p.specializes.clone(),
1879        specializes_span: None,
1880        body: normalize_part_def_body(&p.body),
1881    }
1882}
1883
1884fn normalize_part_def_body(b: &PartDefBody) -> PartDefBody {
1885    match b {
1886        PartDefBody::Semicolon => PartDefBody::Semicolon,
1887        PartDefBody::Brace { elements } => PartDefBody::Brace {
1888            elements: elements
1889                .iter()
1890                .map(normalize_part_def_body_element_node)
1891                .collect(),
1892        },
1893    }
1894}
1895
1896fn normalize_part_def_body_element_node(el: &Node<PartDefBodyElement>) -> Node<PartDefBodyElement> {
1897    let value = match &el.value {
1898        PartDefBodyElement::Error(n) => PartDefBodyElement::Error(dummy_node(n, n.value.clone())),
1899        PartDefBodyElement::Doc(n) => PartDefBodyElement::Doc(dummy_node(n, n.value.clone())),
1900        PartDefBodyElement::Annotation(n) => {
1901            PartDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
1902        }
1903        PartDefBodyElement::Other(text) => PartDefBodyElement::Other(text.clone()),
1904        PartDefBodyElement::AttributeDef(n) => {
1905            PartDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
1906        }
1907        PartDefBodyElement::AttributeUsage(n) => {
1908            PartDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
1909        }
1910        PartDefBodyElement::RequirementUsage(n) => {
1911            PartDefBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
1912        }
1913        PartDefBodyElement::Ref(n) => {
1914            PartDefBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
1915        }
1916        PartDefBodyElement::PortUsage(n) => {
1917            PartDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
1918        }
1919        PartDefBodyElement::PartUsage(n) => {
1920            PartDefBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
1921        }
1922        PartDefBodyElement::OccurrenceUsage(n) => {
1923            PartDefBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
1924        }
1925        PartDefBodyElement::InterfaceUsage(n) => {
1926            PartDefBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
1927        }
1928        PartDefBodyElement::Connect(n) => {
1929            PartDefBodyElement::Connect(dummy_node(n, n.value.clone()))
1930        }
1931        PartDefBodyElement::Perform(n) => {
1932            PartDefBodyElement::Perform(dummy_node(n, n.value.clone()))
1933        }
1934        PartDefBodyElement::Allocate(n) => {
1935            PartDefBodyElement::Allocate(dummy_node(n, n.value.clone()))
1936        }
1937        PartDefBodyElement::OpaqueMember(n) => {
1938            PartDefBodyElement::OpaqueMember(dummy_node(n, n.value.clone()))
1939        }
1940        PartDefBodyElement::ExhibitState(n) => {
1941            PartDefBodyElement::ExhibitState(dummy_node(n, n.value.clone()))
1942        }
1943    };
1944    dummy_node(el, value)
1945}
1946
1947fn normalize_attribute_usage(a: &AttributeUsage) -> AttributeUsage {
1948    AttributeUsage {
1949        name: a.name.clone(),
1950        redefines: a.redefines.clone(),
1951        value: a.value.clone(),
1952        body: a.body.clone(),
1953        name_span: None,
1954        redefines_span: None,
1955    }
1956}
1957
1958fn normalize_part_usage(p: &PartUsage) -> PartUsage {
1959    PartUsage {
1960        is_individual: p.is_individual,
1961        name: p.name.clone(),
1962        type_name: p.type_name.clone(),
1963        multiplicity: p.multiplicity.clone(),
1964        ordered: p.ordered,
1965        subsets: p.subsets.clone(),
1966        redefines: p.redefines.clone(),
1967        value: p.value.clone(),
1968        body: normalize_part_usage_body(&p.body),
1969        name_span: None,
1970        type_ref_span: None,
1971    }
1972}
1973
1974fn normalize_part_usage_body(b: &PartUsageBody) -> PartUsageBody {
1975    match b {
1976        PartUsageBody::Semicolon => PartUsageBody::Semicolon,
1977        PartUsageBody::Brace { elements } => PartUsageBody::Brace {
1978            elements: elements
1979                .iter()
1980                .map(normalize_part_usage_body_element_node)
1981                .collect(),
1982        },
1983    }
1984}
1985
1986fn normalize_perform(p: &Perform) -> Perform {
1987    Perform {
1988        action_name: p.action_name.clone(),
1989        type_name: p.type_name.clone(),
1990        body: normalize_perform_body(&p.body),
1991    }
1992}
1993
1994fn normalize_perform_body(b: &PerformBody) -> PerformBody {
1995    match b {
1996        PerformBody::Semicolon => PerformBody::Semicolon,
1997        PerformBody::Brace { elements } => PerformBody::Brace {
1998            elements: elements
1999                .iter()
2000                .map(normalize_perform_body_element_node)
2001                .collect(),
2002        },
2003    }
2004}
2005
2006fn normalize_perform_body_element_node(el: &Node<PerformBodyElement>) -> Node<PerformBodyElement> {
2007    let value = match &el.value {
2008        PerformBodyElement::Doc(n) => PerformBodyElement::Doc(dummy_node(n, n.value.clone())),
2009        PerformBodyElement::InOut(n) => PerformBodyElement::InOut(dummy_node(
2010            n,
2011            PerformInOutBinding {
2012                direction: n.value.direction,
2013                name: n.value.name.clone(),
2014                value: normalize_expression_node(&n.value.value),
2015            },
2016        )),
2017    };
2018    dummy_node(el, value)
2019}
2020
2021fn normalize_expression_node(node: &Node<Expression>) -> Node<Expression> {
2022    let value = match &node.value {
2023        Expression::LiteralInteger(x) => Expression::LiteralInteger(*x),
2024        Expression::LiteralReal(s) => Expression::LiteralReal(s.clone()),
2025        Expression::LiteralString(s) => Expression::LiteralString(s.clone()),
2026        Expression::LiteralBoolean(b) => Expression::LiteralBoolean(*b),
2027        Expression::FeatureRef(s) => Expression::FeatureRef(s.clone()),
2028        Expression::MemberAccess(base, member) => {
2029            Expression::MemberAccess(Box::new(normalize_expression_node(base)), member.clone())
2030        }
2031        Expression::Index { base, index } => Expression::Index {
2032            base: Box::new(normalize_expression_node(base)),
2033            index: Box::new(normalize_expression_node(index)),
2034        },
2035        Expression::Bracket(inner) => {
2036            Expression::Bracket(Box::new(normalize_expression_node(inner)))
2037        }
2038        Expression::LiteralWithUnit { value: v, unit } => Expression::LiteralWithUnit {
2039            value: Box::new(normalize_expression_node(v)),
2040            unit: Box::new(normalize_expression_node(unit)),
2041        },
2042        Expression::BinaryOp { op, left, right } => Expression::BinaryOp {
2043            op: op.clone(),
2044            left: Box::new(normalize_expression_node(left)),
2045            right: Box::new(normalize_expression_node(right)),
2046        },
2047        Expression::UnaryOp { op, operand } => Expression::UnaryOp {
2048            op: op.clone(),
2049            operand: Box::new(normalize_expression_node(operand)),
2050        },
2051        Expression::Null => Expression::Null,
2052    };
2053    Node::new(Span::dummy(), value)
2054}
2055
2056fn normalize_part_usage_body_element_node(
2057    el: &Node<PartUsageBodyElement>,
2058) -> Node<PartUsageBodyElement> {
2059    let value = match &el.value {
2060        PartUsageBodyElement::Error(n) => {
2061            PartUsageBodyElement::Error(dummy_node(n, n.value.clone()))
2062        }
2063        PartUsageBodyElement::Doc(n) => PartUsageBodyElement::Doc(dummy_node(n, n.value.clone())),
2064        PartUsageBodyElement::Annotation(n) => {
2065            PartUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
2066        }
2067        PartUsageBodyElement::AttributeUsage(n) => {
2068            PartUsageBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2069        }
2070        PartUsageBodyElement::PartUsage(n) => {
2071            PartUsageBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
2072        }
2073        PartUsageBodyElement::OccurrenceUsage(n) => {
2074            PartUsageBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
2075        }
2076        PartUsageBodyElement::PortUsage(n) => {
2077            PartUsageBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2078        }
2079        PartUsageBodyElement::Ref(n) => {
2080            PartUsageBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
2081        }
2082        PartUsageBodyElement::Bind(n) => PartUsageBodyElement::Bind(dummy_node(n, n.value.clone())),
2083        PartUsageBodyElement::InterfaceUsage(n) => {
2084            PartUsageBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
2085        }
2086        PartUsageBodyElement::Connect(n) => {
2087            PartUsageBodyElement::Connect(dummy_node(n, n.value.clone()))
2088        }
2089        PartUsageBodyElement::Perform(n) => {
2090            PartUsageBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
2091        }
2092        PartUsageBodyElement::Allocate(n) => {
2093            PartUsageBodyElement::Allocate(dummy_node(n, n.value.clone()))
2094        }
2095        PartUsageBodyElement::Satisfy(n) => {
2096            PartUsageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
2097        }
2098        PartUsageBodyElement::StateUsage(n) => {
2099            PartUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2100        }
2101        PartUsageBodyElement::MetadataAnnotation(n) => {
2102            PartUsageBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
2103        }
2104    };
2105    dummy_node(el, value)
2106}
2107
2108fn normalize_port_usage(p: &PortUsage) -> PortUsage {
2109    PortUsage {
2110        name: p.name.clone(),
2111        type_name: p.type_name.clone(),
2112        multiplicity: p.multiplicity.clone(),
2113        subsets: p.subsets.clone(),
2114        redefines: p.redefines.clone(),
2115        body: normalize_port_body(&p.body),
2116        name_span: None,
2117        type_ref_span: None,
2118    }
2119}
2120
2121fn normalize_port_body(b: &PortBody) -> PortBody {
2122    match b {
2123        PortBody::Semicolon => PortBody::Semicolon,
2124        PortBody::Brace => PortBody::Brace,
2125        PortBody::BraceWithPorts { elements } => PortBody::BraceWithPorts {
2126            elements: elements
2127                .iter()
2128                .map(|n| dummy_node(n, normalize_port_usage(&n.value)))
2129                .collect(),
2130        },
2131    }
2132}
2133
2134fn normalize_port_def(p: &PortDef) -> PortDef {
2135    PortDef {
2136        identification: p.identification.clone(),
2137        specializes: p.specializes.clone(),
2138        body: normalize_port_def_body(&p.body),
2139    }
2140}
2141
2142fn normalize_port_def_body(b: &PortDefBody) -> PortDefBody {
2143    match b {
2144        PortDefBody::Semicolon => PortDefBody::Semicolon,
2145        PortDefBody::Brace { elements } => PortDefBody::Brace {
2146            elements: elements
2147                .iter()
2148                .map(normalize_port_def_body_element_node)
2149                .collect(),
2150        },
2151    }
2152}
2153
2154fn normalize_port_def_body_element_node(el: &Node<PortDefBodyElement>) -> Node<PortDefBodyElement> {
2155    let value = match &el.value {
2156        PortDefBodyElement::InOutDecl(n) => {
2157            PortDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2158        }
2159        PortDefBodyElement::Doc(n) => PortDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2160        PortDefBodyElement::AttributeDef(n) => {
2161            PortDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
2162        }
2163        PortDefBodyElement::AttributeUsage(n) => {
2164            PortDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2165        }
2166        PortDefBodyElement::PortUsage(n) => {
2167            PortDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2168        }
2169    };
2170    dummy_node(el, value)
2171}
2172
2173fn normalize_interface_def(i: &InterfaceDef) -> InterfaceDef {
2174    InterfaceDef {
2175        identification: i.identification.clone(),
2176        body: normalize_interface_def_body(&i.body),
2177    }
2178}
2179
2180fn normalize_connection_def(c: &ConnectionDef) -> ConnectionDef {
2181    ConnectionDef {
2182        identification: c.identification.clone(),
2183        body: normalize_connection_def_body(&c.body),
2184    }
2185}
2186
2187fn normalize_connection_def_body(b: &ConnectionDefBody) -> ConnectionDefBody {
2188    match b {
2189        ConnectionDefBody::Semicolon => ConnectionDefBody::Semicolon,
2190        ConnectionDefBody::Brace { elements } => ConnectionDefBody::Brace {
2191            elements: elements
2192                .iter()
2193                .map(normalize_connection_def_body_element_node)
2194                .collect(),
2195        },
2196    }
2197}
2198
2199fn normalize_connection_def_body_element_node(
2200    el: &Node<ConnectionDefBodyElement>,
2201) -> Node<ConnectionDefBodyElement> {
2202    let value = match &el.value {
2203        ConnectionDefBodyElement::EndDecl(n) => {
2204            ConnectionDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
2205        }
2206        ConnectionDefBodyElement::RefDecl(n) => {
2207            ConnectionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2208        }
2209        ConnectionDefBodyElement::ConnectStmt(n) => {
2210            ConnectionDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
2211        }
2212    };
2213    dummy_node(el, value)
2214}
2215
2216fn normalize_metadata_def(m: &MetadataDef) -> MetadataDef {
2217    MetadataDef {
2218        is_abstract: m.is_abstract,
2219        identification: m.identification.clone(),
2220        body: m.body.clone(),
2221    }
2222}
2223
2224fn normalize_enum_def(e: &EnumDef) -> EnumDef {
2225    EnumDef {
2226        identification: e.identification.clone(),
2227        body: e.body.clone(),
2228    }
2229}
2230
2231fn normalize_occurrence_def(o: &OccurrenceDef) -> OccurrenceDef {
2232    OccurrenceDef {
2233        is_abstract: o.is_abstract,
2234        identification: o.identification.clone(),
2235        body: o.body.clone(),
2236    }
2237}
2238
2239fn normalize_interface_def_body(b: &InterfaceDefBody) -> InterfaceDefBody {
2240    match b {
2241        InterfaceDefBody::Semicolon => InterfaceDefBody::Semicolon,
2242        InterfaceDefBody::Brace { elements } => InterfaceDefBody::Brace {
2243            elements: elements
2244                .iter()
2245                .map(normalize_interface_def_body_element_node)
2246                .collect(),
2247        },
2248    }
2249}
2250
2251fn normalize_interface_def_body_element_node(
2252    el: &Node<InterfaceDefBodyElement>,
2253) -> Node<InterfaceDefBodyElement> {
2254    let value = match &el.value {
2255        InterfaceDefBodyElement::Doc(n) => {
2256            InterfaceDefBodyElement::Doc(dummy_node(n, n.value.clone()))
2257        }
2258        InterfaceDefBodyElement::EndDecl(n) => {
2259            InterfaceDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
2260        }
2261        InterfaceDefBodyElement::RefDecl(n) => {
2262            InterfaceDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2263        }
2264        InterfaceDefBodyElement::ConnectStmt(n) => {
2265            InterfaceDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
2266        }
2267    };
2268    dummy_node(el, value)
2269}
2270
2271fn normalize_end_decl(e: &EndDecl) -> EndDecl {
2272    EndDecl {
2273        name: e.name.clone(),
2274        type_name: e.type_name.clone(),
2275        name_span: None,
2276        type_ref_span: None,
2277    }
2278}
2279
2280fn normalize_ref_decl(r: &RefDecl) -> RefDecl {
2281    RefDecl {
2282        name: r.name.clone(),
2283        type_name: r.type_name.clone(),
2284        value: r.value.clone(),
2285        body: r.body.clone(),
2286        name_span: None,
2287        type_ref_span: None,
2288    }
2289}
2290
2291fn normalize_action_def(a: &ActionDef) -> ActionDef {
2292    ActionDef {
2293        identification: a.identification.clone(),
2294        body: normalize_action_def_body(&a.body),
2295    }
2296}
2297
2298fn normalize_action_def_body(b: &ActionDefBody) -> ActionDefBody {
2299    match b {
2300        ActionDefBody::Semicolon => ActionDefBody::Semicolon,
2301        ActionDefBody::Brace { elements } => ActionDefBody::Brace {
2302            elements: elements
2303                .iter()
2304                .map(normalize_action_def_body_element_node)
2305                .collect(),
2306        },
2307    }
2308}
2309
2310fn normalize_action_def_body_element_node(
2311    el: &Node<ActionDefBodyElement>,
2312) -> Node<ActionDefBodyElement> {
2313    let value = match &el.value {
2314        ActionDefBodyElement::Error(n) => {
2315            ActionDefBodyElement::Error(dummy_node(n, n.value.clone()))
2316        }
2317        ActionDefBodyElement::InOutDecl(n) => {
2318            ActionDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2319        }
2320        ActionDefBodyElement::Doc(n) => ActionDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2321        ActionDefBodyElement::Annotation(n) => {
2322            ActionDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
2323        }
2324        ActionDefBodyElement::RefDecl(n) => {
2325            ActionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2326        }
2327        ActionDefBodyElement::Perform(n) => {
2328            ActionDefBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
2329        }
2330        ActionDefBodyElement::Bind(n) => ActionDefBodyElement::Bind(dummy_node(n, n.value.clone())),
2331        ActionDefBodyElement::Flow(n) => ActionDefBodyElement::Flow(dummy_node(n, n.value.clone())),
2332        ActionDefBodyElement::FirstStmt(n) => {
2333            ActionDefBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
2334        }
2335        ActionDefBodyElement::MergeStmt(n) => {
2336            ActionDefBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
2337        }
2338        ActionDefBodyElement::StateUsage(n) => {
2339            ActionDefBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2340        }
2341        ActionDefBodyElement::ActionUsage(n) => ActionDefBodyElement::ActionUsage(Box::new(
2342            dummy_node(n, normalize_action_usage(&n.value)),
2343        )),
2344        ActionDefBodyElement::Assign(n) => {
2345            ActionDefBodyElement::Assign(dummy_node(n, n.value.clone()))
2346        }
2347        ActionDefBodyElement::ForLoop(n) => {
2348            ActionDefBodyElement::ForLoop(dummy_node(n, n.value.clone()))
2349        }
2350        ActionDefBodyElement::ThenAction(n) => {
2351            ActionDefBodyElement::ThenAction(dummy_node(n, n.value.clone()))
2352        }
2353        ActionDefBodyElement::Decl(n) => ActionDefBodyElement::Decl(dummy_node(n, n.value.clone())),
2354    };
2355    dummy_node(el, value)
2356}
2357
2358fn normalize_action_usage(a: &ActionUsage) -> ActionUsage {
2359    ActionUsage {
2360        name: a.name.clone(),
2361        type_name: a.type_name.clone(),
2362        accept: a.accept.clone(),
2363        body: normalize_action_usage_body(&a.body),
2364        name_span: None,
2365        type_ref_span: None,
2366    }
2367}
2368
2369fn normalize_action_usage_body(b: &ActionUsageBody) -> ActionUsageBody {
2370    match b {
2371        ActionUsageBody::Semicolon => ActionUsageBody::Semicolon,
2372        ActionUsageBody::Brace { elements } => ActionUsageBody::Brace {
2373            elements: elements
2374                .iter()
2375                .map(normalize_action_usage_body_element_node)
2376                .collect(),
2377        },
2378    }
2379}
2380
2381fn normalize_action_usage_body_element_node(
2382    el: &Node<ActionUsageBodyElement>,
2383) -> Node<ActionUsageBodyElement> {
2384    let value = match &el.value {
2385        ActionUsageBodyElement::Error(n) => {
2386            ActionUsageBodyElement::Error(dummy_node(n, n.value.clone()))
2387        }
2388        ActionUsageBodyElement::Doc(n) => {
2389            ActionUsageBodyElement::Doc(dummy_node(n, n.value.clone()))
2390        }
2391        ActionUsageBodyElement::Annotation(n) => {
2392            ActionUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
2393        }
2394        ActionUsageBodyElement::InOutDecl(n) => {
2395            ActionUsageBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2396        }
2397        ActionUsageBodyElement::RefDecl(n) => {
2398            ActionUsageBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2399        }
2400        ActionUsageBodyElement::Bind(n) => {
2401            ActionUsageBodyElement::Bind(dummy_node(n, n.value.clone()))
2402        }
2403        ActionUsageBodyElement::Flow(n) => {
2404            ActionUsageBodyElement::Flow(dummy_node(n, n.value.clone()))
2405        }
2406        ActionUsageBodyElement::FirstStmt(n) => {
2407            ActionUsageBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
2408        }
2409        ActionUsageBodyElement::MergeStmt(n) => {
2410            ActionUsageBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
2411        }
2412        ActionUsageBodyElement::StateUsage(n) => {
2413            ActionUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2414        }
2415        ActionUsageBodyElement::ActionUsage(n) => ActionUsageBodyElement::ActionUsage(Box::new(
2416            dummy_node(n, normalize_action_usage(&n.value)),
2417        )),
2418        ActionUsageBodyElement::Assign(n) => {
2419            ActionUsageBodyElement::Assign(dummy_node(n, n.value.clone()))
2420        }
2421        ActionUsageBodyElement::ForLoop(n) => {
2422            ActionUsageBodyElement::ForLoop(dummy_node(n, n.value.clone()))
2423        }
2424        ActionUsageBodyElement::ThenAction(n) => {
2425            ActionUsageBodyElement::ThenAction(dummy_node(n, n.value.clone()))
2426        }
2427        ActionUsageBodyElement::Decl(n) => {
2428            ActionUsageBodyElement::Decl(dummy_node(n, n.value.clone()))
2429        }
2430    };
2431    dummy_node(el, value)
2432}