private static function buildExecutionContext(
        Schema $schema,
        DocumentNode $documentNode,
        $rootValue,
        $contextValue,
        $rawVariableValues,
        $operationName = null,
        ?callable $fieldResolver = null,
        ?PromiseAdapter $promiseAdapter = null
    ) {
        $errors    = [];
        $fragments = [];
        /** @var OperationDefinitionNode $operation */
        $operation                    = null;
        $hasMultipleAssumedOperations = false;
        foreach ($documentNode->definitions as $definition) {
            switch ($definition->kind) {
                case NodeKind::OPERATION_DEFINITION:
                    if (! $operationName && $operation) {
                        $hasMultipleAssumedOperations = true;
                    }
                    if (! $operationName ||
                        (isset($definition->name) && $definition->name->value === $operationName)) {
                        $operation = $definition;
                    }
                    break;
                case NodeKind::FRAGMENT_DEFINITION:
                    $fragments[$definition->name->value] = $definition;
                    break;
            }
        }
        if ($operation === null) {
            if ($operationName) {
                $errors[] = new Error(sprintf('Unknown operation named "%s".', $operationName));
            } else {
                $errors[] = new Error('Must provide an operation.');
            }
        } elseif ($hasMultipleAssumedOperations) {
            $errors[] = new Error(
                'Must provide operation name if query contains multiple operations.'
            );
        }
        $variableValues = null;
        if ($operation !== null) {
            [$coercionErrors, $coercedVariableValues] = Values::getVariableValues(
                $schema,
                $operation->variableDefinitions ?: [],
                $rawVariableValues ?: []
            );
            if (empty($coercionErrors)) {
                $variableValues = $coercedVariableValues;
            } else {
                $errors = array_merge($errors, $coercionErrors);
            }
        }
        if (! empty($errors)) {
            return $errors;
        }
        Utils::invariant($operation, 'Has operation if no errors.');
        Utils::invariant($variableValues !== null, 'Has variables if no errors.');

        return new ExecutionContext(
            $schema,
            $fragments,
            $rootValue,
            $contextValue,
            $operation,
            $variableValues,
            $errors,
            $fieldResolver,
            $promiseAdapter
        );
    }