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: private string $currentTokenValue;
18:
19: private int $currentTokenType;
20:
21: private int $currentOffset;
22:
23: private int $expectedTokenType;
24:
25: private ?string $expectedTokenValue;
26:
27: private ?int $currentTokenLine;
28:
29: public function __construct(
30: string $currentTokenValue,
31: int $currentTokenType,
32: int $currentOffset,
33: int $expectedTokenType,
34: ?string $expectedTokenValue,
35: ?int $currentTokenLine
36: )
37: {
38: $this->currentTokenValue = $currentTokenValue;
39: $this->currentTokenType = $currentTokenType;
40: $this->currentOffset = $currentOffset;
41: $this->expectedTokenType = $expectedTokenType;
42: $this->expectedTokenValue = $expectedTokenValue;
43: $this->currentTokenLine = $currentTokenLine;
44:
45: parent::__construct(sprintf(
46: 'Unexpected token %s, expected %s%s at offset %d%s',
47: $this->formatValue($currentTokenValue),
48: Lexer::TOKEN_LABELS[$expectedTokenType],
49: $expectedTokenValue !== null ? sprintf(' (%s)', $this->formatValue($expectedTokenValue)) : '',
50: $currentOffset,
51: $currentTokenLine === null ? '' : sprintf(' on line %d', $currentTokenLine),
52: ));
53: }
54:
55:
56: public function getCurrentTokenValue(): string
57: {
58: return $this->currentTokenValue;
59: }
60:
61:
62: public function getCurrentTokenType(): int
63: {
64: return $this->currentTokenType;
65: }
66:
67:
68: public function getCurrentOffset(): int
69: {
70: return $this->currentOffset;
71: }
72:
73:
74: public function getExpectedTokenType(): int
75: {
76: return $this->expectedTokenType;
77: }
78:
79:
80: public function getExpectedTokenValue(): ?string
81: {
82: return $this->expectedTokenValue;
83: }
84:
85:
86: public function getCurrentTokenLine(): ?int
87: {
88: return $this->currentTokenLine;
89: }
90:
91:
92: private function formatValue(string $value): string
93: {
94: $json = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE);
95: assert($json !== false);
96:
97: return $json;
98: }
99:
100: }
101: