fn process_itf_variant(
    itf: &model::ComInterface,
    ts: ModelTypeSystem,
    itf_variant: &model::ComInterfaceVariant,
    output: &mut Vec<TokenStream>,
    itf_output: &mut InterfaceOutput,
)
{
    let itf_path = &itf.path;
    let itf_ident = &itf.ident;
    let visibility = &itf.visibility;
    let ts_value_tokens = ts.as_typesystem_tokens(itf.span);
    let ts_type_tokens = ts.as_typesystem_type(itf.span);
    let itf_ref = &itf.itf_ref;
    let vtable_path = itf.vtable(ts);
    let attr_cominterfacevariant = quote_spanned!(itf_ident.span() =>
        intercom::attributes::ComInterfaceVariant<#ts_type_tokens>);
    let attr_cominterfacevtablefor = quote_spanned!(itf_ident.span() =>
        intercom::attributes::ComInterfaceVTableFor<I, S, #ts_type_tokens>);

    // Construct the iid(ts) match arm for this type system.
    itf_output
        .iid_arms
        .push(quote_spanned!(itf.span => #ts_value_tokens => Some( <Self as #attr_cominterfacevariant>::iid() ) ));

    // Create a vector for the virtual table fields and insert the base
    // interface virtual table in it if required.
    let mut vtbl_fields = vec![];
    let mut vtbl_values = vec![];
    if let Some(ref base) = itf.base_interface {
        vtbl_values.push(quote_spanned!(itf.span =>
                __base : <dyn #base as #attr_cominterfacevtablefor>::VTABLE));
        vtbl_fields.push(quote_spanned!(itf.span =>
                pub __base : <dyn #base as #attr_cominterfacevariant>::VTable));
    }

    // Gather all the trait methods for the remaining vtable fields.
    for method_info in &itf_variant.methods {
        // Create the vtable field and add it to the vector of fields.
        let (vtbl_field, vtbl_value) = format_method_vtable_entries(itf, method_info, ts);
        vtbl_fields.push(vtbl_field);
        vtbl_values.push(vtbl_value);

        // Ensure the MethodImpl exists for the method.
        // These are shared by type systems so only one type system needs to
        // add them here.
        let method_name = method_info.name.to_string();
        if !itf_output.method_impls.contains_key(&method_name) {
            itf_output
                .method_impls
                .insert(method_name.clone(), MethodImpl::new(method_info.clone()));
        }

        let method_impl = &mut itf_output
            .method_impls
            .get_mut(&method_name)
            .expect("We just ensured this exists three lines up... ;_;");
        method_impl.impls.insert(
            itf_variant.type_system,
            rust_to_com_delegate(itf, itf_variant, &method_info),
        );

        output.push(create_virtual_method(itf, method_info, ts));
    }

    // Create the vtable. We've already gathered all the vtable method
    // pointer fields so defining the struct is simple enough.
    let itf_bound = match itf.item_type {
        utils::InterfaceType::Struct => quote!(),
        utils::InterfaceType::Trait if itf.implemented_by.is_some() => quote!(),
        utils::InterfaceType::Trait => quote!(+ #itf_ident),
    };
    if itf.vtable_of.is_none() {
        output.push(quote_spanned!(itf.span =>
            #[allow(non_camel_case_types)]
            #[allow(non_snake_case)]
            #[allow(clippy::all)]
            #[repr(C)]
            #[doc(hidden)]
            #[derive(Clone, Copy)]
            #visibility struct #vtable_path { #( #vtbl_fields, )* }

            #[allow(unused)]
            impl<I, S> intercom::attributes::ComInterfaceVTableFor<I, S, #ts_type_tokens> for #itf_ref
            where I: ?Sized,
                  S: intercom::attributes::ComClassInterface<I, #ts_type_tokens> + intercom::attributes::ComClass #itf_bound,
            {
                const VTABLE: #vtable_path = #vtable_path {
                    #( #vtbl_values, )*
                };
            }
        ));
    }

    let iid_tokens = utils::get_guid_tokens(&itf_variant.iid, itf.span);
    output.push(quote_spanned!(itf_path.span() =>
        #[allow(non_camel_case_types)]
        #[allow(non_snake_case)]
        #[allow(clippy::all)]
        #[doc(hidden)]
        impl #attr_cominterfacevariant for #itf_ref {
            type VTable = #vtable_path;
            fn iid() -> &'static intercom::IID {
                & #iid_tokens
            }
        }
    ));
}
/// Processes the interface type system variant.
///
/// # Arguments
///
/// * `itf` - Interface details.
/// * `ts` - Type system the variant represents.
/// * `itf_variant` - Interface variant details.
/// * `output` - Direct output emitted for each interface variant.
/// * `itf_output` - Interface variant data for the interface level output.
Processes the interface type system variant.
Processes the interface type system variant .
fn process_itf_variant(
    itf: &model::ComInterface,
    ts: ModelTypeSystem,
    itf_variant: &model::ComInterfaceVariant,
    output: &mut Vec<TokenStream>,
    itf_output: &mut InterfaceOutput,
)
{
    let itf_path = &itf.path;
    let itf_ident = &itf.ident;
    let visibility = &itf.visibility;
    let ts_value_tokens = ts.as_typesystem_tokens(itf.span);
    let ts_type_tokens = ts.as_typesystem_type(itf.span);
    let itf_ref = &itf.itf_ref;
    let vtable_path = itf.vtable(ts);
    let attr_cominterfacevariant = quote_spanned!(itf_ident.span() =>
        intercom::attributes::ComInterfaceVariant<#ts_type_tokens>);
    let attr_cominterfacevtablefor = quote_spanned!(itf_ident.span() =>
        intercom::attributes::ComInterfaceVTableFor<I, S, #ts_type_tokens>);
    // Construct the iid(ts) match arm for this type system.
    itf_output
        .iid_arms
        .push(quote_spanned!(itf.span => #ts_value_tokens => Some( <Self as #attr_cominterfacevariant>::iid() ) ));
    // Create a vector for the virtual table fields and insert the base
    // interface virtual table in it if required.
    let mut vtbl_fields = vec![];
    let mut vtbl_values = vec![];
    if let Some(ref base) = itf.base_interface {
        vtbl_values.push(quote_spanned!(itf.span =>
                __base : <dyn #base as #attr_cominterfacevtablefor>::VTABLE));
        vtbl_fields.push(quote_spanned!(itf.span =>
                pub __base : <dyn #base as #attr_cominterfacevariant>::VTable));
    }
    // Gather all the trait methods for the remaining vtable fields.
    for method_info in &itf_variant.methods {
        // Create the vtable field and add it to the vector of fields.
        let (vtbl_field, vtbl_value) = format_method_vtable_entries(itf, method_info, ts);
        vtbl_fields.push(vtbl_field);
        vtbl_values.push(vtbl_value);
        // Ensure the MethodImpl exists for the method.
        // These are shared by type systems so only one type system needs to
        // add them here.
        let method_name = method_info.name.to_string();
        if !itf_output.method_impls.contains_key(&method_name) {
            itf_output
                .method_impls
                .insert(method_name.clone(), MethodImpl::new(method_info.clone()));
        }
        let method_impl = &mut itf_output
            .method_impls
            .get_mut(&method_name)
            .expect("We just ensured this exists three lines up... ;_;");
        method_impl.impls.insert(
            itf_variant.type_system,
            rust_to_com_delegate(itf, itf_variant, &method_info),
        );
        output.push(create_virtual_method(itf, method_info, ts));
    }
    // Create the vtable. We've already gathered all the vtable method
    // pointer fields so defining the struct is simple enough.
    let itf_bound = match itf.item_type {
        utils::InterfaceType::Struct => quote!(),
        utils::InterfaceType::Trait if itf.implemented_by.is_some() => quote!(),
        utils::InterfaceType::Trait => quote!(+ #itf_ident),
    };
    if itf.vtable_of.is_none() {
        output.push(quote_spanned!(itf.span =>
            #[allow(non_camel_case_types)]
            #[allow(non_snake_case)]
            #[allow(clippy::all)]
            #[repr(C)]
            #[doc(hidden)]
            #[derive(Clone, Copy)]
            #visibility struct #vtable_path { #( #vtbl_fields, )* }
            #[allow(unused)]
            impl<I, S> intercom::attributes::ComInterfaceVTableFor<I, S, #ts_type_tokens> for #itf_ref
            where I: ?Sized,
                  S: intercom::attributes::ComClassInterface<I, #ts_type_tokens> + intercom::attributes::ComClass #itf_bound,
            {
                const VTABLE: #vtable_path = #vtable_path {
                    #( #vtbl_values, )*
                };
            }
        ));
    }
    let iid_tokens = utils::get_guid_tokens(&itf_variant.iid, itf.span);
    output.push(quote_spanned!(itf_path.span() =>
        #[allow(non_camel_case_types)]
        #[allow(non_snake_case)]
        #[allow(clippy::all)]
        #[doc(hidden)]
        impl #attr_cominterfacevariant for #itf_ref {
            type VTable = #vtable_path;
            fn iid() -> &'static intercom::IID {
                & #iid_tokens
            }
        }
    ));
}
fn process_itf_variant ( itf : & model :: ComInterface , ts : ModelTypeSystem , itf_variant : & model :: ComInterfaceVariant , output : & mut Vec < TokenStream > , itf_output : & mut InterfaceOutput , ) { let itf_path = & itf . path ; let itf_ident = & itf . ident ; let visibility = & itf . visibility ; let ts_value_tokens = ts . as_typesystem_tokens ( itf . span ) ; let ts_type_tokens = ts . as_typesystem_type ( itf . span ) ; let itf_ref = & itf . itf_ref ; let vtable_path = itf . vtable ( ts ) ; let attr_cominterfacevariant = quote_spanned ! ( itf_ident span ( ) intercom attributes ComInterfaceVariant ts_type_tokens ) ; let attr_cominterfacevtablefor = quote_spanned ! ( itf_ident span ( ) intercom attributes ComInterfaceVTableFor I S ts_type_tokens ) ; // Construct the iid(ts) match arm for this type system. itf_output . iid_arms . push ( quote_spanned ! ( itf span ts_value_tokens Some ( Self as attr_cominterfacevariant iid ( ) ) ) ) ; // Create a vector for the virtual table fields and insert the base // interface virtual table in it if required. let mut vtbl_fields = vec ! [ ] ; let mut vtbl_values = vec ! [ ] ; if let Some ( ref base ) = itf . base_interface { vtbl_values . push ( quote_spanned ! ( itf span __base dyn base as attr_cominterfacevtablefor VTABLE ) ) ; vtbl_fields . push ( quote_spanned ! ( itf span pub __base dyn base as attr_cominterfacevariant VTable ) ) ; } // Gather all the trait methods for the remaining vtable fields. for method_info in & itf_variant . methods { // Create the vtable field and add it to the vector of fields. let ( vtbl_field , vtbl_value ) = format_method_vtable_entries ( itf , method_info , ts ) ; vtbl_fields . push ( vtbl_field ) ; vtbl_values . push ( vtbl_value ) ; // Ensure the MethodImpl exists for the method. // These are shared by type systems so only one type system needs to // add them here. let method_name = method_info . name . to_string ( ) ; if ! itf_output . method_impls . contains_key ( & method_name ) { itf_output . method_impls . insert ( method_name . clone ( ) , MethodImpl :: new ( method_info . clone ( ) ) ) ; } let method_impl = & mut itf_output . method_impls . get_mut ( & method_name ) . expect ( " " ) ; method_impl . impls . insert ( itf_variant . type_system , rust_to_com_delegate ( itf , itf_variant , & method_info ) , ) ; output . push ( create_virtual_method ( itf , method_info , ts ) ) ; } // Create the vtable. We've already gathered all the vtable method // pointer fields so defining the struct is simple enough. let itf_bound = match itf . item_type { utils :: InterfaceType :: Struct => quote ! ( ) , utils :: InterfaceType :: Trait if itf . implemented_by . is_some ( ) => quote ! ( ) , utils :: InterfaceType :: Trait => quote ! ( itf_ident ) , } ; if itf . vtable_of . is_none ( ) { output . push ( quote_spanned ! ( itf span [ allow ( non_camel_case_types ) ] [ allow ( non_snake_case ) ] [ allow ( clippy all ) ] [ repr ( C ) ] [ doc ( hidden ) ] [ derive ( Clone Copy ) ] visibility struct vtable_path { ( vtbl_fields ) } [ allow ( unused ) ] impl I S intercom attributes ComInterfaceVTableFor I S ts_type_tokens for itf_ref where I Sized S intercom attributes ComClassInterface I ts_type_tokens intercom attributes ComClass itf_bound { const VTABLE vtable_path vtable_path { ( vtbl_values ) } } ) ) ; } let iid_tokens = utils :: get_guid_tokens ( & itf_variant . iid , itf . span ) ; output . push ( quote_spanned ! ( itf_path span ( ) [ allow ( non_camel_case_types ) ] [ allow ( non_snake_case ) ] [ allow ( clippy all ) ] [ doc ( hidden ) ] impl attr_cominterfacevariant for itf_ref { type VTable vtable_path fn iid ( ) ' static intercom IID { iid_tokens } } ) ) ; }
Processes the interface type system variant.
Processes the interface type system variant .
itf
&model::ComInterface
ts
ModelTypeSystem
itf_variant
&model::ComInterfaceVariant
output
&mut Vec<TokenStream>
itf_output
&mut InterfaceOutput
itf
&model::ComInterface
ts
ModelTypeSystem
itf_variant
&model::ComInterfaceVariant
output
&mut Vec<TokenStream>
itf_output
&mut InterfaceOutput