Skip to main content

sdml_core/model/
walk.rs

1/*!
2Provides the capability to walk the in-memory model of an SDML module.
3
4To use the model walker:
5
61. Provide a type, say `MyModuleWalker`.
72. Provide an implementation of `SimpleModuleVisitor` for `MyModuleWalker`.
82. Implement any methods from the trait `SimpleModuleVisitor` of interest to you.
93. Use the function `walk_module_simple` and provide the module you wish to walk and your walker.
10
11```rust,ignore
12#[derive(Debug, Default)]
13pub struct MyModuleWalker {}
14
15impl SimpleModuleVisitor for MyModuleWalker {
16    // implement some methods...
17}
18
19walk_module_simple(
20    &some_module,  // module to walk
21    &mut MyModuleWalker::default(),
22    false,         // ignore constraints
23    true           // include members/variants
24);
25```
26
27*/
28
29use crate::{
30    error::Error,
31    model::{
32        annotations::{Annotation, AnnotationProperty, HasAnnotations},
33        constraints::{ConstraintBody, ControlledLanguageString, FormalConstraint},
34        definitions::{
35            DatatypeDef, Definition, DimensionDef, DimensionIdentity, DimensionParent, EntityDef,
36            EnumDef, EventDef, PropertyDef, RdfDef, SourceEntity, StructureDef, TypeVariant,
37            UnionDef, ValueVariant,
38        },
39        identifiers::IdentifierReference,
40        members::{Member, MemberDef, MemberKind},
41        modules::{Import, ImportStatement, MemberImport, Module, ModuleImport},
42        HasBody, HasOptionalBody,
43    },
44};
45use tracing::info;
46
47// ------------------------------------------------------------------------------------------------
48// Public Types
49// ------------------------------------------------------------------------------------------------
50
51///
52/// The trait that captures the callbacks that [`walk_module_simple`] uses as it traverses the module.
53///
54/// Some functions return a boolean, this indicates whether the walker should continue into any
55/// nested structure for that model element. For example if `structure_start` returns `false` then
56/// no annotations or members within that structure instance will be walked. Note that this also
57/// removes the corresponding `structure_end` as well.
58///
59pub trait SimpleModuleVisitor {
60    const INCLUDE_NESTED: Result<bool, Error> = Ok(true);
61    const NO_NESTED: Result<bool, Error> = Ok(false);
62
63    // --------------------------------------------------------------------------------------------
64    // Module-level
65    // --------------------------------------------------------------------------------------------
66
67    ///
68    /// Called to denote the start of a `Module` instance.
69    ///
70    /// # Nested Calls
71    ///
72    /// - `import` once for each import statement
73    /// - `annotation_start` once for each annotation on the module
74    /// - `definition_start` once for each definition in the module
75    /// - `module_end` once, when imports, annotations, and definitions are complete
76    ///
77    fn module_start(&mut self, _thing: &Module) -> Result<bool, Error> {
78        info!("SimpleModuleWalker::module_start(..) -- skipped");
79        Self::INCLUDE_NESTED
80    }
81
82    ///
83    /// Called to denote the end of a `Module` instance.
84    ///
85    /// # Nested
86    ///
87    /// None.
88    ///
89    fn module_end(&mut self, _thing: &Module) -> Result<(), Error> {
90        info!("SimpleModuleWalker::module_end(..) -- skipped");
91        Ok(())
92    }
93
94    ///
95    /// Called to denote the start of an `ImportStatement` instance.
96    ///
97    /// # Nested
98    ///
99    /// - `module_import`
100    /// - `member_import`
101    ///
102    fn import_statement_start(&mut self, _thing: &ImportStatement) -> Result<bool, Error> {
103        info!("SimpleModuleWalker::import_statement_start(..) -- skipped");
104        Self::INCLUDE_NESTED
105    }
106
107    ///
108    /// Called to denote the end of an `ImportStatement` instance.
109    ///
110    /// # Nested
111    ///
112    /// None.
113    ///
114    fn import_statement_end(&mut self, _thing: &ImportStatement) -> Result<(), Error> {
115        info!("SimpleModuleWalker::import_statement_end(..) -- skipped");
116        Ok(())
117    }
118
119    ///
120    /// Called to handle a `ModuleImport` instance.
121    ///
122    /// # Nested
123    ///
124    /// None.
125    ///
126    fn module_import(&mut self, _thing: &ModuleImport) -> Result<(), Error> {
127        info!("SimpleModuleWalker::module_import(..) -- skipped");
128        Ok(())
129    }
130
131    ///
132    /// Called to handle a `Qualifiedidentifier` instance.
133    ///
134    /// # Nested
135    ///
136    /// None.
137    ///
138    fn member_import(&mut self, _thing: &MemberImport) -> Result<(), Error> {
139        info!("SimpleModuleWalker::member_import(..) -- skipped");
140        Ok(())
141    }
142
143    // --------------------------------------------------------------------------------------------
144    // Annotations
145    // --------------------------------------------------------------------------------------------
146
147    ///
148    /// Called to denote the start of an `Annotation` instance.
149    ///
150    /// # Nested
151    ///
152    /// - `annotation_property`
153    /// - `informal_constraint`
154    /// - `formal_constraint`
155    /// - `annotation_end`
156    ///
157    fn annotation_start(&mut self, _thing: &Annotation) -> Result<bool, Error> {
158        info!("SimpleModuleWalker::annotation_start(..) -- skipped");
159        Self::INCLUDE_NESTED
160    }
161
162    ///
163    /// Called to denote the end of an `Annotation` instance.
164    ///
165    /// # Nested
166    ///
167    /// None.
168    ///
169    fn annotation_end(&mut self, _thing: &Annotation) -> Result<(), Error> {
170        info!("SimpleModuleWalker::annotation_end(..) -- skipped");
171        Ok(())
172    }
173
174    ///
175    /// Called to handle a `AnnotationProperty` instance.
176    ///
177    /// # Nested
178    ///
179    /// None.
180    ///
181    fn annotation_property(&mut self, _thing: &AnnotationProperty) -> Result<(), Error> {
182        info!("SimpleModuleWalker::annotation_property(..) -- skipped");
183        Ok(())
184    }
185
186    ///
187    /// Called to handle a `ControlledLanguageString` instance.
188    ///
189    /// # Nested
190    ///
191    /// None.
192    ///
193    fn informal_constraint(&mut self, _thing: &ControlledLanguageString) -> Result<(), Error> {
194        info!("SimpleModuleWalker::informal_constraint(..) -- skipped");
195        Ok(())
196    }
197
198    ///
199    /// Called to handle a `FormalConstraint` instance.
200    ///
201    /// # Nested
202    ///
203    /// None.
204    ///
205    fn formal_constraint(&mut self, _thing: &FormalConstraint) -> Result<(), Error> {
206        info!("SimpleModuleWalker::formal_constraint(..) -- skipped");
207        Ok(())
208    }
209
210    // --------------------------------------------------------------------------------------------
211    // Definitions
212    // --------------------------------------------------------------------------------------------
213
214    ///
215    /// Called to denote the start of a `Definition` instance.
216    ///
217    /// # Nested
218    ///
219    /// - `datatype_start`
220    /// - `entity_start`
221    /// - `enum_start`
222    /// - `event_start`
223    /// - `property_start`
224    /// - `rdf_start`
225    /// - `structure_start`
226    /// - `union_start`
227    /// - `definition_end`
228    ///
229    fn definition_start(&mut self, _thing: &Definition) -> Result<bool, Error> {
230        info!("SimpleModuleWalker::definition_start(..) -- skipped");
231        Self::INCLUDE_NESTED
232    }
233
234    ///
235    /// Called to denote the end of a `Definition` instance.
236    ///
237    /// # Nested
238    ///
239    /// None
240    ///
241    fn definition_end(&mut self, _thing: &Definition) -> Result<(), Error> {
242        info!("SimpleModuleWalker::definition_end(..) -- skipped");
243        Ok(())
244    }
245
246    ///
247    /// Called to denote the start of a `DatatypeDef` instance.
248    ///
249    /// # Nested
250    ///
251    /// - `annotation_start`
252    /// - `datatype_end`
253    ///
254    fn datatype_start(&mut self, _thing: &DatatypeDef) -> Result<bool, Error> {
255        info!("SimpleModuleWalker::datatype_start(..) -- skipped");
256        Self::INCLUDE_NESTED
257    }
258
259    ///
260    /// Called to denote the end of a `DatatypeDef` instance.
261    ///
262    /// # Nested
263    ///
264    /// None.
265    ///
266    fn datatype_end(&mut self, _thing: &DatatypeDef) -> Result<(), Error> {
267        info!("SimpleModuleWalker::datatype_end(..) -- skipped");
268        Ok(())
269    }
270
271    ///
272    /// Called to denote the start of a `DimensionDef` instance.
273    ///
274    /// # Nested
275    ///
276    /// - `annotation_start`
277    /// - `dimension_entity_start`
278    /// - `dimension_parent_start`
279    /// - `member_start`
280    /// - `dimension_end`
281    ///
282    fn dimension_start(&mut self, _thing: &DimensionDef) -> Result<bool, Error> {
283        info!("SimpleModuleWalker::dimension_start(..) -- skipped");
284        Self::INCLUDE_NESTED
285    }
286
287    ///
288    /// Called to denote the end of a `DimensionDef` instance.
289    ///
290    /// # Nested
291    ///
292    /// None.
293    ///
294    fn dimension_end(&mut self, _thing: &DimensionDef) -> Result<(), Error> {
295        info!("SimpleModuleWalker::dimension_end(..) -- skipped");
296        Ok(())
297    }
298
299    ///
300    /// Called to denote the start of a `DimensionIdentity` instance.
301    ///
302    /// # Nested
303    ///
304    /// - `identity_member_start` or `source_entity_start`
305    /// - `dimension_entity_end`
306    ///
307    fn dimension_identity_start(&mut self, _thing: &DimensionIdentity) -> Result<bool, Error> {
308        info!("SimpleModuleWalker::dimension_identity_start(..) -- skipped");
309        Self::INCLUDE_NESTED
310    }
311
312    ///
313    /// Called to denote the end of a `DimensionIdentity` instance.
314    ///
315    /// # Nested
316    ///
317    /// None.
318    ///
319    fn dimension_identity_end(&mut self, _thing: &DimensionIdentity) -> Result<(), Error> {
320        info!("SimpleModuleWalker::dimension_identity_end(..) -- skipped");
321        Ok(())
322    }
323
324    ///
325    /// Called to denote the start of an `SourceEntity` instance.
326    ///
327    /// # Nested
328    ///
329    /// - `source_entity_end`
330    ///
331    fn source_entity_start(&mut self, _thing: &SourceEntity) -> Result<bool, Error> {
332        info!("SimpleModuleWalker::source_entity_start(..) -- skipped");
333        Self::INCLUDE_NESTED
334    }
335
336    ///
337    /// Called to denote the end of an `SourceEntity` instance.
338    ///
339    /// # Nested
340    ///
341    /// None.
342    ///
343    fn source_entity_end(&mut self, _thing: &SourceEntity) -> Result<(), Error> {
344        info!("SimpleModuleWalker::source_entity_end(..) -- skipped");
345        Ok(())
346    }
347
348    ///
349    /// Called to denote the start of an `EntityDef` instance.
350    ///
351    /// # Nested
352    ///
353    /// - `annotation_start`
354    /// - `identity_member_start`
355    /// - `member_start`
356    /// - `entity_end`
357    ///
358    fn entity_start(&mut self, _thing: &EntityDef) -> Result<bool, Error> {
359        info!("SimpleModuleWalker::import(..) -- skipped");
360        Self::INCLUDE_NESTED
361    }
362
363    ///
364    /// Called to denote the end of an `EntityDef` instance.
365    ///
366    /// # Nested
367    ///
368    /// None.
369    ///
370    fn entity_end(&mut self, _thing: &EntityDef) -> Result<(), Error> {
371        info!("SimpleModuleWalker::import(..) -- skipped");
372        Ok(())
373    }
374
375    ///
376    /// Called to denote the start of an `EnumDef` instance.
377    ///
378    /// # Nested
379    ///
380    /// - `annotation_start`
381    /// - `value_variant_start`
382    /// - `enum_end`
383    ///
384    fn enum_start(&mut self, _thing: &EnumDef) -> Result<bool, Error> {
385        info!("SimpleModuleWalker::enum_start(..) -- skipped");
386        Self::INCLUDE_NESTED
387    }
388
389    ///
390    /// Called to denote the end of an `EnumDef` instance.
391    ///
392    /// # Nested
393    ///
394    /// None.
395    ///
396    fn enum_end(&mut self, _thing: &EnumDef) -> Result<(), Error> {
397        info!("SimpleModuleWalker::enum_end(..) -- skipped");
398        Ok(())
399    }
400
401    ///
402    /// Called to denote the start of an `EventDef` instance.
403    ///
404    /// # Nested
405    ///
406    /// - `annotation_start`
407    /// - `source_entity_start`
408    /// - `member_start`
409    /// - `event_end`
410    ///
411    fn event_start(&mut self, _thing: &EventDef) -> Result<bool, Error> {
412        info!("SimpleModuleWalker::event_start(..) -- skipped");
413        Self::INCLUDE_NESTED
414    }
415
416    ///
417    /// Called to denote the end of an `EventDef` instance.
418    ///
419    /// # Nested
420    ///
421    /// None.
422    ///
423    fn event_end(&mut self, _thing: &EventDef) -> Result<(), Error> {
424        info!("SimpleModuleWalker::event_end(..) -- skipped");
425        Ok(())
426    }
427
428    ///
429    /// Called to denote the start of a `PropertyDev` instance.
430    ///
431    /// # Nested
432    ///
433    /// - `member_definition_start`
434    /// - `property_end`
435    ///
436    fn property_start(&mut self, _thing: &PropertyDef) -> Result<bool, Error> {
437        info!("SimpleModuleWalker::property_start(..) -- skipped");
438        Self::INCLUDE_NESTED
439    }
440
441    ///
442    /// Called to denote the end of a `PropertyDef` instance.
443    ///
444    /// # Nested
445    ///
446    /// None.
447    ///
448    fn property_end(&mut self, _thing: &PropertyDef) -> Result<(), Error> {
449        info!("SimpleModuleWalker::property_end(..) -- skipped");
450        Ok(())
451    }
452
453    ///
454    /// Called to denote the start of a `RdfDef` instance.
455    ///
456    /// # Nested
457    ///
458    /// - `annotation_start`
459    /// - `rdf_end`
460    ///
461    fn rdf_start(&mut self, _thing: &RdfDef) -> Result<bool, Error> {
462        info!("SimpleModuleWalker::rdf_start(..) -- skipped");
463        Self::INCLUDE_NESTED
464    }
465
466    ///
467    /// Called to denote the end of a `RdfDef` instance.
468    ///
469    /// # Nested
470    ///
471    /// None.
472    ///
473    fn rdf_end(&mut self, _thing: &RdfDef) -> Result<(), Error> {
474        info!("SimpleModuleWalker::rdf_end(..) -- skipped");
475        Ok(())
476    }
477
478    ///
479    /// Called to denote the start of a `StructureDef` instance.
480    ///
481    /// # Nested
482    ///
483    /// - `annotation_start`
484    /// - `member_start`
485    /// - `structure_end`
486    ///
487    fn structure_start(&mut self, _thing: &StructureDef) -> Result<bool, Error> {
488        info!("SimpleModuleWalker::structure_start(..) -- skipped");
489        Self::INCLUDE_NESTED
490    }
491
492    ///
493    /// Called to denote the end of a `StructureDef` instance.
494    ///
495    /// # Nested
496    ///
497    /// None.
498    ///
499    fn structure_end(&mut self, _thing: &StructureDef) -> Result<(), Error> {
500        info!("SimpleModuleWalker::structure_end(..) -- skipped");
501        Ok(())
502    }
503
504    ///
505    /// Called to denote the start of an `UnionDef` instance.
506    ///
507    /// # Nested
508    ///
509    /// - `annotation_start`
510    /// - `type_variant_start`
511    /// - `union_end`
512    ///
513    fn union_start(&mut self, _thing: &UnionDef) -> Result<bool, Error> {
514        info!("SimpleModuleWalker::union_start(..) -- skipped");
515        Self::INCLUDE_NESTED
516    }
517
518    ///
519    /// Called to denote the end of an `UnionDef` instance.
520    ///
521    /// # Nested
522    ///
523    /// None.
524    ///
525    fn union_end(&mut self, _thing: &UnionDef) -> Result<(), Error> {
526        info!("SimpleModuleWalker::union_end(..) -- skipped");
527        Ok(())
528    }
529
530    // --------------------------------------------------------------------------------------------
531    // Members and Variants
532    // --------------------------------------------------------------------------------------------
533
534    ///
535    /// Called to denote the start of a `Member` instance.
536    ///
537    /// # Nested
538    ///
539    /// - `property_reference_start`
540    /// - `member_definition_start`
541    /// - `member_end`
542    ///
543    fn member_start(&mut self, _thing: &Member) -> Result<bool, Error> {
544        info!("SimpleModuleWalker::member_start(..) -- skipped");
545        Self::INCLUDE_NESTED
546    }
547
548    ///
549    /// Called to denote the end of a `Member` instance.
550    ///
551    /// # Nested
552    ///
553    /// None.
554    ///
555    fn member_end(&mut self, _thing: &Member) -> Result<(), Error> {
556        info!("SimpleModuleWalker::member_end(..) -- skipped");
557        Ok(())
558    }
559
560    ///
561    /// Called to denote the start of an identity `Member` instance.
562    ///
563    /// # Nested
564    ///
565    /// - `property_reference_start`
566    /// - `member_definition_start`
567    /// - `identity_member_end`
568    ///
569    fn identity_member_start(&mut self, _thing: &Member) -> Result<bool, Error> {
570        info!("SimpleModuleWalker::identity_member_start(..) -- skipped");
571        Self::INCLUDE_NESTED
572    }
573
574    ///
575    /// Called to denote the end of an identity `Member` instance.
576    ///
577    /// # Nested
578    ///
579    /// None.
580    ///
581    fn identity_member_end(&mut self, _thing: &Member) -> Result<(), Error> {
582        info!("SimpleModuleWalker::identity_member_end(..) -- skipped");
583        Ok(())
584    }
585
586    ///
587    /// Called to denote the start of a `DimensionParent` instance.
588    ///
589    /// # Nested
590    ///
591    /// - `dimension_parent_end`
592    ///
593    fn dimension_parent_start(&mut self, _thing: &DimensionParent) -> Result<bool, Error> {
594        info!("SimpleModuleWalker::dimension_parent_start(..) -- skipped");
595        Self::INCLUDE_NESTED
596    }
597
598    ///
599    /// Called to denote the end of a `DimensionParent` instance.
600    ///
601    /// # Nested
602    ///
603    /// None.
604    ///
605    fn dimension_parent_end(&mut self, _thing: &DimensionParent) -> Result<(), Error> {
606        info!("SimpleModuleWalker::dimension_parent_end(..) -- skipped");
607        Ok(())
608    }
609
610    ///
611    /// Called to denote the start of a `MemberDef` instance.
612    ///
613    /// # Nested
614    ///
615    /// - `annotation_start`
616    /// - `member_definition_end`
617    ///
618    fn member_definition_start(&mut self, _thing: &MemberDef) -> Result<bool, Error> {
619        info!("SimpleModuleWalker::member_definition_start(..) -- skipped");
620        Self::INCLUDE_NESTED
621    }
622
623    ///
624    /// Called to denote the end of a `MemberDef` instance.
625    ///
626    /// # Nested
627    ///
628    /// None.
629    ///
630    fn member_definition_end(&mut self, _thing: &MemberDef) -> Result<(), Error> {
631        info!("SimpleModuleWalker::member_definition_end(..) -- skipped");
632        Ok(())
633    }
634
635    ///
636    /// Called to denote the start of a member reference `IdentifierReference` instance.
637    ///
638    /// # Nested
639    ///
640    /// - `property_reference_end`
641    ///
642    fn property_reference_start(&mut self, _thing: &IdentifierReference) -> Result<bool, Error> {
643        info!("SimpleModuleWalker::property_reference_start(..) -- skipped");
644        Self::INCLUDE_NESTED
645    }
646
647    ///
648    /// Called to denote the end of a member reference `IdentifierReference` instance.
649    ///
650    /// # Nested
651    ///
652    /// None.
653    ///
654    fn property_reference_end(&mut self, _thing: &IdentifierReference) -> Result<(), Error> {
655        info!("SimpleModuleWalker::property_reference_end(..) -- skipped");
656        Ok(())
657    }
658
659    ///
660    /// Called to denote the start of a `ValueVariant` instance.
661    ///
662    /// # Nested
663    ///
664    /// - `annotation_start`
665    /// - `value_variant_end`
666    ///
667    fn value_variant_start(&mut self, _thing: &ValueVariant) -> Result<bool, Error> {
668        info!("SimpleModuleWalker::value_variant_start(..) -- skipped");
669        Self::INCLUDE_NESTED
670    }
671
672    ///
673    /// Called to denote the end of a `ValueVariant` instance.
674    ///
675    /// # Nested
676    ///
677    /// None.
678    ///
679    fn value_variant_end(&mut self, _thing: &ValueVariant) -> Result<(), Error> {
680        info!("SimpleModuleWalker::value_variant_end(..) -- skipped");
681        Ok(())
682    }
683
684    ///
685    /// Called to denote the start of a `TypeVarian` instance.
686    ///
687    /// # Nested
688    ///
689    /// - `annotation_start`
690    /// - `type_variant_end`
691    ///
692    fn type_variant_start(&mut self, _thing: &TypeVariant) -> Result<bool, Error> {
693        info!("SimpleModuleWalker::type_variant_start(..) -- skipped");
694        Self::INCLUDE_NESTED
695    }
696
697    ///
698    /// Called to denote the end of a `TypeVariant` instance.
699    ///
700    /// # Nested
701    ///
702    /// None.
703    ///
704    fn type_variant_end(&mut self, _thing: &TypeVariant) -> Result<(), Error> {
705        info!("SimpleModuleWalker::type_variant_end(..) -- skipped");
706        Ok(())
707    }
708}
709
710// ------------------------------------------------------------------------------------------------
711// Private Macros
712// ------------------------------------------------------------------------------------------------
713
714macro_rules! walk_annotations {
715    ($walker: expr, $iterator: expr, $visit_annotations: expr) => {
716        if $visit_annotations {
717            for annotation in $iterator {
718                if $walker.annotation_start(annotation)? {
719                    match annotation {
720                        Annotation::Property(property) => {
721                            $walker.annotation_property(&property)?;
722                        }
723                        Annotation::Constraint(cons) => match cons.body() {
724                            ConstraintBody::Informal(constraint) => {
725                                $walker.informal_constraint(&constraint)?;
726                            }
727                            ConstraintBody::Formal(constraint) => {
728                                $walker.formal_constraint(&constraint)?;
729                            }
730                        },
731                    }
732                    $walker.annotation_end(annotation)?;
733                }
734            }
735        }
736    };
737}
738// ------------------------------------------------------------------------------------------------
739// Public Functions
740// ------------------------------------------------------------------------------------------------
741
742///
743/// Walk the module `module` calling the relevant methods on `walker`.
744///
745pub fn walk_module_simple(
746    module: &Module,
747    walker: &mut impl SimpleModuleVisitor,
748    visit_annotations: bool,
749    visit_members_and_variants: bool,
750) -> Result<(), Error> {
751    if walker.module_start(module)? {
752        for import in module.imports() {
753            if walker.import_statement_start(import)? {
754                for import in import.imports() {
755                    match import {
756                        Import::Module(v) => walker.module_import(v)?,
757                        Import::Member(v) => walker.member_import(v)?,
758                    }
759                }
760                walker.import_statement_end(import)?;
761            }
762        }
763
764        walk_annotations!(walker, module.annotations(), visit_annotations);
765
766        for type_def in module.definitions() {
767            if walker.definition_start(type_def)? {
768                match &type_def {
769                    Definition::Datatype(def) => walk_datatype_def(def, walker, visit_annotations)?,
770                    Definition::Dimension(def) => walk_dimension_def(
771                        def,
772                        walker,
773                        visit_annotations,
774                        visit_members_and_variants,
775                    )?,
776                    Definition::Entity(def) => {
777                        walk_entity_def(def, walker, visit_annotations, visit_members_and_variants)?
778                    }
779                    Definition::Enum(def) => {
780                        walk_enum_def(def, walker, visit_annotations, visit_members_and_variants)?
781                    }
782                    Definition::Event(def) => {
783                        walk_event_def(def, walker, visit_annotations, visit_members_and_variants)?
784                    }
785                    Definition::Property(def) => walk_property_def(def, walker)?,
786                    Definition::Rdf(def) => walk_rdf_def(def, walker, visit_annotations)?,
787                    Definition::Structure(def) => walk_structure_def(
788                        def,
789                        walker,
790                        visit_annotations,
791                        visit_members_and_variants,
792                    )?,
793                    Definition::TypeClass(_) => todo!(),
794                    Definition::Union(def) => {
795                        walk_union_def(def, walker, visit_annotations, visit_members_and_variants)?
796                    }
797                }
798                walker.definition_end(type_def)?;
799            }
800        }
801
802        walker.module_end(module)?;
803    }
804    Ok(())
805}
806
807// ------------------------------------------------------------------------------------------------
808// Private Functions
809// ------------------------------------------------------------------------------------------------
810
811fn walk_datatype_def(
812    thing: &DatatypeDef,
813    walker: &mut impl SimpleModuleVisitor,
814    visit_annotations: bool,
815) -> Result<(), Error> {
816    if walker.datatype_start(thing)? {
817        if let Some(body) = thing.body() {
818            walk_annotations!(walker, body.annotations(), visit_annotations);
819        }
820
821        walker.datatype_end(thing)?;
822    }
823    Ok(())
824}
825
826fn walk_dimension_def(
827    thing: &DimensionDef,
828    walker: &mut impl SimpleModuleVisitor,
829    visit_annotations: bool,
830    visit_members_and_variants: bool,
831) -> Result<(), Error> {
832    if walker.dimension_start(thing)? {
833        if let Some(body) = thing.body() {
834            walk_annotations!(walker, body.annotations(), visit_annotations);
835
836            walk_dimension_identity(body.identity(), walker, visit_annotations)?;
837
838            if visit_members_and_variants {
839                for parent in body.parents() {
840                    walk_dimension_parent(parent, walker)?;
841                }
842
843                for member in body.members() {
844                    walk_member(member, walker, visit_annotations)?;
845                }
846            }
847        }
848
849        walker.dimension_end(thing)?;
850    }
851    Ok(())
852}
853
854fn walk_dimension_identity(
855    thing: &DimensionIdentity,
856    walker: &mut impl SimpleModuleVisitor,
857    visit_annotations: bool,
858) -> Result<(), Error> {
859    if walker.dimension_identity_start(thing)? {
860        match thing {
861            DimensionIdentity::Source(v) => walk_source_entity(v, walker),
862            DimensionIdentity::Identity(v) => walk_identity_member(v, walker, visit_annotations),
863        }?;
864        walker.dimension_identity_end(thing)?;
865    }
866    Ok(())
867}
868
869fn walk_source_entity(
870    thing: &SourceEntity,
871    walker: &mut impl SimpleModuleVisitor,
872) -> Result<(), Error> {
873    if walker.source_entity_start(thing)? {
874        walker.source_entity_end(thing)?;
875    }
876    Ok(())
877}
878
879fn walk_dimension_parent(
880    thing: &DimensionParent,
881    walker: &mut impl SimpleModuleVisitor,
882) -> Result<(), Error> {
883    if walker.dimension_parent_start(thing)? {
884        walker.dimension_parent_end(thing)?;
885    }
886    Ok(())
887}
888
889fn walk_entity_def(
890    thing: &EntityDef,
891    walker: &mut impl SimpleModuleVisitor,
892    visit_annotations: bool,
893    visit_members_and_variants: bool,
894) -> Result<(), Error> {
895    if walker.entity_start(thing)? {
896        if let Some(body) = thing.body() {
897            walk_identity_member(body.identity(), walker, visit_annotations)?;
898
899            walk_annotations!(walker, body.annotations(), visit_annotations);
900
901            if visit_members_and_variants {
902                for member in body.members() {
903                    walk_member(member, walker, visit_annotations)?;
904                }
905            }
906        }
907
908        walker.entity_end(thing)?;
909    }
910    Ok(())
911}
912
913fn walk_enum_def(
914    thing: &EnumDef,
915    walker: &mut impl SimpleModuleVisitor,
916    visit_annotations: bool,
917    visit_members_and_variants: bool,
918) -> Result<(), Error> {
919    if walker.enum_start(thing)? {
920        if let Some(body) = thing.body() {
921            walk_annotations!(walker, body.annotations(), visit_annotations);
922            if visit_members_and_variants {
923                for variant in body.variants() {
924                    walk_value_variant(variant, walker, visit_annotations)?;
925                }
926            }
927        }
928
929        walker.enum_end(thing)?;
930    }
931    Ok(())
932}
933
934fn walk_event_def(
935    thing: &EventDef,
936    walker: &mut impl SimpleModuleVisitor,
937    visit_annotations: bool,
938    visit_members_and_variants: bool,
939) -> Result<(), Error> {
940    if walker.event_start(thing)? {
941        if let Some(body) = thing.body() {
942            walk_annotations!(walker, body.annotations(), visit_annotations);
943
944            if visit_members_and_variants {
945                for member in body.members() {
946                    walk_member(member, walker, visit_annotations)?;
947                }
948            }
949        }
950
951        walker.event_end(thing)?;
952    }
953    Ok(())
954}
955
956fn walk_property_def(
957    thing: &PropertyDef,
958    walker: &mut impl SimpleModuleVisitor,
959) -> Result<(), Error> {
960    if walker.property_start(thing)? {
961        let defn = thing.member_def();
962        if walker.member_definition_start(defn)? {
963            walker.member_definition_end(defn)?;
964        }
965        walker.property_end(thing)?;
966    }
967    Ok(())
968}
969
970fn walk_rdf_def(
971    thing: &RdfDef,
972    walker: &mut impl SimpleModuleVisitor,
973    visit_annotations: bool,
974) -> Result<(), Error> {
975    if walker.rdf_start(thing)? {
976        walk_annotations!(walker, thing.body().annotations(), visit_annotations);
977        walker.rdf_end(thing)?;
978    }
979    Ok(())
980}
981
982fn walk_structure_def(
983    thing: &StructureDef,
984    walker: &mut impl SimpleModuleVisitor,
985    visit_annotations: bool,
986    visit_members_and_variants: bool,
987) -> Result<(), Error> {
988    if walker.structure_start(thing)? {
989        if let Some(body) = thing.body() {
990            walk_annotations!(walker, body.annotations(), visit_annotations);
991
992            if visit_members_and_variants {
993                for member in body.members() {
994                    walk_member(member, walker, visit_annotations)?;
995                }
996            }
997        }
998
999        walker.structure_end(thing)?;
1000    }
1001    Ok(())
1002}
1003
1004fn walk_union_def(
1005    thing: &UnionDef,
1006    walker: &mut impl SimpleModuleVisitor,
1007    visit_annotations: bool,
1008    visit_members_and_variants: bool,
1009) -> Result<(), Error> {
1010    if walker.union_start(thing)? {
1011        if let Some(body) = thing.body() {
1012            walk_annotations!(walker, body.annotations(), visit_annotations);
1013            if visit_members_and_variants {
1014                for variant in body.variants() {
1015                    walk_type_variant(variant, walker, visit_annotations)?;
1016                }
1017            }
1018        }
1019
1020        walker.union_end(thing)?;
1021    }
1022    Ok(())
1023}
1024
1025fn walk_member(
1026    thing: &Member,
1027    walker: &mut impl SimpleModuleVisitor,
1028    visit_annotations: bool,
1029) -> Result<(), Error> {
1030    if walker.member_start(thing)? {
1031        walk_member_common(thing, walker, visit_annotations)?;
1032        walker.member_end(thing)?;
1033    }
1034    Ok(())
1035}
1036
1037fn walk_identity_member(
1038    thing: &Member,
1039    walker: &mut impl SimpleModuleVisitor,
1040    visit_annotations: bool,
1041) -> Result<(), Error> {
1042    if walker.identity_member_start(thing)? {
1043        walk_member_common(thing, walker, visit_annotations)?;
1044        walker.identity_member_end(thing)?;
1045    }
1046    Ok(())
1047}
1048
1049fn walk_member_common(
1050    thing: &Member,
1051    walker: &mut impl SimpleModuleVisitor,
1052    visit_annotations: bool,
1053) -> Result<(), Error> {
1054    match thing.kind() {
1055        MemberKind::Reference(v) => {
1056            if walker.property_reference_start(v)? {
1057                walker.property_reference_end(v)?;
1058            }
1059        }
1060        MemberKind::Definition(v) => {
1061            if walker.member_definition_start(v)? {
1062                if let Some(body) = v.body() {
1063                    walk_annotations!(walker, body.annotations(), visit_annotations);
1064                }
1065                walker.member_definition_end(v)?;
1066            }
1067        }
1068    }
1069
1070    Ok(())
1071}
1072
1073fn walk_value_variant(
1074    thing: &ValueVariant,
1075    walker: &mut impl SimpleModuleVisitor,
1076    visit_annotations: bool,
1077) -> Result<(), Error> {
1078    walker.value_variant_start(thing)?;
1079
1080    if let Some(body) = thing.body() {
1081        walk_annotations!(walker, body.annotations(), visit_annotations);
1082    }
1083
1084    walker.value_variant_end(thing)
1085}
1086
1087fn walk_type_variant(
1088    thing: &TypeVariant,
1089    walker: &mut impl SimpleModuleVisitor,
1090    visit_annotations: bool,
1091) -> Result<(), Error> {
1092    walker.type_variant_start(thing)?;
1093
1094    if let Some(body) = thing.body() {
1095        walk_annotations!(walker, body.annotations(), visit_annotations);
1096    }
1097
1098    walker.type_variant_end(thing)
1099}