void CGenerateWindowsRuntimeAdapter::codeGenerate()

in src/codegen/tool/GenerateWindowsRuntimeAdapter.cpp [528:873]


void CGenerateWindowsRuntimeAdapter::codeGenerate(const schema::CObservableObjectInfo *pPropertyModelInfo)
{
    bool isViewModel = pPropertyModelInfo->getModelType() == ::schema::ModelTypeInfoType_ViewModel;

    _osInterfaceForwardIdl << "\t"  << "interface "<< pPropertyModelInfo->getName() <<";" << std::endl;

    std::wstring typeInfoName = toTypeInfoName(pPropertyModelInfo->getName());

#if 0
	_osRuntimeClassesIdl << FormatW(_winRTRuntimeClass_Template,
		typeInfoName.c_str(),
		pPropertyModelInfo->getName().c_str(),
		nullptr);	
#endif

    std::wostringstream osIdlProperties;
    std::wostringstream osIdlMethods;

    std::wostringstream osIdlPropertiesEnums;
    std::wostringstream osIdlMethodEnums;
    std::wostringstream osIdlEventsEnums;

    std::wostringstream ocClassAdapterContent;

    std::vector<const schema::CObservableObjectInfo *> descendents;
    pPropertyModelInfo->getDescendents(descendents);
    // TODO: we are only generating 'Source' property for 'final'
    // interfaces to avoid the duplication of property names
    if (isViewModel && descendents.size() == 0 )
    {
        const schema::CObservableObjectInfo *pSourceType = ((const schema::CPropertyViewModelInfo *)pPropertyModelInfo)->getSourceType();

        if (!pSourceType->getParent().isFactorySchema())
        {
            // Generate IDL source code
            osIdlProperties << FormatW(_getSourceModelIdl_Template,
                toIdlModelTypeInfo(pSourceType).data(),
                nullptr);

            // Generate Model Adapter source code
            ocClassAdapterContent << FormatW(_getSourceModel_Template,
                toNativeModelTypeName(pSourceType).data(),
                getCoreNamespace(),
                nullptr);
        }
    }

    // Iterate Events
    for(schema::_EventIteratorType::const_iterator iter = pPropertyModelInfo->getEvents().begin();
        iter != pPropertyModelInfo->getEvents().end();
        ++iter)
    {
        // Emit Enum Events
        osIdlEventsEnums << "\t\t" << (*iter)->getName() << " = " << (*iter)->getId() <<  "," << std::endl;
    }

    // Iterate Properties
    for(schema::_PropertyIteratorType::const_iterator iter = pPropertyModelInfo->getProperties().begin();
        iter != pPropertyModelInfo->getProperties().end();
        ++iter)
    {
        bool isPropertyArray = ((*iter)->getPropertyType() & 0x400) != 0;

        // Emit Enum Properties
        osIdlPropertiesEnums << "\t\t" << (*iter)->getName() << " = ";
        if((*iter)->isParent())
        {
            osIdlPropertiesEnums << "0x2001";
        }
        else
        {
            osIdlPropertiesEnums << (*iter)->getId();
        }
        if(isViewModel)
        {
            osIdlPropertiesEnums << " + 0x1000";
        }
        osIdlPropertiesEnums << "," << std::endl;

        UINT32 flags = (*iter)->getFlags();
        if((flags & PropertyFlagType_CanRead))
        {
            // Idl generation
            osIdlProperties << FormatW(isPropertyArray ? _getPropertyArrayIdl_Template:_getPropertyIdl_Template,
                (*iter)->getName().data(),
                toIdlPropertyTypeInfo(*iter).data(),
                nullptr);
            // class adapter generation
            ocClassAdapterContent << FormatW(isPropertyArray ? _getPropertyArray_Template: _getProperty_Template,
                (*iter)->getName().data(),
                toNativePropertyTypeInfo(*iter).data(),
                typeInfoName.data(),
                nullptr);

        }
        if((flags & PropertyFlagType_CanWrite))
        {
            // Idl generation
            osIdlProperties << FormatW(isPropertyArray ? _setPropertyArrayIdl_Template:_setPropertyIdl_Template,
                (*iter)->getName().data(),
                toIdlPropertyTypeInfo(*iter).data(),
                nullptr);

            std::wstring castValue = L"";
            if((flags & PropertyFlagType_IsEnum) && !isPropertyTypeInfoArray(*iter))
            {
                castValue = L"(UINT32)";
            }
            // class adapter generation
            ocClassAdapterContent << FormatW(isPropertyArray ? _setPropertyArrayTemplate: _setPropertyTemplate,
                (*iter)->getName().data(),
                toNativePropertyTypeInfo(*iter).data(),
                typeInfoName.data(),
                castValue.data(),
                nullptr);
        }
    }

    // Iterate Methods
    for(schema::_MethodIteratorType::const_iterator iter = pPropertyModelInfo->getMethods().begin();
        iter != pPropertyModelInfo->getMethods().end();
        ++iter)
    {
       // Emit Enum Methods
        osIdlMethodEnums << "\t\t" << (*iter)->getName() << " = " << (*iter)->getId();
        if(isViewModel)
        {
            osIdlMethodEnums << " + 0x1000";
        }
        osIdlMethodEnums << "," << std::endl;

        // Emit Idl declare method & Adapter Class Content
        osIdlMethods << "\t\t" << "HRESULT " << (*iter)->getName() << "(";
        ocClassAdapterContent << "\t" << "HRESULT STDMETHODCALLTYPE " << (*iter)->getName() << "(";

        std::wostringstream osAdapterParams;
        if((*iter)->getParameters().size())
        {
            osAdapterParams << "\t\t" << "foundation::InspectablePtr parameters[" << (*iter)->getParameters().size() << "];" << std::endl;

        }

        int parameterIndex = 1;
        for(schema::_MethodParamIteratorType::const_iterator iterParam = (*iter)->getParameters().begin();
            iterParam != (*iter)->getParameters().end();
            ++iterParam)
        {
            bool isParamerterArray = ((*iterParam)->getPropertyType() & 0x400) != 0;

            if(iterParam != (*iter)->getParameters().begin())
            {
                osIdlMethods << ",";
                ocClassAdapterContent << ",";
            }
            if(isParamerterArray)
            {
                osIdlMethods << "[in]UINT32 length_" << parameterIndex << ",";
                ocClassAdapterContent << "UINT32 length_" << parameterIndex << ",";
            }

            osIdlMethods << "[in";
            if(isParamerterArray)
            {
                osIdlMethods << ",size_is(length_" << parameterIndex << ")";
            }

            osIdlMethods << "]" << toIdlPropertyTypeInfo(*iterParam) << " " << (*iterParam)->getParameterName();
            ocClassAdapterContent << toNativePropertyTypeInfo(*iterParam) << " " << (*iterParam)->getParameterName();

            if ((*iterParam)->getPropertyType() == foundation::PropertyType_Inspectable)
            {
                osAdapterParams
                    << "\t\tparameters["
                    << (int)(iterParam - (*iter)->getParameters().begin())
                    << "] = " << (*iterParam)->getParameterName() << ";" << std::endl;
            }
            else
            {
                osAdapterParams << "\t\t" << "IFHR_ASSERT(foundation::pv_util::GetPropertyValueStatics()->Create"
                    << toPropertyTypeName((*iterParam)->getPropertyType()) << "(";

                if (isParamerterArray)
                {
                    osAdapterParams << "length_" << parameterIndex << ",";
                }

                // TODO: workaround to force an Enum type to be casted as UINT32
                // the Parameter Info does not give me a way to know a type if an Enum
                if ((*iterParam)->getPropertyType() == foundation::PropertyType_UInt32)
                {
                    osAdapterParams << "(UINT32)";
                }

                if (isParamerterArray && hasPropertyTypeInfoModel(*iterParam))
                {
                    osAdapterParams << "reinterpret_cast<IInspectable **>(" << (*iterParam)->getParameterName() << ")";
                }
                else
                {
                    osAdapterParams << (*iterParam)->getParameterName();
                }
                osAdapterParams
                    << ",parameters["
                    << (int)(iterParam - (*iter)->getParameters().begin())
                    << "].GetAddressOfPtr()));" << std::endl;
            }

            ++parameterIndex;
        }

        bool hasResult = (*iter)->getResultType()->getPropertyType() != foundation::PropertyType::PropertyType_Empty;
        bool isAsync = (*iter)->getIsAsync();
        
        bool isResultArray = ((*iter)->getResultType()->getPropertyType() & 0x400) != 0;
        if (hasResult || isAsync)
        {
            if((*iter)->getParameters().size())
            {
                osIdlMethods << ",";
                ocClassAdapterContent << ",";
            }
            if(isResultArray)
            {
                osIdlMethods << "[out]UINT32 *length,";
                ocClassAdapterContent << "UINT32 *length,";
            }
            osIdlMethods << "[out,";
            if(!(*iter)->getIsAsync() && isResultArray)
            {
                osIdlMethods << "size_is(,*length),";
            }
            osIdlMethods << "retval]" << toIdlResultTypeInfo((*iter)->getResultType(),(*iter)->getIsAsync()) << "*result";
            ocClassAdapterContent << toNativeResultTypeInfo((*iter)->getResultType(),(*iter)->getIsAsync()) << "*result";
        }
        osIdlMethods << ");" << std::endl;
        ocClassAdapterContent << ")" << std::endl;
        ocClassAdapterContent << "\t" << "{" <<std::endl;
        ocClassAdapterContent << "\t\t" << "HRESULT hr = S_OK;" <<std::endl;
        ocClassAdapterContent << "\t\t" << "foundation::InspectablePtr spResult;" <<std::endl;
        ocClassAdapterContent << osAdapterParams.str();
        ocClassAdapterContent << "\t\t" << "IFHR(__super::Invoke(" << typeInfoName << "::Method_" 
            << (*iter)->getName() << "," << (*iter)->getParameters().size() << ",";
        if((*iter)->getParameters().size())
        {
            ocClassAdapterContent << "parameters[0].GetAddressOfPtr()";
        }
        else
        {
            ocClassAdapterContent << "nullptr";
        }
        ocClassAdapterContent << ",spResult.GetAddressOf()));"  <<std::endl;
        if (hasResult || isAsync)
        {
            if((*iter)->getIsAsync())
            {
                ocClassAdapterContent << FormatW(
                    _returnModelAdapter,
                    toNativeAsyncOperation((*iter)->getResultType()).data(),
                    nullptr);
            }
            else if((*iter)->getResultType()->getPropertyType() == foundation::PropertyType::PropertyType_Inspectable)
            {
                ocClassAdapterContent << FormatW(_returnModelAdapter,
                    toNativePropertyTypeInfo((*iter)->getResultType()).data(),
                            nullptr);
            }
            else
            {
                if (isPropertyTypeInfoEnum((*iter)->getResultType()))
                {
                    ocClassAdapterContent << FormatW(_returnEnumValueAdapter,
                        toNativePropertyTypeInfo((*iter)->getResultType()).c_str(),
                        nullptr);
                }
                else
                {
                    ocClassAdapterContent << FormatW(_returnValueAdapter,
                        toPropertyTypeName((*iter)->getResultType()->getPropertyType()).c_str(),
                        isResultArray ? L"length," : L"",
                        nullptr);
                }
            }
        }
        ocClassAdapterContent << "\t\t" << "return S_OK;" <<std::endl;
        ocClassAdapterContent << "\t" << "}" <<std::endl;
    }

    std::wstring idlBaseType;
    if(pPropertyModelInfo->getBaseType())
    {
        idlBaseType = toIdlModelTypeName(pPropertyModelInfo->getBaseType());
    }
    else
    {
        idlBaseType = _idlCoreNamespace;
        idlBaseType += L".IObservableObject";
    }

    _osInterfacesIdl << FormatW(_winRTInterface_Template,
        pPropertyModelInfo->getName().data(),
        toIdlIIDType(pPropertyModelInfo).data(),
        idlBaseType.data(),
        osIdlProperties.str().data(),
        osIdlMethods.str().data(),
        nullptr);

    if(pPropertyModelInfo->getProperties().size())
    {
        _osInterfacesIdl << FormatW(_winRTEnum_Template,
            (typeInfoName + L"Properties").data(),
            osIdlPropertiesEnums.str().data(),
            nullptr);
    }

    if(pPropertyModelInfo->getMethods().size())
    {
        _osInterfacesIdl << FormatW(_winRTEnum_Template,
            (typeInfoName + L"Methods").data(),
            osIdlMethodEnums.str().data(),
            nullptr);
    }

    if(pPropertyModelInfo->getEvents().size())
    {
        _osInterfacesIdl << FormatW(_winRTEnum_Template,
            (typeInfoName + L"Events").data(),
            osIdlEventsEnums.str().data(),
            nullptr);
    }
    
    // Emit Source Adapter Class
    _osModelAdapterSrc << FormatW(
        _classPropertyModelAdapter_Template,
        typeInfoName.data(),
        toNativeModelTypeName(pPropertyModelInfo).data(),
        ocClassAdapterContent.str().data(),
        nullptr);

    // Emit type adapter factory entry
    _osModelAdapterFactoryEntries << FormatW(
        _modelAdapterEntryFactory_Template,
        toNativeModelTypeName(pPropertyModelInfo).data(),
        typeInfoName.data(),
        getFoundationNamespace(),
        nullptr);
}