fn process_itf_variant(
    itf : &model::ComInterface,
    ts : ModelTypeSystem,
    itf_variant : &model::ComInterfaceVariant,
    output : &mut Vec<TokenStream>,
    itf_output : &mut InterfaceOutput,
) {

    let itf_ident = itf.name();
    let visibility = itf.visibility();
    let iid_ident = idents::iid( itf_variant.unique_name() );
    let vtable_ident = idents::vtable_struct( itf_variant.unique_name() );

    // IID_IInterface GUID.
    let iid_tokens = utils::get_guid_tokens( itf_variant.iid() );
    let iid_doc = format!( "`{}` interface ID.", itf_ident );
    output.push( quote!(
        #[doc = #iid_doc]
        #[allow(non_upper_case_globals)]
        #visibility const #iid_ident : ::intercom::IID = #iid_tokens;
    ) );

    // Construct the iid(ts) match arm for this type system.
    let ts_match = ts.as_typesystem_tokens();
    itf_output.iid_arms.push( quote!( #ts_match => Some( & #iid_ident ) ) );

    // Create a vector for the virtual table fields and insert the base
    // interface virtual table in it if required.
    let mut vtbl_fields = vec![];
    if let Some( ref base ) = *itf.base_interface() {
        let vtbl = match base.to_string().as_ref() {
            "IUnknown" => quote!( ::intercom::IUnknownVtbl ),
            _ => { let vtbl = idents::vtable_struct( &base ); quote!( #vtbl ) }
        };
        vtbl_fields.push( quote!( pub __base : #vtbl ) );
    }

    // Gather all the trait methods for the remaining vtable fields.
    let calling_convention = get_calling_convetion();
    for method_info in itf_variant.methods() {

        let method_ident = &method_info.unique_name;
        let in_out_args = method_info.raw_com_args()
                .into_iter()
                .map( |com_arg| {
                    let name = &com_arg.name;
                    let com_ty = &com_arg.handler.com_ty( com_arg.dir );
                    let dir = match com_arg.dir {
                        Direction::In => quote!(),
                        Direction::Out | Direction::Retval => quote!( *mut )
                    };
                    quote!( #name : #dir #com_ty )
                } );
        let self_arg = quote!( self_vtable : ::intercom::RawComPtr );
        let args = iter::once( self_arg ).chain( in_out_args );

        // Create the vtable field and add it to the vector of fields.
        let ret_ty = method_info.returnhandler.com_ty();
        vtbl_fields.push( quote!(
            pub #method_ident :
                unsafe extern #calling_convention fn( #( #args ),* ) -> #ret_ty
        ) );

        let method_name = method_info.display_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_variant, method_info, &vtable_ident ) );
    }

    // Create the vtable. We've already gathered all the vtable method
    // pointer fields so defining the struct is simple enough.
    output.push( quote!(
        #[allow(non_camel_case_types)]
        #[repr(C)]
        #[doc(hidden)]
        #visibility struct #vtable_ident { #( #vtbl_fields, )* }
    ) );
}
/// 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_ident = itf.name();
    let visibility = itf.visibility();
    let iid_ident = idents::iid( itf_variant.unique_name() );
    let vtable_ident = idents::vtable_struct( itf_variant.unique_name() );
    // IID_IInterface GUID.
    let iid_tokens = utils::get_guid_tokens( itf_variant.iid() );
    let iid_doc = format!( "`{}` interface ID.", itf_ident );
    output.push( quote!(
        #[doc = #iid_doc]
        #[allow(non_upper_case_globals)]
        #visibility const #iid_ident : ::intercom::IID = #iid_tokens;
    ) );
    // Construct the iid(ts) match arm for this type system.
    let ts_match = ts.as_typesystem_tokens();
    itf_output.iid_arms.push( quote!( #ts_match => Some( & #iid_ident ) ) );
    // Create a vector for the virtual table fields and insert the base
    // interface virtual table in it if required.
    let mut vtbl_fields = vec![];
    if let Some( ref base ) = *itf.base_interface() {
        let vtbl = match base.to_string().as_ref() {
            "IUnknown" => quote!( ::intercom::IUnknownVtbl ),
            _ => { let vtbl = idents::vtable_struct( &base ); quote!( #vtbl ) }
        };
        vtbl_fields.push( quote!( pub __base : #vtbl ) );
    }
    // Gather all the trait methods for the remaining vtable fields.
    let calling_convention = get_calling_convetion();
    for method_info in itf_variant.methods() {
        let method_ident = &method_info.unique_name;
        let in_out_args = method_info.raw_com_args()
                .into_iter()
                .map( |com_arg| {
                    let name = &com_arg.name;
                    let com_ty = &com_arg.handler.com_ty( com_arg.dir );
                    let dir = match com_arg.dir {
                        Direction::In => quote!(),
                        Direction::Out | Direction::Retval => quote!( *mut )
                    };
                    quote!( #name : #dir #com_ty )
                } );
        let self_arg = quote!( self_vtable : ::intercom::RawComPtr );
        let args = iter::once( self_arg ).chain( in_out_args );
        // Create the vtable field and add it to the vector of fields.
        let ret_ty = method_info.returnhandler.com_ty();
        vtbl_fields.push( quote!(
            pub #method_ident :
                unsafe extern #calling_convention fn( #( #args ),* ) -> #ret_ty
        ) );
        let method_name = method_info.display_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_variant, method_info, &vtable_ident ) );
    }
    // Create the vtable. We've already gathered all the vtable method
    // pointer fields so defining the struct is simple enough.
    output.push( quote!(
        #[allow(non_camel_case_types)]
        #[repr(C)]
        #[doc(hidden)]
        #visibility struct #vtable_ident { #( #vtbl_fields, )* }
    ) );
}
fn process_itf_variant ( itf : & model :: ComInterface , ts : ModelTypeSystem , itf_variant : & model :: ComInterfaceVariant , output : & mut Vec < TokenStream > , itf_output : & mut InterfaceOutput , ) { let itf_ident = itf . name ( ) ; let visibility = itf . visibility ( ) ; let iid_ident = idents :: iid ( itf_variant . unique_name ( ) ) ; let vtable_ident = idents :: vtable_struct ( itf_variant . unique_name ( ) ) ; // IID_IInterface GUID. let iid_tokens = utils :: get_guid_tokens ( itf_variant . iid ( ) ) ; let iid_doc = format ! ( " " itf_ident ) ; output . push ( quote ! ( [ doc iid_doc ] [ allow ( non_upper_case_globals ) ] visibility const iid_ident intercom IID iid_tokens ) ) ; // Construct the iid(ts) match arm for this type system. let ts_match = ts . as_typesystem_tokens ( ) ; itf_output . iid_arms . push ( quote ! ( ts_match Some ( iid_ident ) ) ) ; // Create a vector for the virtual table fields and insert the base // interface virtual table in it if required. let mut vtbl_fields = vec ! [ ] ; if let Some ( ref base ) = * itf . base_interface ( ) { let vtbl = match base . to_string ( ) . as_ref ( ) { " " => quote ! ( intercom IUnknownVtbl ) , _ => { let vtbl = idents :: vtable_struct ( & base ) ; quote ! ( vtbl ) } } ; vtbl_fields . push ( quote ! ( pub __base vtbl ) ) ; } // Gather all the trait methods for the remaining vtable fields. let calling_convention = get_calling_convetion ( ) ; for method_info in itf_variant . methods ( ) { let method_ident = & method_info . unique_name ; let in_out_args = method_info . raw_com_args ( ) . into_iter ( ) . map ( | com_arg | { let name = & com_arg . name ; let com_ty = & com_arg . handler . com_ty ( com_arg . dir ) ; let dir = match com_arg . dir { Direction :: In => quote ! ( ) , Direction :: Out | Direction :: Retval => quote ! ( mut ) } ; quote ! ( name dir com_ty ) } ) ; let self_arg = quote ! ( self_vtable intercom RawComPtr ) ; let args = iter :: once ( self_arg ) . chain ( in_out_args ) ; // Create the vtable field and add it to the vector of fields. let ret_ty = method_info . returnhandler . com_ty ( ) ; vtbl_fields . push ( quote ! ( pub method_ident unsafe extern calling_convention fn ( ( args ) ) ret_ty ) ) ; let method_name = method_info . display_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_variant , method_info , & vtable_ident ) ) ; } // Create the vtable. We've already gathered all the vtable method // pointer fields so defining the struct is simple enough. output . push ( quote ! ( [ allow ( non_camel_case_types ) ] [ repr ( C ) ] [ doc ( hidden ) ] visibility struct vtable_ident { ( vtbl_fields ) } ) ) ; }
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