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