Skip to main content

xsd_schema/
arenas.rs

1//! Arena storage for schema components
2//!
3//! All schema components are stored in arenas to avoid reference cycles.
4//! Each component type has its own SlotMap with typed keys for type safety.
5//!
6//! Uses slotmap for O(1) insertion, lookup, and removal with generation tracking.
7
8use slotmap::SlotMap;
9
10use crate::ids::*;
11#[cfg(feature = "xsd11")]
12use crate::parser::frames::AssertResult;
13use crate::parser::frames::{
14    AlternativeResult, AttributeUseResult, ComplexContentResult, Compositor, DerivationMethod,
15    FieldResult, IdentityKind, OpenContentResult, ParticleResult, QNameRef, SelectorResult,
16    SimpleTypeResult, SimpleTypeVariety, TypeFrameResult, TypeRefResult, WildcardResult,
17};
18use crate::parser::location::SourceRef;
19use crate::schema::annotation::Annotation;
20use crate::schema::model::DerivationSet;
21use crate::types::facets::FacetSet;
22
23// Forward declarations for types that will be defined later
24// These are placeholders until we define the actual types
25
26/// `src-resolve` reference miss deferred from schema compilation to
27/// instance validation. The schema compiles; the error fires only if the
28/// declaration carrying this payload is selected for validating an
29/// instance. Used in XSD 1.0 for explicit element `type` and
30/// `xs:list itemType` references whose target component does not exist.
31#[derive(Debug, Clone)]
32pub struct DeferredSrcResolve {
33    pub message: String,
34    pub source: Option<SourceRef>,
35}
36
37/// Placeholder for SimpleTypeDef (defined in types/simple.rs)
38#[derive(Debug)]
39pub struct SimpleTypeDefData {
40    pub name: Option<NameId>,
41    pub target_namespace: Option<NameId>,
42    pub variety: SimpleTypeVariety,
43    pub base_type: Option<TypeRefResult>,
44    pub item_type: Option<TypeRefResult>,
45    pub member_types: Vec<TypeRefResult>,
46    pub facets: FacetSet,
47    pub final_derivation: DerivationSet,
48    pub id: Option<String>,
49    pub derivation_id: Option<String>,
50    pub annotation: Option<Annotation>,
51    pub source: Option<SourceRef>,
52
53    // Resolved references (populated after reference resolution phase)
54    /// Resolved base type key (for restriction derivation)
55    pub resolved_base_type: Option<TypeKey>,
56    /// Resolved item type key (for list types)
57    pub resolved_item_type: Option<TypeKey>,
58    /// Resolved member type keys (for union types)
59    pub resolved_member_types: Vec<TypeKey>,
60
61    /// Original simple type key before redefine (for base-type resolution)
62    pub redefine_original: Option<SimpleTypeKey>,
63
64    /// Deferred `src-resolve` error for an `xs:list itemType` whose target
65    /// is missing. Reported when this list type is used for validation.
66    pub deferred_item_type_error: Option<DeferredSrcResolve>,
67}
68
69/// Resolved attribute use - stores resolved keys for attribute use references
70#[derive(Debug, Clone)]
71pub struct ResolvedAttributeUse {
72    /// Resolved type key (from type_ref or inline type)
73    pub resolved_type: Option<TypeKey>,
74    /// Resolved attribute reference (for attribute refs)
75    pub resolved_ref: Option<AttributeKey>,
76}
77
78/// Placeholder for ComplexTypeDef (defined in types/complex.rs)
79#[derive(Debug)]
80pub struct ComplexTypeDefData {
81    pub name: Option<NameId>,
82    pub target_namespace: Option<NameId>,
83    pub base_type: Option<TypeRefResult>,
84    pub derivation_method: Option<DerivationMethod>,
85    pub content: ComplexContentResult,
86    pub open_content: Option<OpenContentResult>,
87    pub attributes: Vec<AttributeUseResult>,
88    pub attribute_groups: Vec<QNameRef>,
89    pub attribute_wildcard: Option<WildcardResult>,
90    pub mixed: bool,
91    pub is_abstract: bool,
92    pub final_derivation: DerivationSet,
93    pub block: DerivationSet,
94    pub default_attributes_apply: bool,
95    pub id: Option<String>,
96    #[cfg(feature = "xsd11")]
97    pub assertions: Vec<AssertResult>,
98    #[cfg(feature = "xsd11")]
99    pub xpath_default_namespace: Option<String>,
100    pub annotation: Option<Annotation>,
101    pub source: Option<SourceRef>,
102
103    // Resolved references (populated after reference resolution phase)
104    /// Resolved base type key (for extension/restriction derivation)
105    pub resolved_base_type: Option<TypeKey>,
106    /// Resolved attribute group keys
107    pub resolved_attribute_groups: Vec<AttributeGroupKey>,
108    /// Resolved attribute uses (parallel to attributes vec)
109    pub resolved_attributes: Vec<ResolvedAttributeUse>,
110    /// Resolved inline types for content particle elements (flat depth-first element order)
111    pub resolved_content_particle_types: Vec<Option<TypeKey>>,
112    /// Resolved element keys for local elements in content particles (flat depth-first element order)
113    pub resolved_content_particle_elements: Vec<Option<ElementKey>>,
114    /// Resolved inline simpleType inside simpleContent/restriction
115    /// (§3.4.2.2 clause 1.1 — the B simple type definition).
116    /// Only present when simpleContent has an explicit inline `<xs:simpleType>`.
117    pub resolved_simple_content_type: Option<TypeKey>,
118
119    /// Original complex type key before redefine (for base-type resolution)
120    pub redefine_original: Option<ComplexTypeKey>,
121}
122
123/// Placeholder for ElementDecl (defined in schema/decl.rs)
124#[derive(Debug)]
125pub struct ElementDeclData {
126    pub name: Option<NameId>,
127    pub target_namespace: Option<NameId>,
128    pub ref_name: Option<QNameRef>,
129    pub type_ref: Option<TypeRefResult>,
130    pub inline_type: Option<Box<TypeFrameResult>>,
131    pub substitution_group: Vec<QNameRef>,
132    pub default_value: Option<String>,
133    pub fixed_value: Option<String>,
134    pub nillable: bool,
135    pub is_abstract: bool,
136    pub min_occurs: u32,
137    pub max_occurs: Option<u32>,
138    pub block: DerivationSet,
139    pub final_derivation: DerivationSet,
140    pub form: Option<String>,
141    pub id: Option<String>,
142    pub alternatives: Vec<AlternativeResult>,
143    pub identity_constraints: Vec<IdentityConstraintKey>,
144    /// XSD 1.1: pending identity constraint @ref references (resolved in resolve_all_references)
145    pub pending_ic_refs: Vec<(IdentityKind, QNameRef, Option<SourceRef>)>,
146    pub annotation: Option<Annotation>,
147    pub source: Option<SourceRef>,
148
149    // Resolved references (populated after reference resolution phase)
150    /// Resolved type key (from type_ref or inline_type)
151    pub resolved_type: Option<TypeKey>,
152    /// Resolved element reference (for element refs)
153    pub resolved_ref: Option<ElementKey>,
154    /// Resolved substitution group head elements
155    pub resolved_substitution_groups: Vec<ElementKey>,
156
157    /// Deferred `src-resolve` error for an explicit `type` attribute whose
158    /// target is missing. Reported when this element declaration is
159    /// selected for validation, before any `xs:anyType` fallback.
160    pub deferred_type_error: Option<DeferredSrcResolve>,
161}
162
163/// Placeholder for AttributeDecl (defined in schema/decl.rs)
164#[derive(Debug)]
165pub struct AttributeDeclData {
166    pub name: Option<NameId>,
167    pub target_namespace: Option<NameId>,
168    pub ref_name: Option<QNameRef>,
169    pub type_ref: Option<TypeRefResult>,
170    pub inline_type: Option<Box<SimpleTypeResult>>,
171    pub default_value: Option<String>,
172    pub fixed_value: Option<String>,
173    pub use_kind: Option<String>,
174    pub form: Option<String>,
175    pub inheritable: bool,
176    pub id: Option<String>,
177    pub annotation: Option<Annotation>,
178    pub source: Option<SourceRef>,
179
180    // Resolved references (populated after reference resolution phase)
181    /// Resolved type key (from type_ref or inline_type)
182    pub resolved_type: Option<TypeKey>,
183    /// Resolved attribute reference (for attribute refs)
184    pub resolved_ref: Option<AttributeKey>,
185}
186
187/// Placeholder for AttributeGroup (defined in schema/group.rs)
188#[derive(Debug)]
189pub struct AttributeGroupData {
190    pub name: Option<NameId>,
191    pub target_namespace: Option<NameId>,
192    pub ref_name: Option<QNameRef>,
193    pub attributes: Vec<AttributeUseResult>,
194    pub attribute_groups: Vec<QNameRef>,
195    pub attribute_wildcard: Option<WildcardResult>,
196    pub id: Option<String>,
197    pub annotation: Option<Annotation>,
198    pub source: Option<SourceRef>,
199
200    // Resolved references (populated after reference resolution phase)
201    /// Resolved attribute group reference (for attributeGroup refs)
202    pub resolved_ref: Option<AttributeGroupKey>,
203    /// Resolved nested attribute group keys
204    pub resolved_attribute_groups: Vec<AttributeGroupKey>,
205    /// Resolved attribute uses (parallel to attributes vec)
206    pub resolved_attributes: Vec<ResolvedAttributeUse>,
207
208    /// Original attribute group key before redefine (for self-reference resolution)
209    pub redefine_original: Option<AttributeGroupKey>,
210    /// When this attribute group is a zero-self-reference redefine, the
211    /// deferred §src-redefine 7.2.2 restriction check must verify it is a
212    /// valid restriction of `redefine_original` after reference resolution
213    /// completes. `false` for every non-redefine construction site.
214    pub redefine_requires_restriction_check: bool,
215}
216
217/// Resolved particle term - stores resolved keys for particle references
218#[derive(Debug, Clone)]
219pub enum ResolvedParticleTerm {
220    /// Element with resolved type and ref
221    Element {
222        resolved_type: Option<TypeKey>,
223        resolved_ref: Option<ElementKey>,
224    },
225    /// Group with resolved ref
226    Group { resolved_ref: Option<ModelGroupKey> },
227    /// Wildcard (no resolution needed)
228    Any,
229}
230
231/// Placeholder for ModelGroup (defined in schema/group.rs)
232#[derive(Debug)]
233pub struct ModelGroupData {
234    pub name: Option<NameId>,
235    pub target_namespace: Option<NameId>,
236    pub ref_name: Option<QNameRef>,
237    pub compositor: Option<Compositor>,
238    pub particles: Vec<ParticleResult>,
239    pub min_occurs: u32,
240    pub max_occurs: Option<u32>,
241    pub id: Option<String>,
242    pub annotation: Option<Annotation>,
243    pub source: Option<SourceRef>,
244
245    // Resolved references (populated after reference resolution phase)
246    /// Resolved model group reference (for group refs)
247    pub resolved_ref: Option<ModelGroupKey>,
248    /// Resolved particle terms (parallel to particles vec)
249    pub resolved_particles: Vec<ResolvedParticleTerm>,
250    /// Flat depth-first indexed resolved types for all particles (including nested inline groups)
251    pub resolved_particle_types: Vec<Option<TypeKey>>,
252    /// Flat depth-first indexed resolved element keys for all particles (including nested inline groups)
253    pub resolved_particle_elements: Vec<Option<ElementKey>>,
254
255    /// Original model group key before redefine (for self-reference resolution)
256    pub redefine_original: Option<ModelGroupKey>,
257    /// When this model group is a zero-self-reference redefine, the deferred
258    /// §src-redefine 6.2.2 restriction check must verify it is a valid
259    /// restriction of `redefine_original` after reference resolution
260    /// completes. `false` for every non-redefine construction site.
261    pub redefine_requires_restriction_check: bool,
262}
263
264/// Placeholder for Notation (defined in schema/decl.rs)
265#[derive(Debug)]
266pub struct NotationData {
267    pub name: NameId,
268    pub target_namespace: Option<NameId>,
269    pub public: Option<String>,
270    pub system: Option<String>,
271    pub id: Option<String>,
272    pub annotation: Option<Annotation>,
273    pub source: Option<SourceRef>,
274}
275
276/// Identity constraint (key, unique, keyref) stored in the arena
277#[derive(Debug)]
278pub struct IdentityConstraintData {
279    pub kind: IdentityKind,
280    pub name: NameId,
281    pub ref_name: Option<QNameRef>,
282    pub refer: Option<QNameRef>,
283    pub selector: SelectorResult,
284    pub fields: Vec<FieldResult>,
285    pub id: Option<String>,
286    pub annotation: Option<Annotation>,
287    pub source: Option<SourceRef>,
288}
289
290/// Arena storage for all schema component types
291///
292/// Components are stored in type-specific SlotMaps and accessed via typed keys.
293/// This approach avoids reference cycles and provides O(1) access with generation tracking.
294#[derive(Debug, Default)]
295pub struct SchemaArenas {
296    /// Simple type definitions
297    pub simple_types: SlotMap<SimpleTypeKey, SimpleTypeDefData>,
298    /// Complex type definitions
299    pub complex_types: SlotMap<ComplexTypeKey, ComplexTypeDefData>,
300    /// Element declarations
301    pub elements: SlotMap<ElementKey, ElementDeclData>,
302    /// Attribute declarations
303    pub attributes: SlotMap<AttributeKey, AttributeDeclData>,
304    /// Attribute groups
305    pub attribute_groups: SlotMap<AttributeGroupKey, AttributeGroupData>,
306    /// Named model groups
307    pub model_groups: SlotMap<ModelGroupKey, ModelGroupData>,
308    /// Notations
309    pub notations: SlotMap<NotationKey, NotationData>,
310    /// Identity constraints
311    pub identity_constraints: SlotMap<IdentityConstraintKey, IdentityConstraintData>,
312}
313
314impl SchemaArenas {
315    /// Create new empty arenas
316    pub fn new() -> Self {
317        Self::default()
318    }
319
320    // Simple types
321    pub fn alloc_simple_type(&mut self, data: SimpleTypeDefData) -> SimpleTypeKey {
322        self.simple_types.insert(data)
323    }
324
325    pub fn get_simple_type(&self, key: SimpleTypeKey) -> Option<&SimpleTypeDefData> {
326        self.simple_types.get(key)
327    }
328
329    pub fn get_simple_type_mut(&mut self, key: SimpleTypeKey) -> Option<&mut SimpleTypeDefData> {
330        self.simple_types.get_mut(key)
331    }
332
333    // Complex types
334    pub fn alloc_complex_type(&mut self, data: ComplexTypeDefData) -> ComplexTypeKey {
335        self.complex_types.insert(data)
336    }
337
338    pub fn get_complex_type(&self, key: ComplexTypeKey) -> Option<&ComplexTypeDefData> {
339        self.complex_types.get(key)
340    }
341
342    pub fn get_complex_type_mut(&mut self, key: ComplexTypeKey) -> Option<&mut ComplexTypeDefData> {
343        self.complex_types.get_mut(key)
344    }
345
346    // Elements
347    pub fn alloc_element(&mut self, data: ElementDeclData) -> ElementKey {
348        self.elements.insert(data)
349    }
350
351    pub fn get_element(&self, key: ElementKey) -> Option<&ElementDeclData> {
352        self.elements.get(key)
353    }
354
355    pub fn get_element_mut(&mut self, key: ElementKey) -> Option<&mut ElementDeclData> {
356        self.elements.get_mut(key)
357    }
358
359    // Attributes
360    pub fn alloc_attribute(&mut self, data: AttributeDeclData) -> AttributeKey {
361        self.attributes.insert(data)
362    }
363
364    pub fn get_attribute(&self, key: AttributeKey) -> Option<&AttributeDeclData> {
365        self.attributes.get(key)
366    }
367
368    pub fn get_attribute_mut(&mut self, key: AttributeKey) -> Option<&mut AttributeDeclData> {
369        self.attributes.get_mut(key)
370    }
371
372    // Attribute groups
373    pub fn alloc_attribute_group(&mut self, data: AttributeGroupData) -> AttributeGroupKey {
374        self.attribute_groups.insert(data)
375    }
376
377    pub fn get_attribute_group(&self, key: AttributeGroupKey) -> Option<&AttributeGroupData> {
378        self.attribute_groups.get(key)
379    }
380
381    pub fn get_attribute_group_mut(
382        &mut self,
383        key: AttributeGroupKey,
384    ) -> Option<&mut AttributeGroupData> {
385        self.attribute_groups.get_mut(key)
386    }
387
388    // Model groups
389    pub fn alloc_model_group(&mut self, data: ModelGroupData) -> ModelGroupKey {
390        self.model_groups.insert(data)
391    }
392
393    pub fn get_model_group(&self, key: ModelGroupKey) -> Option<&ModelGroupData> {
394        self.model_groups.get(key)
395    }
396
397    pub fn get_model_group_mut(&mut self, key: ModelGroupKey) -> Option<&mut ModelGroupData> {
398        self.model_groups.get_mut(key)
399    }
400
401    // Notations
402    pub fn alloc_notation(&mut self, data: NotationData) -> NotationKey {
403        self.notations.insert(data)
404    }
405
406    pub fn get_notation(&self, key: NotationKey) -> Option<&NotationData> {
407        self.notations.get(key)
408    }
409
410    pub fn get_notation_mut(&mut self, key: NotationKey) -> Option<&mut NotationData> {
411        self.notations.get_mut(key)
412    }
413
414    // Identity constraints
415    pub fn alloc_identity_constraint(
416        &mut self,
417        data: IdentityConstraintData,
418    ) -> IdentityConstraintKey {
419        self.identity_constraints.insert(data)
420    }
421
422    pub fn get_identity_constraint(
423        &self,
424        key: IdentityConstraintKey,
425    ) -> Option<&IdentityConstraintData> {
426        self.identity_constraints.get(key)
427    }
428
429    pub fn get_identity_constraint_mut(
430        &mut self,
431        key: IdentityConstraintKey,
432    ) -> Option<&mut IdentityConstraintData> {
433        self.identity_constraints.get_mut(key)
434    }
435}
436
437#[cfg(test)]
438mod tests {
439    use super::*;
440
441    fn simple_type_data(name: NameId) -> SimpleTypeDefData {
442        SimpleTypeDefData {
443            name: Some(name),
444            target_namespace: None,
445            variety: SimpleTypeVariety::Atomic,
446            base_type: None,
447            item_type: None,
448            member_types: Vec::new(),
449            facets: FacetSet::new(),
450            final_derivation: DerivationSet::empty(),
451            id: None,
452            derivation_id: None,
453            annotation: None,
454            source: None,
455            // Resolved references
456            resolved_base_type: None,
457            resolved_item_type: None,
458            resolved_member_types: Vec::new(),
459            redefine_original: None,
460            deferred_item_type_error: None,
461        }
462    }
463
464    fn element_data(name: NameId, target_namespace: Option<NameId>) -> ElementDeclData {
465        ElementDeclData {
466            name: Some(name),
467            target_namespace,
468            ref_name: None,
469            type_ref: None,
470            inline_type: None,
471            substitution_group: Vec::new(),
472            default_value: None,
473            fixed_value: None,
474            nillable: false,
475            is_abstract: false,
476            min_occurs: 1,
477            max_occurs: Some(1),
478            block: DerivationSet::empty(),
479            final_derivation: DerivationSet::empty(),
480            form: None,
481            id: None,
482            alternatives: Vec::new(),
483            identity_constraints: Vec::new(),
484            pending_ic_refs: vec![],
485            annotation: None,
486            source: None,
487            // Resolved references
488            resolved_type: None,
489            resolved_ref: None,
490            resolved_substitution_groups: Vec::new(),
491            deferred_type_error: None,
492        }
493    }
494
495    #[test]
496    fn test_alloc_and_get_simple_type() {
497        let mut arenas = SchemaArenas::new();
498        let data = simple_type_data(NameId(1));
499        let key = arenas.alloc_simple_type(data);
500        let retrieved = arenas.get_simple_type(key).unwrap();
501        assert_eq!(retrieved.name, Some(NameId(1)));
502    }
503
504    #[test]
505    fn test_alloc_and_get_element() {
506        let mut arenas = SchemaArenas::new();
507        let data = element_data(NameId(2), Some(NameId(3)));
508        let key = arenas.alloc_element(data);
509        let retrieved = arenas.get_element(key).unwrap();
510        assert_eq!(retrieved.name, Some(NameId(2)));
511        assert_eq!(retrieved.target_namespace, Some(NameId(3)));
512    }
513
514    #[test]
515    fn test_multiple_allocations() {
516        let mut arenas = SchemaArenas::new();
517
518        let key1 = arenas.alloc_simple_type(simple_type_data(NameId(1)));
519        let key2 = arenas.alloc_simple_type(simple_type_data(NameId(2)));
520
521        assert_ne!(key1, key2);
522        assert_eq!(arenas.get_simple_type(key1).unwrap().name, Some(NameId(1)));
523        assert_eq!(arenas.get_simple_type(key2).unwrap().name, Some(NameId(2)));
524    }
525
526    #[test]
527    fn test_mutable_access() {
528        let mut arenas = SchemaArenas::new();
529        let key = arenas.alloc_simple_type(simple_type_data(NameId(1)));
530
531        // Modify through mutable reference
532        if let Some(data) = arenas.get_simple_type_mut(key) {
533            data.name = Some(NameId(99));
534        }
535
536        assert_eq!(arenas.get_simple_type(key).unwrap().name, Some(NameId(99)));
537    }
538
539    #[test]
540    fn test_slotmap_iteration() {
541        let mut arenas = SchemaArenas::new();
542        arenas.alloc_simple_type(simple_type_data(NameId(10)));
543        arenas.alloc_simple_type(simple_type_data(NameId(20)));
544        arenas.alloc_simple_type(simple_type_data(NameId(30)));
545
546        let names: Vec<_> = arenas
547            .simple_types
548            .values()
549            .filter_map(|d| d.name)
550            .map(|n| n.0)
551            .collect();
552        assert_eq!(names.len(), 3);
553        assert!(names.contains(&10));
554        assert!(names.contains(&20));
555        assert!(names.contains(&30));
556    }
557
558    #[test]
559    fn test_key_with_values() {
560        let mut arenas = SchemaArenas::new();
561        let key1 = arenas.alloc_element(element_data(NameId(1), None));
562        let key2 = arenas.alloc_element(element_data(NameId(2), None));
563
564        // Iterate with keys
565        let pairs: Vec<_> = arenas
566            .elements
567            .iter()
568            .map(|(k, v)| (k, v.name.unwrap().0))
569            .collect();
570
571        assert_eq!(pairs.len(), 2);
572        assert!(pairs.iter().any(|(k, _)| *k == key1));
573        assert!(pairs.iter().any(|(k, _)| *k == key2));
574    }
575}