Skip to main content

device_driver_mir/
model.rs

1use std::{
2    collections::HashMap,
3    error::Error,
4    fmt::Display,
5    marker::PhantomData,
6    num::NonZeroU32,
7    ops::{Index, IndexMut, Not},
8};
9
10use convert_case::Boundary;
11use device_driver_common::{
12    bitset::BitSet,
13    identifier::{
14        Global, Identifier, IdentifierRef, Local, Namespace, Operation, RuntimeNamespace, Type,
15    },
16    interner::Istr,
17    span::{Span, SpanExt, Spanned},
18    specifiers::{
19        Access, AddressMode, AddressRange, BaseType, ByteOrder, Integer, NodeType, Repeat,
20        RepeatSource, ResetValue,
21    },
22};
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
25pub enum ObjectType {
26    Device,
27    Block,
28    Register,
29    Command,
30    Buffer,
31    FieldSet,
32    Field,
33    Enum,
34    EnumVariant,
35    Extern,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct ObjectIdConversionError {
40    source: ObjectType,
41    target: ObjectType,
42}
43impl Display for ObjectIdConversionError {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        write!(
46            f,
47            "cannot convert from an ObjectId with type {:?} to {:?}",
48            self.source, self.target
49        )
50    }
51}
52impl Error for ObjectIdConversionError {}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
55pub struct ObjectId(ObjectType, u32);
56
57impl ObjectId {
58    pub fn object_type(self) -> ObjectType {
59        self.0
60    }
61
62    pub fn get(self, manifest: &Manifest) -> Option<Object<'_>> {
63        manifest.object(self)
64    }
65
66    pub fn get_mut(self, manifest: &mut Manifest) -> Option<ObjectMut<'_>> {
67        manifest.object_mut(self)
68    }
69}
70
71impl Default for ObjectId {
72    fn default() -> Self {
73        Self(ObjectType::Device, u32::MAX)
74    }
75}
76
77pub trait Id: Copy {
78    fn index(&self) -> usize;
79    fn create(val: usize) -> Self;
80}
81
82macro_rules! create_id {
83    ($name:ident, $object_type:ident, $manifest_collection:ident) => {
84        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
85        pub struct $name(u32);
86
87        impl $name {
88            pub fn get(self, manifest: &Manifest) -> Option<&$object_type> {
89                manifest.$manifest_collection.get(self)
90            }
91
92            pub fn get_mut(self, manifest: &mut Manifest) -> Option<&mut $object_type> {
93                manifest.$manifest_collection.get_mut(self)
94            }
95        }
96
97        impl Default for $name {
98            fn default() -> Self {
99                Self(u32::MAX)
100            }
101        }
102
103        impl From<$name> for ObjectId {
104            fn from(value: $name) -> Self {
105                Self(ObjectType::$object_type, value.0)
106            }
107        }
108
109        impl TryFrom<ObjectId> for $name {
110            type Error = ObjectIdConversionError;
111            fn try_from(value: ObjectId) -> Result<Self, Self::Error> {
112                if value.0 == ObjectType::$object_type {
113                    Ok(Self(value.1))
114                } else {
115                    Err(ObjectIdConversionError {
116                        source: value.0,
117                        target: ObjectType::$object_type,
118                    })
119                }
120            }
121        }
122
123        impl Id for $name {
124            fn index(&self) -> usize {
125                self.0 as usize
126            }
127
128            fn create(val: usize) -> Self {
129                debug_assert!(u32::try_from(val).is_ok());
130                Self(val as u32)
131            }
132        }
133    };
134}
135
136create_id!(DeviceId, Device, devices);
137create_id!(BlockId, Block, blocks);
138create_id!(RegisterId, Register, registers);
139create_id!(CommandId, Command, commands);
140create_id!(BufferId, Buffer, buffers);
141create_id!(FieldSetId, FieldSet, fieldsets);
142create_id!(FieldId, Field, fields);
143create_id!(EnumId, Enum, enums);
144create_id!(EnumVariantId, EnumVariant, enum_variants);
145create_id!(ExternId, Extern, externs);
146
147#[derive(Debug, Clone, PartialEq, Eq)]
148pub struct ObjectArena<O, ID: Id> {
149    inner: Vec<O>,
150    removed: BitSet,
151    _phantom: PhantomData<ID>,
152}
153
154impl<O: Default, ID: Id> Default for ObjectArena<O, ID> {
155    fn default() -> Self {
156        Self::new()
157    }
158}
159
160impl<O, ID: Id> ObjectArena<O, ID> {
161    pub const fn new() -> Self {
162        Self {
163            inner: Vec::new(),
164            removed: BitSet::new(),
165            _phantom: PhantomData,
166        }
167    }
168
169    pub fn get(&self, id: ID) -> Option<&O> {
170        if !self.removed.get(id.index())? {
171            self.inner.get(id.index())
172        } else {
173            None
174        }
175    }
176
177    pub fn get_mut(&mut self, id: ID) -> Option<&mut O> {
178        if !self.removed.get(id.index())? {
179            self.inner.get_mut(id.index())
180        } else {
181            None
182        }
183    }
184
185    pub fn iter(&self) -> impl Iterator<Item = &O> {
186        self.inner
187            .iter()
188            .enumerate()
189            .filter_map(|(i, obj)| self.removed.get(i)?.not().then_some(obj))
190    }
191
192    pub fn iter_enumerated(&self) -> impl Iterator<Item = (ID, &O)> {
193        self.inner
194            .iter()
195            .enumerate()
196            .filter_map(|(i, obj)| self.removed.get(i)?.not().then_some((ID::create(i), obj)))
197    }
198
199    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut O> {
200        self.inner
201            .iter_mut()
202            .enumerate()
203            .filter_map(|(i, obj)| self.removed.get(i)?.not().then_some(obj))
204    }
205
206    pub fn iter_enumerated_mut(&mut self) -> impl Iterator<Item = (ID, &mut O)> {
207        self.inner
208            .iter_mut()
209            .enumerate()
210            .filter_map(|(i, obj)| self.removed.get(i)?.not().then_some((ID::create(i), obj)))
211    }
212
213    pub fn ids(&self) -> impl Iterator<Item = ID> {
214        (0..self.inner.len()).filter_map(|i| self.removed.get(i)?.not().then_some(ID::create(i)))
215    }
216
217    pub fn push(&mut self, obj: O) -> ID {
218        let new_id = ID::create(self.inner.len());
219        self.inner.push(obj);
220        self.removed.push(false);
221        new_id
222    }
223
224    pub fn remove(&mut self, id: ID) {
225        self.removed.set(id.index(), true);
226    }
227}
228
229impl<O, ID: Id> Index<ID> for ObjectArena<O, ID> {
230    type Output = O;
231
232    fn index(&self, index: ID) -> &Self::Output {
233        self.get(index).unwrap()
234    }
235}
236
237impl<O, ID: Id> IndexMut<ID> for ObjectArena<O, ID> {
238    fn index_mut(&mut self, index: ID) -> &mut Self::Output {
239        self.get_mut(index).unwrap()
240    }
241}
242
243#[derive(Debug, Clone, Default, PartialEq)]
244pub struct Manifest {
245    pub description: Istr,
246    pub name: Spanned<Identifier<Global>>,
247    pub default_access: Option<Access>,
248    pub config: DeviceConfig,
249
250    pub devices: ObjectArena<Device, DeviceId>,
251    pub blocks: ObjectArena<Block, BlockId>,
252    pub registers: ObjectArena<Register, RegisterId>,
253    pub commands: ObjectArena<Command, CommandId>,
254    pub buffers: ObjectArena<Buffer, BufferId>,
255    pub fieldsets: ObjectArena<FieldSet, FieldSetId>,
256    pub fields: ObjectArena<Field, FieldId>,
257    pub enums: ObjectArena<Enum, EnumId>,
258    pub enum_variants: ObjectArena<EnumVariant, EnumVariantId>,
259    pub externs: ObjectArena<Extern, ExternId>,
260
261    pub parent_map: HashMap<ObjectId, Box<[ObjectId]>>,
262
263    pub short_properties_span: Span,
264    pub properties_span: Option<Span>,
265    pub body_span: Option<Span>,
266    pub span: Span,
267}
268
269impl Manifest {
270    pub fn objects(&self) -> impl Iterator<Item = Object<'_>> {
271        self.devices
272            .iter()
273            .map(Object::Device)
274            .chain(self.blocks.iter().map(Object::Block))
275            .chain(self.registers.iter().map(Object::Register))
276            .chain(self.commands.iter().map(Object::Command))
277            .chain(self.buffers.iter().map(Object::Buffer))
278            .chain(self.fieldsets.iter().map(Object::FieldSet))
279            .chain(self.fields.iter().map(Object::Field))
280            .chain(self.enums.iter().map(Object::Enum))
281            .chain(self.enum_variants.iter().map(Object::EnumVariant))
282            .chain(self.externs.iter().map(Object::Extern))
283    }
284
285    pub fn objects_enumerated(&self) -> impl Iterator<Item = (ObjectId, Object<'_>)> {
286        self.devices
287            .iter_enumerated()
288            .map(|(id, obj)| (id.into(), Object::Device(obj)))
289            .chain(
290                self.blocks
291                    .iter_enumerated()
292                    .map(|(id, obj)| (id.into(), Object::Block(obj))),
293            )
294            .chain(
295                self.registers
296                    .iter_enumerated()
297                    .map(|(id, obj)| (id.into(), Object::Register(obj))),
298            )
299            .chain(
300                self.commands
301                    .iter_enumerated()
302                    .map(|(id, obj)| (id.into(), Object::Command(obj))),
303            )
304            .chain(
305                self.buffers
306                    .iter_enumerated()
307                    .map(|(id, obj)| (id.into(), Object::Buffer(obj))),
308            )
309            .chain(
310                self.fieldsets
311                    .iter_enumerated()
312                    .map(|(id, obj)| (id.into(), Object::FieldSet(obj))),
313            )
314            .chain(
315                self.fields
316                    .iter_enumerated()
317                    .map(|(id, obj)| (id.into(), Object::Field(obj))),
318            )
319            .chain(
320                self.enums
321                    .iter_enumerated()
322                    .map(|(id, obj)| (id.into(), Object::Enum(obj))),
323            )
324            .chain(
325                self.enum_variants
326                    .iter_enumerated()
327                    .map(|(id, obj)| (id.into(), Object::EnumVariant(obj))),
328            )
329            .chain(
330                self.externs
331                    .iter_enumerated()
332                    .map(|(id, obj)| (id.into(), Object::Extern(obj))),
333            )
334    }
335
336    pub fn objects_mut(&mut self) -> impl Iterator<Item = ObjectMut<'_>> {
337        self.devices
338            .iter_mut()
339            .map(ObjectMut::Device)
340            .chain(self.blocks.iter_mut().map(ObjectMut::Block))
341            .chain(self.registers.iter_mut().map(ObjectMut::Register))
342            .chain(self.commands.iter_mut().map(ObjectMut::Command))
343            .chain(self.buffers.iter_mut().map(ObjectMut::Buffer))
344            .chain(self.fieldsets.iter_mut().map(ObjectMut::FieldSet))
345            .chain(self.fields.iter_mut().map(ObjectMut::Field))
346            .chain(self.enums.iter_mut().map(ObjectMut::Enum))
347            .chain(self.enum_variants.iter_mut().map(ObjectMut::EnumVariant))
348            .chain(self.externs.iter_mut().map(ObjectMut::Extern))
349    }
350
351    pub fn objects_enumerated_mut(&mut self) -> impl Iterator<Item = (ObjectId, ObjectMut<'_>)> {
352        self.devices
353            .iter_enumerated_mut()
354            .map(|(id, obj)| (id.into(), ObjectMut::Device(obj)))
355            .chain(
356                self.blocks
357                    .iter_enumerated_mut()
358                    .map(|(id, obj)| (id.into(), ObjectMut::Block(obj))),
359            )
360            .chain(
361                self.registers
362                    .iter_enumerated_mut()
363                    .map(|(id, obj)| (id.into(), ObjectMut::Register(obj))),
364            )
365            .chain(
366                self.commands
367                    .iter_enumerated_mut()
368                    .map(|(id, obj)| (id.into(), ObjectMut::Command(obj))),
369            )
370            .chain(
371                self.buffers
372                    .iter_enumerated_mut()
373                    .map(|(id, obj)| (id.into(), ObjectMut::Buffer(obj))),
374            )
375            .chain(
376                self.fieldsets
377                    .iter_enumerated_mut()
378                    .map(|(id, obj)| (id.into(), ObjectMut::FieldSet(obj))),
379            )
380            .chain(
381                self.fields
382                    .iter_enumerated_mut()
383                    .map(|(id, obj)| (id.into(), ObjectMut::Field(obj))),
384            )
385            .chain(
386                self.enums
387                    .iter_enumerated_mut()
388                    .map(|(id, obj)| (id.into(), ObjectMut::Enum(obj))),
389            )
390            .chain(
391                self.enum_variants
392                    .iter_enumerated_mut()
393                    .map(|(id, obj)| (id.into(), ObjectMut::EnumVariant(obj))),
394            )
395            .chain(
396                self.externs
397                    .iter_enumerated_mut()
398                    .map(|(id, obj)| (id.into(), ObjectMut::Extern(obj))),
399            )
400    }
401
402    pub fn object_ids(&self) -> impl Iterator<Item = ObjectId> {
403        self.devices
404            .ids()
405            .map(ObjectId::from)
406            .chain(self.blocks.ids().map(ObjectId::from))
407            .chain(self.registers.ids().map(ObjectId::from))
408            .chain(self.commands.ids().map(ObjectId::from))
409            .chain(self.buffers.ids().map(ObjectId::from))
410            .chain(self.fieldsets.ids().map(ObjectId::from))
411            .chain(self.fields.ids().map(ObjectId::from))
412            .chain(self.enums.ids().map(ObjectId::from))
413            .chain(self.enum_variants.ids().map(ObjectId::from))
414            .chain(self.externs.ids().map(ObjectId::from))
415    }
416
417    pub fn object(&self, id: impl Into<ObjectId>) -> Option<Object<'_>> {
418        let id = id.into();
419        match id.0 {
420            ObjectType::Device => self.devices.get(DeviceId(id.1)).map(Object::Device),
421            ObjectType::Block => self.blocks.get(BlockId(id.1)).map(Object::Block),
422            ObjectType::Register => self.registers.get(RegisterId(id.1)).map(Object::Register),
423            ObjectType::Command => self.commands.get(CommandId(id.1)).map(Object::Command),
424            ObjectType::Buffer => self.buffers.get(BufferId(id.1)).map(Object::Buffer),
425            ObjectType::FieldSet => self.fieldsets.get(FieldSetId(id.1)).map(Object::FieldSet),
426            ObjectType::Field => self.fields.get(FieldId(id.1)).map(Object::Field),
427            ObjectType::Enum => self.enums.get(EnumId(id.1)).map(Object::Enum),
428            ObjectType::EnumVariant => self
429                .enum_variants
430                .get(EnumVariantId(id.1))
431                .map(Object::EnumVariant),
432            ObjectType::Extern => self.externs.get(ExternId(id.1)).map(Object::Extern),
433        }
434    }
435
436    pub fn object_mut(&mut self, id: impl Into<ObjectId>) -> Option<ObjectMut<'_>> {
437        let id = id.into();
438        match id.0 {
439            ObjectType::Device => self.devices.get_mut(DeviceId(id.1)).map(ObjectMut::Device),
440            ObjectType::Block => self.blocks.get_mut(BlockId(id.1)).map(ObjectMut::Block),
441            ObjectType::Register => self
442                .registers
443                .get_mut(RegisterId(id.1))
444                .map(ObjectMut::Register),
445            ObjectType::Command => self
446                .commands
447                .get_mut(CommandId(id.1))
448                .map(ObjectMut::Command),
449            ObjectType::Buffer => self.buffers.get_mut(BufferId(id.1)).map(ObjectMut::Buffer),
450            ObjectType::FieldSet => self
451                .fieldsets
452                .get_mut(FieldSetId(id.1))
453                .map(ObjectMut::FieldSet),
454            ObjectType::Field => self.fields.get_mut(FieldId(id.1)).map(ObjectMut::Field),
455            ObjectType::Enum => self.enums.get_mut(EnumId(id.1)).map(ObjectMut::Enum),
456            ObjectType::EnumVariant => self
457                .enum_variants
458                .get_mut(EnumVariantId(id.1))
459                .map(ObjectMut::EnumVariant),
460            ObjectType::Extern => self.externs.get_mut(ExternId(id.1)).map(ObjectMut::Extern),
461        }
462    }
463
464    /// This assumes [crate::passes::Assumption::NamesUnique]
465    pub fn search_object<T: Namespace>(&self, name: &IdentifierRef<T>) -> Option<Object<'_>> {
466        self.objects().find(|o| name.is_ref_to(o.name()))
467    }
468
469    /// This assumes [crate::passes::Assumption::NamesUnique]
470    pub fn search_fieldset(&self, ref_val: &FieldsetRef) -> Option<&FieldSet> {
471        match ref_val {
472            FieldsetRef::Identifier(identifier_ref) => self
473                .fieldsets
474                .iter()
475                .find(|fs| identifier_ref.is_ref_to(&fs.name.value)),
476            FieldsetRef::Id(id) => self.fieldsets.get(*id),
477        }
478    }
479
480    /// This assumes [crate::passes::Assumption::NamesUnique]
481    pub fn search_type(&self, ref_val: &TypeRef) -> Option<Object<'_>> {
482        match ref_val {
483            TypeRef::Identifier(identifier_ref) => self.search_object(identifier_ref),
484            TypeRef::Id(id) => self.object(*id),
485        }
486    }
487
488    pub fn remove_object(&mut self, id: impl Into<ObjectId>) {
489        let id = id.into();
490
491        let object_ref = self.object(id).map(|object| object.name().take_ref());
492
493        fn remove(manifest: &mut Manifest, id: ObjectId) {
494            match id.0 {
495                ObjectType::Device => manifest.devices.remove(DeviceId(id.1)),
496                ObjectType::Block => manifest.blocks.remove(BlockId(id.1)),
497                ObjectType::Register => manifest.registers.remove(RegisterId(id.1)),
498                ObjectType::Command => manifest.commands.remove(CommandId(id.1)),
499                ObjectType::Buffer => manifest.buffers.remove(BufferId(id.1)),
500                ObjectType::FieldSet => manifest.fieldsets.remove(FieldSetId(id.1)),
501                ObjectType::Field => manifest.fields.remove(FieldId(id.1)),
502                ObjectType::Enum => manifest.enums.remove(EnumId(id.1)),
503                ObjectType::EnumVariant => manifest.enum_variants.remove(EnumVariantId(id.1)),
504                ObjectType::Extern => manifest.externs.remove(ExternId(id.1)),
505            }
506        }
507
508        remove(self, id);
509
510        // Remove the children
511        let mut children = Vec::new();
512        for object_id in self.object_ids() {
513            let parents = self.object_parents(object_id);
514            if parents.contains(&id) {
515                children.push(object_id);
516            }
517        }
518        for child in children {
519            remove(self, child);
520        }
521
522        // Remove from parent
523        if let Some(parent) = self.object_parents(id).last() {
524            self.object_mut(*parent).unwrap().remove_child(id);
525        }
526
527        if let Some(object_ref) = object_ref {
528            // Remove conversion types and repeat sources that target this object
529            for mut object in self.objects_mut() {
530                if let Some(repeat) = object.repeat_mut()
531                    && let RepeatSource::Enum(target) = &repeat.source.value
532                    && target.is_same_ref_as(&object_ref)
533                {
534                    repeat.source = RepeatSource::Count(NonZeroU32::new(1).unwrap())
535                        .with_span(repeat.source.span);
536                }
537
538                if let Some(type_conversion) = object.as_ref().type_conversion() {
539                    let targets_removed_object = match &type_conversion.type_ref.value {
540                        TypeRef::Identifier(identifier_ref) => {
541                            identifier_ref.is_same_ref_as(&object_ref)
542                        }
543                        TypeRef::Id(object_id) => *object_id == id,
544                    };
545                    if targets_removed_object {
546                        object.remove_type_conversion();
547                    }
548                }
549            }
550        }
551    }
552
553    pub(crate) fn populate_parent_map(&mut self) {
554        fn populate(
555            parent_map: &mut HashMap<ObjectId, Box<[ObjectId]>>,
556            manifest: &Manifest,
557            parent_list: Vec<ObjectId>,
558            children: impl Iterator<Item = ObjectId>,
559        ) {
560            for child in children {
561                parent_map.insert(child, parent_list.clone().into());
562
563                let child_object = manifest.object(child).unwrap();
564                if let Some(grand_children) = child_object.child_objects() {
565                    let mut grand_parent_list = parent_list.clone();
566                    grand_parent_list.push(child);
567                    populate(parent_map, manifest, grand_parent_list, grand_children);
568                }
569            }
570        }
571
572        let mut parent_map: HashMap<ObjectId, Box<[ObjectId]>> = Default::default();
573
574        // We know all devices are children of the manifest and nothing else
575        for root_object_id in self
576            .object_ids()
577            .filter(|object_id| self.parent_map.contains_key(object_id))
578        {
579            let object = self.object(root_object_id).unwrap();
580
581            if let Some(children) = object.child_objects() {
582                let parent_list = vec![root_object_id];
583                populate(&mut parent_map, self, parent_list, children);
584            }
585        }
586
587        self.parent_map = parent_map;
588    }
589
590    /// Get the parent list for this object.
591    /// The last parent is the most direct parent.
592    ///
593    /// It is possible one of the parents has been removed.
594    pub fn object_parents(&self, object: impl Into<ObjectId>) -> &[ObjectId] {
595        self.parent_map
596            .get(&object.into())
597            .map(|parent_list| &parent_list[..])
598            .unwrap_or(&[])
599    }
600
601    /// Get the device config that applies to the given object
602    pub fn object_config(&self, object: impl Into<ObjectId>) -> &DeviceConfig {
603        let parents = self.object_parents(object);
604
605        for object_id in parents.iter().rev() {
606            if let Some(object) = self.object(*object_id)
607                && let Some(config) = object.device_config()
608            {
609                return config;
610            }
611        }
612
613        &self.config
614    }
615
616    /// Get the device config that applies to the given object
617    pub fn object_default_access(&self, object: impl Into<ObjectId>) -> Option<Access> {
618        let parents = self.object_parents(object);
619
620        for object_id in parents.iter().rev() {
621            if let Some(object) = self.object(*object_id) {
622                match object {
623                    Object::Device(val) => {
624                        if val.default_access.is_some() {
625                            return val.default_access;
626                        }
627                    }
628                    Object::Block(val) => {
629                        if val.default_access.is_some() {
630                            return val.default_access;
631                        }
632                    }
633                    Object::FieldSet(val) => {
634                        if val.default_access.is_some() {
635                            return val.default_access;
636                        }
637                    }
638                    Object::Register(_) => {}
639                    Object::Command(_) => {}
640                    Object::Buffer(_) => {}
641                    Object::Enum(_) => {}
642                    Object::Extern(_) => {}
643                    Object::Field(_) => {}
644                    Object::EnumVariant(_) => {}
645                }
646            }
647        }
648
649        self.default_access
650    }
651}
652
653#[derive(Debug, Clone, Default, PartialEq)]
654pub struct Device {
655    pub description: Istr,
656    pub name: Spanned<Identifier<Type>>,
657    pub default_access: Option<Access>,
658    pub address_offset: Spanned<i128>,
659    pub device_config: DeviceConfig,
660    pub children: Vec<ObjectId>,
661
662    pub short_properties_span: Span,
663    pub properties_span: Option<Span>,
664    pub body_span: Option<Span>,
665    /// Span of the whole object excluding docs
666    pub span: Span,
667}
668
669#[derive(Debug, Clone, Default, PartialEq)]
670pub struct DeviceConfig {
671    /// The id of the device that owns this config. If None, then this is a manifest config
672    pub owner: Option<DeviceId>,
673    pub byte_order: Option<ByteOrder>,
674    pub register_address_type: Option<Spanned<Integer>>,
675    pub command_address_type: Option<Spanned<Integer>>,
676    pub buffer_address_type: Option<Spanned<Integer>>,
677    pub name_word_boundaries: Option<Vec<Boundary>>,
678    pub register_address_mode: Option<Spanned<AddressMode>>,
679}
680
681impl DeviceConfig {
682    #[must_use]
683    pub fn override_with(&self, other: &Self) -> DeviceConfig {
684        Self {
685            owner: other.owner.or(self.owner),
686            byte_order: other.byte_order.or(self.byte_order),
687            register_address_type: other.register_address_type.or(self.register_address_type),
688            command_address_type: other.command_address_type.or(self.command_address_type),
689            buffer_address_type: other.buffer_address_type.or(self.buffer_address_type),
690            name_word_boundaries: other
691                .name_word_boundaries
692                .as_ref()
693                .or(self.name_word_boundaries.as_ref())
694                .cloned(),
695            register_address_mode: other.register_address_mode.or(self.register_address_mode),
696        }
697    }
698
699    pub fn name_word_boundaries_or_defaults(&self) -> Vec<Boundary> {
700        self.name_word_boundaries
701            .as_deref()
702            .unwrap_or(&const { convert_case::Boundary::defaults() })
703            .to_vec()
704    }
705}
706
707#[derive(Debug, Copy, Clone, PartialEq)]
708pub enum Object<'a> {
709    Device(&'a Device),
710    Block(&'a Block),
711    Register(&'a Register),
712    Command(&'a Command),
713    Buffer(&'a Buffer),
714    FieldSet(&'a FieldSet),
715    Enum(&'a Enum),
716    Extern(&'a Extern),
717    Field(&'a Field),
718    EnumVariant(&'a EnumVariant),
719}
720
721#[derive(Debug, PartialEq)]
722pub enum ObjectMut<'a> {
723    Device(&'a mut Device),
724    Block(&'a mut Block),
725    Register(&'a mut Register),
726    Command(&'a mut Command),
727    Buffer(&'a mut Buffer),
728    FieldSet(&'a mut FieldSet),
729    Enum(&'a mut Enum),
730    Extern(&'a mut Extern),
731    Field(&'a mut Field),
732    EnumVariant(&'a mut EnumVariant),
733}
734
735impl<'a> ObjectMut<'a> {
736    pub fn as_ref(&self) -> Object<'_> {
737        match self {
738            ObjectMut::Device(device) => Object::Device(device),
739            ObjectMut::Block(block) => Object::Block(block),
740            ObjectMut::Register(register) => Object::Register(register),
741            ObjectMut::Command(command) => Object::Command(command),
742            ObjectMut::Buffer(buffer) => Object::Buffer(buffer),
743            ObjectMut::FieldSet(field_set) => Object::FieldSet(field_set),
744            ObjectMut::Enum(e) => Object::Enum(e),
745            ObjectMut::Extern(e) => Object::Extern(e),
746            ObjectMut::Field(field) => Object::Field(field),
747            ObjectMut::EnumVariant(field) => Object::EnumVariant(field),
748        }
749    }
750
751    /// Get a mutable reference to the name of the specific object
752    pub fn name_mut(&mut self) -> &mut Identifier<RuntimeNamespace> {
753        match self {
754            ObjectMut::Device(val) => val.name.as_runtime_namespace_mut(),
755            ObjectMut::Block(val) => val.name.as_runtime_namespace_mut(),
756            ObjectMut::Register(val) => val.name.as_runtime_namespace_mut(),
757            ObjectMut::Command(val) => val.name.as_runtime_namespace_mut(),
758            ObjectMut::Buffer(val) => val.name.as_runtime_namespace_mut(),
759            ObjectMut::FieldSet(val) => val.name.as_runtime_namespace_mut(),
760            ObjectMut::Enum(val) => val.name.as_runtime_namespace_mut(),
761            ObjectMut::Extern(val) => val.name.as_runtime_namespace_mut(),
762            ObjectMut::Field(val) => val.name.as_runtime_namespace_mut(),
763            ObjectMut::EnumVariant(val) => val.name.as_runtime_namespace_mut(),
764        }
765    }
766
767    /// Return the repeat value if it exists
768    pub fn repeat_mut(&mut self) -> Option<&mut Repeat> {
769        match self {
770            ObjectMut::Device(_) => None,
771            ObjectMut::Block(block) => block.repeat.as_mut(),
772            ObjectMut::Register(register) => register.repeat.as_mut(),
773            ObjectMut::Command(command) => command.repeat.as_mut(),
774            ObjectMut::Buffer(_) => None,
775            ObjectMut::FieldSet(_) => None,
776            ObjectMut::Enum(_) => None,
777            ObjectMut::Extern(_) => None,
778            ObjectMut::Field(field) => field.repeat.as_mut(),
779            ObjectMut::EnumVariant(_) => None,
780        }
781    }
782
783    /// Return the type conversion value if it exists
784    pub fn remove_type_conversion(&mut self) {
785        match self {
786            ObjectMut::Device(_) => {}
787            ObjectMut::Block(_) => {}
788            ObjectMut::Register(_) => {}
789            ObjectMut::Command(_) => {}
790            ObjectMut::Buffer(_) => {}
791            ObjectMut::FieldSet(_) => {}
792            ObjectMut::Enum(_) => {}
793            ObjectMut::Extern(_) => {}
794            ObjectMut::Field(field) => field.field_conversion = None,
795            ObjectMut::EnumVariant(_) => {}
796        }
797    }
798
799    fn remove_child(&mut self, id: ObjectId) {
800        match self {
801            ObjectMut::Device(device) => {
802                if let Some(pos) = device.children.iter().position(|child| *child == id) {
803                    device.children.remove(pos);
804                }
805            }
806            ObjectMut::Block(block) => {
807                if let Some(pos) = block.children.iter().position(|child| *child == id) {
808                    block.children.remove(pos);
809                }
810            }
811            ObjectMut::Register(_) => {}
812            ObjectMut::Command(_) => {}
813            ObjectMut::Buffer(_) => {}
814            ObjectMut::FieldSet(field_set) => {
815                if let Some(pos) = field_set
816                    .fields
817                    .iter()
818                    .position(|child| ObjectId::from(*child) == id)
819                {
820                    field_set.fields.remove(pos);
821                }
822            }
823            ObjectMut::Enum(enum_value) => {
824                if let Some(pos) = enum_value
825                    .variants
826                    .iter()
827                    .position(|child| ObjectId::from(*child) == id)
828                {
829                    enum_value.variants.remove(pos);
830                }
831            }
832            ObjectMut::Extern(_) => {}
833            ObjectMut::Field(_) => {}
834            ObjectMut::EnumVariant(_) => {}
835        }
836    }
837}
838
839impl<'a> Object<'a> {
840    pub fn device_config(&self) -> Option<&'a DeviceConfig> {
841        match self {
842            Object::Device(device) => Some(&device.device_config),
843            _ => None,
844        }
845    }
846
847    pub fn child_objects(&self) -> Option<Box<dyn Iterator<Item = ObjectId> + 'a>> {
848        match self {
849            Object::Device(device) => Some(Box::new(device.children.iter().copied())),
850            Object::Block(block) => Some(Box::new(block.children.iter().copied())),
851            Object::FieldSet(fs) => Some(Box::new(fs.fields.iter().copied().map(ObjectId::from))),
852            Object::Enum(e) => Some(Box::new(e.variants.iter().copied().map(ObjectId::from))),
853            _ => None,
854        }
855    }
856
857    /// Get a reference to the name of the specific object
858    pub fn name(&self) -> &'a Identifier<RuntimeNamespace> {
859        match self {
860            Object::Device(val) => val.name.as_runtime_namespace(),
861            Object::Block(val) => val.name.as_runtime_namespace(),
862            Object::Register(val) => val.name.as_runtime_namespace(),
863            Object::Command(val) => val.name.as_runtime_namespace(),
864            Object::Buffer(val) => val.name.as_runtime_namespace(),
865            Object::FieldSet(val) => val.name.as_runtime_namespace(),
866            Object::Enum(val) => val.name.as_runtime_namespace(),
867            Object::Extern(val) => val.name.as_runtime_namespace(),
868            Object::Field(val) => val.name.as_runtime_namespace(),
869            Object::EnumVariant(val) => val.name.as_runtime_namespace(),
870        }
871    }
872
873    /// Get the (markdown) description of the object
874    pub fn description(&self) -> Istr {
875        match self {
876            Object::Device(val) => val.description,
877            Object::Block(val) => val.description,
878            Object::Register(val) => val.description,
879            Object::Command(val) => val.description,
880            Object::Buffer(val) => val.description,
881            Object::FieldSet(val) => val.description,
882            Object::Enum(val) => val.description,
883            Object::Extern(val) => val.description,
884            Object::Field(val) => val.description,
885            Object::EnumVariant(val) => val.description,
886        }
887    }
888
889    /// Get the span of the name of the object
890    pub fn name_span(&self) -> Span {
891        match self {
892            Object::Device(val) => val.name.span,
893            Object::Block(val) => val.name.span,
894            Object::Register(val) => val.name.span,
895            Object::Command(val) => val.name.span,
896            Object::Buffer(val) => val.name.span,
897            Object::FieldSet(val) => val.name.span,
898            Object::Enum(val) => val.name.span,
899            Object::Extern(val) => val.name.span,
900            Object::Field(val) => val.name.span,
901            Object::EnumVariant(val) => val.name.span,
902        }
903    }
904
905    /// Return the address if it is specified.
906    pub fn address(&self) -> Option<Spanned<i128>> {
907        match self {
908            Object::Device(device) => Some(device.address_offset),
909            Object::Block(block) => Some(block.address_offset),
910            Object::Register(register) => Some(register.address),
911            Object::Command(command) => Some(command.address),
912            Object::Buffer(buffer) => Some(buffer.address),
913            Object::FieldSet(_) => None,
914            Object::Enum(_) => None,
915            Object::Extern(_) => None,
916            Object::Field(_) => None,
917            Object::EnumVariant(_) => None,
918        }
919    }
920
921    /// Return the repeat value if it exists
922    pub fn repeat(&self) -> Option<&'a Repeat> {
923        match self {
924            Object::Device(_) => None,
925            Object::Block(block) => block.repeat.as_ref(),
926            Object::Register(register) => register.repeat.as_ref(),
927            Object::Command(command) => command.repeat.as_ref(),
928            Object::Buffer(_) => None,
929            Object::FieldSet(_) => None,
930            Object::Enum(_) => None,
931            Object::Extern(_) => None,
932            Object::Field(field) => field.repeat.as_ref(),
933            Object::EnumVariant(_) => None,
934        }
935    }
936
937    /// Return the type conversion value if it exists
938    pub fn type_conversion(&self) -> Option<&'a TypeConversion> {
939        match self {
940            Object::Device(_) => None,
941            Object::Block(_) => None,
942            Object::Register(_) => None,
943            Object::Command(_) => None,
944            Object::Buffer(_) => None,
945            Object::FieldSet(_) => None,
946            Object::Enum(_) => None,
947            Object::Extern(_) => None,
948            Object::Field(field) => field.field_conversion.as_ref(),
949            Object::EnumVariant(_) => None,
950        }
951    }
952
953    pub fn as_enum(&self) -> Option<&'a Enum> {
954        if let Self::Enum(v) = self {
955            Some(v)
956        } else {
957            None
958        }
959    }
960
961    pub fn base_type(&self) -> Option<&'a Spanned<BaseType>> {
962        match self {
963            Object::Device(_) => None,
964            Object::Block(_) => None,
965            Object::Register(_) => None,
966            Object::Command(_) => None,
967            Object::Buffer(_) => None,
968            Object::FieldSet(_) => None,
969            Object::Enum(enum_value) => Some(&enum_value.base_type),
970            Object::Extern(extern_value) => Some(&extern_value.base_type),
971            Object::Field(field) => Some(&field.base_type),
972            Object::EnumVariant(_) => None,
973        }
974    }
975
976    pub fn allow_address_overlap(&self) -> bool {
977        match self {
978            Object::Device(_) => false,
979            Object::Block(_) => false,
980            Object::Register(register) => register.allow_address_overlap,
981            Object::Command(command) => command.allow_address_overlap,
982            Object::Buffer(_) => false,
983            Object::FieldSet(_) => false,
984            Object::Enum(_) => false,
985            Object::Extern(_) => false,
986            Object::Field(_) => false,
987            Object::EnumVariant(_) => false,
988        }
989    }
990
991    /// The span of the entire object excluding docs
992    pub fn span(&self) -> Span {
993        match self {
994            Object::Device(val) => val.span,
995            Object::Block(val) => val.span,
996            Object::Register(val) => val.span,
997            Object::Command(val) => val.span,
998            Object::Buffer(val) => val.span,
999            Object::FieldSet(val) => val.span,
1000            Object::Enum(val) => val.span,
1001            Object::Extern(val) => val.span,
1002            Object::Field(val) => val.span,
1003            Object::EnumVariant(val) => val.span,
1004        }
1005    }
1006
1007    pub fn short_properties_span(&self) -> Span {
1008        match self {
1009            Object::Device(device) => device.short_properties_span,
1010            Object::Block(block) => block.short_properties_span,
1011            Object::Register(register) => register.short_properties_span,
1012            Object::Command(command) => command.short_properties_span,
1013            Object::Buffer(buffer) => buffer.short_properties_span,
1014            Object::FieldSet(field_set) => field_set.short_properties_span,
1015            Object::Enum(enum_value) => enum_value.short_properties_span,
1016            Object::Extern(extern_value) => extern_value.short_properties_span,
1017            Object::Field(field) => field.short_properties_span,
1018            Object::EnumVariant(_) => Span::empty(),
1019        }
1020    }
1021
1022    pub fn node_type(&self) -> NodeType {
1023        match self {
1024            Object::Device(_) => NodeType::Device,
1025            Object::Block(_) => NodeType::Block,
1026            Object::Register(_) => NodeType::Register,
1027            Object::Command(_) => NodeType::Command,
1028            Object::Buffer(_) => NodeType::Buffer,
1029            Object::FieldSet(_) => NodeType::FieldSet,
1030            Object::Enum(_) => NodeType::Enum,
1031            Object::Extern(_) => NodeType::Extern,
1032            Object::Field(_) => NodeType::Field,
1033            Object::EnumVariant(_) => panic!("Object has no valid node type"),
1034        }
1035    }
1036
1037    /// Get the fieldset refs of the object. Only returns non-zero for registers and commands
1038    pub fn fieldset_refs(&self) -> Vec<Spanned<FieldsetRef>> {
1039        match self {
1040            Object::Device(_) => Vec::new(),
1041            Object::Block(_) => Vec::new(),
1042            Object::Register(r) => vec![r.field_set_ref.clone()],
1043            Object::Command(c) => [c.field_set_ref_in.clone(), c.field_set_ref_out.clone()]
1044                .into_iter()
1045                .flatten()
1046                .collect(),
1047            Object::Buffer(_) => Vec::new(),
1048            Object::FieldSet(_) => Vec::new(),
1049            Object::Enum(_) => Vec::new(),
1050            Object::Extern(_) => Vec::new(),
1051            Object::Field(_) => Vec::new(),
1052            Object::EnumVariant(_) => Vec::new(),
1053        }
1054    }
1055
1056    pub fn properties_span(&self) -> Option<Span> {
1057        match self {
1058            Object::Device(val) => val.properties_span,
1059            Object::Block(val) => val.properties_span,
1060            Object::Register(val) => val.properties_span,
1061            Object::Command(val) => val.properties_span,
1062            Object::Buffer(val) => val.properties_span,
1063            Object::FieldSet(val) => val.properties_span,
1064            Object::Enum(val) => val.properties_span,
1065            Object::Extern(val) => val.properties_span,
1066            Object::Field(val) => val.properties_span,
1067            Object::EnumVariant(_) => None,
1068        }
1069    }
1070
1071    pub fn body_span(&self) -> Option<Span> {
1072        match self {
1073            Object::Device(val) => val.body_span,
1074            Object::Block(val) => val.body_span,
1075            Object::Register(val) => val.body_span,
1076            Object::Command(val) => val.body_span,
1077            Object::Buffer(val) => val.body_span,
1078            Object::FieldSet(val) => val.body_span,
1079            Object::Enum(val) => val.body_span,
1080            Object::Extern(val) => val.body_span,
1081            Object::Field(val) => val.body_span,
1082            Object::EnumVariant(_) => None,
1083        }
1084    }
1085}
1086
1087#[derive(Debug, Clone, Default, PartialEq)]
1088pub struct Block {
1089    pub description: Istr,
1090    pub name: Spanned<Identifier<Global>>,
1091    pub address_offset: Spanned<i128>,
1092    pub repeat: Option<Repeat>,
1093    pub children: Vec<ObjectId>,
1094    pub default_access: Option<Access>,
1095
1096    pub short_properties_span: Span,
1097    pub properties_span: Option<Span>,
1098    pub body_span: Option<Span>,
1099    /// Span of the whole object excluding docs
1100    pub span: Span,
1101}
1102
1103#[derive(Debug, Clone, Default, PartialEq)]
1104pub struct Register {
1105    pub description: Istr,
1106    pub name: Spanned<Identifier<Operation>>,
1107    pub access: Option<Access>,
1108    pub allow_address_overlap: bool,
1109    pub address: Spanned<i128>,
1110    pub reset_value: Option<Spanned<ResetValue>>,
1111    pub repeat: Option<Repeat>,
1112    pub field_set_ref: Spanned<FieldsetRef>,
1113
1114    pub short_properties_span: Span,
1115    pub properties_span: Option<Span>,
1116    pub body_span: Option<Span>,
1117    /// Span of the whole object excluding docs
1118    pub span: Span,
1119}
1120
1121#[derive(Debug, Clone, PartialEq)]
1122pub enum FieldsetRef {
1123    Identifier(IdentifierRef<Type>),
1124    Id(FieldSetId),
1125}
1126
1127impl Default for FieldsetRef {
1128    fn default() -> Self {
1129        Self::Id(FieldSetId::default())
1130    }
1131}
1132
1133impl Display for FieldsetRef {
1134    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1135        match self {
1136            FieldsetRef::Identifier(identifier_ref) => write!(f, "{}", identifier_ref.original()),
1137            FieldsetRef::Id(field_set_id) => write!(f, "{field_set_id:?}"),
1138        }
1139    }
1140}
1141
1142#[derive(Debug, Clone, Default, PartialEq)]
1143pub struct FieldSet {
1144    pub description: Istr,
1145    pub name: Spanned<Identifier<Type>>,
1146    pub size_bytes: Spanned<u32>,
1147    pub byte_order: Option<ByteOrder>,
1148    pub allow_bit_overlap: bool,
1149    pub default_access: Option<Access>,
1150    pub fields: Vec<FieldId>,
1151
1152    pub short_properties_span: Span,
1153    pub properties_span: Option<Span>,
1154    pub body_span: Option<Span>,
1155    /// Span of the whole object excluding docs
1156    pub span: Span,
1157}
1158
1159impl FieldSet {
1160    pub fn size_bits(&self) -> u32 {
1161        self.size_bytes.value * 8
1162    }
1163}
1164
1165#[derive(Debug, Clone, PartialEq)]
1166pub struct TypeConversion {
1167    /// The name of the type we're converting to
1168    pub type_ref: Spanned<TypeRef>,
1169    /// True when we want to use the fallible interface (like a Result<type, error>)
1170    pub fallible: bool,
1171}
1172
1173#[derive(Debug, Clone, PartialEq)]
1174pub enum TypeRef {
1175    Identifier(IdentifierRef<Type>),
1176    Id(ObjectId),
1177}
1178
1179impl Default for TypeRef {
1180    fn default() -> Self {
1181        Self::Id(ObjectId::default())
1182    }
1183}
1184
1185impl Display for TypeRef {
1186    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1187        match self {
1188            TypeRef::Identifier(identifier_ref) => write!(f, "{}", identifier_ref.original()),
1189            TypeRef::Id(field_set_id) => write!(f, "{field_set_id:?}"),
1190        }
1191    }
1192}
1193
1194#[derive(Debug, Clone, Default, PartialEq)]
1195pub struct Field {
1196    pub description: Istr,
1197    pub name: Spanned<Identifier<Local>>,
1198    pub access: Option<Access>,
1199    pub base_type: Spanned<BaseType>,
1200    pub field_conversion: Option<TypeConversion>,
1201    pub field_address: Spanned<AddressRange>,
1202    pub repeat: Option<Repeat>,
1203
1204    pub short_properties_span: Span,
1205    pub properties_span: Option<Span>,
1206    pub body_span: Option<Span>,
1207    /// Span of the whole object excluding docs
1208    pub span: Span,
1209}
1210
1211impl Field {
1212    #[must_use]
1213    pub fn get_type_specifier_string(&self, manifest: &Manifest) -> String {
1214        match &self.field_conversion {
1215            Some(fc) => {
1216                format!(
1217                    "{}:{}{}",
1218                    self.base_type,
1219                    match &fc.type_ref.value {
1220                        TypeRef::Identifier(identifier_ref) => identifier_ref.original(),
1221                        TypeRef::Id(object_id) =>
1222                            manifest.object(*object_id).unwrap().name().original(),
1223                    },
1224                    if fc.fallible { "?" } else { "" }
1225                )
1226            }
1227            None => self.base_type.to_string(),
1228        }
1229    }
1230}
1231
1232#[derive(Debug, Clone, Default, PartialEq)]
1233pub struct Enum {
1234    pub description: Istr,
1235    pub name: Spanned<Identifier<Type>>,
1236    pub variants: Vec<EnumVariantId>,
1237    pub base_type: Spanned<BaseType>,
1238    pub size_bits: Option<u32>,
1239    pub generation_style: Option<EnumGenerationStyle>,
1240
1241    pub short_properties_span: Span,
1242    pub properties_span: Option<Span>,
1243    pub body_span: Option<Span>,
1244    /// Span of the whole object excluding docs
1245    pub span: Span,
1246}
1247
1248impl Enum {
1249    /// Get an iterator over the variants, but with an extra counter to get the specified discriminant for each.
1250    ///
1251    /// *Note:* The validity of this is checked in the [`passes::enum_values_checked`] pass. If this function is run
1252    /// before that pass, there might be weird results.
1253    pub fn iter_variants_with_discriminant(
1254        &self,
1255        enum_variants: &ObjectArena<EnumVariant, EnumVariantId>,
1256    ) -> impl Iterator<Item = (i128, EnumVariantId)> {
1257        let mut next_discriminant = 0;
1258        self.variants.iter().map(move |variant| {
1259            if let Some(discriminant) = enum_variants[*variant].value.specified_discriminant() {
1260                next_discriminant = discriminant + 1;
1261                (discriminant, *variant)
1262            } else {
1263                let discriminant = next_discriminant;
1264                next_discriminant += 1;
1265                (discriminant, *variant)
1266            }
1267        })
1268    }
1269}
1270
1271#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1272pub enum EnumGenerationStyle {
1273    /// Not all basetype values can be converted to a variant
1274    Fallible,
1275    /// All bitpatterns within bits 0..size-bits are covered.
1276    /// The general interface is fallible, but this special knowledge can be used for safety guarantees
1277    InfallibleWithinRange,
1278    /// There's a fallback, so it's always safe
1279    Fallback,
1280}
1281
1282impl EnumGenerationStyle {
1283    /// Returns `true` if the enum generation style is [`Fallible`].
1284    ///
1285    /// [`Fallible`]: EnumGenerationStyle::Fallible
1286    #[must_use]
1287    pub fn is_fallible(&self) -> bool {
1288        matches!(self, Self::Fallible)
1289    }
1290}
1291
1292#[derive(Debug, Clone, Default, PartialEq)]
1293pub struct EnumVariant {
1294    pub description: Istr,
1295    pub name: Spanned<Identifier<Local>>,
1296    pub value: EnumValue,
1297    /// Span of the whole object excluding docs
1298    pub span: Span,
1299}
1300
1301#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
1302pub enum EnumValue {
1303    #[default]
1304    Unspecified,
1305    Specified(i128),
1306    Default(i128),
1307    UnspecifiedDefault,
1308    CatchAll(i128),
1309    UnspecifiedCatchAll,
1310}
1311
1312impl EnumValue {
1313    #[must_use]
1314    pub fn is_default(&self) -> bool {
1315        matches!(self, Self::Default(_) | Self::UnspecifiedDefault)
1316    }
1317
1318    #[must_use]
1319    pub fn is_catch_all(&self) -> bool {
1320        matches!(self, Self::CatchAll(_) | Self::UnspecifiedCatchAll)
1321    }
1322
1323    pub fn specified_discriminant(&self) -> Option<i128> {
1324        match self {
1325            Self::Unspecified | Self::UnspecifiedDefault | Self::UnspecifiedCatchAll => None,
1326            Self::Specified(val) | EnumValue::Default(val) | EnumValue::CatchAll(val) => Some(*val),
1327        }
1328    }
1329
1330    pub fn specify(&mut self, num: i128) {
1331        *self = match self {
1332            EnumValue::Unspecified | EnumValue::Specified(_) => Self::Specified(num),
1333            EnumValue::Default(_) | EnumValue::UnspecifiedDefault => Self::Default(num),
1334            EnumValue::CatchAll(_) | EnumValue::UnspecifiedCatchAll => Self::CatchAll(num),
1335        };
1336    }
1337}
1338
1339#[derive(Debug, Clone, Default, PartialEq)]
1340pub struct Command {
1341    pub description: Istr,
1342    pub name: Spanned<Identifier<Operation>>,
1343    pub address: Spanned<i128>,
1344    pub allow_address_overlap: bool,
1345    pub repeat: Option<Repeat>,
1346
1347    pub field_set_ref_in: Option<Spanned<FieldsetRef>>,
1348    pub field_set_ref_out: Option<Spanned<FieldsetRef>>,
1349
1350    pub short_properties_span: Span,
1351    pub properties_span: Option<Span>,
1352    pub body_span: Option<Span>,
1353    /// Span of the whole object excluding docs
1354    pub span: Span,
1355}
1356
1357#[derive(Debug, Clone, Default, PartialEq)]
1358pub struct Buffer {
1359    pub description: Istr,
1360    pub name: Spanned<Identifier<Operation>>,
1361    pub access: Option<Access>,
1362    pub address: Spanned<i128>,
1363
1364    pub short_properties_span: Span,
1365    pub properties_span: Option<Span>,
1366    pub body_span: Option<Span>,
1367    /// Span of the whole object excluding docs
1368    pub span: Span,
1369}
1370
1371#[derive(Debug, Clone, Default, PartialEq)]
1372pub struct Extern {
1373    pub description: Istr,
1374    pub name: Spanned<Identifier<Type>>,
1375    /// From/into what base type can this extern be converted?
1376    pub base_type: Spanned<BaseType>,
1377    /// If true, this extern can be converted infallibly too
1378    pub supports_infallible: bool,
1379    /// The user-specified size of the max value of the base type that should be expected
1380    pub size_bits: Option<Spanned<u64>>,
1381
1382    pub short_properties_span: Span,
1383    pub properties_span: Option<Span>,
1384    pub body_span: Option<Span>,
1385    /// Span of the whole object excluding docs
1386    pub span: Span,
1387}