<?php

declare (strict_types=1);
namespace DevOwl\RealCookieBanner\Vendor\JsonMachine;

use Generator;
/** @internal */
class Tokens implements \IteratorAggregate, PositionAware
{
    /** @var iterable */
    private $jsonChunks;
    /**
     * @param iterable<string> $jsonChunks
     */
    public function __construct($jsonChunks)
    {
        $this->jsonChunks = $jsonChunks;
    }
    /**
     * @return Generator
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        $insignificantBytes = $this->insignificantBytes();
        $tokenBoundaries = $this->tokenBoundaries();
        $colonCommaBracket = $this->colonCommaBracketTokenBoundaries();
        $inString = \false;
        $tokenBuffer = '';
        $escaping = \false;
        foreach ($this->jsonChunks as $jsonChunk) {
            $bytesLength = \strlen($jsonChunk);
            for ($i = 0; $i < $bytesLength; ++$i) {
                $byte = $jsonChunk[$i];
                if ($escaping) {
                    $escaping = \false;
                    $tokenBuffer .= $byte;
                    continue;
                }
                if (isset($insignificantBytes[$byte])) {
                    // is a JSON-structure insignificant byte
                    $tokenBuffer .= $byte;
                    continue;
                }
                if ($inString) {
                    if ($byte == '"') {
                        $inString = \false;
                    } elseif ($byte == '\\') {
                        $escaping = \true;
                    }
                    $tokenBuffer .= $byte;
                    continue;
                }
                if (isset($tokenBoundaries[$byte])) {
                    if ($tokenBuffer != '') {
                        (yield $tokenBuffer);
                        $tokenBuffer = '';
                    }
                    if (isset($colonCommaBracket[$byte])) {
                        (yield $byte);
                    }
                } else {
                    // else branch matches `"` but also `\` outside of a string literal which is an error anyway but strictly speaking not correctly parsed token
                    $inString = \true;
                    $tokenBuffer .= $byte;
                }
            }
        }
        if ($tokenBuffer != '') {
            (yield $tokenBuffer);
        }
    }
    private function tokenBoundaries()
    {
        $utf8bom1 = "\xef";
        $utf8bom2 = "\xbb";
        $utf8bom3 = "\xbf";
        return \array_merge([$utf8bom1 => \true, $utf8bom2 => \true, $utf8bom3 => \true, ' ' => \true, "\n" => \true, "\r" => \true, "\t" => \true], $this->colonCommaBracketTokenBoundaries());
    }
    private function colonCommaBracketTokenBoundaries() : array
    {
        return ['{' => \true, '}' => \true, '[' => \true, ']' => \true, ':' => \true, ',' => \true];
    }
    private function insignificantBytes() : array
    {
        $insignificantBytes = [];
        foreach (\range(0, 255) as $ord) {
            if (!\in_array(\chr($ord), ['\\', '"', "\xef", "\xbb", "\xbf", ' ', "\n", "\r", "\t", '{', '}', '[', ']', ':', ','])) {
                $insignificantBytes[\chr($ord)] = \true;
            }
        }
        return $insignificantBytes;
    }
    public function getPosition() : int
    {
        return 0;
    }
    public function getLine() : int
    {
        return 1;
    }
    public function getColumn() : int
    {
        return 0;
    }
}
