Coverage Report

Created: 2025-12-29 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/external/antlr4-cpp-runtime~/runtime/src/BufferedTokenStream.cpp
Line
Count
Source
1
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2
 * Use of this file is governed by the BSD 3-clause license that
3
 * can be found in the LICENSE.txt file in the project root.
4
 */
5
6
#include "WritableToken.h"
7
#include "Lexer.h"
8
#include "RuleContext.h"
9
#include "misc/Interval.h"
10
#include "Exceptions.h"
11
#include "support/CPPUtils.h"
12
13
#include "BufferedTokenStream.h"
14
15
using namespace antlr4;
16
using namespace antlrcpp;
17
18
7.55k
BufferedTokenStream::BufferedTokenStream(TokenSource *tokenSource) : _tokenSource(tokenSource){
19
7.55k
  InitializeInstanceFields();
20
7.55k
}
21
22
4.22k
TokenSource* BufferedTokenStream::getTokenSource() const {
23
4.22k
  return _tokenSource;
24
4.22k
}
25
26
27.6M
size_t BufferedTokenStream::index() {
27
27.6M
  return _p;
28
27.6M
}
29
30
25.0M
ssize_t BufferedTokenStream::mark() {
31
25.0M
  return 0;
32
25.0M
}
33
34
25.0M
void BufferedTokenStream::release(ssize_t /*marker*/) {
35
  // no resources to release
36
25.0M
}
37
38
0
void BufferedTokenStream::reset() {
39
0
  seek(0);
40
0
}
41
42
27.6M
void BufferedTokenStream::seek(size_t index) {
43
27.6M
  lazyInit();
44
27.6M
  _p = adjustSeekIndex(index);
45
27.6M
}
46
47
77.3M
size_t BufferedTokenStream::size() {
48
77.3M
  return _tokens.size();
49
77.3M
}
50
51
14.2M
void BufferedTokenStream::consume() {
52
14.2M
  bool skipEofCheck = false;
53
14.2M
  if (!_needSetup) {
54
14.2M
    if (_fetchedEOF) {
55
      // the last token in tokens is EOF. skip check if p indexes any
56
      // fetched token except the last.
57
303k
      skipEofCheck = _p < _tokens.size() - 1;
58
13.9M
    } else {
59
      // no EOF token in tokens. skip check if p indexes a fetched token.
60
13.9M
      skipEofCheck = _p < _tokens.size();
61
13.9M
    }
62
14.2M
  } else {
63
    // not yet initialized
64
0
    skipEofCheck = false;
65
0
  }
66
67
14.2M
  if (!skipEofCheck && LA(1) == Token::EOF) {
68
0
    throw IllegalStateException("cannot consume EOF");
69
0
  }
70
71
14.2M
  if (sync(_p + 1)) {
72
14.2M
    _p = adjustSeekIndex(_p + 1);
73
14.2M
  }
74
14.2M
}
75
76
91.6M
bool BufferedTokenStream::sync(size_t i) {
77
91.6M
  if (i + 1 < _tokens.size())
78
41.2M
    return true;
79
50.3M
  size_t n = i - _tokens.size() + 1; // how many more elements we need?
80
81
50.3M
  if (n > 0) {
82
9.47M
    size_t fetched = fetch(n);
83
9.47M
    return fetched >= n;
84
9.47M
  }
85
86
40.9M
  return true;
87
50.3M
}
88
89
9.47M
size_t BufferedTokenStream::fetch(size_t n) {
90
9.47M
  if (_fetchedEOF) {
91
7.66k
    return 0;
92
7.66k
  }
93
94
9.46M
  size_t i = 0;
95
18.9M
  while (i < n) {
96
9.46M
    std::unique_ptr<Token> t(_tokenSource->nextToken());
97
98
9.46M
    if (is<WritableToken *>(t.get())) {
99
9.46M
      (static_cast<WritableToken *>(t.get()))->setTokenIndex(_tokens.size());
100
9.46M
    }
101
102
9.46M
    _tokens.push_back(std::move(t));
103
9.46M
    ++i;
104
105
9.46M
    if (_tokens.back()->getType() == Token::EOF) {
106
7.39k
      _fetchedEOF = true;
107
7.39k
      break;
108
7.39k
    }
109
9.46M
  }
110
111
9.46M
  return i;
112
9.47M
}
113
114
44.1k
Token* BufferedTokenStream::get(size_t i) const {
115
44.1k
  if (i >= _tokens.size()) {
116
0
    throw IndexOutOfBoundsException(std::string("token index ") +
117
0
                                    std::to_string(i) +
118
0
                                    std::string(" out of range 0..") +
119
0
                                    std::to_string(_tokens.size() - 1));
120
0
  }
121
44.1k
  return _tokens[i].get();
122
44.1k
}
123
124
0
std::vector<Token *> BufferedTokenStream::get(size_t start, size_t stop) {
125
0
  std::vector<Token *> subset;
126
127
0
  lazyInit();
128
129
0
  if (_tokens.empty()) {
130
0
    return subset;
131
0
  }
132
133
0
  if (stop >= _tokens.size()) {
134
0
    stop = _tokens.size() - 1;
135
0
  }
136
0
  for (size_t i = start; i <= stop; i++) {
137
0
    Token *t = _tokens[i].get();
138
0
    if (t->getType() == Token::EOF) {
139
0
      break;
140
0
    }
141
0
    subset.push_back(t);
142
0
  }
143
0
  return subset;
144
0
}
145
146
76.4M
size_t BufferedTokenStream::LA(ssize_t i) {
147
76.4M
  return LT(i)->getType();
148
76.4M
}
149
150
0
Token* BufferedTokenStream::LB(size_t k) {
151
0
  if (k > _p) {
152
0
    return nullptr;
153
0
  }
154
0
  return _tokens[_p - k].get();
155
0
}
156
157
0
Token* BufferedTokenStream::LT(ssize_t k) {
158
0
  lazyInit();
159
0
  if (k == 0) {
160
0
    return nullptr;
161
0
  }
162
0
  if (k < 0) {
163
0
    return LB(-k);
164
0
  }
165
166
0
  size_t i = _p + k - 1;
167
0
  sync(i);
168
0
  if (i >= _tokens.size()) { // return EOF token
169
                             // EOF must be last token
170
0
    return _tokens.back().get();
171
0
  }
172
173
0
  return _tokens[i].get();
174
0
}
175
176
0
ssize_t BufferedTokenStream::adjustSeekIndex(size_t i) {
177
0
  return i;
178
0
}
179
180
181M
void BufferedTokenStream::lazyInit() {
181
181M
  if (_needSetup) {
182
7.55k
    setup();
183
7.55k
  }
184
181M
}
185
186
7.55k
void BufferedTokenStream::setup() {
187
7.55k
  _needSetup = false;
188
7.55k
  sync(0);
189
7.55k
  _p = adjustSeekIndex(0);
190
7.55k
}
191
192
0
void BufferedTokenStream::setTokenSource(TokenSource *tokenSource) {
193
0
  _tokenSource = tokenSource;
194
0
  _tokens.clear();
195
0
  _fetchedEOF = false;
196
0
  _needSetup = true;
197
0
}
198
199
0
std::vector<Token *> BufferedTokenStream::getTokens() {
200
0
  std::vector<Token *> result;
201
0
  for (auto &t : _tokens)
202
0
    result.push_back(t.get());
203
0
  return result;
204
0
}
205
206
0
std::vector<Token *> BufferedTokenStream::getTokens(size_t start, size_t stop) {
207
0
  return getTokens(start, stop, std::vector<size_t>());
208
0
}
209
210
0
std::vector<Token *> BufferedTokenStream::getTokens(size_t start, size_t stop, const std::vector<size_t> &types) {
211
0
  lazyInit();
212
0
  if (stop >= _tokens.size() || start >= _tokens.size()) {
213
0
    throw IndexOutOfBoundsException(std::string("start ") +
214
0
                                    std::to_string(start) +
215
0
                                    std::string(" or stop ") +
216
0
                                    std::to_string(stop) +
217
0
                                    std::string(" not in 0..") +
218
0
                                    std::to_string(_tokens.size() - 1));
219
0
  }
220
221
0
  std::vector<Token *> filteredTokens;
222
223
0
  if (start > stop) {
224
0
    return filteredTokens;
225
0
  }
226
227
0
  for (size_t i = start; i <= stop; i++) {
228
0
    Token *tok = _tokens[i].get();
229
230
0
    if (types.empty() || std::find(types.begin(), types.end(), tok->getType()) != types.end()) {
231
0
      filteredTokens.push_back(tok);
232
0
    }
233
0
  }
234
0
  return filteredTokens;
235
0
}
236
237
0
std::vector<Token *> BufferedTokenStream::getTokens(size_t start, size_t stop, size_t ttype) {
238
0
  std::vector<size_t> s;
239
0
  s.push_back(ttype);
240
0
  return getTokens(start, stop, s);
241
0
}
242
243
41.9M
ssize_t BufferedTokenStream::nextTokenOnChannel(size_t i, size_t channel) {
244
41.9M
  sync(i);
245
41.9M
  if (i >= size()) {
246
0
    return size() - 1;
247
0
  }
248
249
41.9M
  Token *token = _tokens[i].get();
250
41.9M
  while (token->getChannel() != channel) {
251
19.8k
    if (token->getType() == Token::EOF) {
252
0
      return i;
253
0
    }
254
19.8k
    i++;
255
19.8k
    sync(i);
256
19.8k
    token = _tokens[i].get();
257
19.8k
  }
258
41.9M
  return i;
259
41.9M
}
260
261
35.4M
ssize_t BufferedTokenStream::previousTokenOnChannel(size_t i, size_t channel) {
262
35.4M
  sync(i);
263
35.4M
  if (i >= size()) {
264
    // the EOF token is on every channel
265
0
    return size() - 1;
266
0
  }
267
268
35.4M
  while (true) {
269
35.4M
    Token *token = _tokens[i].get();
270
35.4M
    if (token->getType() == Token::EOF || token->getChannel() == channel) {
271
35.4M
      return i;
272
35.4M
    }
273
274
41.4k
    if (i == 0)
275
1.31k
      return -1;
276
40.1k
    i--;
277
40.1k
  }
278
0
  return i;
279
35.4M
}
280
281
0
std::vector<Token *> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex, ssize_t channel) {
282
0
  lazyInit();
283
0
  if (tokenIndex >= _tokens.size()) {
284
0
    throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(_tokens.size() - 1));
285
0
  }
