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<TokenStream>,
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<TokenStream>,
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<TokenStream>,
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 let (Some(type_ref), true) = (type_ref, self.ident.name.is_generated()) {
356                    type_ref.type_ident.clone()
357                } else if self.ident.name.as_str().is_empty() {
358                    *unknown += 1;
359
360                    format_ident!("Unknown{unknown}")
361                } else {
362                    format_variant_ident(&self.ident.name, self.display_name.as_deref())
363                };
364
365                let target_type = type_ref.map(TypeRef::to_ident_path);
366
367                Some(Ok(EnumerationTypeVariant {
368                    info: self,
369                    variant_ident,
370                    target_type,
371                }))
372            }
373        }
374    }
375}
376
377/// Contains additional information for the rendering process
378/// of a [`TypeVariant::All`], [`TypeVariant::Choice`],
379/// [`TypeVariant::Sequence`] or [`TypeVariant::ComplexType`] type.
380///
381/// To simplify the rendering process this recursive type was added to the
382/// generator. It basically boils down to the following:
383///
384///   - A complex type with a `choice` will result in a struct with a enum
385///     content type.
386///   - A complex type with a `all` or `sequence` will result in a struct
387///     with a struct content type.
388///   - A simple `choice` will result in a single enum type.
389///   - A simple `all` or `sequence` will result in a single sequence.
390///
391/// Additional improvements may be applied to the type, to reduce the complexity
392/// of the generated type (for example flattening the content if possible).
393#[derive(Debug)]
394pub enum ComplexType<'types> {
395    /// The type represents an enumeration.
396    ///
397    /// This is normally used for `choice` elements.
398    Enum {
399        /// The main type.
400        type_: ComplexTypeEnum<'types>,
401
402        /// The content of the main type (if needed).
403        content_type: Option<Box<ComplexType<'types>>>,
404    },
405
406    /// The type represents a struct.
407    ///
408    /// This is normally used for `all`
409    Struct {
410        /// The main type.
411        type_: ComplexTypeStruct<'types>,
412
413        /// The content of the main type (if needed).
414        content_type: Option<Box<ComplexType<'types>>>,
415    },
416}
417
418/// Contains basic information for that is shared between [`ComplexTypeEnum`]
419/// and [`ComplexTypeStruct`].
420#[derive(Debug)]
421pub struct ComplexTypeBase {
422    /// The identifier of the rendered type.
423    pub type_ident: Ident2,
424
425    /// List of traits that needs to be implemented by this type.
426    pub trait_impls: Vec<TokenStream>,
427
428    /// Name of the XML tag of the type (if the type represents an element in the XML).
429    pub tag_name: Option<String>,
430
431    /// `true` if the type is a complex type, `false` otherwise.
432    pub is_complex: bool,
433
434    /// `true` if the type is dynamic, `false` otherwise.
435    pub is_dynamic: bool,
436
437    /// Identifier of the serializer for this type.
438    pub serializer_ident: Ident2,
439
440    /// Identifier of the state of the serializer for this type.
441    pub serializer_state_ident: Ident2,
442
443    /// Identifier of the deserializer for this type.
444    pub deserializer_ident: Ident2,
445
446    /// Identifier of the state of the deserializer for this type.
447    pub deserializer_state_ident: Ident2,
448}
449
450/// Represents a rust enum.
451///
452/// Is used as part of the [`ComplexType`].
453#[derive(Debug)]
454pub struct ComplexTypeEnum<'types> {
455    /// Basic type information.
456    pub base: ComplexTypeBase,
457
458    /// List of `xs:element`s or variants contained in this enum
459    pub elements: Vec<ComplexTypeElement<'types>>,
460
461    /// Content of the `xs:any`.
462    pub any_element: Option<&'types AnyInfo>,
463
464    /// Content of the `xs:anyAttribute`.
465    pub any_attribute: Option<&'types AnyAttributeInfo>,
466}
467
468/// Represents a rust struct.
469///
470/// Is used as part of the [`ComplexType`].
471#[derive(Debug)]
472pub struct ComplexTypeStruct<'types> {
473    /// Basic type information.
474    pub base: ComplexTypeBase,
475
476    /// Additional information about the content of the struct.
477    pub mode: StructMode<'types>,
478
479    /// List of `xs:attribute`s contained in this struct.
480    pub attributes: Vec<ComplexTypeAttribute<'types>>,
481
482    /// Content of the `xs:anyAttribute`.
483    pub any_attribute: Option<&'types AnyAttributeInfo>,
484}
485
486/// Content of a rust struct.
487///
488/// Used by [`ComplexTypeStruct`] to tell how the actual content of the struct
489/// should be rendered.
490#[derive(Debug)]
491pub enum StructMode<'types> {
492    /// The struct does not contain any `xs:element`s.
493    Empty {
494        /// Content of the `xs:any`.
495        any_element: Option<&'types AnyInfo>,
496    },
497
498    /// The content of the struct is another generated type that contains
499    /// the actual data.
500    Content {
501        /// Information about the content of the struct.
502        content: ComplexTypeContent,
503    },
504
505    /// The content of the struct is a `xs:all` group.
506    All {
507        /// List of `xs:element`s inside the group.
508        elements: Vec<ComplexTypeElement<'types>>,
509
510        /// Content of the `xs:any`.
511        any_element: Option<&'types AnyInfo>,
512    },
513
514    /// The content of the struct is a `xs:sequence` group.
515    Sequence {
516        /// List of `xs:element`s inside the group.
517        elements: Vec<ComplexTypeElement<'types>>,
518
519        /// Content of the `xs:any`.
520        any_element: Option<&'types AnyInfo>,
521    },
522}
523
524/// Contains details about the content of a struct.
525///
526/// Is used by [`StructMode`] to define the content of a struct.
527#[derive(Debug)]
528pub struct ComplexTypeContent {
529    /// Occurrence of the content within this struct.
530    pub occurs: Occurs,
531
532    /// `true` if the content is a simple type (e.g. a enum, union, string,
533    /// integer, ...), `false` otherwise.
534    pub is_simple: bool,
535
536    /// Minimum occurrence.
537    pub min_occurs: MinOccurs,
538
539    /// Maximum occurrence.
540    pub max_occurs: MaxOccurs,
541
542    /// Actual target type of the content.
543    pub target_type: IdentPath,
544}
545
546/// Contains the details of an XML element.
547///
548/// Is used in [`ComplexTypeEnum`] or [`StructMode`].
549#[derive(Debug)]
550pub struct ComplexTypeElement<'types> {
551    /// Reference to the original type information.
552    pub info: &'types ElementInfo,
553
554    /// Occurrence of the element within it's parent type.
555    pub occurs: Occurs,
556
557    /// Name of the element as string.
558    pub s_name: String,
559
560    /// Name of the element as byte string literal.
561    pub b_name: Literal,
562
563    /// Name of the XML tag of the element.
564    pub tag_name: String,
565
566    /// Field identifier of the element.
567    pub field_ident: Ident2,
568
569    /// Variant identifier of the element.
570    pub variant_ident: Ident2,
571
572    /// Actual target type of the element.
573    pub target_type: IdentPath,
574
575    /// `true` if this element needs some indirection
576    /// (like a `Box` or a `Vec`), `false` otherwise.
577    pub need_indirection: bool,
578
579    /// `true` if the target type of this element is dynamic,
580    /// `false` otherwise.
581    pub target_is_dynamic: bool,
582}
583
584/// Contains the details of an XML attribute.
585///
586/// Is used in [`ComplexTypeStruct`].
587#[derive(Debug)]
588pub struct ComplexTypeAttribute<'types> {
589    /// Reference to the original type information.
590    pub info: &'types AttributeInfo,
591
592    /// Identifier of the attribute.
593    pub ident: Ident2,
594
595    /// Name of the attribute as string.
596    pub s_name: String,
597
598    /// Name of the attribute as byte string literal.
599    pub b_name: Literal,
600
601    /// Name of the attribute inside the XML tag.
602    pub tag_name: String,
603
604    /// `true` if this attribute is optional, `false` otherwise.
605    pub is_option: bool,
606
607    /// The actual target type of the attribute.
608    pub target_type: IdentPath,
609
610    /// The default value of the attribute.
611    pub default_value: Option<TokenStream>,
612}
613
614#[derive(Debug, Clone)]
615enum TypeMode {
616    All,
617    Choice,
618    Sequence,
619    Simple { target_type: IdentPath },
620}
621
622impl<'types> ComplexType<'types> {
623    fn new_all(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
624        Self::new(
625            req,
626            TypeMode::All,
627            1,
628            MaxOccurs::Bounded(1),
629            &[],
630            None,
631            &info.elements,
632            info.any.as_ref(),
633        )
634    }
635
636    fn new_choice(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
637        Self::new(
638            req,
639            TypeMode::Choice,
640            1,
641            MaxOccurs::Bounded(1),
642            &[],
643            None,
644            &info.elements,
645            info.any.as_ref(),
646        )
647    }
648
649    fn new_sequence(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
650        Self::new(
651            req,
652            TypeMode::Sequence,
653            1,
654            MaxOccurs::Bounded(1),
655            &[],
656            None,
657            &info.elements,
658            info.any.as_ref(),
659        )
660    }
661
662    fn new_complex(info: &'types ComplexInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
663        let (type_mode, elements, any_element) = match info.content.as_ref().and_then(|ident| {
664            req.types
665                .get_resolved_type(ident)
666                .map(|ty| (&ty.variant, ident))
667        }) {
668            None => (TypeMode::Sequence, &[][..], None),
669            Some((TypeVariant::All(si), _)) => (TypeMode::All, &si.elements[..], si.any.as_ref()),
670            Some((TypeVariant::Choice(si), _)) => {
671                (TypeMode::Choice, &si.elements[..], si.any.as_ref())
672            }
673            Some((TypeVariant::Sequence(si), _)) => {
674                (TypeMode::Sequence, &si.elements[..], si.any.as_ref())
675            }
676            Some((
677                TypeVariant::BuildIn(_)
678                | TypeVariant::Union(_)
679                | TypeVariant::Enumeration(_)
680                | TypeVariant::Reference(_),
681                ident,
682            )) => {
683                let content_ref = req.get_or_create_type_ref(ident.clone())?;
684                let target_type = content_ref.to_ident_path();
685
686                (TypeMode::Simple { target_type }, &[][..], None)
687            }
688            Some((x, _)) => {
689                let ident = &req.current_type_ref().type_ident;
690
691                tracing::warn!("Complex type has unexpected content: ident={ident}, info={info:#?}, content={x:#?}!");
692
693                (TypeMode::Sequence, &[][..], None)
694            }
695        };
696
697        Self::new(
698            req,
699            type_mode,
700            info.min_occurs,
701            info.max_occurs,
702            &info.attributes,
703            info.any_attribute.as_ref(),
704            elements,
705            any_element,
706        )
707    }
708
709    #[allow(clippy::too_many_arguments)]
710    fn new(
711        req: Request<'_, 'types>,
712        type_mode: TypeMode,
713        min_occurs: MinOccurs,
714        max_occurs: MaxOccurs,
715        attributes: &'types [AttributeInfo],
716        any_attribute: Option<&'types AnyAttributeInfo>,
717        elements: &'types [ElementInfo],
718        any_element: Option<&'types AnyInfo>,
719    ) -> Result<Self, Error> {
720        match type_mode {
721            TypeMode::Simple { target_type } => Self::new_simple(
722                req,
723                target_type,
724                min_occurs,
725                max_occurs,
726                attributes,
727                any_attribute,
728            ),
729            TypeMode::Choice => Self::new_enum(
730                req,
731                min_occurs,
732                max_occurs,
733                attributes,
734                any_attribute,
735                elements,
736                any_element,
737            ),
738            TypeMode::All | TypeMode::Sequence => Self::new_struct(
739                req,
740                &type_mode,
741                min_occurs,
742                max_occurs,
743                attributes,
744                any_attribute,
745                elements,
746                any_element,
747            ),
748        }
749    }
750
751    fn new_simple(
752        mut req: Request<'_, 'types>,
753        target_type: IdentPath,
754        min_occurs: MinOccurs,
755        max_occurs: MaxOccurs,
756        attributes: &'types [AttributeInfo],
757        any_attribute: Option<&'types AnyAttributeInfo>,
758    ) -> Result<Self, Error> {
759        let base = ComplexTypeBase::new(&mut req)?;
760        let occurs = Occurs::from_occurs(min_occurs, max_occurs);
761        let attributes = attributes
762            .iter()
763            .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
764            .collect::<Result<Vec<_>, _>>()?;
765
766        let content = ComplexTypeContent {
767            occurs,
768            is_simple: true,
769            min_occurs,
770            max_occurs,
771            target_type,
772        };
773        let type_ = ComplexTypeStruct {
774            base,
775
776            mode: StructMode::Content { content },
777
778            attributes,
779            any_attribute,
780        };
781
782        Ok(Self::Struct {
783            type_,
784            content_type: None,
785        })
786    }
787
788    fn new_enum(
789        mut req: Request<'_, 'types>,
790        min_occurs: MinOccurs,
791        max_occurs: MaxOccurs,
792        attributes: &'types [AttributeInfo],
793        any_attribute: Option<&'types AnyAttributeInfo>,
794        elements: &'types [ElementInfo],
795        any_element: Option<&'types AnyInfo>,
796    ) -> Result<Self, Error> {
797        let base = ComplexTypeBase::new(&mut req)?;
798        let occurs = Occurs::from_occurs(min_occurs, max_occurs);
799        let flatten = occurs == Occurs::Single
800            && attributes.is_empty()
801            && req.check_flags(GeneratorFlags::FLATTEN_ENUM_CONTENT);
802
803        let attributes = attributes
804            .iter()
805            .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
806            .collect::<Result<Vec<_>, _>>()?;
807
808        let mut any_element = any_element;
809        let mut elements = elements
810            .iter()
811            .filter_map(|info| {
812                ComplexTypeElement::new_variant(info, &mut req, occurs.is_direct()).transpose()
813            })
814            .collect::<Result<Vec<_>, _>>()?;
815
816        if flatten {
817            let type_ = ComplexTypeEnum {
818                base,
819                elements,
820                any_element,
821                any_attribute,
822            };
823
824            return Ok(ComplexType::Enum {
825                type_,
826                content_type: None,
827            });
828        }
829
830        let type_ident = &base.type_ident;
831        let content_ident = format_ident!("{type_ident}Content");
832        let has_content = occurs.is_some() && !elements.is_empty();
833
834        let content_type = has_content.then(|| {
835            let type_ = ComplexTypeEnum {
836                base: ComplexTypeBase::new_empty(content_ident.clone()),
837                elements: take(&mut elements),
838                any_element: any_element.take(),
839                any_attribute: None,
840            };
841
842            Box::new(ComplexType::Enum {
843                type_,
844                content_type: None,
845            })
846        });
847
848        let mode = if has_content {
849            let type_ref = req.current_type_ref();
850            let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
851            let content = ComplexTypeContent {
852                occurs,
853                is_simple: false,
854                min_occurs,
855                max_occurs,
856                target_type,
857            };
858
859            StructMode::Content { content }
860        } else {
861            StructMode::Empty { any_element }
862        };
863
864        let type_ = ComplexTypeStruct {
865            base,
866            mode,
867
868            attributes,
869            any_attribute,
870        };
871
872        Ok(ComplexType::Struct {
873            type_,
874            content_type,
875        })
876    }
877
878    #[allow(clippy::too_many_arguments)]
879    fn new_struct(
880        mut req: Request<'_, 'types>,
881        type_mode: &TypeMode,
882        min_occurs: MinOccurs,
883        max_occurs: MaxOccurs,
884        attributes: &'types [AttributeInfo],
885        any_attribute: Option<&'types AnyAttributeInfo>,
886        elements: &'types [ElementInfo],
887        any_element: Option<&'types AnyInfo>,
888    ) -> Result<Self, Error> {
889        let base = ComplexTypeBase::new(&mut req)?;
890        let occurs = Occurs::from_occurs(min_occurs, max_occurs);
891        let flatten =
892            occurs == Occurs::Single && req.check_flags(GeneratorFlags::FLATTEN_STRUCT_CONTENT);
893
894        let attributes = attributes
895            .iter()
896            .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
897            .collect::<Result<Vec<_>, _>>()?;
898
899        let elements = elements
900            .iter()
901            .filter_map(|info| {
902                ComplexTypeElement::new_field(info, &mut req, occurs.is_direct()).transpose()
903            })
904            .collect::<Result<Vec<_>, _>>()?;
905
906        if flatten {
907            let mode = match type_mode {
908                _ if elements.is_empty() => StructMode::Empty { any_element },
909                TypeMode::All => StructMode::All {
910                    elements,
911                    any_element,
912                },
913                TypeMode::Sequence => StructMode::Sequence {
914                    elements,
915                    any_element,
916                },
917                _ => crate::unreachable!(),
918            };
919
920            let type_ = ComplexTypeStruct {
921                base,
922                mode,
923
924                attributes,
925                any_attribute,
926            };
927
928            return Ok(ComplexType::Struct {
929                type_,
930                content_type: None,
931            });
932        }
933
934        let type_ident = &base.type_ident;
935        let content_ident = format_ident!("{type_ident}Content");
936        let has_content = occurs.is_some() && !elements.is_empty();
937
938        let content_type = has_content.then(|| {
939            let mode = match type_mode {
940                TypeMode::All => StructMode::All {
941                    elements,
942                    any_element,
943                },
944                TypeMode::Sequence => StructMode::Sequence {
945                    elements,
946                    any_element,
947                },
948                _ => crate::unreachable!(),
949            };
950
951            let type_ = ComplexTypeStruct {
952                base: ComplexTypeBase::new_empty(content_ident.clone()),
953                mode,
954
955                attributes: Vec::new(),
956                any_attribute: None,
957            };
958
959            Box::new(ComplexType::Struct {
960                type_,
961                content_type: None,
962            })
963        });
964
965        let mode = if has_content {
966            let type_ref = req.current_type_ref();
967            let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
968            let content = ComplexTypeContent {
969                occurs,
970                is_simple: false,
971                min_occurs,
972                max_occurs,
973                target_type,
974            };
975
976            StructMode::Content { content }
977        } else {
978            StructMode::Empty { any_element }
979        };
980
981        let type_ = ComplexTypeStruct {
982            base,
983            mode,
984
985            attributes,
986            any_attribute,
987        };
988
989        Ok(ComplexType::Struct {
990            type_,
991            content_type,
992        })
993    }
994}
995
996impl ComplexTypeBase {
997    pub(super) fn element_tag(&self) -> Option<&String> {
998        self.is_complex.then_some(self.tag_name.as_ref()).flatten()
999    }
1000
1001    pub(crate) fn represents_element(&self) -> bool {
1002        self.is_complex && self.tag_name.is_some() && !self.is_dynamic
1003    }
1004
1005    fn new(req: &mut Request<'_, '_>) -> Result<Self, Error> {
1006        let type_ref = req.current_type_ref();
1007        let type_ident = type_ref.type_ident.clone();
1008
1009        let mut ret = Self::new_empty(type_ident);
1010        ret.tag_name = Some(make_tag_name(req.types, req.ident));
1011        ret.trait_impls = req.make_trait_impls()?;
1012
1013        if let Some(TypeVariant::ComplexType(ci)) = req.types.get_variant(req.ident) {
1014            ret.is_complex = true;
1015            ret.is_dynamic = ci.is_dynamic;
1016        }
1017
1018        Ok(ret)
1019    }
1020
1021    fn new_empty(type_ident: Ident2) -> Self {
1022        let serializer_ident = format_ident!("{type_ident}Serializer");
1023        let serializer_state_ident = format_ident!("{type_ident}SerializerState");
1024
1025        let deserializer_ident = format_ident!("{type_ident}Deserializer");
1026        let deserializer_state_ident = format_ident!("{type_ident}DeserializerState");
1027
1028        Self {
1029            type_ident,
1030            trait_impls: Vec::new(),
1031
1032            tag_name: None,
1033            is_complex: false,
1034            is_dynamic: false,
1035
1036            serializer_ident,
1037            serializer_state_ident,
1038
1039            deserializer_ident,
1040            deserializer_state_ident,
1041        }
1042    }
1043}
1044
1045impl Deref for ComplexTypeEnum<'_> {
1046    type Target = ComplexTypeBase;
1047
1048    fn deref(&self) -> &Self::Target {
1049        &self.base
1050    }
1051}
1052
1053impl ComplexTypeStruct<'_> {
1054    pub(super) fn is_unit_struct(&self) -> bool {
1055        matches!(&self.mode, StructMode::Empty { .. }) && !self.has_attributes()
1056    }
1057
1058    pub(super) fn has_attributes(&self) -> bool {
1059        !self.attributes.is_empty()
1060    }
1061
1062    pub(super) fn has_content(&self) -> bool {
1063        match &self.mode {
1064            StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } => {
1065                !elements.is_empty()
1066            }
1067            StructMode::Content { .. } => true,
1068            StructMode::Empty { .. } => false,
1069        }
1070    }
1071
1072    pub(super) fn elements(&self) -> &[ComplexTypeElement<'_>] {
1073        if let StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } = &self.mode
1074        {
1075            elements
1076        } else {
1077            &[]
1078        }
1079    }
1080
1081    pub(super) fn any_element(&self) -> Option<&AnyInfo> {
1082        if let StructMode::All { any_element, .. } | StructMode::Sequence { any_element, .. } =
1083            &self.mode
1084        {
1085            *any_element
1086        } else {
1087            None
1088        }
1089    }
1090
1091    pub(super) fn content(&self) -> Option<&ComplexTypeContent> {
1092        if let StructMode::Content { content, .. } = &self.mode {
1093            Some(content)
1094        } else {
1095            None
1096        }
1097    }
1098}
1099
1100impl Deref for ComplexTypeStruct<'_> {
1101    type Target = ComplexTypeBase;
1102
1103    fn deref(&self) -> &Self::Target {
1104        &self.base
1105    }
1106}
1107
1108impl<'types> ComplexTypeElement<'types> {
1109    fn new_variant(
1110        info: &'types ElementInfo,
1111        req: &mut Request<'_, 'types>,
1112        direct_usage: bool,
1113    ) -> Result<Option<Self>, Error> {
1114        let force_box = req.box_flags.intersects(BoxFlags::ENUM_ELEMENTS);
1115
1116        Self::new(info, req, direct_usage, force_box)
1117    }
1118
1119    fn new_field(
1120        info: &'types ElementInfo,
1121        req: &mut Request<'_, 'types>,
1122        direct_usage: bool,
1123    ) -> Result<Option<Self>, Error> {
1124        let force_box = req.box_flags.intersects(BoxFlags::STRUCT_ELEMENTS);
1125
1126        Self::new(info, req, direct_usage, force_box)
1127    }
1128
1129    fn new(
1130        info: &'types ElementInfo,
1131        req: &mut Request<'_, 'types>,
1132        direct_usage: bool,
1133        force_box: bool,
1134    ) -> Result<Option<Self>, Error> {
1135        let occurs = Occurs::from_occurs(info.min_occurs, info.max_occurs);
1136        if occurs == Occurs::None {
1137            return Ok(None);
1138        }
1139
1140        let tag_name = make_tag_name(req.types, &info.ident);
1141        let s_name = info.ident.name.to_string();
1142        let b_name = Literal::byte_string(s_name.as_bytes());
1143        let field_ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1144        let variant_ident = format_variant_ident(&info.ident.name, info.display_name.as_deref());
1145
1146        let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1147        let target_type = target_ref.to_ident_path();
1148
1149        let need_box = req.current_type_ref().boxed_elements.contains(&info.ident);
1150        let need_indirection = (direct_usage && need_box) || force_box;
1151        let target_is_dynamic = is_dynamic(&info.type_, req.types);
1152
1153        Ok(Some(Self {
1154            info,
1155            occurs,
1156            s_name,
1157            b_name,
1158            tag_name,
1159            field_ident,
1160            variant_ident,
1161            target_type,
1162            need_indirection,
1163            target_is_dynamic,
1164        }))
1165    }
1166}
1167
1168impl<'types> ComplexTypeAttribute<'types> {
1169    fn new_field(
1170        info: &'types AttributeInfo,
1171        req: &mut Request<'_, 'types>,
1172    ) -> Result<Option<Self>, Error> {
1173        if info.use_ == Use::Prohibited {
1174            return Ok(None);
1175        }
1176
1177        let current_module = req.current_module();
1178        let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1179        let ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1180        let target_type = target_ref.to_ident_path();
1181        let s_name = info.ident.name.to_string();
1182        let b_name = Literal::byte_string(s_name.as_bytes());
1183        let tag_name = make_tag_name(req.types, &info.ident);
1184
1185        let default_value = info
1186            .default
1187            .as_ref()
1188            .map(|default| req.get_default(current_module, default, &info.type_))
1189            .transpose()?;
1190        let is_option = matches!((&info.use_, &default_value), (Use::Optional, None));
1191
1192        Ok(Some(Self {
1193            info,
1194            ident,
1195            s_name,
1196            b_name,
1197            tag_name,
1198            is_option,
1199            target_type,
1200            default_value,
1201        }))
1202    }
1203}
1204
1205/* Request */
1206
1207/// Helper type that is used to request the code generation for a specific type.
1208struct Request<'a, 'types> {
1209    pub ident: &'a Ident,
1210    pub config: &'a Config<'types>,
1211
1212    state: &'a mut State<'types>,
1213}
1214
1215impl<'a, 'types> Request<'a, 'types> {
1216    fn new(ident: &'a Ident, config: &'a Config<'types>, state: &'a mut State<'types>) -> Self {
1217        Self {
1218            ident,
1219            config,
1220            state,
1221        }
1222    }
1223
1224    fn current_module(&self) -> Option<NamespaceId> {
1225        self.check_flags(GeneratorFlags::USE_MODULES)
1226            .then_some(self.ident.ns)
1227            .flatten()
1228    }
1229
1230    fn current_type_ref(&self) -> &TypeRef {
1231        self.state.cache.get(self.ident).unwrap()
1232    }
1233
1234    fn get_trait_infos(&mut self) -> &TraitInfos {
1235        self.state
1236            .trait_infos
1237            .get_or_insert_with(|| TraitInfos::new(self.config.types))
1238    }
1239
1240    fn get_or_create_type_ref(&mut self, ident: Ident) -> Result<&TypeRef, Error> {
1241        self.state.get_or_create_type_ref(self.config, ident)
1242    }
1243
1244    fn make_trait_impls(&mut self) -> Result<Vec<TokenStream>, Error> {
1245        let ident = self.ident.clone();
1246        let current_ns = self.current_module();
1247        let module_path = ModulePath::from_namespace(current_ns, self.types);
1248
1249        self.get_trait_infos()
1250            .get(&ident)
1251            .into_iter()
1252            .flat_map(|info| &info.traits_all)
1253            .cloned()
1254            .collect::<Vec<_>>()
1255            .into_iter()
1256            .map(|ident| {
1257                let type_ref = self.get_or_create_type_ref(ident.clone())?;
1258                let ident = format_ident!("{}Trait", type_ref.type_ident);
1259                let trait_type = type_ref.to_ident_path().with_ident(ident);
1260                let trait_ident = trait_type.relative_to(&module_path);
1261
1262                Ok(trait_ident)
1263            })
1264            .collect::<Result<Vec<_>, _>>()
1265    }
1266
1267    fn get_default(
1268        &mut self,
1269        current_ns: Option<NamespaceId>,
1270        default: &str,
1271        ident: &Ident,
1272    ) -> Result<TokenStream, Error> {
1273        let types = self.types;
1274        let ty = types
1275            .get(ident)
1276            .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1277        let type_ref = self.get_or_create_type_ref(ident.clone())?;
1278
1279        macro_rules! build_in {
1280            ($ty:ty) => {
1281                if let Ok(val) = default.parse::<$ty>() {
1282                    return Ok(quote!(#val));
1283                }
1284            };
1285        }
1286
1287        match &ty.variant {
1288            TypeVariant::BuildIn(BuildInInfo::U8) => build_in!(u8),
1289            TypeVariant::BuildIn(BuildInInfo::U16) => build_in!(u16),
1290            TypeVariant::BuildIn(BuildInInfo::U32) => build_in!(u32),
1291            TypeVariant::BuildIn(BuildInInfo::U64) => build_in!(u64),
1292            TypeVariant::BuildIn(BuildInInfo::U128) => build_in!(u128),
1293            TypeVariant::BuildIn(BuildInInfo::Usize) => build_in!(usize),
1294
1295            TypeVariant::BuildIn(BuildInInfo::I8) => build_in!(i8),
1296            TypeVariant::BuildIn(BuildInInfo::I16) => build_in!(i16),
1297            TypeVariant::BuildIn(BuildInInfo::I32) => build_in!(i32),
1298            TypeVariant::BuildIn(BuildInInfo::I64) => build_in!(i64),
1299            TypeVariant::BuildIn(BuildInInfo::I128) => build_in!(i128),
1300            TypeVariant::BuildIn(BuildInInfo::Isize) => build_in!(isize),
1301
1302            TypeVariant::BuildIn(BuildInInfo::F32) => build_in!(f32),
1303            TypeVariant::BuildIn(BuildInInfo::F64) => build_in!(f64),
1304
1305            TypeVariant::BuildIn(BuildInInfo::Bool) => {
1306                match default.to_ascii_lowercase().as_str() {
1307                    "true" | "yes" | "1" => return Ok(quote!(true)),
1308                    "false" | "no" | "0" => return Ok(quote!(false)),
1309                    _ => (),
1310                }
1311            }
1312            TypeVariant::BuildIn(BuildInInfo::String) => {
1313                return Ok(quote!(String::from(#default)));
1314            }
1315            TypeVariant::BuildIn(BuildInInfo::Custom(x)) => {
1316                if let Some(x) = x.default(default) {
1317                    return Ok(x);
1318                }
1319            }
1320
1321            TypeVariant::Enumeration(ei) => {
1322                let module_path = ModulePath::from_namespace(current_ns, types);
1323                let target_type = type_ref.to_ident_path().relative_to(&module_path);
1324
1325                for var in &*ei.variants {
1326                    if var.type_.is_none() && var.ident.name.as_str() == default {
1327                        let variant_ident =
1328                            format_variant_ident(&var.ident.name, var.display_name.as_deref());
1329
1330                        return Ok(quote!(#target_type :: #variant_ident));
1331                    }
1332
1333                    if let Some(target_ident) = &var.type_ {
1334                        if let Ok(default) = self.get_default(current_ns, default, target_ident) {
1335                            let variant_ident = match self.state.cache.get(target_ident) {
1336                                Some(type_ref) if var.ident.name.is_generated() => {
1337                                    type_ref.type_ident.clone()
1338                                }
1339                                _ => format_variant_ident(
1340                                    &var.ident.name,
1341                                    var.display_name.as_deref(),
1342                                ),
1343                            };
1344
1345                            return Ok(quote!(#target_type :: #variant_ident(#default)));
1346                        }
1347                    }
1348                }
1349            }
1350
1351            TypeVariant::Union(ui) => {
1352                let module_path = ModulePath::from_namespace(current_ns, types);
1353                let target_type = type_ref.to_ident_path().relative_to(&module_path);
1354
1355                for ty in &*ui.types {
1356                    if let Ok(code) = self.get_default(current_ns, default, &ty.type_) {
1357                        let variant_ident = match self.state.cache.get(&ty.type_) {
1358                            Some(type_ref) if ty.type_.name.is_generated() => {
1359                                type_ref.type_ident.clone()
1360                            }
1361                            _ => format_variant_ident(&ty.type_.name, ty.display_name.as_deref()),
1362                        };
1363
1364                        return Ok(quote! {
1365                            #target_type :: #variant_ident ( #code )
1366                        });
1367                    }
1368                }
1369            }
1370
1371            TypeVariant::Reference(ti) => match Occurs::from_occurs(ti.min_occurs, ti.max_occurs) {
1372                Occurs::Single => return self.get_default(current_ns, default, &ti.type_),
1373                Occurs::DynamicList if default.is_empty() => {
1374                    let module_path = ModulePath::from_namespace(current_ns, types);
1375                    let target_type = type_ref.to_ident_path().relative_to(&module_path);
1376
1377                    return Ok(quote! { #target_type(Vec::new()) });
1378                }
1379                _ => (),
1380            },
1381
1382            _ => (),
1383        }
1384
1385        Err(Error::InvalidDefaultValue(
1386            ident.clone(),
1387            default.to_owned(),
1388        ))
1389    }
1390}
1391
1392impl<'types> Deref for Request<'_, 'types> {
1393    type Target = Config<'types>;
1394
1395    fn deref(&self) -> &Self::Target {
1396        self.config
1397    }
1398}
1399
1400/* Helper */
1401
1402fn is_dynamic(ident: &Ident, types: &Types) -> bool {
1403    let Some(ty) = types.get(ident) else {
1404        return false;
1405    };
1406
1407    match &ty.variant {
1408        TypeVariant::Dynamic(_) => true,
1409        TypeVariant::ComplexType(ci) => ci.is_dynamic,
1410        TypeVariant::Reference(x) if x.is_single() => is_dynamic(&x.type_, types),
1411        _ => false,
1412    }
1413}
1414
1415fn make_tag_name(types: &Types, ident: &Ident) -> String {
1416    let name = ident.name.to_string();
1417
1418    if let Some(module) = ident
1419        .ns
1420        .as_ref()
1421        .and_then(|ns| types.modules.get(ns))
1422        .and_then(|module| module.name.as_ref())
1423    {
1424        format!("{module}:{name}")
1425    } else {
1426        name
1427    }
1428}
1429
1430fn make_derived_type_data<'types>(
1431    req: &mut Request<'_, 'types>,
1432    ident: &'types Ident,
1433) -> Result<DerivedType, Error> {
1434    let s_name = ident.name.to_string();
1435    let b_name = Literal::byte_string(s_name.as_bytes());
1436
1437    let ty = req
1438        .types
1439        .get(ident)
1440        .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1441    let base_ident = if let TypeVariant::Dynamic(di) = &ty.variant {
1442        di.type_.clone()
1443    } else {
1444        None
1445    };
1446    let ident = base_ident.unwrap_or(ident.clone());
1447
1448    let target_ref = req.get_or_create_type_ref(ident.clone())?;
1449    let target_type = target_ref.to_ident_path();
1450    let variant_ident = format_variant_ident(&ident.name, None);
1451
1452    Ok(DerivedType {
1453        ident,
1454        b_name,
1455        target_type,
1456        variant_ident,
1457    })
1458}