1use crate::error::{SchemaError, SchemaResult};
23use crate::ids::*;
24use crate::parser::frames::SimpleTypeVariety;
25use crate::parser::frames::{QNameRef, TypeRefResult};
26use crate::parser::location::SourceRef;
27use crate::schema::composition::ComponentKind;
28use crate::schema::SchemaSet;
29
30pub(crate) fn check_namespace_visible_ns(
37 schema_set: &SchemaSet,
38 namespace: Option<NameId>,
39 local_name: NameId,
40 source: Option<&SourceRef>,
41 kind_label: &str,
42) -> SchemaResult<()> {
43 let Some(source) = source else { return Ok(()) };
44 let Some(doc) = schema_set.documents.get(source.doc_id as usize) else {
45 return Ok(());
46 };
47 if doc.can_see_namespace(namespace, &schema_set.name_table) {
48 return Ok(());
49 }
50 let location = schema_set.source_maps.locate(source);
51 let qname_str = format_resolved_qname(&schema_set.name_table, namespace, local_name);
52 let ns_label = match namespace {
53 Some(ns) => format!("'{}'", schema_set.name_table.resolve_ref(ns)),
54 None => "the absent namespace".to_string(),
55 };
56 Err(SchemaError::structural(
57 "src-resolve",
58 format!(
59 "{} reference '{}' to namespace {} is not <xs:import>-ed by schema document '{}'",
60 kind_label, qname_str, ns_label, doc.base_uri,
61 ),
62 location,
63 ))
64}
65
66pub(crate) fn check_namespace_visible(
69 schema_set: &SchemaSet,
70 qname: &QNameRef,
71 source: Option<&SourceRef>,
72 kind_label: &str,
73) -> SchemaResult<()> {
74 check_namespace_visible_ns(schema_set, qname.namespace, qname.local_name, source, kind_label)
75}
76
77pub struct ReferenceResolver<'a> {
82 schema_set: &'a SchemaSet,
83}
84
85impl<'a> ReferenceResolver<'a> {
86 pub fn new(schema_set: &'a SchemaSet) -> Self {
88 Self { schema_set }
89 }
90
91 pub fn resolve_type_ref(
96 &self,
97 qname: &QNameRef,
98 source: Option<&SourceRef>,
99 ) -> SchemaResult<TypeKey> {
100 let namespace = qname.namespace;
102
103 if let Some(type_key) = self
105 .schema_set
106 .get_built_in_type_by_qname(namespace, qname.local_name)
107 {
108 return Ok(type_key);
109 }
110
111 check_namespace_visible(self.schema_set, qname, source, "Type")?;
113
114 if let Some(type_key) = self.schema_set.lookup_type(namespace, qname.local_name) {
116 return Ok(type_key);
117 }
118
119 let location = source.and_then(|s| self.schema_set.source_maps.locate(s));
121 Err(SchemaError::structural(
122 "src-resolve",
123 format_type_not_found_message(self.schema_set, qname, "Type"),
124 location,
125 ))
126 }
127
128 pub fn try_resolve_type_ref(
133 &self,
134 qname: &QNameRef,
135 source: Option<&SourceRef>,
136 ) -> SchemaResult<Option<TypeKey>> {
137 if let Some(type_key) = self
138 .schema_set
139 .get_built_in_type_by_qname(qname.namespace, qname.local_name)
140 {
141 return Ok(Some(type_key));
142 }
143 check_namespace_visible(self.schema_set, qname, source, "Type")?;
144 Ok(self.schema_set.lookup_type(qname.namespace, qname.local_name))
145 }
146
147 pub fn try_resolve_element_ref(
150 &self,
151 qname: &QNameRef,
152 source: Option<&SourceRef>,
153 ) -> SchemaResult<Option<ElementKey>> {
154 check_namespace_visible(self.schema_set, qname, source, "Element")?;
155 Ok(self
156 .schema_set
157 .lookup_element(qname.namespace, qname.local_name))
158 }
159
160 pub fn resolve_type_ref_result(
165 &self,
166 type_ref: &TypeRefResult,
167 source: Option<&SourceRef>,
168 ) -> SchemaResult<Option<TypeKey>> {
169 match type_ref {
170 TypeRefResult::QName(qname) => Ok(Some(self.resolve_type_ref(qname, source)?)),
171 TypeRefResult::Inline(_) => {
172 Ok(None)
176 }
177 }
178 }
179
180 fn resolve_ref<K: Copy>(
187 &self,
188 qname: &QNameRef,
189 source: Option<&SourceRef>,
190 kind_label: &str,
191 component_kind: ComponentKind,
192 lookup: impl FnOnce(&SchemaSet, Option<NameId>, NameId) -> Option<K>,
193 ) -> SchemaResult<K> {
194 check_namespace_visible(self.schema_set, qname, source, kind_label)?;
196 if let Some(key) = lookup(self.schema_set, qname.namespace, qname.local_name) {
197 return Ok(key);
198 }
199 let location = source.and_then(|s| self.schema_set.source_maps.locate(s));
200 let name_str = self.format_qname(qname);
201 let note = self.schema_set.format_provenance_note(
202 component_kind,
203 qname.namespace,
204 qname.local_name,
205 );
206 Err(SchemaError::structural(
207 "src-resolve",
208 format!("{} '{}' not found{}", kind_label, name_str, note),
209 location,
210 ))
211 }
212
213 pub fn resolve_element_ref(
215 &self,
216 qname: &QNameRef,
217 source: Option<&SourceRef>,
218 ) -> SchemaResult<ElementKey> {
219 self.resolve_ref(
220 qname,
221 source,
222 "Element",
223 ComponentKind::Element,
224 SchemaSet::lookup_element,
225 )
226 }
227
228 pub fn resolve_attribute_ref(
230 &self,
231 qname: &QNameRef,
232 source: Option<&SourceRef>,
233 ) -> SchemaResult<AttributeKey> {
234 self.resolve_ref(
235 qname,
236 source,
237 "Attribute",
238 ComponentKind::Attribute,
239 SchemaSet::lookup_attribute,
240 )
241 }
242
243 pub fn resolve_group_ref(
245 &self,
246 qname: &QNameRef,
247 source: Option<&SourceRef>,
248 ) -> SchemaResult<ModelGroupKey> {
249 self.resolve_ref(
250 qname,
251 source,
252 "Group",
253 ComponentKind::ModelGroup,
254 SchemaSet::lookup_model_group,
255 )
256 }
257
258 pub fn resolve_attribute_group_ref(
260 &self,
261 qname: &QNameRef,
262 source: Option<&SourceRef>,
263 ) -> SchemaResult<AttributeGroupKey> {
264 self.resolve_ref(
265 qname,
266 source,
267 "Attribute group",
268 ComponentKind::AttributeGroup,
269 SchemaSet::lookup_attribute_group,
270 )
271 }
272
273 pub fn resolve_notation_ref(
275 &self,
276 qname: &QNameRef,
277 source: Option<&SourceRef>,
278 ) -> SchemaResult<NotationKey> {
279 self.resolve_ref(
280 qname,
281 source,
282 "Notation",
283 ComponentKind::Notation,
284 SchemaSet::lookup_notation,
285 )
286 }
287
288 fn format_qname(&self, qname: &QNameRef) -> String {
290 format_resolved_qname(
291 &self.schema_set.name_table,
292 qname.namespace,
293 qname.local_name,
294 )
295 }
296}
297
298pub(crate) fn format_resolved_qname(
300 name_table: &crate::namespace::NameTable,
301 namespace: Option<crate::ids::NameId>,
302 local_name: crate::ids::NameId,
303) -> String {
304 let local = name_table.resolve(local_name);
305 if let Some(ns_id) = namespace {
306 let ns = name_table.resolve(ns_id);
307 if ns.is_empty() {
308 local
309 } else {
310 format!("{{{}}}{}", ns, local)
311 }
312 } else {
313 local
314 }
315}
316
317#[derive(Debug, Default)]
319pub struct ResolvedReferences {
320 pub resolved_type: Option<TypeKey>,
322 pub resolved_ref: Option<ElementKey>,
324 pub resolved_substitution_groups: Vec<ElementKey>,
326 pub resolved_attr_ref: Option<AttributeKey>,
328 pub resolved_base_type: Option<TypeKey>,
330 pub resolved_item_type: Option<TypeKey>,
332 pub resolved_member_types: Vec<TypeKey>,
334 pub resolved_attribute_groups: Vec<AttributeGroupKey>,
336 pub resolved_group_ref: Option<ModelGroupKey>,
338}
339
340#[derive(Debug, Default)]
342pub struct ResolutionStats {
343 pub types_resolved: usize,
345 pub elements_resolved: usize,
347 pub attributes_resolved: usize,
349 pub groups_resolved: usize,
351 pub attribute_groups_resolved: usize,
353 pub notations_resolved: usize,
355 pub errors: usize,
357}
358
359fn drain_pending_ic_refs_for(
365 schema_set: &mut SchemaSet,
366 key: ElementKey,
367 defer_failures: bool,
368 errors: &mut Vec<SchemaError>,
369) {
370 let pending = std::mem::take(&mut schema_set.arenas.elements[key].pending_ic_refs);
371 if pending.is_empty() {
372 return;
373 }
374 let target_ns = schema_set.arenas.elements[key].target_namespace;
375 let mut still_pending = Vec::new();
376 for (kind, ref_name, source) in pending {
377 match crate::schema::inline::resolve_ic_ref(
378 kind,
379 &ref_name,
380 source.as_ref(),
381 target_ns,
382 schema_set,
383 ) {
384 Ok(target_key) => {
385 schema_set.arenas.elements[key]
386 .identity_constraints
387 .push(target_key);
388 }
389 Err(e) => {
390 if defer_failures {
391 still_pending.push((kind, ref_name, source));
392 } else {
393 errors.push(e);
394 }
395 }
396 }
397 }
398 if !still_pending.is_empty() {
399 schema_set.arenas.elements[key].pending_ic_refs = still_pending;
400 }
401}
402
403pub fn finalize_pending_ic_refs(schema_set: &mut SchemaSet) -> SchemaResult<()> {
411 let element_keys: Vec<ElementKey> = schema_set.arenas.elements.keys().collect();
412 let mut errors: Vec<SchemaError> = Vec::new();
413 for key in element_keys {
414 drain_pending_ic_refs_for(schema_set, key, false, &mut errors);
415 }
416 if let Some(first) = errors.into_iter().next() {
417 return Err(first);
418 }
419 Ok(())
420}
421
422pub fn resolve_all_references(schema_set: &mut SchemaSet) -> SchemaResult<ResolutionStats> {
433 let mut stats = ResolutionStats::default();
434 let mut errors: Vec<SchemaError> = Vec::new();
435
436 let element_keys: Vec<ElementKey> = schema_set.arenas.elements.keys().collect();
441 let attribute_keys: Vec<AttributeKey> = schema_set.arenas.attributes.keys().collect();
442 let simple_type_keys: Vec<SimpleTypeKey> = schema_set.arenas.simple_types.keys().collect();
443 let complex_type_keys: Vec<ComplexTypeKey> = schema_set.arenas.complex_types.keys().collect();
444 let model_group_keys: Vec<ModelGroupKey> = schema_set.arenas.model_groups.keys().collect();
445 let attribute_group_keys: Vec<AttributeGroupKey> =
446 schema_set.arenas.attribute_groups.keys().collect();
447
448 for key in &element_keys {
450 if let Err(e) = resolve_element_references(schema_set, *key, &mut stats) {
451 errors.push(e);
452 stats.errors += 1;
453 }
454 }
455
456 if errors.is_empty() {
461 loop {
462 let mut changed = false;
463 for &key in &element_keys {
464 let (needs_type, subst_groups) = {
465 let elem = schema_set.arenas.elements.get(key).unwrap();
466 (
467 elem.resolved_type.is_none()
468 && elem.resolved_ref.is_none()
469 && elem.deferred_type_error.is_none()
470 && !elem.resolved_substitution_groups.is_empty(),
471 elem.resolved_substitution_groups.clone(),
472 )
473 };
474 if needs_type {
475 for &head_key in &subst_groups {
476 if let Some(head_type) = schema_set
477 .arenas
478 .elements
479 .get(head_key)
480 .and_then(|h| h.resolved_type)
481 {
482 let elem = schema_set.arenas.elements.get_mut(key).unwrap();
483 assign_element_type(elem, head_type);
484 changed = true;
485 break;
486 }
487 }
488 }
489 }
490 if !changed {
491 break;
492 }
493 }
494 for &key in &element_keys {
501 let needs_deferred = {
502 let elem = schema_set.arenas.elements.get(key).unwrap();
503 elem.resolved_type.is_none()
504 && elem.resolved_ref.is_none()
505 && elem.deferred_type_error.is_none()
506 && !elem.resolved_substitution_groups.is_empty()
507 };
508 if !needs_deferred {
509 continue;
510 }
511 let inherited = {
512 let elem = schema_set.arenas.elements.get(key).unwrap();
513 elem.resolved_substitution_groups
514 .iter()
515 .find_map(|&head_key| {
516 schema_set
517 .arenas
518 .elements
519 .get(head_key)
520 .and_then(|h| h.deferred_type_error.clone())
521 })
522 };
523 if let Some(deferred) = inherited {
524 if let Some(elem) = schema_set.arenas.elements.get_mut(key) {
525 elem.deferred_type_error = Some(deferred);
526 }
527 }
528 }
529 let any_type = TypeKey::Complex(schema_set.any_type_key());
535 for &key in &element_keys {
536 if let Some(elem) = schema_set.arenas.elements.get_mut(key) {
537 if elem.resolved_type.is_none()
538 && elem.resolved_ref.is_none()
539 && elem.deferred_type_error.is_none()
540 {
541 assign_element_type(elem, any_type);
542 }
543 }
544 }
545 }
546
547 for &key in &element_keys {
553 drain_pending_ic_refs_for(schema_set, key, true, &mut errors);
554 }
555
556 for key in attribute_keys {
558 if let Err(e) = resolve_attribute_references(schema_set, key, &mut stats) {
559 errors.push(e);
560 stats.errors += 1;
561 }
562 }
563
564 for key in simple_type_keys.clone() {
571 if let Err(e) = resolve_simple_type_references(schema_set, key, &mut stats) {
572 errors.push(e);
573 stats.errors += 1;
574 }
575 }
576 for key in simple_type_keys {
577 if let Err(e) = resolve_simple_type_references(schema_set, key, &mut stats) {
578 errors.push(e);
579 stats.errors += 1;
580 }
581 }
582
583 for &key in &complex_type_keys {
585 if let Err(e) = resolve_complex_type_references(schema_set, key, &mut stats) {
586 errors.push(e);
587 stats.errors += 1;
588 }
589 }
590
591 for key in model_group_keys {
593 if let Err(e) = resolve_model_group_references(schema_set, key, &mut stats) {
594 errors.push(e);
595 stats.errors += 1;
596 }
597 }
598
599 for key in attribute_group_keys {
601 if let Err(e) = resolve_attribute_group_references(schema_set, key, &mut stats) {
602 errors.push(e);
603 stats.errors += 1;
604 }
605 }
606
607 let notation_keys: Vec<NotationKey> = schema_set.arenas.notations.keys().collect();
614 for key in notation_keys {
615 if let Err(e) = resolve_notation_references(schema_set, key, &mut stats) {
616 errors.push(e);
617 stats.errors += 1;
618 }
619 }
620
621 let mut doc_default_attr_groups: Vec<Option<AttributeGroupKey>> =
624 Vec::with_capacity(schema_set.documents.len());
625 for doc in &schema_set.documents {
626 if let Some(ref qname) = doc.default_attributes {
627 if let Err(e) = check_namespace_visible_ns(
628 schema_set,
629 qname.namespace_uri,
630 qname.local_name,
631 doc.source.as_ref(),
632 "Attribute group",
633 ) {
634 errors.push(e);
635 stats.errors += 1;
636 doc_default_attr_groups.push(None);
637 continue;
638 }
639 if let Some(key) =
640 schema_set.lookup_attribute_group(qname.namespace_uri, qname.local_name)
641 {
642 doc_default_attr_groups.push(Some(key));
643 stats.attribute_groups_resolved += 1;
644 } else {
645 let location = schema_set.locate(doc.source.as_ref());
647 let name_str = format_resolved_qname(
648 &schema_set.name_table,
649 qname.namespace_uri,
650 qname.local_name,
651 );
652 errors.push(SchemaError::structural(
653 "src-resolve",
654 format!("Attribute group '{}' not found", name_str),
655 location,
656 ));
657 stats.errors += 1;
658 doc_default_attr_groups.push(None);
659 }
660 } else {
661 doc_default_attr_groups.push(None);
662 }
663 }
664
665 for &key in &complex_type_keys {
667 let doc_id = {
668 let type_def = match schema_set.arenas.complex_types.get(key) {
669 Some(td) => td,
670 None => continue,
671 };
672 if !type_def.default_attributes_apply {
673 continue;
674 }
675 match type_def.source.as_ref() {
676 Some(src) => src.defaults_doc(),
679 None => continue, }
681 };
682 if let Some(Some(group_key)) = doc_default_attr_groups.get(doc_id as usize) {
683 let group_key = *group_key;
684 let type_def = schema_set.arenas.complex_types.get_mut(key).unwrap();
685 if !type_def.resolved_attribute_groups.contains(&group_key) {
686 type_def.resolved_attribute_groups.push(group_key);
687 }
688 }
689 }
690
691 if let Err(e) = validate_particle_qname_visibility(schema_set) {
697 errors.push(e);
698 stats.errors += 1;
699 }
700
701 if let Some(first_error) = errors.into_iter().next() {
703 return Err(first_error);
704 }
705
706 Ok(stats)
707}
708
709fn validate_particle_qname_visibility(schema_set: &SchemaSet) -> SchemaResult<()> {
717 use crate::parser::frames::{ParticleResult, ParticleTerm};
718
719 fn visit(
720 schema_set: &SchemaSet,
721 particles: &[ParticleResult],
722 depth: usize,
723 ) -> SchemaResult<()> {
724 if depth > 64 {
725 return Ok(());
726 }
727 for particle in particles {
728 match &particle.term {
729 ParticleTerm::Element(elem) => {
730 let src = elem.source.as_ref().or(particle.source.as_ref());
731 if let Some(ref_qn) = &elem.ref_name {
732 check_namespace_visible(schema_set, ref_qn, src, "Element")?;
733 }
734 if let Some(TypeRefResult::QName(qname)) = &elem.type_ref {
735 check_namespace_visible(schema_set, qname, src, "Type")?;
736 }
737 }
738 ParticleTerm::Group(group_def) => {
739 if let Some(ref_qn) = &group_def.ref_name {
740 check_namespace_visible(
741 schema_set,
742 ref_qn,
743 particle.source.as_ref(),
744 "Group",
745 )?;
746 }
747 visit(schema_set, &group_def.particles, depth + 1)?;
748 }
749 ParticleTerm::Any(_) => {}
750 }
751 }
752 Ok(())
753 }
754
755 for (_, ct) in schema_set.arenas.complex_types.iter() {
756 if let crate::parser::frames::ComplexContentResult::Complex(content) = &ct.content {
757 if let Some(particle) = &content.particle {
758 visit(schema_set, std::slice::from_ref(particle), 0)?;
759 }
760 }
761 }
762 Ok(())
763}
764
765fn assign_element_type(elem: &mut crate::arenas::ElementDeclData, type_key: TypeKey) {
768 elem.resolved_type = Some(type_key);
769 #[cfg(feature = "xsd11")]
770 for alt in &mut elem.alternatives {
771 if alt.resolved_type.is_none() && alt.type_ref.is_none() {
772 alt.resolved_type = Some(type_key);
773 }
774 }
775}
776
777fn resolve_element_references(
779 schema_set: &mut SchemaSet,
780 key: ElementKey,
781 stats: &mut ResolutionStats,
782) -> SchemaResult<()> {
783 let (type_qname, ref_name, substitution_groups, source, already_resolved_type) = {
786 let elem = schema_set
787 .arenas
788 .elements
789 .get(key)
790 .ok_or_else(|| SchemaError::internal("Element not found in arena"))?;
791
792 let type_qname = match &elem.type_ref {
794 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
795 _ => None,
796 };
797
798 (
799 type_qname,
800 elem.ref_name.clone(),
801 elem.substitution_group.clone(),
802 elem.source.clone(),
803 elem.resolved_type, )
805 };
806
807 let resolver = ReferenceResolver::new(schema_set);
809
810 let lazy_src_resolve = schema_set.is_xsd10();
813
814 let mut deferred_type_error: Option<crate::arenas::DeferredSrcResolve> = None;
818 let mut resolved_type = if already_resolved_type.is_some() {
819 already_resolved_type
821 } else if let Some(ref qname) = type_qname {
822 if lazy_src_resolve {
823 match resolver.try_resolve_type_ref(qname, source.as_ref())? {
824 Some(type_key) => {
825 stats.types_resolved += 1;
826 Some(type_key)
827 }
828 None => {
829 deferred_type_error = Some(build_deferred_type_resolve(
830 schema_set,
831 qname,
832 source.as_ref(),
833 "Type",
834 ));
835 None
836 }
837 }
838 } else {
839 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
840 stats.types_resolved += 1;
841 Some(type_key)
842 }
843 } else {
844 None
845 };
846 if resolved_type.is_none()
853 && deferred_type_error.is_none()
854 && ref_name.is_none()
855 && substitution_groups.is_empty()
856 {
857 resolved_type = Some(TypeKey::Complex(schema_set.any_type_key()));
858 }
859
860 let resolved_ref = if let Some(ref qname) = ref_name {
862 let elem_key = resolver.resolve_element_ref(qname, source.as_ref())?;
863 stats.elements_resolved += 1;
864 Some(elem_key)
865 } else {
866 None
867 };
868
869 let mut resolved_subst_groups = Vec::with_capacity(substitution_groups.len());
874 for qname in &substitution_groups {
875 if lazy_src_resolve {
876 match resolver.try_resolve_element_ref(qname, source.as_ref())? {
877 Some(elem_key) => {
878 stats.elements_resolved += 1;
879 resolved_subst_groups.push(elem_key);
880 }
881 None => {
882 }
884 }
885 } else {
886 let elem_key = resolver.resolve_element_ref(qname, source.as_ref())?;
887 stats.elements_resolved += 1;
888 resolved_subst_groups.push(elem_key);
889 }
890 }
891
892 #[cfg(feature = "xsd11")]
894 let resolved_alt_types = {
895 let elem = schema_set
896 .arenas
897 .elements
898 .get(key)
899 .ok_or_else(|| SchemaError::internal("Element not found in arena"))?;
900 let mut alt_types: Vec<Option<TypeKey>> = Vec::with_capacity(elem.alternatives.len());
901 for alt in &elem.alternatives {
902 if alt.resolved_type.is_some() {
903 alt_types.push(alt.resolved_type);
905 } else if let Some(TypeRefResult::QName(ref qname)) = alt.type_ref {
906 let resolver = ReferenceResolver::new(schema_set);
907 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
908 stats.types_resolved += 1;
909 alt_types.push(Some(type_key));
910 } else {
911 alt_types.push(resolved_type);
913 }
914 }
915 alt_types
916 };
917
918 if let Some(elem) = schema_set.arenas.elements.get_mut(key) {
920 elem.resolved_type = resolved_type;
921 elem.resolved_ref = resolved_ref;
922 elem.resolved_substitution_groups = resolved_subst_groups;
923 elem.deferred_type_error = deferred_type_error;
924
925 #[cfg(feature = "xsd11")]
926 for (i, alt_type) in resolved_alt_types.into_iter().enumerate() {
927 if let Some(alt) = elem.alternatives.get_mut(i) {
928 alt.resolved_type = alt_type;
929 }
930 }
931 }
932
933 Ok(())
934}
935
936fn format_type_not_found_message(
941 schema_set: &SchemaSet,
942 qname: &QNameRef,
943 label: &str,
944) -> String {
945 let name_str = format_resolved_qname(&schema_set.name_table, qname.namespace, qname.local_name);
946 let simple_note = schema_set.format_provenance_note(
947 ComponentKind::SimpleType,
948 qname.namespace,
949 qname.local_name,
950 );
951 let note = if simple_note.is_empty() {
952 schema_set.format_provenance_note(
953 ComponentKind::ComplexType,
954 qname.namespace,
955 qname.local_name,
956 )
957 } else {
958 simple_note
959 };
960 format!("{} '{}' not found{}", label, name_str, note)
961}
962
963fn build_deferred_type_resolve(
965 schema_set: &SchemaSet,
966 qname: &QNameRef,
967 source: Option<&SourceRef>,
968 label: &str,
969) -> crate::arenas::DeferredSrcResolve {
970 crate::arenas::DeferredSrcResolve {
971 message: format_type_not_found_message(schema_set, qname, label),
972 source: source.cloned(),
973 }
974}
975
976fn resolve_attribute_references(
978 schema_set: &mut SchemaSet,
979 key: AttributeKey,
980 stats: &mut ResolutionStats,
981) -> SchemaResult<()> {
982 let (type_qname, ref_name, source, already_resolved_type) = {
985 let attr = schema_set
986 .arenas
987 .attributes
988 .get(key)
989 .ok_or_else(|| SchemaError::internal("Attribute not found in arena"))?;
990
991 let type_qname = match &attr.type_ref {
993 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
994 _ => None,
995 };
996
997 (
998 type_qname,
999 attr.ref_name.clone(),
1000 attr.source.clone(),
1001 attr.resolved_type,
1002 )
1003 };
1004
1005 let resolver = ReferenceResolver::new(schema_set);
1007
1008 let resolved_type = if already_resolved_type.is_some() {
1010 already_resolved_type
1012 } else if let Some(ref qname) = type_qname {
1013 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
1014 stats.types_resolved += 1;
1015 Some(type_key)
1016 } else {
1017 None
1018 };
1019
1020 let resolved_ref = if let Some(ref qname) = ref_name {
1022 let attr_key = resolver.resolve_attribute_ref(qname, source.as_ref())?;
1023 stats.attributes_resolved += 1;
1024 Some(attr_key)
1025 } else {
1026 None
1027 };
1028
1029 if let Some(attr) = schema_set.arenas.attributes.get_mut(key) {
1031 attr.resolved_type = resolved_type;
1032 attr.resolved_ref = resolved_ref;
1033 }
1034
1035 Ok(())
1036}
1037
1038fn resolve_simple_type_references(
1040 schema_set: &mut SchemaSet,
1041 key: SimpleTypeKey,
1042 stats: &mut ResolutionStats,
1043) -> SchemaResult<()> {
1044 let (
1047 base_qname,
1048 item_qname,
1049 member_qnames,
1050 source,
1051 already_resolved_base,
1052 already_resolved_item,
1053 already_resolved_members,
1054 redefine_original,
1055 type_name,
1056 type_ns,
1057 ) = {
1058 let type_def = schema_set
1059 .arenas
1060 .simple_types
1061 .get(key)
1062 .ok_or_else(|| SchemaError::internal("Simple type not found in arena"))?;
1063
1064 let base_qname = match &type_def.base_type {
1066 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
1067 _ => None,
1068 };
1069 let item_qname = match &type_def.item_type {
1070 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
1071 _ => None,
1072 };
1073 let member_qnames: Vec<_> = type_def
1074 .member_types
1075 .iter()
1076 .filter_map(|tr| match tr {
1077 TypeRefResult::QName(qname) => Some(qname.clone()),
1078 _ => None,
1079 })
1080 .collect();
1081
1082 (
1083 base_qname,
1084 item_qname,
1085 member_qnames,
1086 type_def.source.clone(),
1087 type_def.resolved_base_type,
1088 type_def.resolved_item_type,
1089 type_def.resolved_member_types.clone(),
1090 type_def.redefine_original,
1091 type_def.name,
1092 type_def.target_namespace,
1093 )
1094 };
1095
1096 let resolver = ReferenceResolver::new(schema_set);
1098
1099 let resolved_base = if already_resolved_base.is_some() {
1102 already_resolved_base
1103 } else if let Some(ref qname) = base_qname {
1104 let is_redefine_self_ref = redefine_original.is_some()
1105 && Some(qname.local_name) == type_name
1106 && qname.namespace == type_ns;
1107 if is_redefine_self_ref {
1108 stats.types_resolved += 1;
1109 Some(TypeKey::Simple(redefine_original.unwrap()))
1110 } else {
1111 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
1112 stats.types_resolved += 1;
1113 Some(type_key)
1114 }
1115 } else {
1116 None
1117 };
1118
1119 let lazy_src_resolve = schema_set.is_xsd10();
1125 let mut deferred_item_error: Option<crate::arenas::DeferredSrcResolve> = None;
1126 let resolved_item = if already_resolved_item.is_some() {
1127 already_resolved_item
1128 } else if let Some(ref qname) = item_qname {
1129 if lazy_src_resolve {
1130 match resolver.try_resolve_type_ref(qname, source.as_ref())? {
1131 Some(type_key) => {
1132 stats.types_resolved += 1;
1133 Some(type_key)
1134 }
1135 None => {
1136 deferred_item_error = Some(build_deferred_type_resolve(
1137 schema_set,
1138 qname,
1139 source.as_ref(),
1140 "List item type",
1141 ));
1142 None
1143 }
1144 }
1145 } else {
1146 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
1147 stats.types_resolved += 1;
1148 Some(type_key)
1149 }
1150 } else {
1151 None
1152 };
1153
1154 let mut resolved_members = Vec::new();
1157 for qname in &member_qnames {
1158 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
1159 stats.types_resolved += 1;
1160 resolved_members.push(type_key);
1161 }
1162 resolved_members.extend(already_resolved_members);
1163
1164 let resolved_base = if resolved_base.is_none() {
1169 let variety = schema_set
1170 .arenas
1171 .simple_types
1172 .get(key)
1173 .map(|t| t.variety)
1174 .unwrap_or(SimpleTypeVariety::Atomic);
1175 if matches!(variety, SimpleTypeVariety::List | SimpleTypeVariety::Union) {
1176 let any_simple = schema_set.builtin_types().any_simple_type;
1177 Some(TypeKey::Simple(any_simple))
1178 } else {
1179 None
1180 }
1181 } else {
1182 resolved_base
1183 };
1184
1185 if let Some(type_def) = schema_set.arenas.simple_types.get_mut(key) {
1187 type_def.resolved_base_type = resolved_base;
1188 type_def.resolved_item_type = resolved_item;
1189 type_def.resolved_member_types = resolved_members;
1190 type_def.deferred_item_type_error = deferred_item_error;
1191 }
1192
1193 if let Some(TypeKey::Simple(base_sk)) = resolved_base {
1197 let (base_variety, base_members, base_item, base_deferred_item) = {
1198 if let Some(base_def) = schema_set.arenas.simple_types.get(base_sk) {
1199 (
1200 base_def.variety,
1201 base_def.resolved_member_types.clone(),
1202 base_def.resolved_item_type,
1203 base_def.deferred_item_type_error.clone(),
1204 )
1205 } else {
1206 (SimpleTypeVariety::Atomic, Vec::new(), None, None)
1207 }
1208 };
1209 if let Some(type_def) = schema_set.arenas.simple_types.get_mut(key) {
1210 if type_def.variety == SimpleTypeVariety::Atomic
1211 && base_variety != SimpleTypeVariety::Atomic
1212 {
1213 type_def.variety = base_variety;
1214 }
1215 if base_variety == SimpleTypeVariety::Union && type_def.resolved_member_types.is_empty()
1216 {
1217 type_def.resolved_member_types = base_members;
1218 }
1219 if base_variety == SimpleTypeVariety::List && type_def.resolved_item_type.is_none() {
1220 type_def.resolved_item_type = base_item;
1221 if type_def.deferred_item_type_error.is_none() {
1225 type_def.deferred_item_type_error = base_deferred_item;
1226 }
1227 }
1228 }
1229 }
1230
1231 Ok(())
1232}
1233
1234fn resolve_complex_type_references(
1236 schema_set: &mut SchemaSet,
1237 key: ComplexTypeKey,
1238 stats: &mut ResolutionStats,
1239) -> SchemaResult<()> {
1240 use crate::arenas::ResolvedAttributeUse;
1241
1242 let (
1245 base_qname,
1246 attribute_groups,
1247 attribute_uses,
1248 source,
1249 already_resolved_base,
1250 redefine_original,
1251 type_name,
1252 type_ns,
1253 already_resolved_attrs,
1254 ) = {
1255 let type_def = schema_set
1256 .arenas
1257 .complex_types
1258 .get(key)
1259 .ok_or_else(|| SchemaError::internal("Complex type not found in arena"))?;
1260
1261 let base_qname = match &type_def.base_type {
1263 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
1264 _ => None,
1265 };
1266
1267 let attribute_uses: Vec<_> = type_def
1269 .attributes
1270 .iter()
1271 .map(|attr_use| {
1272 let type_qname = match &attr_use.attribute.type_ref {
1273 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
1274 _ => None,
1275 };
1276 (
1277 attr_use.attribute.ref_name.clone(),
1278 type_qname,
1279 attr_use.attribute.source.clone(),
1280 )
1281 })
1282 .collect();
1283
1284 let already_resolved_attrs = type_def.resolved_attributes.clone();
1286
1287 (
1288 base_qname,
1289 type_def.attribute_groups.clone(),
1290 attribute_uses,
1291 type_def.source.clone(),
1292 type_def.resolved_base_type,
1293 type_def.redefine_original,
1294 type_def.name,
1295 type_def.target_namespace,
1296 already_resolved_attrs,
1297 )
1298 };
1299
1300 let resolver = ReferenceResolver::new(schema_set);
1302
1303 let resolved_base = if already_resolved_base.is_some() {
1306 already_resolved_base
1307 } else if let Some(ref qname) = base_qname {
1308 let is_redefine_self_ref = redefine_original.is_some()
1309 && Some(qname.local_name) == type_name
1310 && qname.namespace == type_ns;
1311 if is_redefine_self_ref {
1312 stats.types_resolved += 1;
1313 Some(TypeKey::Complex(redefine_original.unwrap()))
1314 } else {
1315 let type_key = resolver.resolve_type_ref(qname, source.as_ref())?;
1316 stats.types_resolved += 1;
1317 Some(type_key)
1318 }
1319 } else {
1320 None
1321 };
1322
1323 let mut resolved_attr_groups = Vec::with_capacity(attribute_groups.len());
1325 for qname in &attribute_groups {
1326 let group_key = resolver.resolve_attribute_group_ref(qname, source.as_ref())?;
1327 stats.attribute_groups_resolved += 1;
1328 resolved_attr_groups.push(group_key);
1329 }
1330
1331 let mut resolved_attrs = Vec::with_capacity(attribute_uses.len());
1333 for (i, (ref_name, type_qname, attr_source)) in attribute_uses.iter().enumerate() {
1334 let resolved_type = if let Some(ref qname) = type_qname {
1335 let type_key = resolver.resolve_type_ref(qname, attr_source.as_ref())?;
1336 stats.types_resolved += 1;
1337 Some(type_key)
1338 } else {
1339 already_resolved_attrs.get(i).and_then(|r| r.resolved_type)
1341 };
1342 let resolved_ref = if let Some(ref qname) = ref_name {
1343 let attr_key = resolver.resolve_attribute_ref(qname, attr_source.as_ref())?;
1344 stats.attributes_resolved += 1;
1345 Some(attr_key)
1346 } else {
1347 already_resolved_attrs.get(i).and_then(|r| r.resolved_ref)
1349 };
1350 resolved_attrs.push(ResolvedAttributeUse {
1351 resolved_type,
1352 resolved_ref,
1353 });
1354 }
1355
1356 if let Some(type_def) = schema_set.arenas.complex_types.get_mut(key) {
1358 type_def.resolved_base_type = resolved_base;
1359 type_def.resolved_attribute_groups = resolved_attr_groups;
1360 type_def.resolved_attributes = resolved_attrs;
1361 }
1362
1363 Ok(())
1364}
1365
1366fn resolve_model_group_references(
1368 schema_set: &mut SchemaSet,
1369 key: ModelGroupKey,
1370 stats: &mut ResolutionStats,
1371) -> SchemaResult<()> {
1372 use crate::arenas::ResolvedParticleTerm;
1373 use crate::parser::frames::ParticleTerm;
1374
1375 let group = schema_set
1377 .arenas
1378 .model_groups
1379 .get(key)
1380 .ok_or_else(|| SchemaError::internal("Model group not found in arena"))?;
1381
1382 let ref_name = group.ref_name.clone();
1384 let source = group.source.clone();
1385 let particles_clone = group.particles.clone();
1386
1387 let redefine_original = group.redefine_original;
1389 let group_name = group.name;
1390 let group_ns = group.target_namespace;
1391
1392 let existing_resolved: Vec<_> = group.resolved_particles.clone();
1395 let existing_particle_types = group.resolved_particle_types.clone();
1396
1397 let particle_info: Vec<_> = group
1399 .particles
1400 .iter()
1401 .map(|p| match &p.term {
1402 ParticleTerm::Element(elem) => {
1403 let type_qname = match &elem.type_ref {
1404 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
1405 _ => None,
1406 };
1407 (0, elem.ref_name.clone(), type_qname, p.source.clone())
1408 }
1409 ParticleTerm::Group(grp) => (1, grp.ref_name.clone(), None, p.source.clone()),
1410 ParticleTerm::Any(_) => (2, None, None, p.source.clone()),
1411 })
1412 .collect();
1413
1414 let resolver = ReferenceResolver::new(schema_set);
1416
1417 let resolved_ref = if let Some(ref qname) = ref_name {
1419 let group_key = resolver.resolve_group_ref(qname, source.as_ref())?;
1420 stats.groups_resolved += 1;
1421 Some(group_key)
1422 } else {
1423 None
1424 };
1425
1426 let mut resolved_particles = Vec::with_capacity(particle_info.len());
1428 for (i, (kind, elem_or_group_ref, type_qname, particle_source)) in
1429 particle_info.iter().enumerate()
1430 {
1431 match kind {
1432 0 => {
1433 let already_resolved_type = existing_resolved.get(i).and_then(|rp| {
1435 if let ResolvedParticleTerm::Element {
1436 resolved_type: Some(key),
1437 ..
1438 } = rp
1439 {
1440 Some(*key)
1441 } else {
1442 None
1443 }
1444 });
1445 let resolved_type = if let Some(key) = already_resolved_type {
1446 Some(key)
1447 } else if let Some(ref qname) = type_qname {
1448 let type_key = resolver.resolve_type_ref(qname, particle_source.as_ref())?;
1449 stats.types_resolved += 1;
1450 Some(type_key)
1451 } else {
1452 None
1453 };
1454 let resolved_elem_ref = if let Some(ref qname) = elem_or_group_ref {
1455 let elem_key = resolver.resolve_element_ref(qname, particle_source.as_ref())?;
1456 stats.elements_resolved += 1;
1457 Some(elem_key)
1458 } else {
1459 None
1460 };
1461 resolved_particles.push(ResolvedParticleTerm::Element {
1462 resolved_type,
1463 resolved_ref: resolved_elem_ref,
1464 });
1465 }
1466 1 => {
1467 let resolved_group_ref = if let Some(ref qname) = elem_or_group_ref {
1469 let is_self_ref = redefine_original.is_some()
1470 && Some(qname.local_name) == group_name
1471 && qname.namespace == group_ns;
1472 let grp_key = if is_self_ref {
1473 redefine_original.unwrap()
1474 } else {
1475 resolver.resolve_group_ref(qname, particle_source.as_ref())?
1476 };
1477 stats.groups_resolved += 1;
1478 Some(grp_key)
1479 } else {
1480 None
1481 };
1482 resolved_particles.push(ResolvedParticleTerm::Group {
1483 resolved_ref: resolved_group_ref,
1484 });
1485 }
1486 _ => {
1487 resolved_particles.push(ResolvedParticleTerm::Any);
1489 }
1490 }
1491 }
1492
1493 let mut resolved_particle_types = Vec::new();
1495 let mut flat_idx = 0;
1496 resolve_model_group_particle_types_recursive(
1497 &particles_clone,
1498 &existing_particle_types,
1499 &resolver,
1500 &mut flat_idx,
1501 &mut resolved_particle_types,
1502 stats,
1503 )?;
1504
1505 if let Some(group) = schema_set.arenas.model_groups.get_mut(key) {
1507 group.resolved_ref = resolved_ref;
1508 group.resolved_particles = resolved_particles;
1509 group.resolved_particle_types = resolved_particle_types;
1510 }
1511
1512 Ok(())
1513}
1514
1515fn resolve_model_group_particle_types_recursive(
1517 particles: &[crate::parser::frames::ParticleResult],
1518 existing_types: &[Option<TypeKey>],
1519 resolver: &ReferenceResolver,
1520 flat_idx: &mut usize,
1521 resolved_types: &mut Vec<Option<TypeKey>>,
1522 stats: &mut ResolutionStats,
1523) -> SchemaResult<()> {
1524 use crate::parser::frames::ParticleTerm;
1525
1526 for particle in particles {
1527 match &particle.term {
1528 ParticleTerm::Element(elem) => {
1529 let idx = *flat_idx;
1530 *flat_idx += 1;
1531 let already_resolved = existing_types.get(idx).copied().flatten();
1533 let resolved_type = if let Some(key) = already_resolved {
1534 Some(key)
1535 } else {
1536 match &elem.type_ref {
1538 Some(TypeRefResult::QName(qname)) => {
1539 let type_key =
1540 resolver.resolve_type_ref(qname, particle.source.as_ref())?;
1541 stats.types_resolved += 1;
1542 Some(type_key)
1543 }
1544 _ => None,
1545 }
1546 };
1547 while resolved_types.len() <= idx {
1548 resolved_types.push(None);
1549 }
1550 resolved_types[idx] = resolved_type;
1551 }
1552 ParticleTerm::Group(group_def) if group_def.ref_name.is_none() => {
1553 resolve_model_group_particle_types_recursive(
1554 &group_def.particles,
1555 existing_types,
1556 resolver,
1557 flat_idx,
1558 resolved_types,
1559 stats,
1560 )?;
1561 }
1562 _ => {} }
1564 }
1565 Ok(())
1566}
1567
1568fn resolve_attribute_group_references(
1570 schema_set: &mut SchemaSet,
1571 key: AttributeGroupKey,
1572 stats: &mut ResolutionStats,
1573) -> SchemaResult<()> {
1574 use crate::arenas::ResolvedAttributeUse;
1575
1576 let group = schema_set
1578 .arenas
1579 .attribute_groups
1580 .get(key)
1581 .ok_or_else(|| SchemaError::internal("Attribute group not found in arena"))?;
1582
1583 let ref_name = group.ref_name.clone();
1585 let nested_groups = group.attribute_groups.clone();
1586 let source = group.source.clone();
1587
1588 let redefine_original = group.redefine_original;
1590 let group_name = group.name;
1591 let group_ns = group.target_namespace;
1592
1593 let attribute_uses: Vec<_> = group
1595 .attributes
1596 .iter()
1597 .map(|attr_use| {
1598 let type_qname = match &attr_use.attribute.type_ref {
1599 Some(TypeRefResult::QName(qname)) => Some(qname.clone()),
1600 _ => None,
1601 };
1602 (
1603 attr_use.attribute.ref_name.clone(),
1604 type_qname,
1605 attr_use.attribute.source.clone(),
1606 )
1607 })
1608 .collect();
1609
1610 let already_resolved_attrs = group.resolved_attributes.clone();
1612
1613 let resolver = ReferenceResolver::new(schema_set);
1615
1616 let resolved_ref = if let Some(ref qname) = ref_name {
1618 let group_key = resolver.resolve_attribute_group_ref(qname, source.as_ref())?;
1619 stats.attribute_groups_resolved += 1;
1620 Some(group_key)
1621 } else {
1622 None
1623 };
1624
1625 let mut resolved_nested = Vec::with_capacity(nested_groups.len());
1627 for qname in &nested_groups {
1628 let is_self_ref = redefine_original.is_some()
1629 && Some(qname.local_name) == group_name
1630 && qname.namespace == group_ns;
1631 let group_key = if is_self_ref {
1632 redefine_original.unwrap()
1633 } else {
1634 resolver.resolve_attribute_group_ref(qname, source.as_ref())?
1635 };
1636 stats.attribute_groups_resolved += 1;
1637 resolved_nested.push(group_key);
1638 }
1639
1640 let mut resolved_attrs = Vec::with_capacity(attribute_uses.len());
1642 for (i, (ref_name_opt, type_qname, attr_source)) in attribute_uses.iter().enumerate() {
1643 let resolved_type = if let Some(ref qname) = type_qname {
1644 let type_key = resolver.resolve_type_ref(qname, attr_source.as_ref())?;
1645 stats.types_resolved += 1;
1646 Some(type_key)
1647 } else {
1648 already_resolved_attrs.get(i).and_then(|r| r.resolved_type)
1650 };
1651 let resolved_attr_ref = if let Some(ref qname) = ref_name_opt {
1652 let attr_key = resolver.resolve_attribute_ref(qname, attr_source.as_ref())?;
1653 stats.attributes_resolved += 1;
1654 Some(attr_key)
1655 } else {
1656 already_resolved_attrs.get(i).and_then(|r| r.resolved_ref)
1658 };
1659 resolved_attrs.push(ResolvedAttributeUse {
1660 resolved_type,
1661 resolved_ref: resolved_attr_ref,
1662 });
1663 }
1664
1665 if let Some(group) = schema_set.arenas.attribute_groups.get_mut(key) {
1667 group.resolved_ref = resolved_ref;
1668 group.resolved_attribute_groups = resolved_nested;
1669 group.resolved_attributes = resolved_attrs;
1670 }
1671
1672 Ok(())
1673}
1674
1675fn resolve_notation_references(
1682 schema_set: &mut SchemaSet,
1683 key: NotationKey,
1684 stats: &mut ResolutionStats,
1685) -> SchemaResult<()> {
1686 let _notation = schema_set
1688 .arenas
1689 .notations
1690 .get(key)
1691 .ok_or_else(|| SchemaError::internal("Notation not found in arena"))?;
1692
1693 stats.notations_resolved += 1;
1695
1696 Ok(())
1701}
1702
1703#[cfg(test)]
1704mod tests {
1705 use super::*;
1706 use crate::namespace::table::well_known;
1707
1708 #[test]
1709 fn test_reference_resolver_creation() {
1710 let schema_set = SchemaSet::new();
1711 let _resolver = ReferenceResolver::new(&schema_set);
1712 }
1713
1714 #[test]
1715 fn test_resolve_builtin_type() {
1716 let schema_set = SchemaSet::new();
1717 let resolver = ReferenceResolver::new(&schema_set);
1718
1719 let string_name = schema_set.name_table.get("string").unwrap();
1721 let qname = QNameRef {
1722 prefix: None,
1723 local_name: string_name,
1724 namespace: Some(well_known::XS_NAMESPACE),
1725 };
1726
1727 let result = resolver.resolve_type_ref(&qname, None);
1728 assert!(result.is_ok(), "Should resolve xs:string");
1729
1730 if let Ok(TypeKey::Simple(key)) = result {
1731 let string_key = schema_set.builtin_types().string;
1733 assert_eq!(key, string_key);
1734 } else {
1735 panic!("Expected Simple type key");
1736 }
1737 }
1738
1739 #[test]
1740 fn test_resolve_builtin_integer() {
1741 let schema_set = SchemaSet::new();
1742 let resolver = ReferenceResolver::new(&schema_set);
1743
1744 let integer_name = schema_set.name_table.get("integer").unwrap();
1746 let qname = QNameRef {
1747 prefix: None,
1748 local_name: integer_name,
1749 namespace: Some(well_known::XS_NAMESPACE),
1750 };
1751
1752 let result = resolver.resolve_type_ref(&qname, None);
1753 assert!(result.is_ok(), "Should resolve xs:integer");
1754 }
1755
1756 #[test]
1757 fn test_resolve_builtin_any_type() {
1758 let schema_set = SchemaSet::new();
1759 let resolver = ReferenceResolver::new(&schema_set);
1760
1761 let any_type_name = schema_set.name_table.get("anyType").unwrap();
1762 let qname = QNameRef {
1763 prefix: None,
1764 local_name: any_type_name,
1765 namespace: Some(well_known::XS_NAMESPACE),
1766 };
1767
1768 let result = resolver.resolve_type_ref(&qname, None);
1769 assert!(result.is_ok(), "Should resolve xs:anyType");
1770
1771 if let Ok(TypeKey::Complex(key)) = result {
1772 assert_eq!(key, schema_set.builtin_types().any_type);
1773 } else {
1774 panic!("Expected Complex type key");
1775 }
1776 }
1777
1778 #[test]
1779 fn test_resolve_unknown_type_error() {
1780 let schema_set = SchemaSet::new();
1781
1782 let unknown_name = schema_set.name_table.add("nonExistentType");
1784
1785 let resolver = ReferenceResolver::new(&schema_set);
1786 let qname = QNameRef {
1787 prefix: None,
1788 local_name: unknown_name,
1789 namespace: Some(well_known::XS_NAMESPACE),
1790 };
1791
1792 let result = resolver.resolve_type_ref(&qname, None);
1793 assert!(result.is_err(), "Should fail for unknown type");
1794 }
1795
1796 #[test]
1797 fn test_format_qname_with_namespace() {
1798 let schema_set = SchemaSet::new();
1799 let resolver = ReferenceResolver::new(&schema_set);
1800
1801 let string_name = schema_set.name_table.get("string").unwrap();
1803 let qname = QNameRef {
1804 prefix: None,
1805 local_name: string_name,
1806 namespace: Some(well_known::XS_NAMESPACE),
1807 };
1808
1809 let formatted = resolver.format_qname(&qname);
1810 assert!(formatted.contains("string"));
1811 assert!(formatted.contains("XMLSchema"));
1812 }
1813
1814 #[test]
1815 fn test_format_qname_without_namespace() {
1816 let schema_set = SchemaSet::new();
1817
1818 let local_name = schema_set.name_table.add("localType");
1820
1821 let resolver = ReferenceResolver::new(&schema_set);
1822 let qname = QNameRef {
1823 prefix: None,
1824 local_name,
1825 namespace: None,
1826 };
1827
1828 let formatted = resolver.format_qname(&qname);
1829 assert_eq!(formatted, "localType");
1830 }
1831
1832 #[test]
1833 fn test_resolution_stats_default() {
1834 let stats = ResolutionStats::default();
1835 assert_eq!(stats.types_resolved, 0);
1836 assert_eq!(stats.elements_resolved, 0);
1837 assert_eq!(stats.errors, 0);
1838 }
1839
1840 #[test]
1841 fn test_resolve_all_references_empty_schema() {
1842 let mut schema_set = SchemaSet::new();
1843
1844 let result = resolve_all_references(&mut schema_set);
1846 assert!(result.is_ok());
1847
1848 let stats = result.unwrap();
1849 assert_eq!(stats.errors, 0);
1851 }
1852
1853 #[test]
1854 fn test_resolve_user_defined_element_with_builtin_type() {
1855 use crate::arenas::ElementDeclData;
1856 use crate::parser::frames::QNameRef;
1857 use crate::schema::model::DerivationSet;
1858
1859 let mut schema_set = SchemaSet::new();
1860
1861 let elem_name = schema_set.name_table.add("myElement");
1863 let string_name = schema_set.name_table.get("string").unwrap();
1864
1865 let type_ref = TypeRefResult::QName(QNameRef {
1867 prefix: None,
1868 local_name: string_name,
1869 namespace: Some(well_known::XS_NAMESPACE),
1870 });
1871
1872 let elem_data = ElementDeclData {
1873 name: Some(elem_name),
1874 target_namespace: None,
1875 ref_name: None,
1876 type_ref: Some(type_ref),
1877 inline_type: None,
1878 substitution_group: Vec::new(),
1879 default_value: None,
1880 fixed_value: None,
1881 nillable: false,
1882 is_abstract: false,
1883 min_occurs: 1,
1884 max_occurs: Some(1),
1885 block: DerivationSet::empty(),
1886 final_derivation: DerivationSet::empty(),
1887 form: None,
1888 id: None,
1889 alternatives: Vec::new(),
1890 identity_constraints: Vec::new(),
1891 pending_ic_refs: vec![],
1892 annotation: None,
1893 source: None,
1894 resolved_type: None,
1895 resolved_ref: None,
1896 resolved_substitution_groups: Vec::new(),
1897 deferred_type_error: None,
1898 };
1899
1900 let elem_key = schema_set.arenas.alloc_element(elem_data);
1901
1902 let result = resolve_all_references(&mut schema_set);
1904 assert!(result.is_ok(), "Resolution should succeed: {:?}", result);
1905
1906 let elem = schema_set.arenas.elements.get(elem_key).unwrap();
1908 assert!(elem.resolved_type.is_some(), "Type should be resolved");
1909
1910 if let Some(TypeKey::Simple(key)) = elem.resolved_type {
1911 assert_eq!(key, schema_set.builtin_types().string);
1912 } else {
1913 panic!("Expected Simple type key for xs:string");
1914 }
1915 }
1916
1917 #[test]
1918 fn test_resolve_attribute_with_builtin_type() {
1919 use crate::arenas::AttributeDeclData;
1920 use crate::parser::frames::QNameRef;
1921
1922 let mut schema_set = SchemaSet::new();
1923
1924 let attr_name = schema_set.name_table.add("myAttribute");
1926 let integer_name = schema_set.name_table.get("integer").unwrap();
1927
1928 let type_ref = TypeRefResult::QName(QNameRef {
1930 prefix: None,
1931 local_name: integer_name,
1932 namespace: Some(well_known::XS_NAMESPACE),
1933 });
1934
1935 let attr_data = AttributeDeclData {
1936 name: Some(attr_name),
1937 target_namespace: None,
1938 ref_name: None,
1939 type_ref: Some(type_ref),
1940 inline_type: None,
1941 default_value: None,
1942 fixed_value: None,
1943 use_kind: None,
1944 form: None,
1945 inheritable: false,
1946 id: None,
1947 annotation: None,
1948 source: None,
1949 resolved_type: None,
1950 resolved_ref: None,
1951 };
1952
1953 let attr_key = schema_set.arenas.alloc_attribute(attr_data);
1954
1955 let result = resolve_all_references(&mut schema_set);
1957 assert!(result.is_ok());
1958
1959 let attr = schema_set.arenas.attributes.get(attr_key).unwrap();
1961 assert!(attr.resolved_type.is_some(), "Type should be resolved");
1962 }
1963
1964 #[test]
1965 fn test_resolve_element_already_resolved_inline_type() {
1966 use crate::arenas::ElementDeclData;
1967 use crate::schema::model::DerivationSet;
1968
1969 let mut schema_set = SchemaSet::new();
1970
1971 let elem_name = schema_set.name_table.add("myElement");
1972
1973 let string_key = schema_set.builtin_types().string;
1975
1976 let elem_data = ElementDeclData {
1977 name: Some(elem_name),
1978 target_namespace: None,
1979 ref_name: None,
1980 type_ref: None,
1981 inline_type: None,
1982 substitution_group: Vec::new(),
1983 default_value: None,
1984 fixed_value: None,
1985 nillable: false,
1986 is_abstract: false,
1987 min_occurs: 1,
1988 max_occurs: Some(1),
1989 block: DerivationSet::empty(),
1990 final_derivation: DerivationSet::empty(),
1991 form: None,
1992 id: None,
1993 alternatives: Vec::new(),
1994 identity_constraints: Vec::new(),
1995 pending_ic_refs: vec![],
1996 annotation: None,
1997 source: None,
1998 resolved_type: Some(TypeKey::Simple(string_key)),
2000 resolved_ref: None,
2001 resolved_substitution_groups: Vec::new(),
2002 deferred_type_error: None,
2003 };
2004
2005 let elem_key = schema_set.arenas.alloc_element(elem_data);
2006
2007 let result = resolve_all_references(&mut schema_set);
2009 assert!(result.is_ok());
2010
2011 let elem = schema_set.arenas.elements.get(elem_key).unwrap();
2013 assert!(elem.resolved_type.is_some());
2014 assert_eq!(elem.resolved_type, Some(TypeKey::Simple(string_key)));
2015 }
2016
2017 #[test]
2018 fn test_resolver_preserves_inline_resolved_type_in_model_group() {
2019 use crate::arenas::{ModelGroupData, ResolvedParticleTerm};
2020 use crate::parser::frames::{Compositor, ElementFrameResult, ParticleResult, ParticleTerm};
2021
2022 let mut schema_set = SchemaSet::new();
2023
2024 let elem_name = schema_set.name_table.add("detail");
2025 let group_name = schema_set.name_table.add("myGroup");
2026
2027 let string_key = schema_set.builtin_types().string;
2029
2030 let group_data = ModelGroupData {
2032 name: Some(group_name),
2033 target_namespace: None,
2034 ref_name: None,
2035 compositor: Some(Compositor::Sequence),
2036 particles: vec![ParticleResult {
2037 term: ParticleTerm::Element(ElementFrameResult {
2038 name: Some(elem_name),
2039 ref_name: None,
2040 target_namespace: None,
2041 type_ref: None, inline_type: None,
2043 substitution_group: vec![],
2044 default_value: None,
2045 fixed_value: None,
2046 nillable: false,
2047 is_abstract: false,
2048 min_occurs: 1,
2049 max_occurs: Some(1),
2050 block: None,
2051 final_derivation: None,
2052 form: None,
2053 id: None,
2054 alternatives: vec![],
2055 identity_constraints: vec![],
2056 identity_constraint_refs: vec![],
2057 annotation: None,
2058 source: None,
2059 }),
2060 min_occurs: 1,
2061 max_occurs: Some(1),
2062 source: None,
2063 }],
2064 min_occurs: 1,
2065 max_occurs: Some(1),
2066 id: None,
2067 annotation: None,
2068 source: None,
2069 resolved_ref: None,
2070 resolved_particles: vec![ResolvedParticleTerm::Element {
2072 resolved_type: Some(TypeKey::Simple(string_key)),
2073 resolved_ref: None,
2074 }],
2075 resolved_particle_types: vec![Some(TypeKey::Simple(string_key))],
2076 resolved_particle_elements: Vec::new(),
2077 redefine_original: None,
2078 redefine_requires_restriction_check: false,
2079 };
2080
2081 let group_key = schema_set.arenas.alloc_model_group(group_data);
2082
2083 let result = resolve_all_references(&mut schema_set);
2085 assert!(result.is_ok());
2086
2087 let group = schema_set.arenas.model_groups.get(group_key).unwrap();
2089 assert_eq!(group.resolved_particles.len(), 1);
2090 match &group.resolved_particles[0] {
2091 ResolvedParticleTerm::Element {
2092 resolved_type: Some(TypeKey::Simple(key)),
2093 ..
2094 } => {
2095 assert_eq!(*key, string_key, "Inline-resolved type should be preserved");
2096 }
2097 other => panic!("Expected Element with pre-resolved type, got {:?}", other),
2098 }
2099 }
2100
2101 fn setup_default_attrs_test(
2104 default_attributes_apply: bool,
2105 ) -> (
2106 SchemaSet,
2107 crate::ids::ComplexTypeKey,
2108 crate::ids::AttributeGroupKey,
2109 ) {
2110 use crate::arenas::{AttributeGroupData, ComplexTypeDefData};
2111 use crate::namespace::QualifiedName;
2112 use crate::parser::frames::ComplexContentResult;
2113 use crate::parser::location::{SourceRef, SourceSpan};
2114 use crate::schema::model::{DerivationSet, SchemaDocument};
2115
2116 let mut schema_set = SchemaSet::new();
2117
2118 let group_name = schema_set.name_table.add("commonAttrs");
2119 let group_data = AttributeGroupData {
2120 name: Some(group_name),
2121 target_namespace: None,
2122 ref_name: None,
2123 attributes: Vec::new(),
2124 attribute_groups: Vec::new(),
2125 attribute_wildcard: None,
2126 id: None,
2127 annotation: None,
2128 source: None,
2129 resolved_ref: None,
2130 resolved_attribute_groups: Vec::new(),
2131 resolved_attributes: Vec::new(),
2132 redefine_original: None,
2133 redefine_requires_restriction_check: false,
2134 };
2135 let group_key = schema_set.arenas.alloc_attribute_group(group_data);
2136 schema_set
2137 .get_or_create_namespace(None)
2138 .register_attribute_group(group_name, group_key);
2139
2140 let doc_id = schema_set.documents.len() as u32;
2141 let mut doc = SchemaDocument::new(doc_id, "test.xsd".to_string());
2142 doc.default_attributes = Some(QualifiedName::local(group_name));
2143 schema_set.documents.push(doc);
2144
2145 let type_name = schema_set.name_table.add("myType");
2146 let ct_data = ComplexTypeDefData {
2147 name: Some(type_name),
2148 target_namespace: None,
2149 base_type: None,
2150 derivation_method: None,
2151 content: ComplexContentResult::Empty,
2152 open_content: None,
2153 attributes: Vec::new(),
2154 attribute_groups: Vec::new(),
2155 attribute_wildcard: None,
2156 mixed: false,
2157 is_abstract: false,
2158 final_derivation: DerivationSet::empty(),
2159 block: DerivationSet::empty(),
2160 default_attributes_apply,
2161 id: None,
2162 #[cfg(feature = "xsd11")]
2163 assertions: Vec::new(),
2164 #[cfg(feature = "xsd11")]
2165 xpath_default_namespace: None,
2166 annotation: None,
2167 source: Some(SourceRef::new(doc_id, SourceSpan::new(0, 0))),
2168 resolved_base_type: None,
2169 resolved_attribute_groups: Vec::new(),
2170 resolved_attributes: Vec::new(),
2171 resolved_content_particle_types: Vec::new(),
2172 resolved_content_particle_elements: Vec::new(),
2173 resolved_simple_content_type: None,
2174 redefine_original: None,
2175 };
2176 let ct_key = schema_set.arenas.alloc_complex_type(ct_data);
2177
2178 (schema_set, ct_key, group_key)
2179 }
2180
2181 #[test]
2182 fn test_resolve_default_attributes_injects_group() {
2183 let (mut schema_set, ct_key, group_key) = setup_default_attrs_test(true);
2184
2185 let result = resolve_all_references(&mut schema_set);
2186 assert!(result.is_ok(), "Resolution should succeed: {:?}", result);
2187
2188 let ct = schema_set.arenas.complex_types.get(ct_key).unwrap();
2189 assert!(
2190 ct.resolved_attribute_groups.contains(&group_key),
2191 "Default attribute group should be injected into resolved_attribute_groups"
2192 );
2193 }
2194
2195 #[test]
2196 fn test_resolve_default_attributes_opt_out() {
2197 let (mut schema_set, ct_key, _group_key) = setup_default_attrs_test(false);
2198
2199 let result = resolve_all_references(&mut schema_set);
2200 assert!(result.is_ok(), "Resolution should succeed: {:?}", result);
2201
2202 let ct = schema_set.arenas.complex_types.get(ct_key).unwrap();
2203 assert!(
2204 ct.resolved_attribute_groups.is_empty(),
2205 "Default attribute group should NOT be injected when defaultAttributesApply=false"
2206 );
2207 }
2208}