com.auritylab.graphql.kotlin.toolkit.codegen.CodegenController.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of codegen Show documentation
Show all versions of codegen Show documentation
GraphQL Code generator for Kotlin
package com.auritylab.graphql.kotlin.toolkit.codegen
import com.auritylab.graphql.kotlin.toolkit.codegen.generator.FileGenerator
import com.auritylab.graphql.kotlin.toolkit.codegen.generator.GeneratorFactory
import com.auritylab.graphql.kotlin.toolkit.common.directive.DirectiveFacade
import com.auritylab.graphql.kotlin.toolkit.common.helper.GraphQLTypeHelper
import graphql.schema.GraphQLEnumType
import graphql.schema.GraphQLFieldDefinition
import graphql.schema.GraphQLFieldsContainer
import graphql.schema.GraphQLInputObjectType
import graphql.schema.GraphQLInterfaceType
import graphql.schema.GraphQLObjectType
import graphql.schema.GraphQLType
/**
* Will build the [FileGenerator]s for the given [types] using the [generatorFactory].
*/
internal class CodegenController(
private val options: CodegenOptions,
private val types: List,
private val generatorFactory: GeneratorFactory
) {
/**
* Will build all [FileGenerator]s which are needed for the given [types].
*/
fun buildGenerators(): Collection {
return listOf(
buildEnumGenerators(),
buildInputObjectGenerators(),
buildObjectTypeGenerators(),
buildInterfaceTypeGenerators(),
buildAdditionalGenerators(),
buildPaginationGenerators()
).flatten()
}
/**
* Will build the generators for all [GraphQLEnumType].
*/
private fun buildEnumGenerators(): Collection =
types.filterIsInstance()
.map { generatorFactory.enum(it) }
/**
* Will build the generators for all [GraphQLInputObjectType].
*/
private fun buildInputObjectGenerators(): Collection =
types.filterIsInstance()
.map { generatorFactory.inputObject(it) }
/**
* Will build the generators for all [GraphQLObjectType].
*/
private fun buildObjectTypeGenerators(): Collection =
types.filterIsInstance()
.flatMap { objectType ->
val internalGenerators = mutableListOf()
val objectHasGenerate = DirectiveFacade.generate[objectType]
val objectHasRepresentation = DirectiveFacade.representation[objectType]
val objectHasResolver = DirectiveFacade.resolver[objectType]
// Generate for object type if the directive is given and does not have a representation class.
if ((options.generateAll && !objectHasRepresentation) || (objectHasGenerate && !objectHasRepresentation))
internalGenerators.add(generatorFactory.objectType(objectType))
objectType.fieldDefinitions.forEach { fieldDefinition ->
if (options.generateAll ||
objectHasResolver ||
DirectiveFacade.resolver[fieldDefinition]
) internalGenerators.add(getSwitchedFieldResolverGenerator(objectType, fieldDefinition))
}
return@flatMap internalGenerators
}
/**
* Will build the generators for all [GraphQLInterfaceType].
*/
private fun buildInterfaceTypeGenerators(): Collection =
types.filterIsInstance()
.flatMap { interfaceType ->
val internalGenerators = mutableListOf()
val generatedForInterface = DirectiveFacade.resolver[interfaceType]
interfaceType.fieldDefinitions.forEach { fieldDefinition ->
if (options.generateAll ||
generatedForInterface ||
DirectiveFacade.resolver[fieldDefinition]
) internalGenerators.add(getSwitchedFieldResolverGenerator(interfaceType, fieldDefinition))
}
return@flatMap internalGenerators
}
/**
* Will build the field resolver [FileGenerator] for the given [container] and [field].ø
* This will differ if the given field has pagination or not.
*
* @return The default FieldResolver or the PaginationFieldResolver.
*/
private fun getSwitchedFieldResolverGenerator(
container: GraphQLFieldsContainer,
field: GraphQLFieldDefinition
): FileGenerator = if (DirectiveFacade.pagination[field] && GraphQLTypeHelper.isList(field.type))
generatorFactory.paginationFieldResolver(container, field)
else
generatorFactory.fieldResolver(container, field)
/**
* Will build the generators for all additionally required types.
*/
private fun buildAdditionalGenerators(): Collection {
return listOf(
generatorFactory.valueWrapper()
)
}
/**
* Will build the generators for the pagination support.
*/
private fun buildPaginationGenerators(): Collection {
return listOf(
generatorFactory.paginationInfo(),
generatorFactory.paginationConnection(),
generatorFactory.paginationEdge(),
generatorFactory.paginationPageInfo()
)
}
}