in src/SchemaGenerator.cpp [106:478]
bool Generator::outputHeader() const noexcept
{
std::ofstream headerFile(_headerPath, std::ios_base::trunc);
IncludeGuardScope includeGuard { headerFile,
std::filesystem::path(_headerPath).filename().string() };
headerFile << R"cpp(#include "graphqlservice/internal/Schema.h"
// Check if the library version is compatible with schemagen )cpp"
<< graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion
<< R"cpp(.0
static_assert(graphql::internal::MajorVersion == )cpp"
<< graphql::internal::MajorVersion
<< R"cpp(, "regenerate with schemagen: major version mismatch");
static_assert(graphql::internal::MinorVersion == )cpp"
<< graphql::internal::MinorVersion
<< R"cpp(, "regenerate with schemagen: minor version mismatch");
#include <memory>
#include <string>
#include <vector>
)cpp";
NamespaceScope graphqlNamespace { headerFile, "graphql" };
NamespaceScope schemaNamespace { headerFile, _loader.getSchemaNamespace() };
NamespaceScope objectNamespace { headerFile, "object", true };
PendingBlankLine pendingSeparator { headerFile };
std::string_view queryType;
if (!_loader.isIntrospection())
{
for (const auto& operation : _loader.getOperationTypes())
{
if (operation.operation == service::strQuery)
{
queryType = operation.type;
break;
}
}
}
if (!_loader.getEnumTypes().empty())
{
pendingSeparator.reset();
for (const auto& enumType : _loader.getEnumTypes())
{
headerFile << R"cpp(enum class )cpp" << enumType.cppType << R"cpp(
{
)cpp";
bool firstValue = true;
for (const auto& value : enumType.values)
{
if (!firstValue)
{
headerFile << R"cpp(,
)cpp";
}
firstValue = false;
headerFile << R"cpp( )cpp" << value.value;
}
headerFile << R"cpp(
};
)cpp";
}
}
if (!_loader.getInputTypes().empty())
{
pendingSeparator.reset();
// Output the full declarations
for (const auto& inputType : _loader.getInputTypes())
{
headerFile << R"cpp(struct )cpp" << inputType.cppType << R"cpp(
{
)cpp";
for (const auto& inputField : inputType.fields)
{
headerFile << getFieldDeclaration(inputField) << R"cpp( {};
)cpp";
}
headerFile << R"cpp(};
)cpp";
}
}
if (!_loader.getInterfaceTypes().empty())
{
objectNamespace.enter();
headerFile << std::endl;
// Forward declare all of the interface types
for (const auto& interfaceType : _loader.getInterfaceTypes())
{
headerFile << R"cpp(class )cpp" << interfaceType.cppType << R"cpp(;
)cpp";
}
headerFile << std::endl;
}
if (!_loader.getUnionTypes().empty())
{
if (objectNamespace.enter())
{
headerFile << std::endl;
}
// Forward declare all of the union types
for (const auto& unionType : _loader.getUnionTypes())
{
headerFile << R"cpp(class )cpp" << unionType.cppType << R"cpp(;
)cpp";
}
headerFile << std::endl;
}
if (!_loader.getObjectTypes().empty())
{
if (_loader.isIntrospection())
{
if (objectNamespace.exit())
{
headerFile << std::endl;
}
// Forward declare all of the concrete types for the Introspection schema
for (const auto& objectType : _loader.getObjectTypes())
{
headerFile << R"cpp(class )cpp" << objectType.cppType << R"cpp(;
)cpp";
}
headerFile << std::endl;
}
if (objectNamespace.enter())
{
headerFile << std::endl;
}
// Forward declare all of the object types
for (const auto& objectType : _loader.getObjectTypes())
{
headerFile << R"cpp(class )cpp" << objectType.cppType << R"cpp(;
)cpp";
}
headerFile << std::endl;
}
if (objectNamespace.exit())
{
headerFile << std::endl;
}
if (!_loader.isIntrospection())
{
bool firstOperation = true;
headerFile << R"cpp(class Operations final
: public service::Request
{
public:
explicit Operations()cpp";
for (const auto& operation : _loader.getOperationTypes())
{
if (!firstOperation)
{
headerFile << R"cpp(, )cpp";
}
firstOperation = false;
headerFile << R"cpp(std::shared_ptr<object::)cpp" << operation.cppType << R"cpp(> )cpp"
<< operation.operation;
}
headerFile << R"cpp();
)cpp";
if (!_loader.getOperationTypes().empty())
{
firstOperation = true;
headerFile << R"cpp(
template <)cpp";
for (const auto& operation : _loader.getOperationTypes())
{
if (!firstOperation)
{
headerFile << R"cpp(, )cpp";
}
firstOperation = false;
headerFile << R"cpp(class T)cpp" << operation.cppType;
}
headerFile << R"cpp(>
explicit Operations()cpp";
firstOperation = true;
for (const auto& operation : _loader.getOperationTypes())
{
if (!firstOperation)
{
headerFile << R"cpp(, )cpp";
}
firstOperation = false;
headerFile << R"cpp(std::shared_ptr<T)cpp" << operation.cppType << R"cpp(> )cpp"
<< operation.operation;
}
headerFile << R"cpp()
: Operations {)cpp";
firstOperation = true;
for (const auto& operation : _loader.getOperationTypes())
{
if (!firstOperation)
{
headerFile << R"cpp(,)cpp";
}
firstOperation = false;
headerFile << R"cpp( std::make_shared<object::)cpp" << operation.cppType
<< R"cpp(>(std::move()cpp" << operation.operation << R"cpp()))cpp";
}
headerFile << R"cpp( }
{
}
)cpp";
}
headerFile << R"cpp(
private:
)cpp";
for (const auto& operation : _loader.getOperationTypes())
{
headerFile << R"cpp( std::shared_ptr<object::)cpp" << operation.cppType
<< R"cpp(> _)cpp" << operation.operation << R"cpp(;
)cpp";
}
headerFile << R"cpp(};
)cpp";
}
if (!_loader.getInterfaceTypes().empty())
{
for (const auto& interfaceType : _loader.getInterfaceTypes())
{
headerFile << R"cpp(void Add)cpp" << interfaceType.cppType
<< R"cpp(Details(const std::shared_ptr<schema::InterfaceType>& type)cpp"
<< interfaceType.cppType
<< R"cpp(, const std::shared_ptr<schema::Schema>& schema);
)cpp";
}
headerFile << std::endl;
}
if (!_loader.getUnionTypes().empty())
{
for (const auto& unionType : _loader.getUnionTypes())
{
headerFile << R"cpp(void Add)cpp" << unionType.cppType
<< R"cpp(Details(const std::shared_ptr<schema::UnionType>& type)cpp"
<< unionType.cppType
<< R"cpp(, const std::shared_ptr<schema::Schema>& schema);
)cpp";
}
headerFile << std::endl;
}
if (!_loader.getObjectTypes().empty())
{
for (const auto& objectType : _loader.getObjectTypes())
{
headerFile << R"cpp(void Add)cpp" << objectType.cppType
<< R"cpp(Details(const std::shared_ptr<schema::ObjectType>& type)cpp"
<< objectType.cppType
<< R"cpp(, const std::shared_ptr<schema::Schema>& schema);
)cpp";
}
headerFile << std::endl;
}
if (_loader.isIntrospection())
{
headerFile
<< R"cpp(GRAPHQLSERVICE_EXPORT void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema);
)cpp";
if (!_loader.getEnumTypes().empty() || !_loader.getInputTypes().empty())
{
if (schemaNamespace.exit())
{
headerFile << std::endl;
}
NamespaceScope serviceNamespace { headerFile, "service" };
headerFile << R"cpp(
#ifdef GRAPHQL_DLLEXPORTS
// Export all of the built-in converters
)cpp";
for (const auto& enumType : _loader.getEnumTypes())
{
headerFile << R"cpp(template <>
GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace()
<< R"cpp(::)cpp" << enumType.cppType << R"cpp( ModifiedArgument<)cpp"
<< _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType
<< R"cpp(>::convert(
const response::Value& value);
template <>
GRAPHQLSERVICE_EXPORT AwaitableResolver ModifiedResult<)cpp"
<< _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType
<< R"cpp(>::convert(
AwaitableScalar<)cpp" << _loader.getSchemaNamespace()
<< R"cpp(::)cpp" << enumType.cppType
<< R"cpp(> result, ResolverParams params);
template <>
GRAPHQLSERVICE_EXPORT void ModifiedResult<)cpp"
<< _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType
<< R"cpp(>::validateScalar(
const response::Value& value);
)cpp";
}
for (const auto& inputType : _loader.getInputTypes())
{
headerFile << R"cpp(template <>
GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace()
<< R"cpp(::)cpp" << inputType.cppType << R"cpp( ModifiedArgument<)cpp"
<< inputType.cppType << R"cpp(>::convert(
const response::Value& value);
)cpp";
}
headerFile << R"cpp(#endif // GRAPHQL_DLLEXPORTS
)cpp";
}
}
else
{
headerFile << R"cpp(std::shared_ptr<schema::Schema> GetSchema();
)cpp";
}
return true;
}