286
287
0
  ssize_t nextOnChannel = nextTokenOnChannel(tokenIndex + 1, Lexer::DEFAULT_TOKEN_CHANNEL);
288
0
  size_t to;
289
0
  size_t from = tokenIndex + 1;
290
  // if none onchannel to right, nextOnChannel=-1 so set to = last token
291
0
  if (nextOnChannel == -1) {
292
0
    to = static_cast<ssize_t>(size() - 1);
293
0
  } else {
294
0
    to = nextOnChannel;
295
0
  }
296
297
0
  return filterForChannel(from, to, channel);
298
0
}
299
300
0
std::vector<Token *> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex) {
301
0
  return getHiddenTokensToRight(tokenIndex, -1);
302
0
}
303
304
0
std::vector<Token *> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex, ssize_t channel) {
305
0
  lazyInit();
306
0
  if (tokenIndex >= _tokens.size()) {
307
0
    throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(_tokens.size() - 1));
308
0
  }
309
310
0
  if (tokenIndex == 0) {
311
    // Obviously no tokens can appear before the first token.
312
0
    return { };
313
0
  }
314
315
0
  ssize_t prevOnChannel = previousTokenOnChannel(tokenIndex - 1, Lexer::DEFAULT_TOKEN_CHANNEL);
