xsd_parser/generator/
data.rs

1use std::mem::take;
2use std::ops::Deref;
3
4use proc_macro2::{Ident as Ident2, Literal, TokenStream};
5use quote::{format_ident, quote};
6
7use crate::{
8    code::{format_field_ident, format_variant_ident, IdentPath, ModulePath},
9    schema::{xs::Use, MaxOccurs, MinOccurs, NamespaceId},
10    types::{
11        AnyAttributeInfo, AnyInfo, AttributeInfo, BuildInInfo, ComplexInfo, DynamicInfo,
12        ElementInfo, EnumerationInfo, GroupInfo, Ident, ReferenceInfo, Type, TypeVariant, Types,
13        UnionInfo, UnionTypeInfo, VariantInfo,
14    },
15};
16
17use super::{
18    misc::Occurs, BoxFlags, Config, Error, GeneratorFlags, State, TraitInfos, TypeRef, TypedefMode,
19};
20
21/// Represents the type data that is generated by teh generator for a type that
22/// needs to be rendered.
23///
24/// The generator adds additional useful data that is needed for the rendering
25/// process to the actual [`Type`] that needs to be rendered. So instead of
26/// passing the type directly to the renderer and re-calculate the data inside
27/// every renderer, the type is once evaluated by the generator and then any
28/// renderer can profit from the enriched data.
29#[derive(Debug)]
30pub enum TypeData<'types> {
31    /// Corresponds to [`TypeVariant::BuildIn`].
32    BuildIn(BuildInType<'types>),
33
34    /// Corresponds to [`TypeVariant::Union`].
35    Union(UnionType<'types>),
36
37    /// Corresponds to [`TypeVariant::Dynamic`].
38    Dynamic(DynamicType<'types>),
39
40    /// Corresponds to [`TypeVariant::Reference`].
41    Reference(ReferenceType<'types>),
42
43    /// Corresponds to [`TypeVariant::Enumeration`].
44    Enumeration(EnumerationType<'types>),
45
46    /// Corresponds to [`TypeVariant::All`], [`TypeVariant::Choice`],
47    /// [`TypeVariant::Sequence`] or [`TypeVariant::ComplexType`].
48    Complex(ComplexType<'types>),
49}
50
51impl<'types> TypeData<'types> {
52    pub(super) fn new(
53        ty: &'types Type,
54        ident: &Ident,
55        config: &Config<'types>,
56        state: &mut State<'types>,
57    ) -> Result<Self, Error> {
58        let req = Request::new(ident, config, state);
59
60        Ok(match &ty.variant {
61            TypeVariant::BuildIn(x) => Self::BuildIn(BuildInType::new(x)),
62            TypeVariant::Union(x) => Self::Union(UnionType::new(x, req)?),
63            TypeVariant::Dynamic(x) => Self::Dynamic(DynamicType::new(x, req)?),
64            TypeVariant::Reference(x) => Self::Reference(ReferenceType::new(x, req)?),
65            TypeVariant::Enumeration(x) => Self::Enumeration(EnumerationType::new(x, req)?),
66            TypeVariant::All(x) => Self::Complex(ComplexType::new_all(x, req)?),
67            TypeVariant::Choice(x) => Self::Complex(ComplexType::new_choice(x, req)?),
68            TypeVariant::Sequence(x) => Self::Complex(ComplexType::new_sequence(x, req)?),
69            TypeVariant::ComplexType(x) => Self::Complex(ComplexType::new_complex(x, req)?),
70        })
71    }
72}
73
74/// Contains additional information for the rendering process
75/// of a [`TypeVariant::BuildIn`] type.
76#[derive(Debug)]
77pub struct BuildInType<'types> {
78    /// Reference to the original type information.
79    pub info: &'types BuildInInfo,
80}
81
82impl<'types> BuildInType<'types> {
83    fn new(info: &'types BuildInInfo) -> Self {
84        Self { info }
85    }
86}
87
88/// Contains additional information for the rendering process
89/// of a [`TypeVariant::Union`] type.
90#[derive(Debug)]
91pub struct UnionType<'types> {
92    /// Reference to the original type information.
93    pub info: &'types UnionInfo,
94
95    /// The identifier of the rendered type.
96    pub type_ident: Ident2,
97
98    /// List of variants contained in this union.
99    pub variants: Vec<UnionTypeVariant<'types>>,
100
101    /// List of traits that needs to be implemented by this type.
102    pub trait_impls: Vec<IdentPath>,
103}
104
105/// Type variant used in [`UnionType`].
106#[derive(Debug)]
107pub struct UnionTypeVariant<'types> {
108    /// Reference to the original type information.
109    pub info: &'types UnionTypeInfo,
110
111    /// The type that is stored by the this variant.
112    pub target_type: IdentPath,
113
114    /// Identifier of this variant.
115    pub variant_ident: Ident2,
116}
117
118impl<'types> UnionType<'types> {
119    fn new(info: &'types UnionInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
120        let type_ident = req.current_type_ref().type_ident.clone();
121        let trait_impls = req.make_trait_impls()?;
122        let variants = info
123            .types
124            .iter()
125            .map(|info| info.make_variant(&mut req))
126            .collect::<Result<_, _>>()?;
127
128        Ok(Self {
129            info,
130            type_ident,
131            variants,
132            trait_impls,
133        })
134    }
135}
136
137impl UnionTypeInfo {
138    fn make_variant<'types>(
139        &'types self,
140        req: &mut Request<'_, 'types>,
141    ) -> Result<UnionTypeVariant<'types>, Error> {
142        let type_ref = req.get_or_create_type_ref(self.type_.clone())?;
143        let target_type = type_ref.to_ident_path();
144        let variant_ident = format_variant_ident(&self.type_.name, self.display_name.as_deref());
145
146        Ok(UnionTypeVariant {
147            info: self,
148            target_type,
149            variant_ident,
150        })
151    }
152}
153
154/// Contains additional information for the rendering process
155/// of a [`TypeVariant::Dynamic`] type.
156#[derive(Debug)]
157pub struct DynamicType<'types> {
158    /// Reference to the original type information.
159    pub info: &'types DynamicInfo,
160
161    /// The identifier of the rendered type.
162    pub type_ident: Ident2,
163
164    /// The identifier of the trait that needs to be implemented
165    /// by the derived types.
166    pub trait_ident: Ident2,
167
168    /// Identifier of the deserializer for this type.
169    pub deserializer_ident: Ident2,
170
171    /// List of additional traits that need to be implemented by the derived
172    /// types (if this type was inherited from another dynamic type).
173    pub sub_traits: Option<Vec<IdentPath>>,
174
175    /// List of derived types.
176    pub derived_types: Vec<DerivedType>,
177}
178
179/// Represents a derived type used by [`DynamicType`].
180#[derive(Debug)]
181pub struct DerivedType {
182    /// Identifier of the derived type.
183    pub ident: Ident,
184
185    /// Name of the derived type as byte string literal.
186    pub b_name: Literal,
187
188    /// The actual target type of this derived type information.
189    pub target_type: IdentPath,
190
191    /// Name of the variant used for this derived type information.
192    pub variant_ident: Ident2,
193}
194
195impl<'types> DynamicType<'types> {
196    fn new(info: &'types DynamicInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
197        let type_ident = req.current_type_ref().type_ident.clone();
198        let trait_ident = format_ident!("{type_ident}Trait");
199        let ident = req.ident.clone();
200        let sub_traits = req
201            .get_trait_infos()
202            .get(&ident)
203            .map(|info| info.traits_direct.clone())
204            .map(|traits_direct| {
205                traits_direct
206                    .iter()
207                    .map(|ident| {
208                        req.get_or_create_type_ref(ident.clone()).map(|x| {
209                            let ident = format_ident!("{}Trait", x.type_ident);
210
211                            x.to_ident_path().with_ident(ident)
212                        })
213                    })
214                    .collect::<Result<Vec<_>, _>>()
215            })
216            .transpose()?;
217        let derived_types = info
218            .derived_types
219            .iter()
220            .map(|ident| make_derived_type_data(&mut req, ident))
221            .collect::<Result<Vec<_>, _>>()?;
222
223        let deserializer_ident = format_ident!("{type_ident}Deserializer");
224
225        Ok(Self {
226            info,
227            type_ident,
228            trait_ident,
229            deserializer_ident,
230            sub_traits,
231            derived_types,
232        })
233    }
234}
235
236/// Contains additional information for the rendering process
237/// of a [`TypeVariant::Reference`] type.
238#[derive(Debug)]
239pub struct ReferenceType<'types> {
240    /// Reference to the original type information.
241    pub info: &'types ReferenceInfo,
242
243    /// Typedef mode that should be used to render this reference type.
244    pub mode: TypedefMode,
245
246    /// Occurrence of the referenced type within this type.
247    pub occurs: Occurs,
248
249    /// The identifier of the rendered type.
250    pub type_ident: Ident2,
251
252    /// Actual target type of this referenced type.
253    pub target_type: IdentPath,
254
255    /// List of traits that needs to be implemented by this type.
256    pub trait_impls: Vec<IdentPath>,
257}
258
259impl<'types> ReferenceType<'types> {
260    fn new(info: &'types ReferenceInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
261        let occurs = Occurs::from_occurs(info.min_occurs, info.max_occurs);
262        let type_ident = req.current_type_ref().type_ident.clone();
263        let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
264        let target_type = target_ref.to_ident_path();
265        let trait_impls = req.make_trait_impls()?;
266
267        let mode = match (req.typedef_mode, occurs) {
268            (TypedefMode::Auto, Occurs::None | Occurs::Single) => TypedefMode::Typedef,
269            (TypedefMode::Auto, _) => TypedefMode::NewType,
270            (mode, _) => mode,
271        };
272
273        Ok(Self {
274            info,
275            mode,
276            occurs,
277            type_ident,
278            target_type,
279            trait_impls,
280        })
281    }
282}
283
284/// Contains additional information for the rendering process
285/// of a [`TypeVariant::Enumeration`] type.
286#[derive(Debug)]
287pub struct EnumerationType<'types> {
288    /// Reference to the original type information.
289    pub info: &'types EnumerationInfo,
290
291    /// The identifier of the rendered type.
292    pub type_ident: Ident2,
293
294    /// List of variants of this enumeration.
295    pub variants: Vec<EnumerationTypeVariant<'types>>,
296
297    /// List of traits that needs to be implemented by this type.
298    pub trait_impls: Vec<IdentPath>,
299}
300
301/// Represents a enumeration variant used by [`EnumerationType`].
302#[derive(Debug)]
303pub struct EnumerationTypeVariant<'types> {
304    /// Reference to the original type information.
305    pub info: &'types VariantInfo,
306
307    /// Name of this variant.
308    pub variant_ident: Ident2,
309
310    /// Target type of this variant.
311    pub target_type: Option<IdentPath>,
312}
313
314impl<'types> EnumerationType<'types> {
315    fn new(info: &'types EnumerationInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
316        let mut unknown = 0usize;
317        let type_ident = req.current_type_ref().type_ident.clone();
318        let trait_impls = req.make_trait_impls()?;
319
320        let variants = info
321            .variants
322            .iter()
323            .filter_map(|var| var.make_variant(&mut unknown, &mut req))
324            .collect::<Result<Vec<_>, _>>()?;
325
326        Ok(EnumerationType {
327            info,
328            type_ident,
329            variants,
330            trait_impls,
331        })
332    }
333}
334
335impl VariantInfo {
336    fn make_variant<'types>(
337        &'types self,
338        unknown: &mut usize,
339        req: &mut Request<'_, 'types>,
340    ) -> Option<Result<EnumerationTypeVariant<'types>, Error>> {
341        match self.use_ {
342            Use::Prohibited => None,
343            Use::Required | Use::Optional => {
344                let type_ref = if let Some(t) = &self.type_ {
345                    match req.get_or_create_type_ref(t.clone()) {
346                        Ok(target_ref) => Some(target_ref),
347                        Err(error) => return Some(Err(error)),
348                    }
349                } else {
350                    None
351                };
352
353                let variant_ident = if let Some(display_name) = self.display_name.as_deref() {
354                    format_ident!("{display_name}")
355                } else if self.ident.name.as_str().is_empty() {
356                    *unknown += 1;
357
358                    format_ident!("Unknown{unknown}")
359                } else {
360                    format_variant_ident(&self.ident.name, self.display_name.as_deref())
361                };
362
363                let target_type = type_ref.map(TypeRef::to_ident_path);
364
365                Some(Ok(EnumerationTypeVariant {
366                    info: self,
367                    variant_ident,
368                    target_type,
369                }))
370            }
371        }
372    }
373}
374
375/// Contains additional information for the rendering process
376/// of a [`TypeVariant::All`], [`TypeVariant::Choice`],
377/// [`TypeVariant::Sequence`] or [`TypeVariant::ComplexType`] type.
378///
379/// To simplify the rendering process this recursive type was added to the
380/// generator. It basically boils down to the following:
381///
382///   - A complex type with a `choice` will result in a struct with a enum
383///     content type.
384///   - A complex type with a `all` or `sequence` will result in a struct
385///     with a struct content type.
386///   - A simple `choice` will result in a single enum type.
387///   - A simple `all` or `sequence` will result in a single sequence.
388///
389/// Additional improvements may be applied to the type, to reduce the complexity
390/// of the generated type (for example flattening the content if possible).
391#[derive(Debug)]
392pub enum ComplexType<'types> {
393    /// The type represents an enumeration.
394    ///
395    /// This is normally used for `choice` elements.
396    Enum {
397        /// The main type.
398        type_: ComplexTypeEnum<'types>,
399
400        /// The content of the main type (if needed).
401        content_type: Option<Box<ComplexType<'types>>>,
402    },
403
404    /// The type represents a struct.
405    ///
406    /// This is normally used for `all`
407    Struct {
408        /// The main type.
409        type_: ComplexTypeStruct<'types>,
410
411        /// The content of the main type (if needed).
412        content_type: Option<Box<ComplexType<'types>>>,
413    },
414}
415
416/// Contains basic information for that is shared between [`ComplexTypeEnum`]
417/// and [`ComplexTypeStruct`].
418#[derive(Debug)]
419pub struct ComplexTypeBase {
420    /// The identifier of the rendered type.
421    pub type_ident: Ident2,
422
423    /// List of traits that needs to be implemented by this type.
424    pub trait_impls: Vec<IdentPath>,
425
426    /// Name of the XML tag of the type (if the type represents an element in the XML).
427    pub tag_name: Option<String>,
428
429    /// `true` if the type is a complex type, `false` otherwise.
430    pub is_complex: bool,
431
432    /// `true` if the type is dynamic, `false` otherwise.
433    pub is_dynamic: bool,
434
435    /// Identifier of the serializer for this type.
436    pub serializer_ident: Ident2,
437
438    /// Identifier of the state of the serializer for this type.
439    pub serializer_state_ident: Ident2,
440
441    /// Identifier of the deserializer for this type.
442    pub deserializer_ident: Ident2,
443
444    /// Identifier of the state of the deserializer for this type.
445    pub deserializer_state_ident: Ident2,
446}
447
448/// Represents a rust enum.
449///
450/// Is used as part of the [`ComplexType`].
451#[derive(Debug)]
452pub struct ComplexTypeEnum<'types> {
453    /// Basic type information.
454    pub base: ComplexTypeBase,
455
456    /// List of `xs:element`s or variants contained in this enum
457    pub elements: Vec<ComplexTypeElement<'types>>,
458
459    /// Content of the `xs:any`.
460    pub any_element: Option<&'types AnyInfo>,
461
462    /// Content of the `xs:anyAttribute`.
463    pub any_attribute: Option<&'types AnyAttributeInfo>,
464}
465
466/// Represents a rust struct.
467///
468/// Is used as part of the [`ComplexType`].
469#[derive(Debug)]
470pub struct ComplexTypeStruct<'types> {
471    /// Basic type information.
472    pub base: ComplexTypeBase,
473
474    /// Additional information about the content of the struct.
475    pub mode: StructMode<'types>,
476
477    /// List of `xs:attribute`s contained in this struct.
478    pub attributes: Vec<ComplexTypeAttribute<'types>>,
479
480    /// Content of the `xs:anyAttribute`.
481    pub any_attribute: Option<&'types AnyAttributeInfo>,
482}
483
484/// Content of a rust struct.
485///
486/// Used by [`ComplexTypeStruct`] to tell how the actual content of the struct
487/// should be rendered.
488#[derive(Debug)]
489pub enum StructMode<'types> {
490    /// The struct does not contain any `xs:element`s.
491    Empty {
492        /// Content of the `xs:any`.
493        any_element: Option<&'types AnyInfo>,
494    },
495
496    /// The content of the struct is another generated type that contains
497    /// the actual data.
498    Content {
499        /// Information about the content of the struct.
500        content: ComplexTypeContent,
501    },
502
503    /// The content of the struct is a `xs:all` group.
504    All {
505        /// List of `xs:element`s inside the group.
506        elements: Vec<ComplexTypeElement<'types>>,
507
508        /// Content of the `xs:any`.
509        any_element: Option<&'types AnyInfo>,
510    },
511
512    /// The content of the struct is a `xs:sequence` group.
513    Sequence {
514        /// List of `xs:element`s inside the group.
515        elements: Vec<ComplexTypeElement<'types>>,
516
517        /// Content of the `xs:any`.
518        any_element: Option<&'types AnyInfo>,
519    },
520}
521
522/// Contains details about the content of a struct.
523///
524/// Is used by [`StructMode`] to define the content of a struct.
525#[derive(Debug)]
526pub struct ComplexTypeContent {
527    /// Occurrence of the content within this struct.
528    pub occurs: Occurs,
529
530    /// `true` if the content is a simple type (e.g. a enum, union, string,
531    /// integer, ...), `false` otherwise.
532    pub is_simple: bool,
533
534    /// Minimum occurrence.
535    pub min_occurs: MinOccurs,
536
537    /// Maximum occurrence.
538    pub max_occurs: MaxOccurs,
539
540    /// Actual target type of the content.
541    pub target_type: IdentPath,
542}
543
544/// Contains the details of an XML element.
545///
546/// Is used in [`ComplexTypeEnum`] or [`StructMode`].
547#[derive(Debug)]
548pub struct ComplexTypeElement<'types> {
549    /// Reference to the original type information.
550    pub info: &'types ElementInfo,
551
552    /// Occurrence of the element within it's parent type.
553    pub occurs: Occurs,
554
555    /// Name of the element as string.
556    pub s_name: String,
557
558    /// Name of the element as byte string literal.
559    pub b_name: Literal,
560
561    /// Name of the XML tag of the element.
562    pub tag_name: String,
563
564    /// Field identifier of the element.
565    pub field_ident: Ident2,
566
567    /// Variant identifier of the element.
568    pub variant_ident: Ident2,
569
570    /// Actual target type of the element.
571    pub target_type: IdentPath,
572
573    /// `true` if this element needs some indirection
574    /// (like a `Box` or a `Vec`), `false` otherwise.
575    pub need_indirection: bool,
576
577    /// `true` if the target type of this element is dynamic,
578    /// `false` otherwise.
579    pub target_is_dynamic: bool,
580}
581
582/// Contains the details of an XML attribute.
583///
584/// Is used in [`ComplexTypeStruct`].
585#[derive(Debug)]
586pub struct ComplexTypeAttribute<'types> {
587    /// Reference to the original type information.
588    pub info: &'types AttributeInfo,
589
590    /// Identifier of the attribute.
591    pub ident: Ident2,
592
593    /// Name of the attribute as string.
594    pub s_name: String,
595
596    /// Name of the attribute as byte string literal.
597    pub b_name: Literal,
598
599    /// Name of the attribute inside the XML tag.
600    pub tag_name: String,
601
602    /// `true` if this attribute is optional, `false` otherwise.
603    pub is_option: bool,
604
605    /// The actual target type of the attribute.
606    pub target_type: IdentPath,
607
608    /// The default value of the attribute.
609    pub default_value: Option<TokenStream>,
610}
611
612#[derive(Debug, Clone)]
613enum TypeMode {
614    All,
615    Choice,
616    Sequence,
617    Simple { target_type: IdentPath },
618}
619
620impl<'types> ComplexType<'types> {
621    fn new_all(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
622        Self::new(
623            req,
624            TypeMode::All,
625            1,
626            MaxOccurs::Bounded(1),
627            &[],
628            None,
629            &info.elements,
630            info.any.as_ref(),
631        )
632    }
633
634    fn new_choice(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
635        Self::new(
636            req,
637            TypeMode::Choice,
638            1,
639            MaxOccurs::Bounded(1),
640            &[],
641            None,
642            &info.elements,
643            info.any.as_ref(),
644        )
645    }
646
647    fn new_sequence(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
648        Self::new(
649            req,
650            TypeMode::Sequence,
651            1,
652            MaxOccurs::Bounded(1),
653            &[],
654            None,
655            &info.elements,
656            info.any.as_ref(),
657        )
658    }
659
660    fn new_complex(info: &'types ComplexInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
661        let (type_mode, elements, any_element) = match info.content.as_ref().and_then(|ident| {
662            req.types
663                .get_resolved_type(ident)
664                .map(|ty| (&ty.variant, ident))
665        }) {
666            None => (TypeMode::Sequence, &[][..], None),
667            Some((TypeVariant::All(si), _)) => (TypeMode::All, &si.elements[..], si.any.as_ref()),
668            Some((TypeVariant::Choice(si), _)) => {
669                (TypeMode::Choice, &si.elements[..], si.any.as_ref())
670            }
671            Some((TypeVariant::Sequence(si), _)) => {
672                (TypeMode::Sequence, &si.elements[..], si.any.as_ref())
673            }
674            Some((
675                TypeVariant::BuildIn(_)
676                | TypeVariant::Union(_)
677                | TypeVariant::Enumeration(_)
678                | TypeVariant::Reference(_),
679                ident,
680            )) => {
681                let content_ref = req.get_or_create_type_ref(ident.clone())?;
682                let target_type = content_ref.to_ident_path();
683
684                (TypeMode::Simple { target_type }, &[][..], None)
685            }
686            Some((x, _)) => {
687                let ident = &req.current_type_ref().type_ident;
688
689                tracing::warn!("Complex type has unexpected content: ident={ident}, info={info:#?}, content={x:#?}!");
690
691                (TypeMode::Sequence, &[][..], None)
692            }
693        };
694
695        Self::new(
696            req,
697            type_mode,
698            info.min_occurs,
699            info.max_occurs,
700            &info.attributes,
701            info.any_attribute.as_ref(),
702            elements,
703            any_element,
704        )
705    }
706
707    #[allow(clippy::too_many_arguments)]
708    fn new(
709        req: Request<'_, 'types>,
710        type_mode: TypeMode,
711        min_occurs: MinOccurs,
712        max_occurs: MaxOccurs,
713        attributes: &'types [AttributeInfo],
714        any_attribute: Option<&'types AnyAttributeInfo>,
715        elements: &'types [ElementInfo],
716        any_element: Option<&'types AnyInfo>,
717    ) -> Result<Self, Error> {
718        match type_mode {
719            TypeMode::Simple { target_type } => Self::new_simple(
720                req,
721                target_type,
722                min_occurs,
723                max_occurs,
724                attributes,
725                any_attribute,
726            ),
727            TypeMode::Choice => Self::new_enum(
728                req,
729                min_occurs,
730                max_occurs,
731                attributes,
732                any_attribute,
733                elements,
734                any_element,
735            ),
736            TypeMode::All | TypeMode::Sequence => Self::new_struct(
737                req,
738                &type_mode,
739                min_occurs,
740                max_occurs,
741                attributes,
742                any_attribute,
743                elements,
744                any_element,
745            ),
746        }
747    }
748
749    fn new_simple(
750        mut req: Request<'_, 'types>,
751        target_type: IdentPath,
752        min_occurs: MinOccurs,
753        max_occurs: MaxOccurs,
754        attributes: &'types [AttributeInfo],
755        any_attribute: Option<&'types AnyAttributeInfo>,
756    ) -> Result<Self, Error> {
757        let base = ComplexTypeBase::new(&mut req)?;
758        let occurs = Occurs::from_occurs(min_occurs, max_occurs);
759        let attributes = attributes
760            .iter()
761            .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
762            .collect::<Result<Vec<_>, _>>()?;
763
764        let content = ComplexTypeContent {
765            occurs,
766            is_simple: true,
767            min_occurs,
768            max_occurs,
769            target_type,
770        };
771        let type_ = ComplexTypeStruct {
772            base,
773
774            mode: StructMode::Content { content },
775
776            attributes,
777            any_attribute,
778        };
779
780        Ok(Self::Struct {
781            type_,
782            content_type: None,
783        })
784    }
785
786    fn new_enum(
787        mut req: Request<'_, 'types>,
788        min_occurs: MinOccurs,
789        max_occurs: MaxOccurs,
790        attributes: &'types [AttributeInfo],
791        any_attribute: Option<&'types AnyAttributeInfo>,
792        elements: &'types [ElementInfo],
793        any_element: Option<&'types AnyInfo>,
794    ) -> Result<Self, Error> {
795        let base = ComplexTypeBase::new(&mut req)?;
796        let occurs = Occurs::from_occurs(min_occurs, max_occurs);
797        let flatten = occurs == Occurs::Single
798            && attributes.is_empty()
799            && req.check_flags(GeneratorFlags::FLATTEN_ENUM_CONTENT);
800
801        let attributes = attributes
802            .iter()
803            .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
804            .collect::<Result<Vec<_>, _>>()?;
805
806        let mut any_element = any_element;
807        let mut elements = elements
808            .iter()
809            .filter_map(|info| {
810                ComplexTypeElement::new_variant(info, &mut req, occurs.is_direct()).transpose()
811            })
812            .collect::<Result<Vec<_>, _>>()?;
813
814        if flatten {
815            let type_ = ComplexTypeEnum {
816                base,
817                elements,
818                any_element,
819                any_attribute,
820            };
821
822            return Ok(ComplexType::Enum {
823                type_,
824                content_type: None,
825            });
826        }
827
828        let type_ident = &base.type_ident;
829        let content_ident = format_ident!("{type_ident}Content");
830        let has_content = occurs.is_some() && !elements.is_empty();
831
832        let content_type = has_content.then(|| {
833            let type_ = ComplexTypeEnum {
834                base: ComplexTypeBase::new_empty(content_ident.clone()),
835                elements: take(&mut elements),
836                any_element: any_element.take(),
837                any_attribute: None,
838            };
839
840            Box::new(ComplexType::Enum {
841                type_,
842                content_type: None,
843            })
844        });
845
846        let mode = if has_content {
847            let type_ref = req.current_type_ref();
848            let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
849            let content = ComplexTypeContent {
850                occurs,
851                is_simple: false,
852                min_occurs,
853                max_occurs,
854                target_type,
855            };
856
857            StructMode::Content { content }
858        } else {
859            StructMode::Empty { any_element }
860        };
861
862        let type_ = ComplexTypeStruct {
863            base,
864            mode,
865
866            attributes,
867            any_attribute,
868        };
869
870        Ok(ComplexType::Struct {
871            type_,
872            content_type,
873        })
874    }
875
876    #[allow(clippy::too_many_arguments)]
877    fn new_struct(
878        mut req: Request<'_, 'types>,
879        type_mode: &TypeMode,
880        min_occurs: MinOccurs,
881        max_occurs: MaxOccurs,
882        attributes: &'types [AttributeInfo],
883        any_attribute: Option<&'types AnyAttributeInfo>,
884        elements: &'types [ElementInfo],
885        any_element: Option<&'types AnyInfo>,
886    ) -> Result<Self, Error> {
887        let base = ComplexTypeBase::new(&mut req)?;
888        let occurs = Occurs::from_occurs(min_occurs, max_occurs);
889        let flatten =
890            occurs == Occurs::Single && req.check_flags(GeneratorFlags::FLATTEN_STRUCT_CONTENT);
891
892        let attributes = attributes
893            .iter()
894            .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
895            .collect::<Result<Vec<_>, _>>()?;
896
897        let elements = elements
898            .iter()
899            .filter_map(|info| {
900                ComplexTypeElement::new_field(info, &mut req, occurs.is_direct()).transpose()
901            })
902            .collect::<Result<Vec<_>, _>>()?;
903
904        if flatten {
905            let mode = match type_mode {
906                _ if elements.is_empty() => StructMode::Empty { any_element },
907                TypeMode::All => StructMode::All {
908                    elements,
909                    any_element,
910                },
911                TypeMode::Sequence => StructMode::Sequence {
912                    elements,
913                    any_element,
914                },
915                _ => crate::unreachable!(),
916            };
917
918            let type_ = ComplexTypeStruct {
919                base,
920                mode,
921
922                attributes,
923                any_attribute,
924            };
925
926            return Ok(ComplexType::Struct {
927                type_,
928                content_type: None,
929            });
930        }
931
932        let type_ident = &base.type_ident;
933        let content_ident = format_ident!("{type_ident}Content");
934        let has_content = occurs.is_some() && !elements.is_empty();
935
936        let content_type = has_content.then(|| {
937            let mode = match type_mode {
938                TypeMode::All => StructMode::All {
939                    elements,
940                    any_element,
941                },
942                TypeMode::Sequence => StructMode::Sequence {
943                    elements,
944                    any_element,
945                },
946                _ => crate::unreachable!(),
947            };
948
949            let type_ = ComplexTypeStruct {
950                base: ComplexTypeBase::new_empty(content_ident.clone()),
951                mode,
952
953                attributes: Vec::new(),
954                any_attribute: None,
955            };
956
957            Box::new(ComplexType::Struct {
958                type_,
959                content_type: None,
960            })
961        });
962
963        let mode = if has_content {
964            let type_ref = req.current_type_ref();
965            let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
966            let content = ComplexTypeContent {
967                occurs,
968                is_simple: false,
969                min_occurs,
970                max_occurs,
971                target_type,
972            };
973
974            StructMode::Content { content }
975        } else {
976            StructMode::Empty { any_element }
977        };
978
979        let type_ = ComplexTypeStruct {
980            base,
981            mode,
982
983            attributes,
984            any_attribute,
985        };
986
987        Ok(ComplexType::Struct {
988            type_,
989            content_type,
990        })
991    }
992}
993
994impl ComplexTypeBase {
995    pub(super) fn element_tag(&self) -> Option<&String> {
996        self.is_complex.then_some(self.tag_name.as_ref()).flatten()
997    }
998
999    pub(crate) fn represents_element(&self) -> bool {
1000        self.is_complex && self.tag_name.is_some() && !self.is_dynamic
1001    }
1002
1003    fn new(req: &mut Request<'_, '_>) -> Result<Self, Error> {
1004        let type_ref = req.current_type_ref();
1005        let type_ident = type_ref.type_ident.clone();
1006
1007        let mut ret = Self::new_empty(type_ident);
1008        ret.tag_name = Some(make_tag_name(req.types, req.ident));
1009        ret.trait_impls = req.make_trait_impls()?;
1010
1011        if let Some(TypeVariant::ComplexType(ci)) = req.types.get_variant(req.ident) {
1012            ret.is_complex = true;
1013            ret.is_dynamic = ci.is_dynamic;
1014        }
1015
1016        Ok(ret)
1017    }
1018
1019    fn new_empty(type_ident: Ident2) -> Self {
1020        let serializer_ident = format_ident!("{type_ident}Serializer");
1021        let serializer_state_ident = format_ident!("{type_ident}SerializerState");
1022
1023        let deserializer_ident = format_ident!("{type_ident}Deserializer");
1024        let deserializer_state_ident = format_ident!("{type_ident}DeserializerState");
1025
1026        Self {
1027            type_ident,
1028            trait_impls: Vec::new(),
1029
1030            tag_name: None,
1031            is_complex: false,
1032            is_dynamic: false,
1033
1034            serializer_ident,
1035            serializer_state_ident,
1036
1037            deserializer_ident,
1038            deserializer_state_ident,
1039        }
1040    }
1041}
1042
1043impl Deref for ComplexTypeEnum<'_> {
1044    type Target = ComplexTypeBase;
1045
1046    fn deref(&self) -> &Self::Target {
1047        &self.base
1048    }
1049}
1050
1051impl ComplexTypeStruct<'_> {
1052    pub(super) fn is_unit_struct(&self) -> bool {
1053        matches!(&self.mode, StructMode::Empty { .. }) && !self.has_attributes()
1054    }
1055
1056    pub(super) fn has_attributes(&self) -> bool {
1057        !self.attributes.is_empty()
1058    }
1059
1060    pub(super) fn has_content(&self) -> bool {
1061        match &self.mode {
1062            StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } => {
1063                !elements.is_empty()
1064            }
1065            StructMode::Content { .. } => true,
1066            StructMode::Empty { .. } => false,
1067        }
1068    }
1069
1070    pub(super) fn elements(&self) -> &[ComplexTypeElement<'_>] {
1071        if let StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } = &self.mode
1072        {
1073            elements
1074        } else {
1075            &[]
1076        }
1077    }
1078
1079    pub(super) fn any_element(&self) -> Option<&AnyInfo> {
1080        if let StructMode::All { any_element, .. } | StructMode::Sequence { any_element, .. } =
1081            &self.mode
1082        {
1083            *any_element
1084        } else {
1085            None
1086        }
1087    }
1088
1089    pub(super) fn content(&self) -> Option<&ComplexTypeContent> {
1090        if let StructMode::Content { content, .. } = &self.mode {
1091            Some(content)
1092        } else {
1093            None
1094        }
1095    }
1096}
1097
1098impl Deref for ComplexTypeStruct<'_> {
1099    type Target = ComplexTypeBase;
1100
1101    fn deref(&self) -> &Self::Target {
1102        &self.base
1103    }
1104}
1105
1106impl<'types> ComplexTypeElement<'types> {
1107    fn new_variant(
1108        info: &'types ElementInfo,
1109        req: &mut Request<'_, 'types>,
1110        direct_usage: bool,
1111    ) -> Result<Option<Self>, Error> {
1112        let force_box = req.box_flags.intersects(BoxFlags::ENUM_ELEMENTS);
1113
1114        Self::new(info, req, direct_usage, force_box)
1115    }
1116
1117    fn new_field(
1118        info: &'types ElementInfo,
1119        req: &mut Request<'_, 'types>,
1120        direct_usage: bool,
1121    ) -> Result<Option<Self>, Error> {
1122        let force_box = req.box_flags.intersects(BoxFlags::STRUCT_ELEMENTS);
1123
1124        Self::new(info, req, direct_usage, force_box)
1125    }
1126
1127    fn new(
1128        info: &'types ElementInfo,
1129        req: &mut Request<'_, 'types>,
1130        direct_usage: bool,
1131        force_box: bool,
1132    ) -> Result<Option<Self>, Error> {
1133        let occurs = Occurs::from_occurs(info.min_occurs, info.max_occurs);
1134        if occurs == Occurs::None {
1135            return Ok(None);
1136        }
1137
1138        let tag_name = make_tag_name(req.types, &info.ident);
1139        let s_name = info.ident.name.to_string();
1140        let b_name = Literal::byte_string(s_name.as_bytes());
1141        let field_ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1142        let variant_ident = format_variant_ident(&info.ident.name, info.display_name.as_deref());
1143
1144        let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1145        let target_type = target_ref.to_ident_path();
1146
1147        let need_box = req.current_type_ref().boxed_elements.contains(&info.ident);
1148        let need_indirection = (direct_usage && need_box) || force_box;
1149        let target_is_dynamic = is_dynamic(&info.type_, req.types);
1150
1151        Ok(Some(Self {
1152            info,
1153            occurs,
1154            s_name,
1155            b_name,
1156            tag_name,
1157            field_ident,
1158            variant_ident,
1159            target_type,
1160            need_indirection,
1161            target_is_dynamic,
1162        }))
1163    }
1164}
1165
1166impl<'types> ComplexTypeAttribute<'types> {
1167    fn new_field(
1168        info: &'types AttributeInfo,
1169        req: &mut Request<'_, 'types>,
1170    ) -> Result<Option<Self>, Error> {
1171        if info.use_ == Use::Prohibited {
1172            return Ok(None);
1173        }
1174
1175        let current_module = req.current_module();
1176        let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1177        let ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1178        let target_type = target_ref.to_ident_path();
1179        let s_name = info.ident.name.to_string();
1180        let b_name = Literal::byte_string(s_name.as_bytes());
1181        let tag_name = make_tag_name(req.types, &info.ident);
1182
1183        let default_value = info
1184            .default
1185            .as_ref()
1186            .map(|default| req.get_default(current_module, default, &info.type_))
1187            .transpose()?;
1188        let is_option = matches!((&info.use_, &default_value), (Use::Optional, None));
1189
1190        Ok(Some(Self {
1191            info,
1192            ident,
1193            s_name,
1194            b_name,
1195            tag_name,
1196            is_option,
1197            target_type,
1198            default_value,
1199        }))
1200    }
1201}
1202
1203/* Request */
1204
1205/// Helper type that is used to request the code generation for a specific type.
1206struct Request<'a, 'types> {
1207    pub ident: &'a Ident,
1208    pub config: &'a Config<'types>,
1209
1210    state: &'a mut State<'types>,
1211}
1212
1213impl<'a, 'types> Request<'a, 'types> {
1214    fn new(ident: &'a Ident, config: &'a Config<'types>, state: &'a mut State<'types>) -> Self {
1215        Self {
1216            ident,
1217            config,
1218            state,
1219        }
1220    }
1221
1222    fn current_module(&self) -> Option<NamespaceId> {
1223        self.check_flags(GeneratorFlags::USE_MODULES)
1224            .then_some(self.ident.ns)
1225            .flatten()
1226    }
1227
1228    fn current_type_ref(&self) -> &TypeRef {
1229        self.state.cache.get(self.ident).unwrap()
1230    }
1231
1232    fn get_trait_infos(&mut self) -> &TraitInfos {
1233        self.state
1234            .trait_infos
1235            .get_or_insert_with(|| TraitInfos::new(self.config.types))
1236    }
1237
1238    fn get_or_create_type_ref(&mut self, ident: Ident) -> Result<&TypeRef, Error> {
1239        self.state.get_or_create_type_ref(self.config, ident)
1240    }
1241
1242    fn make_trait_impls(&mut self) -> Result<Vec<IdentPath>, Error> {
1243        let ident = self.ident.clone();
1244
1245        self.get_trait_infos()
1246            .get(&ident)
1247            .into_iter()
1248            .flat_map(|info| &info.traits_all)
1249            .cloned()
1250            .collect::<Vec<_>>()
1251            .into_iter()
1252            .map(|ident| {
1253                let type_ref = self.get_or_create_type_ref(ident.clone())?;
1254                let ident = format_ident!("{}Trait", type_ref.type_ident);
1255                let trait_type = type_ref.to_ident_path().with_ident(ident);
1256
1257                Ok(trait_type)
1258            })
1259            .collect::<Result<Vec<_>, _>>()
1260    }
1261
1262    fn get_default(
1263        &mut self,
1264        current_ns: Option<NamespaceId>,
1265        default: &str,
1266        ident: &Ident,
1267    ) -> Result<TokenStream, Error> {
1268        let types = self.types;
1269        let ty = types
1270            .get(ident)
1271            .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1272        let type_ref = self.get_or_create_type_ref(ident.clone())?;
1273
1274        macro_rules! build_in {
1275            ($ty:ty) => {
1276                if let Ok(val) = default.parse::<$ty>() {
1277                    return Ok(quote!(#val));
1278                }
1279            };
1280        }
1281
1282        match &ty.variant {
1283            TypeVariant::BuildIn(BuildInInfo::U8) => build_in!(u8),
1284            TypeVariant::BuildIn(BuildInInfo::U16) => build_in!(u16),
1285            TypeVariant::BuildIn(BuildInInfo::U32) => build_in!(u32),
1286            TypeVariant::BuildIn(BuildInInfo::U64) => build_in!(u64),
1287            TypeVariant::BuildIn(BuildInInfo::U128) => build_in!(u128),
1288            TypeVariant::BuildIn(BuildInInfo::Usize) => build_in!(usize),
1289
1290            TypeVariant::BuildIn(BuildInInfo::I8) => build_in!(i8),
1291            TypeVariant::BuildIn(BuildInInfo::I16) => build_in!(i16),
1292            TypeVariant::BuildIn(BuildInInfo::I32) => build_in!(i32),
1293            TypeVariant::BuildIn(BuildInInfo::I64) => build_in!(i64),
1294            TypeVariant::BuildIn(BuildInInfo::I128) => build_in!(i128),
1295            TypeVariant::BuildIn(BuildInInfo::Isize) => build_in!(isize),
1296
1297            TypeVariant::BuildIn(BuildInInfo::F32) => build_in!(f32),
1298            TypeVariant::BuildIn(BuildInInfo::F64) => build_in!(f64),
1299
1300            TypeVariant::BuildIn(BuildInInfo::Bool) => {
1301                match default.to_ascii_lowercase().as_str() {
1302                    "true" | "yes" | "1" => return Ok(quote!(true)),
1303                    "false" | "no" | "0" => return Ok(quote!(false)),
1304                    _ => (),
1305                }
1306            }
1307            TypeVariant::BuildIn(BuildInInfo::String) => {
1308                return Ok(quote!(String::from(#default)));
1309            }
1310            TypeVariant::BuildIn(BuildInInfo::Custom(x)) => {
1311                if let Some(x) = x.default(default) {
1312                    return Ok(x);
1313                }
1314            }
1315
1316            TypeVariant::Enumeration(ei) => {
1317                let module_path = ModulePath::from_namespace(current_ns, types);
1318                let target_type = type_ref.to_ident_path().relative_to(&module_path);
1319
1320                for var in &*ei.variants {
1321                    if var.type_.is_none() && var.ident.name.as_str() == default {
1322                        let variant_ident =
1323                            format_variant_ident(&var.ident.name, var.display_name.as_deref());
1324
1325                        return Ok(quote!(#target_type :: #variant_ident));
1326                    }
1327
1328                    if let Some(target_ident) = &var.type_ {
1329                        if let Ok(default) = self.get_default(current_ns, default, target_ident) {
1330                            let variant_ident =
1331                                format_variant_ident(&var.ident.name, var.display_name.as_deref());
1332
1333                            return Ok(quote!(#target_type :: #variant_ident(#default)));
1334                        }
1335                    }
1336                }
1337            }
1338
1339            TypeVariant::Union(ui) => {
1340                let module_path = ModulePath::from_namespace(current_ns, types);
1341                let target_type = type_ref.to_ident_path().relative_to(&module_path);
1342
1343                for ty in &*ui.types {
1344                    if let Ok(code) = self.get_default(current_ns, default, &ty.type_) {
1345                        let variant_ident =
1346                            format_variant_ident(&ty.type_.name, ty.display_name.as_deref());
1347
1348                        return Ok(quote! {
1349                            #target_type :: #variant_ident ( #code )
1350                        });
1351                    }
1352                }
1353            }
1354
1355            TypeVariant::Reference(ti) => match Occurs::from_occurs(ti.min_occurs, ti.max_occurs) {
1356                Occurs::Single => return self.get_default(current_ns, default, &ti.type_),
1357                Occurs::DynamicList if default.is_empty() => {
1358                    let module_path = ModulePath::from_namespace(current_ns, types);
1359                    let target_type = type_ref.to_ident_path().relative_to(&module_path);
1360
1361                    return Ok(quote! { #target_type(Vec::new()) });
1362                }
1363                _ => (),
1364            },
1365
1366            _ => (),
1367        }
1368
1369        Err(Error::InvalidDefaultValue(
1370            ident.clone(),
1371            default.to_owned(),
1372        ))
1373    }
1374}
1375
1376impl<'types> Deref for Request<'_, 'types> {
1377    type Target = Config<'types>;
1378
1379    fn deref(&self) -> &Self::Target {
1380        self.config
1381    }
1382}
1383
1384/* Helper */
1385
1386fn is_dynamic(ident: &Ident, types: &Types) -> bool {
1387    let Some(ty) = types.get(ident) else {
1388        return false;
1389    };
1390
1391    match &ty.variant {
1392        TypeVariant::Dynamic(_) => true,
1393        TypeVariant::ComplexType(ci) => ci.is_dynamic,
1394        TypeVariant::Reference(x) if x.is_single() => is_dynamic(&x.type_, types),
1395        _ => false,
1396    }
1397}
1398
1399fn make_tag_name(types: &Types, ident: &Ident) -> String {
1400    let name = ident.name.to_string();
1401
1402    if let Some(module) = ident
1403        .ns
1404        .as_ref()
1405        .and_then(|ns| types.modules.get(ns))
1406        .and_then(|module| module.name.as_ref())
1407    {
1408        format!("{module}:{name}")
1409    } else {
1410        name
1411    }
1412}
1413
1414fn make_derived_type_data<'types>(
1415    req: &mut Request<'_, 'types>,
1416    ident: &'types Ident,
1417) -> Result<DerivedType, Error> {
1418    let s_name = ident.name.to_string();
1419    let b_name = Literal::byte_string(s_name.as_bytes());
1420
1421    let ty = req
1422        .types
1423        .get(ident)
1424        .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1425    let base_ident = if let TypeVariant::Dynamic(di) = &ty.variant {
1426        di.type_.clone()
1427    } else {
1428        None
1429    };
1430    let ident = base_ident.unwrap_or(ident.clone());
1431
1432    let target_ref = req.get_or_create_type_ref(ident.clone())?;
1433    let target_type = target_ref.to_ident_path();
1434    let variant_ident = format_variant_ident(&ident.name, None);
1435
1436    Ok(DerivedType {
1437        ident,
1438        b_name,
1439        target_type,
1440        variant_ident,
1441    })
1442}