protected function handleArgDirectivesRecursively(
        InputType $type,
        InputValueDefinitionNode $astNode,
        array $argumentPath
    ): void {
        if ($type instanceof NonNull) {
            $this->handleArgDirectivesRecursively(
                $type->getWrappedType(),
                $astNode,
                $argumentPath
            );

            return;
        }

        $directives = $this->directiveFactory->createArgDirectives($astNode);

        if (
            $directives->contains(function (Directive $directive): bool {
                return $directive instanceof SpreadDirective;
            })
            && $type instanceof InputObjectType
        ) {
            $this->spreadPaths [] = $argumentPath;
        }

        // Handle the argument itself. At this point, it can be wrapped
        // in a list or an input object
        $this->handleArgWithAssociatedDirectives($type, $astNode, $directives, $argumentPath);

        // If we no value or null is given, we bail here to prevent
        // infinitely going down a chain of nested input objects
        if (! $this->argValueExists($argumentPath) || $this->argValue($argumentPath) === null) {
            return;
        }

        if ($type instanceof InputObjectType) {
            foreach ($type->getFields() as $field) {
                $this->handleArgDirectivesRecursively(
                    $field->type,
                    $field->astNode,
                    array_merge($argumentPath, [$field->name])
                );
            }
        }

        if ($type instanceof ListOfType) {
            foreach ($this->argValue($argumentPath) as $index => $value) {
                // here we are passing by reference so the `$argValue[$key]` is intended.
                $this->handleArgDirectivesRecursively(
                    $type->ofType,
                    $astNode,
                    array_merge($argumentPath, [$index])
                );
            }
        }
    }