void CGenerateObjectiveC::codeGenerate()

in src/codegen/tool/GenerateObjectiveC.cpp [252:637]


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

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

    schema::CObservableObjectInfo *pBaseType = (schema::CObservableObjectInfo *)pPropertyModelInfo->getBaseType();
    
    std::wstring protocolBaseName = pBaseType ? pBaseType->getName(): L"PMODObservableObject";
    
    _osForwardsInc << "@protocol " << pPropertyModelInfo->getName() << ";" << std::endl;
    _osProtocolsInc << "@protocol " << pPropertyModelInfo->getName() << " <" << protocolBaseName << ">" <<  std::endl;
    
    // protocol implementation
    std::wstring baseClassName = pBaseType ? _adapterPrefix + toTypeInfoName(pBaseType->getName()) : L"PMODObservableObject";
    _osProtocolsSrc << "@interface " << _adapterPrefix << typeInfoName << ": " << baseClassName << "<" << pPropertyModelInfo->getName() << ">" << std::endl;

    _osProtocolsSrc << "@end" << std::endl << std::endl;
    _osProtocolsSrc << "@implementation " << _adapterPrefix << typeInfoName << std::endl;

    std::wstring interfaceAdapterSelector;
    if (_useInterfaceAdapter)
    {
        interfaceAdapterSelector = typeInfoName;
        interfaceAdapterSelector[0] = tolower(interfaceAdapterSelector[0]);
        
        std::wstring typeInfoNameWithNamespace = this->getNativeNamespaceLookup(pPropertyModelInfo->getParent().getNamespace());
        typeInfoNameWithNamespace += L"::";
        typeInfoNameWithNamespace += pPropertyModelInfo->getName();
        
        _osProtocolsSrc << FormatW(
                                  _ns_InterfaceAdapterSelectors_Template,
                                  typeInfoNameWithNamespace.c_str(),
                                  interfaceAdapterSelector.c_str(),
                                  nullptr
                                  );
    }

    if(isViewModel)
    {
        const schema::CPropertyViewModelInfo *pPropertyViewModelInfo = (const schema::CPropertyViewModelInfo *)pPropertyModelInfo;
        
        std::wstring sourcetInterfaceName = pPropertyViewModelInfo->getSourceType()->getName();
        // forward source type
        _osForwardsInc << "@protocol " << sourcetInterfaceName << ";" << std::endl;
        
        _osProtocolsInc << FormatW(_ns_SourceInc_Template,
                                  sourcetInterfaceName.data(),
                                  nullptr);

        _osProtocolsSrc << FormatW(_ns_SourceSrc_Template,
                                  sourcetInterfaceName.data(),
                                  nullptr);

    }

    // Properties enum Start
    if(pPropertyModelInfo->getProperties().size())
    {
        _osEnumsPropertiesInc << "typedef enum " << std::endl;
        _osEnumsPropertiesInc << "{" << std::endl;
    }
    
    // Iterate Properties
    for(schema::_PropertyIteratorType::const_iterator iter = pPropertyModelInfo->getProperties().begin();
        iter != pPropertyModelInfo->getProperties().end();
        ++iter)
    {
        // generate property id
        _osEnumsPropertiesInc << '\t' << typeInfoName << "_Property_" << (*iter)->getName() << " = " << (*iter)->getId() << ',' << std::endl;

        UINT32 flags = (*iter)->getFlags();
        std::wstring objectiveCTypeName = toObjectiveCType(*iter);
        bool isNumberValue = (*iter)->getPropertyType() <= foundation::PropertyType::PropertyType_Boolean;
        
        if((flags & PropertyFlagType_CanRead))
        {
            std::wstring nsPropertyName = (*iter)->getName();
            nsPropertyName[0] = tolower(nsPropertyName[0]);
            
            // Emit Inc 
            _osProtocolsInc << "-(" << objectiveCTypeName << ") " << nsPropertyName << ";" << std::endl;
            
            // Emit Src
            _osProtocolsSrc << "-(" << objectiveCTypeName << ") " << nsPropertyName  << std::endl;
            _osProtocolsSrc << "{" << std::endl;
            
            if (_useInterfaceAdapter)
            {
                _osProtocolsSrc << "\t";
                emitModelTypeVarDeclare(_osProtocolsSrc, (*iter), L"value");

                _osProtocolsSrc << "\t" << "[PMODInterop throwIfFailed : (";
                _osProtocolsSrc << "self." << interfaceAdapterSelector << "->Get" << (*iter)->getName() << "(";

                emitOutputPtrVar(_osProtocolsSrc,(*iter),L"value");
                _osProtocolsSrc  << "))];" << std::endl;

                _osProtocolsSrc << "\t";
                emitNSReturn(_osProtocolsSrc,*iter,L"value");
            }
            else
            {
                _osProtocolsSrc << "\t" << "return ";
                if(isNumberValue)
                {
                    if(flags & PropertyFlagType_IsEnum)
                    {
                        // cast to enum return
                        _osProtocolsSrc << "(" << (*iter)->getModelType()->getName() << ")";
                    }
                    _osProtocolsSrc << "[[";
                }
                else
                {
                    // generate cast to the returned value
                    _osProtocolsSrc << "(" << objectiveCTypeName << ")[";
                }
                _osProtocolsSrc << "self valueForProperty:" << getNamespace()
                    << "::" << typeInfoName << "::Property_" << (*iter)->getName() << "]";
                if(isNumberValue)
                {
                    _osProtocolsSrc << " " << toNSNumberValue((*iter)->getPropertyType()) << "]";
                }
                _osProtocolsSrc << ";" << std::endl;
            }
            _osProtocolsSrc << "}" << std::endl;
        }
        if((flags & PropertyFlagType_CanWrite))
        {
            // Emit Inc
            _osProtocolsInc << "-(void) set" << (*iter)->getName() << ":(" << objectiveCTypeName << ") value;" << std::endl;
            
            // Emit Src
            _osProtocolsSrc << "-(void) set" << (*iter)->getName() << ":(" << objectiveCTypeName << ") value" << std::endl;
            _osProtocolsSrc << "{" << std::endl;
 
            if (_useInterfaceAdapter)
            {
                emitFoundationVar(
                    _osProtocolsSrc,
                    (*iter),
                    L"value",
                    L"value_foundation");
                _osProtocolsSrc << "\t" << "[PMODInterop throwIfFailed : (";
                _osProtocolsSrc << "self." << interfaceAdapterSelector << "->Set" << (*iter)->getName() << "(";
                emitInputPtrVar(_osProtocolsSrc,*iter,L"value_foundation");
                _osProtocolsSrc << "))];" << std::endl;
            }
            else
            {
                _osProtocolsSrc << "\t" << "[self setValueForProperty:" << getNamespace()
                    << "::" << typeInfoName << "::Property_" << (*iter)->getName() << " value:";
                if(isNumberValue)
                {
                    _osProtocolsSrc << "[NSNumber " << toNSNumberWithValue((*iter)->getPropertyType()) << ":value]";
                }
                else
                {
                    _osProtocolsSrc << "value";
                }
                _osProtocolsSrc << "];" << std::endl;
            }

            _osProtocolsSrc << "}" << std::endl;
        }
        _osProtocolsInc << std::endl;
        _osProtocolsSrc << std::endl;
    }
    
    // Iterate Methods
    for(schema::_MethodIteratorType::const_iterator iter = pPropertyModelInfo->getMethods().begin();
        iter != pPropertyModelInfo->getMethods().end();
        ++iter)
    {
        std::wstring nsMethodName = (*iter)->getName();
        nsMethodName[0] = tolower(nsMethodName[0]);

        bool isAsync = (*iter)->getIsAsync();
        
        std::wstring objcResultTypeName = isAsync ?
            toObjectiveCAsyncOperation():
            toObjectiveCType((*iter)->getResultType());
        
        bool hasResult = (*iter)->getResultType() && (*iter)->getResultType()->getPropertyType() != foundation::PropertyType_Empty;
        // Emit Inc
        _osProtocolsInc << "-(" << objcResultTypeName << ") " << nsMethodName;
        // Emit Src
        _osProtocolsSrc << "-(" << objcResultTypeName << ") " << nsMethodName;
       
        std::wostringstream osAdaptersVars;
        std::wostringstream osAdapterInvoke;

        std::wostringstream osAttachParameters;
        // generate Param Array
        for(schema::_MethodParamIteratorType::const_iterator iterParam = (*iter)->getParameters().begin();
            iterParam != (*iter)->getParameters().end();
            ++iterParam)
        {
            std::wstring objcParamTypeName = toObjectiveCType(*iterParam);

            if (iterParam != (*iter)->getParameters().begin())
            {
                _osProtocolsInc << (*iterParam)->getParameterName();
                _osProtocolsSrc << (*iterParam)->getParameterName();
                if (_useInterfaceAdapter)
                {
                    osAdapterInvoke << ",";
                }
            }
            // Emit Inc
            _osProtocolsInc << ":";
            _osProtocolsInc << "(" << objcParamTypeName << ") " << (*iterParam)->getParameterName() << ' ';
            // Emit Src
            _osProtocolsSrc << ":";
            _osProtocolsSrc << "(" << objcParamTypeName << ") " << (*iterParam)->getParameterName() << ' ';

            if (_useInterfaceAdapter)
            {
                std::wstring varAdapterName = (*iterParam)->getParameterName() + L"_foundation";
                emitFoundationVar(
                    osAdaptersVars,
                    (*iterParam),
                    (*iterParam)->getParameterName().c_str(),
                    varAdapterName.c_str());

                emitInputPtrVar(osAdapterInvoke, (*iterParam), varAdapterName.c_str());
            }
            else
            {
                // attach parameter
                osAttachParameters << '\t' << "params[" << (size_t)(iterParam-(*iter)->getParameters().begin()) << "]";
            
                foundation::PropertyType paramPropertyType =  (*iterParam)->getPropertyType();
            
                if(paramPropertyType >= foundation::PropertyType_UInt8 &&
                   paramPropertyType <= foundation::PropertyType_Boolean)
                {
                    osAttachParameters << " = " << getFoundationNamespace()
                    << "::CreateValue(" << (*iterParam)->getParameterName();
                    if(paramPropertyType == foundation::PropertyType_Boolean)
                    {
                        osAttachParameters << " ? true:false";
                    }
                    osAttachParameters << ");" << std::endl;
                }
                else
                {
                    osAttachParameters << ".Attach(";
                    osAttachParameters << "[PMODInterop fromNSValue:" << (*iterParam)->getParameterName() << "]);" << std::endl;
                }
            }
        }
        _osProtocolsInc << ";" << std::endl;
        
        std::wostringstream osReturnStatement;
        if(hasResult || isAsync)
        {
            if (_useInterfaceAdapter)
            {
                osAdaptersVars << "\t";
                if (isAsync)
                {
                    osAdaptersVars
                        << "foundation::ComPtr<"
                        << toPropertyTypeInfoAsync((*iter)->getResultType(),true)
                        << "> result;" << std::endl;
                }
                else
                {
                    emitModelTypeVarDeclare(osAdaptersVars, (*iter)->getResultType(), L"result");
                }
            }
            else
            {
                foundation::PropertyType resultPropertyType = (*iter)->getResultType()->getPropertyType();
                if(! isAsync && (
                   resultPropertyType >= foundation::PropertyType_UInt8 &&
                   resultPropertyType <= foundation::PropertyType_Boolean)
                   )
                {
                    osReturnStatement << '\t' << toCoreType(resultPropertyType) << " resultValue;" << std::endl;
                    osReturnStatement << '\t' << getFoundationNamespace() << "::pv_util::GetValue(result,&resultValue);" << std::endl;
                    osReturnStatement << '\t' << "return resultValue;";
                }
                else
                {
                    osReturnStatement << '\t' << "return (" << objcResultTypeName << ") [self toNSObject:result];" << std::endl;
                }
            }
        }

        if (_useInterfaceAdapter)
        {
            _osProtocolsSrc << std::endl << "{" << std::endl;
            _osProtocolsSrc << osAdaptersVars.str().c_str() << std::endl;
            _osProtocolsSrc << "\t" << "[PMODInterop throwIfFailed : ";
            _osProtocolsSrc << "self." << interfaceAdapterSelector << "->" << (*iter)->getName() << "(";
            _osProtocolsSrc << osAdapterInvoke.str();
            if (hasResult || isAsync)
            {
                if ((*iter)->getParameters().size())
                {
                    _osProtocolsSrc << ",";
                }
                if (isAsync)
                {
                    _osProtocolsSrc << "result.GetAddressOf()";
                }
                else
                {
                    emitOutputPtrVar(_osProtocolsSrc, (*iter)->getResultType(),L"result");
                }
            }
            _osProtocolsSrc << ")];" << std::endl;
            _osProtocolsSrc << "\t";
            if (hasResult || isAsync)
            {
                if (isAsync)
                {
                    _osProtocolsSrc << "return (id<PMODAsyncOperation>)[self toNSObject : result];" << std::endl;
                }
                else
                {
                    emitNSReturn(_osProtocolsSrc, (*iter)->getResultType(), L"result");
                }
            }

            _osProtocolsSrc << "}" << std::endl;
        }
        else
        {
            std::wostringstream osCount;
            osCount << (*iter)->getParameters().size();
        
            _osProtocolsSrc << FormatW(_ns_MethodInvoke_Template,
                         (getNamespace() + L"::" + typeInfoName).data(),
                         (*iter)->getName().data(),
                         osCount.str().data(),
                         osAttachParameters.str().data(),
                         osReturnStatement.str().data(),
                         nullptr);
        }
     }
    
    _osProtocolsInc << "@end" << std::endl << std::endl;
    _osProtocolsSrc << "@end" << std::endl << std::endl;
 
    if(pPropertyModelInfo->getProperties().size())
    {
        _osEnumsPropertiesInc << "} " << typeInfoName << "_Properties" << ";" << std::endl;
        _osEnumsPropertiesInc << std::endl;
    }

    // generate EventInfo enums
    if(pPropertyModelInfo->getEvents().size())
    {
        _osEnumsEventsInc << "typedef enum " << std::endl;
        _osEnumsEventsInc << "{" << std::endl;
        for(schema::_EventIteratorType::const_iterator iter = pPropertyModelInfo->getEvents().begin();
            iter != pPropertyModelInfo->getEvents().end();
            ++iter)
        {
            // generate event id
            _osEnumsEventsInc << '\t' << typeInfoName << "_Event_" << (*iter)->getName() << " = " << (*iter)->getId() << ',' << std::endl;
        }
        _osEnumsEventsInc << "} " << typeInfoName << "_Events" << ";" << std::endl;
        _osEnumsEventsInc << std::endl;
        
    }

    // register factory entries
    _osFactoryEntries <<  "\t" << "[adapterFactory registerAdapterFactoryClass:[PMODInterop toIIDString:" <<
        this->getNamespace() << "::" << typeInfoName << "::IIDType] adapterClass:[" << _adapterPrefix << typeInfoName << " class]];" << std::endl;
    
    // factory types 
    _osFactoryTypesInc << "+(NSString *) " << typeInfoName << "Type;" << std::endl;
    _osFactoryTypesSrc << FormatW(
        _nsFactoryTypeSrc_Template,
        typeInfoName.data(),
        this->getNamespace().data(),
        typeInfoName.data(),
        nullptr);
    

}