1use crate::int_stream::{EOF, IntStream, UNKNOWN_SOURCE_NAME};
2use std::rc::Rc;
3
4use crate::token::{
5 CommonToken, DEFAULT_CHANNEL, TOKEN_EOF, Token, TokenRef, TokenSource, TokenSourceError,
6};
7
8#[derive(Debug)]
9pub struct CommonTokenStream<S> {
10 source: S,
11 tokens: Vec<TokenRef>,
12 public_tokens: Vec<CommonToken>,
13 next_visible_after: Vec<usize>,
14 cursor: usize,
15 fetched_eof: bool,
16 channel: i32,
17 source_errors: Vec<TokenSourceError>,
18}
19
20const UNKNOWN_NEXT_VISIBLE: usize = usize::MAX;
21
22impl<S> CommonTokenStream<S>
23where
24 S: TokenSource,
25{
26 pub const fn new(source: S) -> Self {
28 Self::with_channel(source, DEFAULT_CHANNEL)
29 }
30
31 pub const fn with_channel(source: S, channel: i32) -> Self {
33 Self {
34 source,
35 tokens: Vec::new(),
36 public_tokens: Vec::new(),
37 next_visible_after: Vec::new(),
38 cursor: 0,
39 fetched_eof: false,
40 channel,
41 source_errors: Vec::new(),
42 }
43 }
44
45 pub fn fill(&mut self) {
47 while !self.fetched_eof {
48 self.fetch_one();
49 }
50 self.cursor = self.adjust_seek_index(self.cursor);
51 }
52
53 pub fn get(&mut self, index: usize) -> Option<&CommonToken> {
56 self.sync(index);
57 self.tokens.get(index).map(Rc::as_ref)
58 }
59
60 pub fn get_ref(&mut self, index: usize) -> Option<TokenRef> {
62 self.sync(index);
63 self.tokens.get(index).map(Rc::clone)
64 }
65
66 pub fn lt(&mut self, offset: isize) -> Option<&CommonToken> {
69 if offset == 0 {
70 return None;
71 }
72 if offset < 0 {
73 return offset
74 .checked_neg()
75 .map(isize::cast_unsigned)
76 .and_then(|offset| self.lb(offset));
77 }
78
79 let mut index = self.next_token_on_channel(self.cursor, self.channel);
80 let mut remaining = offset;
81 while remaining > 1 {
82 index = self.next_token_on_channel(index + 1, self.channel);
83 remaining -= 1;
84 }
85 self.sync(index);
86 self.tokens.get(index).map(Rc::as_ref)
87 }
88
89 pub fn lt_ref(&mut self, offset: isize) -> Option<TokenRef> {
92 if offset == 0 {
93 return None;
94 }
95 if offset < 0 {
96 return offset
97 .checked_neg()
98 .map(isize::cast_unsigned)
99 .and_then(|offset| self.lb_ref(offset));
100 }
101
102 let mut index = self.next_token_on_channel(self.cursor, self.channel);
103 let mut remaining = offset;
104 while remaining > 1 {
105 index = self.next_token_on_channel(index + 1, self.channel);
106 remaining -= 1;
107 }
108 self.sync(index);
109 self.tokens.get(index).map(Rc::clone)
110 }
111
112 pub fn lb(&self, offset: usize) -> Option<&CommonToken> {
113 if offset == 0 || self.cursor == 0 {
114 return None;
115 }
116 let mut index = self.cursor;
117 let mut remaining = offset;
118 while remaining > 0 {
119 index = self.previous_token_on_channel(index, self.channel)?;
120 remaining -= 1;
121 }
122 self.tokens.get(index).map(Rc::as_ref)
123 }
124
125 fn lb_ref(&self, offset: usize) -> Option<TokenRef> {
126 if offset == 0 || self.cursor == 0 {
127 return None;
128 }
129 let mut index = self.cursor;
130 let mut remaining = offset;
131 while remaining > 0 {
132 index = self.previous_token_on_channel(index, self.channel)?;
133 remaining -= 1;
134 }
135 self.tokens.get(index).map(Rc::clone)
136 }
137
138 pub const fn token_source(&self) -> &S {
139 &self.source
140 }
141
142 pub fn tokens(&self) -> &[CommonToken] {
143 &self.public_tokens
144 }
145
146 fn sync(&mut self, index: usize) -> bool {
148 if index < self.tokens.len() {
149 return true;
150 }
151 let needed = index + 1 - self.tokens.len();
152 self.fetch(needed) >= needed
153 }
154
155 fn fetch(&mut self, count: usize) -> usize {
157 let mut fetched = 0;
158 while fetched < count && !self.fetched_eof {
159 self.fetch_one();
160 fetched += 1;
161 }
162 fetched
163 }
164
165 fn fetch_one(&mut self) {
166 let mut token = self.source.next_token();
167 self.source_errors.extend(self.source.drain_errors());
168 let token_index = isize::try_from(self.tokens.len()).unwrap_or(isize::MAX);
169 token.set_token_index(token_index);
170 self.fetched_eof = token.token_type() == TOKEN_EOF;
171 self.tokens.push(Rc::new(token.clone()));
172 self.public_tokens.push(token);
173 self.next_visible_after.push(UNKNOWN_NEXT_VISIBLE);
174 }
175
176 fn adjust_seek_index(&mut self, index: usize) -> usize {
179 self.next_token_on_channel(index, self.channel)
180 }
181
182 fn next_token_on_channel(&mut self, mut index: usize, channel: i32) -> usize {
184 self.sync(index);
185 while let Some(token) = self.tokens.get(index) {
186 if token.token_type() == TOKEN_EOF || token.channel() == channel {
187 return index;
188 }
189 index += 1;
190 self.sync(index);
191 }
192 index
193 }
194
195 fn previous_token_on_channel(&self, mut index: usize, channel: i32) -> Option<usize> {
197 while index > 0 {
198 index -= 1;
199 let token = self.tokens.get(index)?;
200 if token.token_type() == TOKEN_EOF || token.channel() == channel {
201 return Some(index);
202 }
203 }
204 None
205 }
206
207 pub fn previous_visible_token_index(&mut self, index: usize) -> Option<usize> {
216 if index > 0 {
217 self.sync(index - 1);
218 }
219 self.previous_token_on_channel(index, self.channel)
220 }
221}
222
223impl<S> IntStream for CommonTokenStream<S>
224where
225 S: TokenSource,
226{
227 fn consume(&mut self) {
228 if self.la(1) == EOF {
229 return;
230 }
231 let current = self.next_token_on_channel(self.cursor, self.channel);
232 self.cursor = self.adjust_seek_index(current + 1);
233 }
234
235 fn la(&mut self, offset: isize) -> i32 {
236 self.la_token(offset)
237 }
238
239 fn index(&self) -> usize {
240 self.cursor
241 }
242
243 fn seek(&mut self, index: usize) {
244 self.cursor = self.adjust_seek_index(index);
245 }
246
247 fn size(&self) -> usize {
248 self.tokens.len()
249 }
250
251 fn source_name(&self) -> &str {
252 let source_name = self.source.source_name();
253 if source_name.is_empty() {
254 UNKNOWN_SOURCE_NAME
255 } else {
256 source_name
257 }
258 }
259}
260
261impl<S> CommonTokenStream<S>
262where
263 S: TokenSource,
264{
265 pub fn la_token(&mut self, offset: isize) -> i32 {
266 self.lt(offset).map_or(TOKEN_EOF, Token::token_type)
267 }
268
269 pub fn token_type_at_index(&mut self, index: usize) -> i32 {
275 self.sync(index);
276 self.tokens
277 .get(index)
278 .map_or(TOKEN_EOF, |token| token.token_type())
279 }
280
281 pub const fn channel(&self) -> i32 {
283 self.channel
284 }
285
286 pub fn next_visible_after(&mut self, index: usize) -> usize {
291 self.sync(index);
292 if let Some(cached) = self
293 .next_visible_after
294 .get(index)
295 .copied()
296 .filter(|cached| *cached != UNKNOWN_NEXT_VISIBLE)
297 {
298 return cached;
299 }
300
301 let mut next = index + 1;
302 let found = loop {
303 self.sync(next);
304 match self.tokens.get(next) {
305 Some(token)
306 if token.token_type() != TOKEN_EOF && token.channel() != self.channel =>
307 {
308 next += 1;
309 continue;
310 }
311 _ => break next,
312 }
313 };
314 if let Some(slot) = self.next_visible_after.get_mut(index) {
315 *slot = found;
316 }
317 found
318 }
319
320 pub fn text(&mut self, start: usize, stop: usize) -> String {
321 self.sync(stop);
322 if start > stop || start >= self.tokens.len() {
323 return String::new();
324 }
325 self.tokens[start..=stop.min(self.tokens.len().saturating_sub(1))]
329 .iter()
330 .take_while(|token| token.token_type() != TOKEN_EOF)
331 .map(|token| token.text())
332 .collect::<Vec<_>>()
333 .join("")
334 }
335
336 pub fn text_all(&mut self) -> String {
340 self.fill();
341 self.tokens
342 .iter()
343 .filter(|token| token.token_type() != TOKEN_EOF)
344 .map(|token| token.text())
345 .collect()
346 }
347
348 pub fn drain_source_errors(&mut self) -> Vec<TokenSourceError> {
351 std::mem::take(&mut self.source_errors)
352 }
353
354 pub const fn is_filled(&self) -> bool {
355 self.fetched_eof
356 }
357}
358
359#[cfg(test)]
360mod tests {
361 use super::*;
362 use crate::token::{CommonToken, HIDDEN_CHANNEL};
363
364 #[derive(Debug)]
365 struct VecTokenSource {
366 tokens: Vec<CommonToken>,
367 index: usize,
368 }
369
370 impl TokenSource for VecTokenSource {
371 fn next_token(&mut self) -> CommonToken {
372 let token = self
373 .tokens
374 .get(self.index)
375 .cloned()
376 .unwrap_or_else(|| CommonToken::eof("vec", self.index, 1, self.index));
377 self.index += 1;
378 token
379 }
380
381 fn line(&self) -> usize {
382 1
383 }
384
385 fn column(&self) -> usize {
386 self.index
387 }
388
389 fn source_name(&self) -> &'static str {
390 "vec"
391 }
392 }
393
394 #[test]
395 fn stream_skips_hidden_channel_for_lookahead() {
396 let source = VecTokenSource {
397 tokens: vec![
398 CommonToken::new(1).with_text("a"),
399 CommonToken::new(2)
400 .with_text(" ")
401 .with_channel(HIDDEN_CHANNEL),
402 CommonToken::new(3).with_text("b"),
403 CommonToken::eof("vec", 3, 1, 3),
404 ],
405 index: 0,
406 };
407 let mut stream = CommonTokenStream::new(source);
408 assert_eq!(stream.la_token(1), 1);
409 stream.consume();
410 assert_eq!(stream.la_token(1), 3);
411 assert_eq!(
412 stream
413 .lt(-1)
414 .expect("look-behind token should be buffered")
415 .token_type(),
416 1
417 );
418 }
419
420 #[test]
421 fn lookahead_skips_hidden_token_at_initial_cursor() {
422 let source = VecTokenSource {
423 tokens: vec![
424 CommonToken::new(2)
425 .with_text(" ")
426 .with_channel(HIDDEN_CHANNEL),
427 CommonToken::new(1).with_text("a"),
428 CommonToken::eof("vec", 2, 1, 2),
429 ],
430 index: 0,
431 };
432 let mut stream = CommonTokenStream::new(source);
433
434 assert_eq!(stream.la_token(1), 1);
435 assert_eq!(stream.lt(1).and_then(Token::text), Some("a"));
436 stream.consume();
437 assert_eq!(stream.la_token(1), TOKEN_EOF);
438 }
439
440 #[test]
441 fn text_returns_empty_when_start_is_past_buffer() {
442 let source = VecTokenSource {
443 tokens: vec![
444 CommonToken::new(1).with_text("a"),
445 CommonToken::eof("vec", 1, 1, 1),
446 ],
447 index: 0,
448 };
449 let mut stream = CommonTokenStream::new(source);
450
451 assert_eq!(stream.text(10, 12), "");
452 }
453
454 #[test]
455 fn tokens_returns_public_slice() {
456 let source = VecTokenSource {
457 tokens: vec![
458 CommonToken::new(1).with_text("a"),
459 CommonToken::new(2).with_text("b"),
460 CommonToken::eof("vec", 2, 1, 2),
461 ],
462 index: 0,
463 };
464 let mut stream = CommonTokenStream::new(source);
465 stream.fill();
466
467 fn token_count(tokens: &[CommonToken]) -> usize {
468 tokens.len()
469 }
470
471 let tokens = stream.tokens();
472 assert_eq!(token_count(tokens), 3);
473 assert_eq!(tokens[0].token_type(), 1);
474 assert_eq!(tokens.first().map(Token::token_type), Some(1));
475 assert_eq!(
476 tokens.iter().next_back().map(Token::token_type),
477 Some(TOKEN_EOF)
478 );
479 }
480}