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