xref: /plugin/combo/vendor/antlr/antlr4-php-runtime/src/CommonToken.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
1*37748cd8SNickeau<?php
2*37748cd8SNickeau
3*37748cd8SNickeaudeclare(strict_types=1);
4*37748cd8SNickeau
5*37748cd8SNickeaunamespace Antlr\Antlr4\Runtime;
6*37748cd8SNickeau
7*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Utils\Pair;
8*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Utils\StringUtils;
9*37748cd8SNickeau
10*37748cd8SNickeaufinal class CommonToken implements WritableToken
11*37748cd8SNickeau{
12*37748cd8SNickeau    /**
13*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getType()} and
14*37748cd8SNickeau     * {@see CommonToken::setType()}.
15*37748cd8SNickeau     *
16*37748cd8SNickeau     * @var int
17*37748cd8SNickeau     */
18*37748cd8SNickeau    protected $type;
19*37748cd8SNickeau
20*37748cd8SNickeau    /**
21*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getLine()} and
22*37748cd8SNickeau     * {@see CommonToken::setLine()}.
23*37748cd8SNickeau     *
24*37748cd8SNickeau     * @var int
25*37748cd8SNickeau     */
26*37748cd8SNickeau    protected $line = 0;
27*37748cd8SNickeau
28*37748cd8SNickeau    /**
29*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getCharPositionInLine()}
30*37748cd8SNickeau     * and {@see CommonToken::setCharPositionInLine()}.
31*37748cd8SNickeau     *
32*37748cd8SNickeau     * @var int
33*37748cd8SNickeau     */
34*37748cd8SNickeau    protected $charPositionInLine = -1;
35*37748cd8SNickeau
36*37748cd8SNickeau    /**
37*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getChannel()} and
38*37748cd8SNickeau     * {@see CommonToken::setChannel()}.
39*37748cd8SNickeau     *
40*37748cd8SNickeau     * @var int
41*37748cd8SNickeau     */
42*37748cd8SNickeau    protected $channel = Token::DEFAULT_CHANNEL;
43*37748cd8SNickeau
44*37748cd8SNickeau    /**
45*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getTokenSource()} and
46*37748cd8SNickeau     * {@see CommonToken::getInputStream()}.
47*37748cd8SNickeau     *
48*37748cd8SNickeau     *
49*37748cd8SNickeau     * These properties share a field to reduce the memory footprint of
50*37748cd8SNickeau     * {@see CommonToken}. Tokens created by a {@see CommonTokenFactory} from
51*37748cd8SNickeau     * the same source and input stream share a reference to the same
52*37748cd8SNickeau     * {@see Pair} containing these values.
53*37748cd8SNickeau     *
54*37748cd8SNickeau     * @var Pair
55*37748cd8SNickeau     */
56*37748cd8SNickeau    protected $source;
57*37748cd8SNickeau
58*37748cd8SNickeau    /**
59*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getText()} when the token
60*37748cd8SNickeau     * text is explicitly set in the constructor or via {@see CommonToken::setText()}.
61*37748cd8SNickeau     *
62*37748cd8SNickeau     * @see CommonToken::getText()
63*37748cd8SNickeau     *
64*37748cd8SNickeau     * @var string|null
65*37748cd8SNickeau     */
66*37748cd8SNickeau    protected $text;
67*37748cd8SNickeau
68*37748cd8SNickeau    /**
69*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getTokenIndex()} and
70*37748cd8SNickeau     * {@see CommonToken::setTokenIndex()}.
71*37748cd8SNickeau     *
72*37748cd8SNickeau     * @var int
73*37748cd8SNickeau     */
74*37748cd8SNickeau    protected $index = -1;
75*37748cd8SNickeau
76*37748cd8SNickeau    /**
77*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getStartIndex()} and
78*37748cd8SNickeau     * {@see CommonToken::setStartIndex()}.
79*37748cd8SNickeau     *
80*37748cd8SNickeau     * @var int
81*37748cd8SNickeau     */
82*37748cd8SNickeau    protected $start;
83*37748cd8SNickeau
84*37748cd8SNickeau    /**
85*37748cd8SNickeau     * This is the backing field for {@see CommonToken::getStopIndex()} and
86*37748cd8SNickeau     * {@see CommonToken::setStopIndex()}.
87*37748cd8SNickeau     *
88*37748cd8SNickeau     * @var int
89*37748cd8SNickeau     */
90*37748cd8SNickeau    protected $stop;
91*37748cd8SNickeau
92*37748cd8SNickeau    public function __construct(
93*37748cd8SNickeau        int $type,
94*37748cd8SNickeau        ?Pair $source = null,
95*37748cd8SNickeau        ?int $channel = null,
96*37748cd8SNickeau        int $start = -1,
97*37748cd8SNickeau        int $stop = -1
98*37748cd8SNickeau    ) {
99*37748cd8SNickeau        if ($source !== null && !$source->a instanceof TokenSource) {
100*37748cd8SNickeau            throw new \RuntimeException('Unexpected token source type.');
101*37748cd8SNickeau        }
102*37748cd8SNickeau
103*37748cd8SNickeau        if ($source !== null && !$source->b instanceof CharStream) {
104*37748cd8SNickeau            throw new \RuntimeException('Unexpected stream type.');
105*37748cd8SNickeau        }
106*37748cd8SNickeau
107*37748cd8SNickeau        $this->source = $source ?? self::emptySource();
108*37748cd8SNickeau        $this->type = $type;
109*37748cd8SNickeau        $this->channel = $channel ?? Token::DEFAULT_CHANNEL;
110*37748cd8SNickeau        $this->start = $start;
111*37748cd8SNickeau        $this->stop = $stop;
112*37748cd8SNickeau
113*37748cd8SNickeau        $tokenSource = $this->source->a;
114*37748cd8SNickeau
115*37748cd8SNickeau        if ($tokenSource instanceof TokenSource) {
116*37748cd8SNickeau            $this->line = $tokenSource->getLine();
117*37748cd8SNickeau            $this->charPositionInLine = $tokenSource->getCharPositionInLine();
118*37748cd8SNickeau        }
119*37748cd8SNickeau    }
120*37748cd8SNickeau
121*37748cd8SNickeau    /**
122*37748cd8SNickeau     * An empty {@see Pair}, which is used as the default value of
123*37748cd8SNickeau     * {@see CommonToken::source()} for tokens that do not have a source.
124*37748cd8SNickeau     */
125*37748cd8SNickeau    public static function emptySource() : Pair
126*37748cd8SNickeau    {
127*37748cd8SNickeau        static $source;
128*37748cd8SNickeau
129*37748cd8SNickeau        return $source = $source ?? new Pair(null, null);
130*37748cd8SNickeau    }
131*37748cd8SNickeau
132*37748cd8SNickeau    /**
133*37748cd8SNickeau     * Constructs a new {@see CommonToken} as a copy of another {@see Token}.
134*37748cd8SNickeau     *
135*37748cd8SNickeau     * If `oldToken` is also a {@see CommonToken} instance, the newly constructed
136*37748cd8SNickeau     * token will share a reference to the {@see CommonToken::text()} field and
137*37748cd8SNickeau     * the {@see Pair} stored in {@see CommonToken::source()}. Otherwise,
138*37748cd8SNickeau     * {@see CommonToken::text()} will be assigned the result of calling
139*37748cd8SNickeau     * {@see CommonToken::getText()}, and {@see CommonToken::source()} will be
140*37748cd8SNickeau     * constructed from the result of {@see Token::getTokenSource()} and
141*37748cd8SNickeau     * {@see Token::getInputStream()}.
142*37748cd8SNickeau     */
143*37748cd8SNickeau    public function clone() : CommonToken
144*37748cd8SNickeau    {
145*37748cd8SNickeau        $token = new self($this->type, $this->source, $this->channel, $this->start, $this->stop);
146*37748cd8SNickeau
147*37748cd8SNickeau        $token->index = $this->index;
148*37748cd8SNickeau        $token->line = $this->line;
149*37748cd8SNickeau        $token->charPositionInLine = $this->charPositionInLine;
150*37748cd8SNickeau
151*37748cd8SNickeau        $token->setText($this->text);
152*37748cd8SNickeau
153*37748cd8SNickeau        return $token;
154*37748cd8SNickeau    }
155*37748cd8SNickeau
156*37748cd8SNickeau    public function getType() : int
157*37748cd8SNickeau    {
158*37748cd8SNickeau        return $this->type;
159*37748cd8SNickeau    }
160*37748cd8SNickeau
161*37748cd8SNickeau    public function setType(int $type) : void
162*37748cd8SNickeau    {
163*37748cd8SNickeau        $this->type = $type;
164*37748cd8SNickeau    }
165*37748cd8SNickeau
166*37748cd8SNickeau    public function getLine() : int
167*37748cd8SNickeau    {
168*37748cd8SNickeau        return $this->line;
169*37748cd8SNickeau    }
170*37748cd8SNickeau
171*37748cd8SNickeau    public function setLine(int $line) : void
172*37748cd8SNickeau    {
173*37748cd8SNickeau        $this->line = $line;
174*37748cd8SNickeau    }
175*37748cd8SNickeau
176*37748cd8SNickeau    public function getText() : ?string
177*37748cd8SNickeau    {
178*37748cd8SNickeau        if ($this->text !== null) {
179*37748cd8SNickeau            return $this->text;
180*37748cd8SNickeau        }
181*37748cd8SNickeau
182*37748cd8SNickeau        $input = $this->getInputStream();
183*37748cd8SNickeau
184*37748cd8SNickeau        if ($input === null) {
185*37748cd8SNickeau            return null;
186*37748cd8SNickeau        }
187*37748cd8SNickeau
188*37748cd8SNickeau        $n = $input->getLength();
189*37748cd8SNickeau
190*37748cd8SNickeau        if ($this->start < $n && $this->stop < $n) {
191*37748cd8SNickeau            return $input->getText($this->start, $this->stop);
192*37748cd8SNickeau        }
193*37748cd8SNickeau
194*37748cd8SNickeau        return '<EOF>';
195*37748cd8SNickeau    }
196*37748cd8SNickeau
197*37748cd8SNickeau    /**
198*37748cd8SNickeau     * Explicitly set the text for this token. If `text` is not `null`, then
199*37748cd8SNickeau     * {@see CommonToken::getText()} will return this value rather than
200*37748cd8SNickeau     * extracting the text from the input.
201*37748cd8SNickeau     *
202*37748cd8SNickeau     * @param string $text The explicit text of the token, or `null`
203*37748cd8SNickeau     *                     if the text should be obtained from the input
204*37748cd8SNickeau     *                     along with the start and stop indexes of the token.
205*37748cd8SNickeau     */
206*37748cd8SNickeau    public function setText(?string $text) : void
207*37748cd8SNickeau    {
208*37748cd8SNickeau        $this->text = $text;
209*37748cd8SNickeau    }
210*37748cd8SNickeau
211*37748cd8SNickeau    public function getCharPositionInLine() : int
212*37748cd8SNickeau    {
213*37748cd8SNickeau        return $this->charPositionInLine;
214*37748cd8SNickeau    }
215*37748cd8SNickeau
216*37748cd8SNickeau    public function setCharPositionInLine(int $charPositionInLine) : void
217*37748cd8SNickeau    {
218*37748cd8SNickeau        $this->charPositionInLine = $charPositionInLine;
219*37748cd8SNickeau    }
220*37748cd8SNickeau
221*37748cd8SNickeau    public function getChannel() : int
222*37748cd8SNickeau    {
223*37748cd8SNickeau        return $this->channel;
224*37748cd8SNickeau    }
225*37748cd8SNickeau
226*37748cd8SNickeau    public function setChannel(int $channel) : void
227*37748cd8SNickeau    {
228*37748cd8SNickeau        $this->channel = $channel;
229*37748cd8SNickeau    }
230*37748cd8SNickeau
231*37748cd8SNickeau    public function getStartIndex() : int
232*37748cd8SNickeau    {
233*37748cd8SNickeau        return $this->start;
234*37748cd8SNickeau    }
235*37748cd8SNickeau
236*37748cd8SNickeau    public function setStartIndex(int $index) : void
237*37748cd8SNickeau    {
238*37748cd8SNickeau        $this->start = $index;
239*37748cd8SNickeau    }
240*37748cd8SNickeau
241*37748cd8SNickeau    public function getStopIndex() : int
242*37748cd8SNickeau    {
243*37748cd8SNickeau        return $this->stop;
244*37748cd8SNickeau    }
245*37748cd8SNickeau
246*37748cd8SNickeau    public function setStopIndex(int $index) : void
247*37748cd8SNickeau    {
248*37748cd8SNickeau        $this->stop = $index;
249*37748cd8SNickeau    }
250*37748cd8SNickeau
251*37748cd8SNickeau    public function getTokenIndex() : int
252*37748cd8SNickeau    {
253*37748cd8SNickeau        return $this->index;
254*37748cd8SNickeau    }
255*37748cd8SNickeau
256*37748cd8SNickeau    public function setTokenIndex(int $tokenIndex) : void
257*37748cd8SNickeau    {
258*37748cd8SNickeau        $this->index = $tokenIndex;
259*37748cd8SNickeau    }
260*37748cd8SNickeau
261*37748cd8SNickeau    public function getTokenSource() : ?TokenSource
262*37748cd8SNickeau    {
263*37748cd8SNickeau        $source = $this->source->a;
264*37748cd8SNickeau
265*37748cd8SNickeau        if ($source !== null && !$source instanceof TokenSource) {
266*37748cd8SNickeau            throw new \RuntimeException('Unexpected token source type.');
267*37748cd8SNickeau        }
268*37748cd8SNickeau
269*37748cd8SNickeau        return $source;
270*37748cd8SNickeau    }
271*37748cd8SNickeau
272*37748cd8SNickeau    public function getInputStream() : ?CharStream
273*37748cd8SNickeau    {
274*37748cd8SNickeau        $stream = $this->source->b;
275*37748cd8SNickeau
276*37748cd8SNickeau        if ($stream !== null && !$stream instanceof CharStream) {
277*37748cd8SNickeau            throw new \RuntimeException('Unexpected token source type.');
278*37748cd8SNickeau        }
279*37748cd8SNickeau
280*37748cd8SNickeau        return $stream;
281*37748cd8SNickeau    }
282*37748cd8SNickeau
283*37748cd8SNickeau    public function getSource() : Pair
284*37748cd8SNickeau    {
285*37748cd8SNickeau        return $this->source;
286*37748cd8SNickeau    }
287*37748cd8SNickeau
288*37748cd8SNickeau    public function __toString() : string
289*37748cd8SNickeau    {
290*37748cd8SNickeau        return \sprintf(
291*37748cd8SNickeau            '[@%d,%d:%d=\'%s\',<%d>%s,%d:%d]',
292*37748cd8SNickeau            $this->getTokenIndex(),
293*37748cd8SNickeau            $this->start,
294*37748cd8SNickeau            $this->stop,
295*37748cd8SNickeau            StringUtils::escapeWhitespace($this->getText() ?? ''),
296*37748cd8SNickeau            $this->type,
297*37748cd8SNickeau            $this->channel > 0 ? ',channel=' . $this->channel : '',
298*37748cd8SNickeau            $this->line,
299*37748cd8SNickeau            $this->charPositionInLine
300*37748cd8SNickeau        );
301*37748cd8SNickeau    }
302*37748cd8SNickeau}
303