|   1:  | <?php declare(strict_types = 1); | 
|   2:  |  | 
|   3:  | namespace PHPStan\PhpDocParser\Parser; | 
|   4:  |  | 
|   5:  | use Exception; | 
|   6:  | use PHPStan\PhpDocParser\Lexer\Lexer; | 
|   7:  | use function assert; | 
|   8:  | use function json_encode; | 
|   9:  | use function sprintf; | 
|  10:  | use const JSON_INVALID_UTF8_SUBSTITUTE; | 
|  11:  | use const JSON_UNESCAPED_SLASHES; | 
|  12:  | use const JSON_UNESCAPED_UNICODE; | 
|  13:  |  | 
|  14:  | class ParserException extends Exception | 
|  15:  | { | 
|  16:  |  | 
|  17:  | 	 | 
|  18:  | 	private $currentTokenValue; | 
|  19:  |  | 
|  20:  | 	 | 
|  21:  | 	private $currentTokenType; | 
|  22:  |  | 
|  23:  | 	 | 
|  24:  | 	private $currentOffset; | 
|  25:  |  | 
|  26:  | 	 | 
|  27:  | 	private $expectedTokenType; | 
|  28:  |  | 
|  29:  | 	 | 
|  30:  | 	private $expectedTokenValue; | 
|  31:  |  | 
|  32:  | 	 | 
|  33:  | 	private $currentTokenLine; | 
|  34:  |  | 
|  35:  | 	public function __construct( | 
|  36:  | 		string $currentTokenValue, | 
|  37:  | 		int $currentTokenType, | 
|  38:  | 		int $currentOffset, | 
|  39:  | 		int $expectedTokenType, | 
|  40:  | 		?string $expectedTokenValue = null, | 
|  41:  | 		?int $currentTokenLine = null | 
|  42:  | 	) | 
|  43:  | 	{ | 
|  44:  | 		$this->currentTokenValue = $currentTokenValue; | 
|  45:  | 		$this->currentTokenType = $currentTokenType; | 
|  46:  | 		$this->currentOffset = $currentOffset; | 
|  47:  | 		$this->expectedTokenType = $expectedTokenType; | 
|  48:  | 		$this->expectedTokenValue = $expectedTokenValue; | 
|  49:  | 		$this->currentTokenLine = $currentTokenLine; | 
|  50:  |  | 
|  51:  | 		parent::__construct(sprintf( | 
|  52:  | 			'Unexpected token %s, expected %s%s at offset %d%s', | 
|  53:  | 			$this->formatValue($currentTokenValue), | 
|  54:  | 			Lexer::TOKEN_LABELS[$expectedTokenType], | 
|  55:  | 			$expectedTokenValue !== null ? sprintf(' (%s)', $this->formatValue($expectedTokenValue)) : '', | 
|  56:  | 			$currentOffset, | 
|  57:  | 			$currentTokenLine === null ? '' : sprintf(' on line %d', $currentTokenLine) | 
|  58:  | 		)); | 
|  59:  | 	} | 
|  60:  |  | 
|  61:  |  | 
|  62:  | 	public function getCurrentTokenValue(): string | 
|  63:  | 	{ | 
|  64:  | 		return $this->currentTokenValue; | 
|  65:  | 	} | 
|  66:  |  | 
|  67:  |  | 
|  68:  | 	public function getCurrentTokenType(): int | 
|  69:  | 	{ | 
|  70:  | 		return $this->currentTokenType; | 
|  71:  | 	} | 
|  72:  |  | 
|  73:  |  | 
|  74:  | 	public function getCurrentOffset(): int | 
|  75:  | 	{ | 
|  76:  | 		return $this->currentOffset; | 
|  77:  | 	} | 
|  78:  |  | 
|  79:  |  | 
|  80:  | 	public function getExpectedTokenType(): int | 
|  81:  | 	{ | 
|  82:  | 		return $this->expectedTokenType; | 
|  83:  | 	} | 
|  84:  |  | 
|  85:  |  | 
|  86:  | 	public function getExpectedTokenValue(): ?string | 
|  87:  | 	{ | 
|  88:  | 		return $this->expectedTokenValue; | 
|  89:  | 	} | 
|  90:  |  | 
|  91:  |  | 
|  92:  | 	public function getCurrentTokenLine(): ?int | 
|  93:  | 	{ | 
|  94:  | 		return $this->currentTokenLine; | 
|  95:  | 	} | 
|  96:  |  | 
|  97:  |  | 
|  98:  | 	private function formatValue(string $value): string | 
|  99:  | 	{ | 
| 100:  | 		$json = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE); | 
| 101:  | 		assert($json !== false); | 
| 102:  |  | 
| 103:  | 		return $json; | 
| 104:  | 	} | 
| 105:  |  | 
| 106:  | } | 
| 107:  |  |