316
0
  if (prevOnChannel == static_cast<ssize_t>(tokenIndex - 1)) {
317
0
    return { };
318
0
  }
319
  // if none onchannel to left, prevOnChannel=-1 then from=0
320
0
  size_t from = static_cast<size_t>(prevOnChannel + 1);
321
0
  size_t to = tokenIndex - 1;
322
323
0
  return filterForChannel(from, to, channel);
324
0
}
325
326
0
std::vector<Token *> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex) {
327
0
  return getHiddenTokensToLeft(tokenIndex, -1);
328
0
}
329
330
0
std::vector<Token *> BufferedTokenStream::filterForChannel(size_t from, size_t to, ssize_t channel) {
331
0
  std::vector<Token *> hidden;
332
0
  for (size_t i = from; i <= to; i++) {
333
0
    Token *t = _tokens[i].get();
334
0
    if (channel == -1) {
335
0
      if (t->getChannel() != Lexer::DEFAULT_TOKEN_CHANNEL) {
336
0
        hidden.push_back(t);
337
0
      }
338
0
    } else {
339
0
      if (t->getChannel() == static_cast<size_t>(channel)) {
340
0
        hidden.push_back(t);
341
0
      }
342
0
    }
343
0
  }
344
345
0
  return hidden;
346
0
}
347
348
0
bool BufferedTokenStream::isInitialized() const {
349
0
  return !_needSetup;
350
0
}
351
352
/**
353
 * Get the text of all tokens in this buffer.
354
 */
