private function generate($value, $depth, array $options, array $recursion = [])
    {
        if ($this->detectRecursion($value, $options, $recursion)) {
            $recursion[] = $value;
        }

        if ($options['recursion.max'] !== false && $depth > (int) $options['recursion.max']) {
            throw new \RuntimeException('Maximum encoding depth reached');
        }

        $callback = function ($value, $level = 0, array $overrides = []) use ($depth, $options, $recursion) {
            return $this->generate($value, $depth + (int) $level, $overrides + $options, $recursion);
        };

        return $this->encodeValue($value, $depth, $options, $callback);
    }