1use crate::int_stream::{EOF, IntStream, UNKNOWN_SOURCE_NAME};
4use std::cell::Cell;
5
6pub use crate::token::TokenIter;
7use crate::token::{
8 DEFAULT_CHANNEL, TOKEN_EOF, Token, TokenId, TokenSink, TokenSource, TokenSourceError,
9 TokenSpec, TokenStore, TokenStoreError, TokenView,
10};
11
12#[derive(Debug)]
13struct BufferedSourceError {
14 token_index: usize,
15 error: TokenSourceError,
16}
17
18#[derive(Debug)]
19pub struct CommonTokenStream<S> {
20 source: S,
21 store: TokenStore,
22 source_token_count: usize,
23 source_error_count: usize,
24 next_visible_after: Vec<usize>,
25 cursor: usize,
26 channel: i32,
27 requested_token_count: Cell<usize>,
28 source_errors: Vec<BufferedSourceError>,
29}
30
31const UNKNOWN_NEXT_VISIBLE: usize = usize::MAX;
32
33fn buffer_token_source<S>(
34 source: &mut S,
35) -> Result<(TokenStore, Vec<BufferedSourceError>), TokenStoreError>
36where
37 S: TokenSource,
38{
39 let source_name = source.source_name().to_owned();
40 let mut store = TokenStore::new(source.source_text(), source_name);
41 let mut source_errors = Vec::new();
42 loop {
43 let expected_id = store.len();
44 let mut sink = TokenSink::new(&mut store);
45 let id = source.next_token(&mut sink)?;
46 let appended = sink.token_count().saturating_sub(expected_id);
47 if appended != 1 || id.index() != expected_id {
48 return Err(TokenStoreError::invalid_source_output(
49 expected_id,
50 id.index(),
51 appended,
52 ));
53 }
54 source_errors.extend(
55 source
56 .drain_errors()
57 .into_iter()
58 .map(|error| BufferedSourceError {
59 token_index: id.index(),
60 error,
61 }),
62 );
63 let token = sink
64 .view(id)
65 .expect("token source returned an ID it did not emit");
66 if token.token_type() == TOKEN_EOF {
67 break;
68 }
69 }
70 Ok((store, source_errors))
71}
72
73impl<S> CommonTokenStream<S>
74where
75 S: TokenSource,
76{
77 pub fn new(source: S) -> Self {
83 Self::try_new(source).unwrap_or_else(|error| panic!("failed to buffer tokens: {error}"))
84 }
85
86 pub fn try_new(source: S) -> Result<Self, TokenStoreError> {
87 Self::try_with_channel(source, DEFAULT_CHANNEL)
88 }
89
90 pub fn with_channel(source: S, channel: i32) -> Self {
93 Self::try_with_channel(source, channel)
94 .unwrap_or_else(|error| panic!("failed to buffer tokens: {error}"))
95 }
96
97 pub fn try_with_channel(mut source: S, channel: i32) -> Result<Self, TokenStoreError> {
98 let (store, source_errors) = buffer_token_source(&mut source)?;
99 let source_token_count = store.len();
100 let source_error_count = source_errors.len();
101 let mut stream = Self {
102 source,
103 store,
104 source_token_count,
105 source_error_count,
106 next_visible_after: vec![UNKNOWN_NEXT_VISIBLE; source_token_count],
107 cursor: 0,
108 channel,
109 requested_token_count: Cell::new(0),
110 source_errors,
111 };
112 stream.cursor = stream.adjust_seek_index(0);
113 stream.requested_token_count.set(0);
114 Ok(stream)
115 }
116
117 pub fn set_token_source(&mut self, source: S) {
122 self.try_set_token_source(source)
123 .unwrap_or_else(|error| panic!("failed to buffer tokens: {error}"));
124 }
125
126 pub fn try_set_token_source(&mut self, source: S) -> Result<(), TokenStoreError> {
128 let replacement = Self::try_with_channel(source, self.channel)?;
129 *self = replacement;
130 Ok(())
131 }
132
133 pub fn refill(&mut self) {
139 self.try_refill()
140 .unwrap_or_else(|error| panic!("failed to buffer tokens: {error}"));
141 }
142
143 pub fn try_refill(&mut self) -> Result<(), TokenStoreError> {
145 let (store, source_errors) = buffer_token_source(&mut self.source)?;
146 self.store = store;
147 self.source_token_count = self.store.len();
148 self.source_error_count = source_errors.len();
149 self.next_visible_after = vec![UNKNOWN_NEXT_VISIBLE; self.source_token_count];
150 self.cursor = self.adjust_seek_index(0);
151 self.requested_token_count.set(0);
152 self.source_errors = source_errors;
153 Ok(())
154 }
155
156 pub fn fill(&mut self) {
159 self.note_requested_count(self.source_token_count);
160 self.cursor = self.adjust_seek_index(self.cursor);
161 }
162
163 pub fn get(&self, index: usize) -> Option<TokenView<'_>> {
165 self.get_id(index).and_then(|id| self.store.view(id))
166 }
167
168 pub fn get_id(&self, index: usize) -> Option<TokenId> {
170 self.note_requested_count(index.saturating_add(1));
171 (index < self.source_token_count)
172 .then(|| TokenId::try_from(index).ok())
173 .flatten()
174 }
175
176 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
179 self.lt_id(offset).and_then(|id| self.store.view(id))
180 }
181
182 pub fn lt_id(&self, offset: isize) -> Option<TokenId> {
184 if offset == 0 {
185 return None;
186 }
187 if offset < 0 {
188 return offset
189 .checked_neg()
190 .map(isize::cast_unsigned)
191 .and_then(|offset| self.lb_id(offset));
192 }
193
194 let mut index = self.next_token_on_channel(self.cursor, self.channel);
195 let mut remaining = offset;
196 while remaining > 1 {
197 index = self.next_token_on_channel(index + 1, self.channel);
198 remaining -= 1;
199 }
200 self.get_id(index)
201 }
202
203 pub fn lb(&self, offset: usize) -> Option<TokenView<'_>> {
204 self.lb_id(offset).and_then(|id| self.store.view(id))
205 }
206
207 fn lb_id(&self, offset: usize) -> Option<TokenId> {
208 if offset == 0 || self.cursor == 0 {
209 return None;
210 }
211 let mut index = self.cursor;
212 let mut remaining = offset;
213 while remaining > 0 {
214 index = self.previous_token_on_channel(index, self.channel)?;
215 remaining -= 1;
216 }
217 self.get_id(index)
218 }
219
220 pub const fn token_source(&self) -> &S {
221 &self.source
222 }
223
224 pub const fn token_source_mut(&mut self) -> &mut S {
226 &mut self.source
227 }
228
229 pub fn tokens(&self) -> TokenIter<'_> {
231 self.note_requested_count(self.source_token_count);
232 self.store.iter_prefix(self.source_token_count)
233 }
234
235 pub const fn token_count(&self) -> usize {
236 self.source_token_count
237 }
238
239 pub const fn number_of_source_errors(&self) -> usize {
243 self.source_error_count
244 }
245
246 #[must_use]
248 pub const fn token_store(&self) -> &TokenStore {
249 &self.store
250 }
251
252 #[must_use]
254 pub fn into_token_store(self) -> TokenStore {
255 self.store
256 }
257
258 pub(crate) fn token_view(&self, id: TokenId) -> Option<TokenView<'_>> {
259 self.store.view(id)
260 }
261
262 pub(crate) fn insert(&mut self, spec: TokenSpec) -> Result<TokenId, TokenStoreError> {
263 self.store.push(spec)
264 }
265
266 fn note_requested_count(&self, count: usize) {
267 self.requested_token_count.set(
268 self.requested_token_count
269 .get()
270 .max(count.min(self.source_token_count)),
271 );
272 }
273
274 fn adjust_seek_index(&self, index: usize) -> usize {
277 self.next_token_on_channel(index, self.channel)
278 }
279
280 fn next_token_on_channel(&self, mut index: usize, channel: i32) -> usize {
282 while let Some(id) = self.get_id(index) {
283 if self.store.token_type(id) == Some(TOKEN_EOF)
284 || self.store.channel(id) == Some(channel)
285 {
286 return index;
287 }
288 index += 1;
289 }
290 index
291 }
292
293 fn previous_token_on_channel(&self, mut index: usize, channel: i32) -> Option<usize> {
295 while index > 0 {
296 index -= 1;
297 let id = self.get_id(index)?;
298 if self.store.token_type(id) == Some(TOKEN_EOF)
299 || self.store.channel(id) == Some(channel)
300 {
301 return Some(index);
302 }
303 }
304 None
305 }
306
307 pub fn previous_visible_token_index(&self, index: usize) -> Option<usize> {
310 self.previous_token_on_channel(index, self.channel)
311 }
312}
313
314impl<S> IntStream for CommonTokenStream<S>
315where
316 S: TokenSource,
317{
318 fn consume(&mut self) {
319 if self.la(1) == EOF {
320 return;
321 }
322 let current = self.next_token_on_channel(self.cursor, self.channel);
323 self.cursor = self.adjust_seek_index(current + 1);
324 }
325
326 fn la(&mut self, offset: isize) -> i32 {
327 self.la_token(offset)
328 }
329
330 fn index(&self) -> usize {
331 self.cursor
332 }
333
334 fn seek(&mut self, index: usize) {
335 self.cursor = self.adjust_seek_index(index);
336 }
337
338 fn size(&self) -> usize {
339 self.source_token_count
340 }
341
342 fn source_name(&self) -> &str {
343 let source_name = self.source.source_name();
344 if source_name.is_empty() {
345 UNKNOWN_SOURCE_NAME
346 } else {
347 source_name
348 }
349 }
350}
351
352impl<S> CommonTokenStream<S>
353where
354 S: TokenSource,
355{
356 pub fn la_token(&self, offset: isize) -> i32 {
357 self.lt_id(offset)
358 .and_then(|id| self.store.token_type(id))
359 .unwrap_or(TOKEN_EOF)
360 }
361
362 pub fn token_type_at_index(&self, index: usize) -> i32 {
365 self.get_id(index)
366 .and_then(|id| self.store.token_type(id))
367 .unwrap_or(TOKEN_EOF)
368 }
369
370 pub const fn channel(&self) -> i32 {
372 self.channel
373 }
374
375 pub fn next_visible_after(&mut self, index: usize) -> usize {
378 if let Some(cached) = self
379 .next_visible_after
380 .get(index)
381 .copied()
382 .filter(|cached| *cached != UNKNOWN_NEXT_VISIBLE)
383 {
384 return cached;
385 }
386
387 let mut next = index + 1;
388 let found = loop {
389 match self.get_id(next) {
390 Some(id)
391 if self.store.token_type(id) != Some(TOKEN_EOF)
392 && self.store.channel(id) != Some(self.channel) =>
393 {
394 next += 1;
395 continue;
396 }
397 _ => break next,
398 }
399 };
400 if let Some(slot) = self.next_visible_after.get_mut(index) {
401 *slot = found;
402 }
403 found
404 }
405
406 pub fn text(&self, start: usize, stop: usize) -> String {
407 if start > stop || start >= self.source_token_count {
408 return String::new();
409 }
410 (start..=stop.min(self.source_token_count.saturating_sub(1)))
411 .filter_map(|index| self.get(index))
412 .take_while(|token| token.token_type() != TOKEN_EOF)
413 .map(|token| token.text_or_empty())
414 .collect()
415 }
416
417 pub fn text_all(&self) -> String {
419 self.tokens()
420 .filter(|token| token.token_type() != TOKEN_EOF)
421 .map(|token| token.text_or_empty())
422 .collect()
423 }
424
425 pub fn drain_source_errors(&mut self) -> Vec<TokenSourceError> {
427 let requested = self.requested_token_count.get();
428 let ready = self
429 .source_errors
430 .partition_point(|buffered| buffered.token_index < requested);
431 self.source_errors
432 .drain(..ready)
433 .map(|buffered| buffered.error)
434 .collect()
435 }
436
437 pub const fn is_filled(&self) -> bool {
438 true
439 }
440}
441
442#[cfg(test)]
443mod tests {
444 use super::*;
445 use crate::token::HIDDEN_CHANNEL;
446 use std::collections::VecDeque;
447
448 #[derive(Debug)]
449 struct VecTokenSource {
450 tokens: VecDeque<TokenSpec>,
451 index: usize,
452 }
453
454 impl TokenSource for VecTokenSource {
455 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
456 let spec = self
457 .tokens
458 .pop_front()
459 .unwrap_or_else(|| TokenSpec::eof(self.index, self.index, 1, self.index));
460 self.index += 1;
461 sink.push(spec)
462 }
463
464 fn line(&self) -> usize {
465 1
466 }
467
468 fn column(&self) -> usize {
469 self.index
470 }
471
472 fn source_name(&self) -> &'static str {
473 "vec"
474 }
475 }
476
477 #[derive(Debug)]
478 struct ErrorTokenSource {
479 tokens: VecDeque<(TokenSpec, Vec<TokenSourceError>)>,
480 pending_errors: Vec<TokenSourceError>,
481 index: usize,
482 }
483
484 impl TokenSource for ErrorTokenSource {
485 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
486 let (spec, errors) = self.tokens.pop_front().unwrap_or_else(|| {
487 (
488 TokenSpec::eof(self.index, self.index, 1, self.index),
489 Vec::new(),
490 )
491 });
492 self.index += 1;
493 self.pending_errors = errors;
494 sink.push(spec)
495 }
496
497 fn line(&self) -> usize {
498 1
499 }
500
501 fn column(&self) -> usize {
502 self.index
503 }
504
505 fn source_name(&self) -> &'static str {
506 "errors"
507 }
508
509 fn drain_errors(&mut self) -> Vec<TokenSourceError> {
510 std::mem::take(&mut self.pending_errors)
511 }
512 }
513
514 #[derive(Debug, Default)]
515 struct StaleIdTokenSource {
516 previous: Option<TokenId>,
517 }
518
519 impl TokenSource for StaleIdTokenSource {
520 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
521 let emitted = sink.push(TokenSpec::explicit(1, "x"))?;
522 Ok(self.previous.replace(emitted).unwrap_or(emitted))
523 }
524
525 fn line(&self) -> usize {
526 1
527 }
528
529 fn column(&self) -> usize {
530 0
531 }
532
533 fn source_name(&self) -> &'static str {
534 "stale-id"
535 }
536 }
537
538 fn source(tokens: Vec<TokenSpec>) -> VecTokenSource {
539 VecTokenSource {
540 tokens: tokens.into(),
541 index: 0,
542 }
543 }
544
545 #[test]
546 fn stream_skips_hidden_channel_for_lookahead() {
547 let mut stream = CommonTokenStream::new(source(vec![
548 TokenSpec::explicit(1, "a"),
549 TokenSpec::explicit(2, " ").with_channel(HIDDEN_CHANNEL),
550 TokenSpec::explicit(3, "b"),
551 TokenSpec::eof(3, 3, 1, 3),
552 ]));
553 assert_eq!(stream.la_token(1), 1);
554 stream.consume();
555 assert_eq!(stream.la_token(1), 3);
556 assert_eq!(
557 stream
558 .lt(-1)
559 .expect("look-behind token should be buffered")
560 .token_type(),
561 1
562 );
563 }
564
565 #[test]
566 fn text_returns_empty_when_start_is_past_buffer() {
567 let stream = CommonTokenStream::new(source(vec![
568 TokenSpec::explicit(1, "a"),
569 TokenSpec::eof(1, 1, 1, 1),
570 ]));
571 assert_eq!(stream.text(10, 12), "");
572 }
573
574 #[test]
575 fn text_concatenates_borrowed_token_text() {
576 let stream = CommonTokenStream::new(source(vec![
577 TokenSpec::explicit(1, "a"),
578 TokenSpec::explicit(2, "b"),
579 TokenSpec::eof(2, 2, 1, 2),
580 ]));
581 assert_eq!(stream.text(0, 1), "ab");
582 assert_eq!(stream.text_all(), "ab");
583 }
584
585 #[test]
586 fn construction_rejects_stale_non_eof_token_id() {
587 let error = CommonTokenStream::try_new(StaleIdTokenSource::default())
588 .expect_err("a stale token ID must terminate buffering with an error");
589
590 assert!(error.to_string().contains("return ID 1"));
591 assert!(error.to_string().contains("returned ID 0"));
592 }
593
594 #[test]
595 fn source_errors_remain_hidden_until_their_token_is_requested() {
596 let suffix_error = TokenSourceError::new(1, 4, "token recognition error at: '@'");
597 let mut stream = CommonTokenStream::new(ErrorTokenSource {
598 tokens: [
599 (TokenSpec::explicit(1, "x"), Vec::new()),
600 (TokenSpec::explicit(2, "y"), Vec::new()),
601 (TokenSpec::eof(3, 3, 1, 3), vec![suffix_error.clone()]),
602 ]
603 .into(),
604 pending_errors: Vec::new(),
605 index: 0,
606 });
607
608 assert_eq!(stream.number_of_source_errors(), 1);
609 assert!(stream.drain_source_errors().is_empty());
610 assert_eq!(stream.token_type_at_index(1), 2);
611 assert!(stream.drain_source_errors().is_empty());
612
613 assert_eq!(stream.token_type_at_index(2), TOKEN_EOF);
614 assert_eq!(stream.drain_source_errors(), vec![suffix_error]);
615 assert_eq!(stream.number_of_source_errors(), 1);
616
617 stream.refill();
618 assert_eq!(stream.number_of_source_errors(), 0);
619 }
620
621 #[test]
622 fn tokens_returns_borrowing_views() {
623 let stream = CommonTokenStream::new(source(vec![
624 TokenSpec::explicit(1, "a"),
625 TokenSpec::explicit(2, "b"),
626 TokenSpec::eof(2, 2, 1, 2),
627 ]));
628 assert_eq!(stream.tokens().len(), 3);
629 assert_eq!(
630 stream.tokens().next().map(|token| token.token_type()),
631 Some(1)
632 );
633 assert_eq!(
634 stream.tokens().next_back().map(|token| token.token_type()),
635 Some(TOKEN_EOF)
636 );
637 }
638
639 #[test]
640 fn stream_tokens_exclude_parser_insertions_but_store_iterates_them() {
641 let mut stream = CommonTokenStream::new(source(vec![
642 TokenSpec::explicit(1, "a"),
643 TokenSpec::eof(1, 1, 1, 1),
644 ]));
645 stream
646 .insert(TokenSpec::explicit(2, "<missing token>"))
647 .expect("synthetic token should fit");
648
649 assert_eq!(stream.tokens().len(), 2);
650 assert_eq!(stream.token_store().iter().len(), 3);
651 assert_eq!(
652 stream
653 .token_store()
654 .iter()
655 .next_back()
656 .and_then(|token| token.text()),
657 Some("<missing token>")
658 );
659 }
660
661 #[test]
662 fn set_token_source_replaces_buffer_and_preserves_channel() {
663 let mut stream = CommonTokenStream::with_channel(
664 source(vec![
665 TokenSpec::explicit(1, "old").with_channel(2),
666 TokenSpec::eof(3, 3, 1, 3),
667 ]),
668 2,
669 );
670
671 stream.set_token_source(source(vec![
672 TokenSpec::explicit(2, "new").with_channel(2),
673 TokenSpec::eof(3, 3, 1, 3),
674 ]));
675
676 assert_eq!(stream.channel(), 2);
677 assert_eq!(stream.index(), 0);
678 assert_eq!(stream.number_of_source_errors(), 0);
679 assert_eq!(stream.la_token(1), 2);
680 assert_eq!(stream.text_all(), "new");
681 }
682
683 #[test]
684 fn refill_reuses_mutated_token_source_in_place() {
685 let mut stream = CommonTokenStream::new(source(vec![
686 TokenSpec::explicit(1, "old"),
687 TokenSpec::eof(3, 3, 1, 3),
688 ]));
689 let source = stream.token_source_mut();
690 source.tokens = vec![TokenSpec::explicit(2, "new"), TokenSpec::eof(3, 3, 1, 3)].into();
691 source.index = 0;
692
693 stream.refill();
694
695 assert_eq!(stream.index(), 0);
696 assert_eq!(stream.number_of_source_errors(), 0);
697 assert_eq!(stream.la_token(1), 2);
698 assert_eq!(stream.text_all(), "new");
699 }
700}