355
std::string BufferedTokenStream::getSourceName() const
356
0
{
357
0
  return _tokenSource->getSourceName();
358
0
}
359
360
0
std::string BufferedTokenStream::getText() {
361
0
  fill();
362
0
  return getText(misc::Interval(0U, size() - 1));
363
0
}
364
365
2.66k
std::string BufferedTokenStream::getText(const misc::Interval &interval) {
366
2.66k
  lazyInit();
367
2.66k
  size_t start = interval.a;
368
2.66k
  size_t stop = interval.b;
369
2.66k
  if (start == INVALID_INDEX || stop == INVALID_INDEX) {
370
0
    return "";
371
0
  }
372
2.66k
  sync(stop);
373
2.66k
  if (stop >= _tokens.size()) {
374
0
    stop = _tokens.size() - 1;
375
0
  }
376
377
2.66k
  std::stringstream ss;
378
9.23k
  for (size_t i = start; i <= stop; i++) {
379
7.03k
    Token *t = _tokens[i].get();
380
7.03k
    if (t->getType() == Token::EOF) {
381
462
      break;
382
462
    }
383
6.57k
    ss << t->getText();
384
6.57k
  }
385
2.66k
  return ss.str();
386
2.66k
}
387
388
0
std::string BufferedTokenStream::getText(RuleContext *ctx) {
389
0
  return getText(ctx->getSourceInterval());
390
0
}
391
392
2.66k
std::string BufferedTokenStream::getText(Token *start, Token *stop) {
393
2.66k
  if (start != nullptr && stop != nullptr) {
394
2.66k
    return getText(misc::Interval(start->getTokenIndex(), stop->getTokenIndex()));
395
2.66k
  }
396
397
0
  return "";
398
2.66k
}
399
400
0
void BufferedTokenStream::fill() {
401
0
  lazyInit();
402
0
  const size_t blockSize = 1000;
403
0
  while (true) {
404
0
    size_t fetched = fetch(blockSize);
405
0
    if (fetched < blockSize) {
406
0
      return;
407
0
    }
408
0
  }
409
0
}
410
411
7.55k
void BufferedTokenStream::InitializeInstanceFields() {
412
7.55k
  _needSetup = true;
413
7.55k
  _fetchedEOF = false;
414
7.55k
}