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