void CGenerateFastCppTemplate::emitPropertyAccessMethods()

in src/codegen/tool/GenerateFastCppTemplate.cpp [1801:2027]


void CGenerateFastCppTemplate::emitPropertyAccessMethods(
    std::wostream& osPublicAccess,
    std::wostream& osInternalAccess,
    std::wostream& osPrivateAccess,
    std::wostream& osPrivateAccessDeclare,
    const schema::CPropertyInfo*pPropertyInfo)
{
    std::wstring typeInfoName = toTypeInfoName(pPropertyInfo->getParent().getName());

    std::wstring typeInfoNameCodeGen = this->toCodeGenTypeName(typeInfoName);

    std::wstring propertyNameCodeGen = this->toCodeGenTypeName(pPropertyInfo->getName());
    std::wstring propertyNameMemberCodeGen = this->toCodeGenVarName(pPropertyInfo->getName());

    bool isPropertyArray = (pPropertyInfo->getPropertyType() & 0x400) != 0;
    bool isAncestor = (pPropertyInfo->getFlags() & PropertyFlagType_IsAncestor) != 0;
    bool isWeakRef = (pPropertyInfo->getFlags() & PropertyFlagType_IsWeakReference) != 0;
    bool isEnum = (pPropertyInfo->getFlags() & PropertyFlagType_IsEnum) != 0;

    osPublicAccess << "\t// Property:" << pPropertyInfo->getName() << std::endl;

    // Emit public Get method
    osPublicAccess << "\tHRESULT " << "Get" << pPropertyInfo->getName() << "(";
    emitDeclarePropertyTypeInfo(osPublicAccess, pPropertyInfo, true);
    osPublicAccess << " pValue) override" << std::endl;
    osPublicAccess << "\t{" << std::endl;
    if (isAncestor)
    {
        osPublicAccess << FormatW(_fastModelAncestorPropertyGet_Template,
            toTypeInfoName(pPropertyInfo->getParent().getName().c_str()).data(),
            pPropertyInfo->getName().data(),
            nullptr) << std::endl;
    }
    else
    {

        osPublicAccess << "\t\treturn this->GetPropertyInternal("
            << typeInfoName << "::Property_" << pPropertyInfo->getName() << ",[=] {" << std::endl
            << "\t\t\tfoundation::library::FoundationCriticalSection cs(this->GetCriticalSection());" << std::endl;

        if (pPropertyInfo->isRuntimeActivated())
        {
            osPublicAccess << FormatW(_fastModelEnsureActivationCall_Template,propertyNameCodeGen.data(), nullptr);
        }
        else
        {
            osPublicAccess << "\t\t\treturn this->Get" << propertyNameCodeGen << "Internal(" << (isPropertyArray ? "size ," : "") << "pValue);" << std::endl;
        }
        osPublicAccess << "\t\t});" << std::endl;

    }
    osPublicAccess << "\t}" << std::endl;

    bool canWriteProperty = (pPropertyInfo->getFlags() & PropertyFlagType_CanWrite) != 0;
    // emit set property access (public or private depending on schema flags)
    if (!isAncestor)
    {
        std::wostream& osSetProperty = canWriteProperty ? osPublicAccess : osPrivateAccess;

        bool isArray = isPropertyTypeInfoArray(pPropertyInfo);

        // Emit public set method
        osSetProperty << "\tHRESULT " << "Set" << pPropertyInfo->getName() << "(";
        emitDeclarePropertyTypeInfo(osSetProperty, pPropertyInfo, false);
        osSetProperty << " value) override" << std::endl;
        osSetProperty << "\t{" << std::endl;

        osSetProperty << "\t\treturn this->Set" << (isEnum && !isArray ? "Enum" : "") << "PropertyInternal("
            << typeInfoName
            << "::Property_"
            << pPropertyInfo->getName()
            << (isPropertyArray ? ", size" : "")
            << ", ";
        if (isEnum && !isArray) {
            osSetProperty << FormatW(L"{0}::{1}::TypeId,", 
                this->getNamespaceLookup(pPropertyInfo->getModelType()).c_str(),
                toTypeInfoName((const schema::CEnumTypeInfo *)pPropertyInfo->getModelType()).c_str(), nullptr);
        }
        osSetProperty << "value); " << std::endl;
        osSetProperty << "\t}" << std::endl;
    }

    
    // generate private access only if the property is write only
    if ((pPropertyInfo->getFlags() & PropertyFlagType_CanRead) == 0)
    {
        // Emit set internal interface declare
        osPrivateAccessDeclare << "\tvirtual HRESULT " << "Get" << pPropertyInfo->getName() << "(";
        emitDeclarePropertyTypeInfo(osPrivateAccessDeclare, pPropertyInfo, true);
        osPrivateAccessDeclare << " value) = 0;" << std::endl;
    }

    // Simple getters and setters
    std::wostringstream typeDeclare;
    emitModelTypeVarDeclare(typeDeclare, pPropertyInfo, L"value");

    std::wostringstream returnTypeDeclare;
    emitWrapperPropertyTypeInfo(returnTypeDeclare, pPropertyInfo);

    // emit simple getter
    if (isAncestor || pPropertyInfo->isParent())
    {   
        osPublicAccess << FormatW(_fastModelGetAncestorTypeDirectly_Template,
            returnTypeDeclare.str().data(),            
            pPropertyInfo->getName().data(),
            typeDeclare.str().data(),
            nullptr) << std::endl;
    }
    else if (isWeakRef)
    {
        osPublicAccess << FormatW(_fastModelGetWeakPropertyRef_Template,
            returnTypeDeclare.str().data(),
            pPropertyInfo->getName().data(),
            typeDeclare.str().data(),
            propertyNameCodeGen.data(),
            nullptr) << std::endl;
    }
    else if (!pPropertyInfo->isCustomContainer())
    {
        std::wostringstream typeDeclareArray;
        if (isPropertyArray)
        {            
            typeDeclareArray << "const ";
            emitArrayWrapperType(typeDeclareArray, pPropertyInfo, L"", true);
        }

        // make simple types getter methods be const.
        std::wstring methodConst;
        if (!pPropertyInfo->getModelType() || pPropertyInfo->getModelType()->getModelType() == schema::ModelTypeInfoType_Enum)
        {
            methodConst = L"const";
        }
        
        osPublicAccess << FormatW(_fastModelGetArrayWrapperRef_Template,
            isPropertyArray ? typeDeclareArray.str().data() : returnTypeDeclare.str().data(),
            pPropertyInfo->getName().data(),
            toContainerPropertyName(pPropertyInfo->getName().c_str()).data(), 
            methodConst.data(),
            nullptr) << std::endl;
    }

    // exit if its ancestor we dont need internal setters.
    if (isAncestor)
    {
        return;
    }

    // Emit internal get method
    osInternalAccess << "\tvirtual HRESULT " << "Get" << propertyNameCodeGen << "Internal(";
    emitDeclarePropertyTypeInfo(osInternalAccess, pPropertyInfo, true);
    osInternalAccess << " pValue)" << std::endl;
    osInternalAccess << "\t{" << std::endl;
    if (pPropertyInfo->isCustomContainer())
    {
        osInternalAccess << "\t\tfoundation_assert(false);" << std::endl;
        osInternalAccess << "\t\treturn S_OK;\n" << std::endl;
    }
    else if (pPropertyInfo->getModelType() && pPropertyInfo->getModelType()->getModelType() == schema::ModelTypeInfoType_Command)
    {
        osInternalAccess << "\t\treturn foundation::QueryInterfaceIf(_" << propertyNameMemberCodeGen << "Value";
        if (pPropertyInfo->isAutoGenerate())
        {
            // it is a class command
            osInternalAccess << "->CastToUnknown()";
        }
        osInternalAccess << ", pValue); " << std::endl;
    }	
    else
    {
        emitInternalGetBodyMethods(osInternalAccess, pPropertyInfo);
    }
    osInternalAccess << "\t}" << std::endl;

    if (!pPropertyInfo->isParent())
    {		
        // Emit internal set method
        osInternalAccess << "\tvirtual HRESULT " << "Set" << propertyNameCodeGen << "Internal(";
        emitDeclarePropertyTypeInfo(osInternalAccess, pPropertyInfo, false);
        osInternalAccess << " value)" << std::endl;
        osInternalAccess << "\t{" << std::endl;
        if (pPropertyInfo->getFlags() & PropertyFlagType_IsWeakReference)
        {
            osInternalAccess <<"\t\treturn "<< toContainerPropertyName(pPropertyInfo->getName().c_str()) << ".Attach(value);" << std::endl;
        }
        else if (pPropertyInfo->isCustomContainer())
        {
            osInternalAccess << "\t\tfoundation_assert(false);" << std::endl;
            osInternalAccess << "\t\treturn S_OK;" << std::endl;
        }
        else if (pPropertyInfo->getModelType() && pPropertyInfo->getModelType()->getModelType() == schema::ModelTypeInfoType_Command)
        {
            //TODO:: do nothing for now...
            osInternalAccess << "\t\treturn S_OK;" << std::endl;
        }
        else if (isPropertyArray)
        {
            std::wstring containerPropertyName = toContainerPropertyName(pPropertyInfo->getName().c_str());
            if (isPropertyTypeInfoEnum(pPropertyInfo))
            {
                osInternalAccess << "\t\t" << containerPropertyName << ".CopyFrom(size,value);" << std::endl;
                osInternalAccess << "\t\t" << "return S_OK;" << std::endl;
            }
            else
            {
                osInternalAccess << FormatW(_fastModelSetInternalArraySupport,
                    containerPropertyName.data(),
                    nullptr) << std::endl;
            }
        }
        else
        {
            osInternalAccess << "\t\t" << toContainerPropertyName(pPropertyInfo->getName().c_str()) << " = " << "value;" << std::endl;
            osInternalAccess << "\t\treturn S_OK;" << std::endl;
        }
        
        osInternalAccess << "\t}" << std::endl;
    }

    // generate private access only if the property is read only
    if ((pPropertyInfo->getFlags() & PropertyFlagType_CanWrite) == 0)
    {
        // Emit set internal interface declare
        osPrivateAccessDeclare << "\tvirtual HRESULT " << "Set" << pPropertyInfo->getName() << "(";
        emitDeclarePropertyTypeInfo(osPrivateAccessDeclare, pPropertyInfo, false);
        osPrivateAccessDeclare << " value) = 0;" << std::endl;
    }
}