public function build($documentAST)
    {
        /** @var \GraphQL\Language\AST\TypeDefinitionNode $typeDefinition */
        foreach ($documentAST->typeDefinitions() as $typeDefinition) {
            $type = $this->nodeFactory->handle($typeDefinition);
            $this->typeRegistry->register($type);

            switch ($type->name) {
                case 'Query':
                    /** @var \Nuwave\Lighthouse\Schema\Conversion\DefinitionNodeConverter $queryType */
                    $queryType = $type;
                    continue 2;
                case 'Mutation':
                    /** @var \GraphQL\Type\Definition\ObjectType $mutationType */
                    $mutationType = $type;
                    continue 2;
                case 'Subscription':
                    /** @var \GraphQL\Type\Definition\ObjectType $subscriptionType */
                    $subscriptionType = $type;
                    continue 2;
                default:
                    $types[] = $type;
            }
        }

        if (empty($queryType)) {
            throw new InvariantViolation(
                'The root Query type must be present in the schema.'
            );
        }

        $config = SchemaConfig::create()
            // Always set Query since it is required
            ->setQuery(
                $queryType
            )
            ->setDirectives(
                $this->convertDirectives($documentAST)
                    ->toArray()
            );

        // Those are optional so only add them if they are present in the schema
        if (isset($mutationType)) {
            $config->setMutation($mutationType);
        }
        if (isset($subscriptionType)) {
            $config->setSubscription($subscriptionType);
        }
        // Not using lazy loading, as we do not have a way of discovering
        // orphaned types at the moment
        if (isset($types)) {
            $config->setTypes($types);
        }

        return new Schema($config);
    }