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