in src/SchemaGenerator.cpp [680:983]
void Generator::outputObjectDeclaration(
std::ostream& headerFile, const ObjectType& objectType, bool isQueryType) const
{
headerFile << R"cpp(class )cpp" << objectType.cppType << R"cpp( final
: public service::Object
{
private:
)cpp";
for (const auto& outputField : objectType.fields)
{
headerFile << getResolverDeclaration(outputField);
}
headerFile << R"cpp(
service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const;
)cpp";
if (!_options.noIntrospection && isQueryType)
{
headerFile
<< R"cpp( service::AwaitableResolver resolve_schema(service::ResolverParams&& params) const;
service::AwaitableResolver resolve_type(service::ResolverParams&& params) const;
std::shared_ptr<schema::Schema> _schema;
)cpp";
}
headerFile << R"cpp(
struct Concept
{
virtual ~Concept() = default;
)cpp";
if (!_loader.isIntrospection())
{
headerFile
<< R"cpp( virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0;
virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0;
)cpp";
}
for (const auto& outputField : objectType.fields)
{
headerFile << getFieldDeclaration(outputField);
}
headerFile << R"cpp( };
template <class T>
struct Model
: Concept
{
Model(std::shared_ptr<T>&& pimpl) noexcept
: _pimpl { std::move(pimpl) }
{
}
)cpp";
for (const auto& outputField : objectType.fields)
{
std::string fieldName(outputField.cppName);
fieldName[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(fieldName[0])));
headerFile << R"cpp(
)cpp" << _loader.getOutputCppType(outputField)
<< R"cpp( )cpp" << outputField.accessor << fieldName << R"cpp(()cpp";
bool firstArgument = _loader.isIntrospection();
if (!firstArgument)
{
headerFile << R"cpp(service::FieldParams&& params)cpp";
}
for (const auto& argument : outputField.arguments)
{
if (!firstArgument)
{
headerFile << R"cpp(, )cpp";
}
headerFile << _loader.getInputCppType(argument) << R"cpp(&& )cpp" << argument.cppName
<< R"cpp(Arg)cpp";
firstArgument = false;
}
headerFile << R"cpp() const final
{
)cpp";
std::ostringstream ossPassedArguments;
firstArgument = true;
for (const auto& argument : outputField.arguments)
{
if (!firstArgument)
{
ossPassedArguments << R"cpp(, )cpp";
}
ossPassedArguments << R"cpp(std::move()cpp" << argument.cppName << R"cpp(Arg))cpp";
firstArgument = false;
}
const auto passedArguments = ossPassedArguments.str();
if (_loader.isIntrospection())
{
headerFile << R"cpp(return { _pimpl->)cpp" << outputField.accessor << fieldName
<< R"cpp(()cpp";
if (!passedArguments.empty())
{
headerFile << passedArguments;
}
headerFile << R"cpp() };)cpp";
}
else
{
headerFile << R"cpp(if constexpr (methods::)cpp" << objectType.cppType
<< R"cpp(Has::)cpp" << outputField.accessor << fieldName
<< R"cpp(WithParams<T>)
{
return { _pimpl->)cpp"
<< outputField.accessor << fieldName << R"cpp((std::move(params))cpp";
if (!passedArguments.empty())
{
headerFile << R"cpp(, )cpp" << passedArguments;
}
headerFile << R"cpp() };
}
else)cpp";
if (!_options.stubs)
{
headerFile << R"cpp(
{
static_assert(methods::)cpp"
<< objectType.cppType << R"cpp(Has::)cpp" << outputField.accessor
<< fieldName << R"cpp(<T>, R"msg()cpp" << objectType.cppType
<< R"cpp(::)cpp" << outputField.accessor << fieldName
<< R"cpp( is not implemented)msg");)cpp";
}
else
{
headerFile << R"cpp( if constexpr (methods::)cpp" << objectType.cppType
<< R"cpp(Has::)cpp" << outputField.accessor << fieldName << R"cpp(<T>)
{)cpp";
}
headerFile << R"cpp(
return { _pimpl->)cpp"
<< outputField.accessor << fieldName << R"cpp(()cpp";
if (!passedArguments.empty())
{
headerFile << passedArguments;
}
headerFile << R"cpp() };
})cpp";
if (_options.stubs)
{
headerFile << R"cpp(
else
{
throw std::runtime_error(R"ex()cpp"
<< objectType.cppType << R"cpp(::)cpp" << outputField.accessor
<< fieldName << R"cpp( is not implemented)ex");
})cpp";
}
}
headerFile << R"cpp(
}
)cpp";
}
if (!_loader.isIntrospection())
{
headerFile << R"cpp(
void beginSelectionSet(const service::SelectionSetParams& params) const final
{
if constexpr (methods::)cpp"
<< objectType.cppType << R"cpp(Has::beginSelectionSet<T>)
{
_pimpl->beginSelectionSet(params);
}
}
void endSelectionSet(const service::SelectionSetParams& params) const final
{
if constexpr (methods::)cpp"
<< objectType.cppType << R"cpp(Has::endSelectionSet<T>)
{
_pimpl->endSelectionSet(params);
}
}
)cpp";
}
headerFile << R"cpp(
private:
const std::shared_ptr<T> _pimpl;
};
)cpp";
if (_loader.isIntrospection())
{
headerFile << R"cpp( const std::unique_ptr<const Concept> _pimpl;
service::TypeNames getTypeNames() const noexcept;
service::ResolverMap getResolvers() const noexcept;
public:
GRAPHQLSERVICE_EXPORT )cpp"
<< objectType.cppType << R"cpp((std::shared_ptr<)cpp"
<< SchemaLoader::getIntrospectionNamespace() << R"cpp(::)cpp"
<< objectType.cppType << R"cpp(> pimpl) noexcept;
GRAPHQLSERVICE_EXPORT ~)cpp"
<< objectType.cppType << R"cpp(();
};
)cpp";
}
else
{
headerFile << R"cpp( )cpp" << objectType.cppType
<< R"cpp((std::unique_ptr<const Concept>&& pimpl) noexcept;
)cpp";
if (!objectType.interfaces.empty())
{
headerFile << R"cpp( // Interfaces which this type implements
)cpp";
for (auto interfaceName : objectType.interfaces)
{
headerFile << R"cpp( friend )cpp" << _loader.getSafeCppName(interfaceName)
<< R"cpp(;
)cpp";
}
headerFile << std::endl;
}
if (!objectType.unions.empty())
{
headerFile << R"cpp( // Unions which include this type
)cpp";
for (auto unionName : objectType.unions)
{
headerFile << R"cpp( friend )cpp" << _loader.getSafeCppName(unionName)
<< R"cpp(;
)cpp";
}
headerFile << std::endl;
}
if (!objectType.interfaces.empty() || !objectType.unions.empty())
{
headerFile << R"cpp( template <class I>
static constexpr bool implements() noexcept
{
return implements::)cpp"
<< objectType.cppType << R"cpp(Is<I>;
}
)cpp";
}
headerFile
<< R"cpp( service::TypeNames getTypeNames() const noexcept;
service::ResolverMap getResolvers() const noexcept;
void beginSelectionSet(const service::SelectionSetParams& params) const final;
void endSelectionSet(const service::SelectionSetParams& params) const final;
const std::unique_ptr<const Concept> _pimpl;
public:
template <class T>
)cpp" << objectType.cppType
<< R"cpp((std::shared_ptr<T> pimpl) noexcept
: )cpp"
<< objectType.cppType
<< R"cpp( { std::unique_ptr<const Concept> { std::make_unique<Model<T>>(std::move(pimpl)) } }
{
}
};
)cpp";
}