Skip to main content

antlr4_runtime/
tree.rs

1use crate::errors::AntlrError;
2use crate::recognizer::Recognizer;
3use crate::token::{Token, TokenId, TokenStore, TokenView};
4use std::any::Any;
5use std::collections::BTreeMap;
6use std::fmt;
7use std::mem::size_of;
8
9const NONE: u32 = u32::MAX;
10const FLAG_MATCHED_CHILD: u8 = 1 << 0;
11const FLAG_START_PRESENT: u8 = 1 << 1;
12const FLAG_STOP_PRESENT: u8 = 1 << 2;
13const VISITOR_STACK_RED_ZONE: usize = 1024 * 1024;
14const VISITOR_STACK_SIZE: usize = 4 * 1024 * 1024;
15
16#[repr(transparent)]
17#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
18pub struct NodeId(u32);
19
20impl NodeId {
21    pub(crate) const fn placeholder() -> Self {
22        Self(NONE)
23    }
24
25    #[must_use]
26    pub const fn index(self) -> usize {
27        self.0 as usize
28    }
29}
30
31/// Compact parser result. The tree data lives in [`ParseTreeStorage`].
32pub type ParseTree = NodeId;
33
34#[repr(u8)]
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub enum NodeKind {
37    Rule,
38    Terminal,
39    Error,
40}
41
42#[derive(Debug)]
43struct ChildLink {
44    node: NodeId,
45    next: u32,
46}
47
48#[derive(Debug)]
49struct RuleExtra {
50    int_returns: BTreeMap<String, i64>,
51    exception: Option<AntlrError>,
52    attrs: Option<GeneratedAttrs>,
53}
54
55#[derive(Debug)]
56enum ParseTreeExtra {
57    Rule(RuleExtra),
58}
59
60/// Flat, structure-of-arrays concrete syntax tree storage.
61///
62/// Every node is addressed by [`NodeId`]. Rule children occupy one range in
63/// `children`; `child_links` is parser scratch used only while rule contexts
64/// are open and is never exposed as part of the completed tree.
65#[derive(Debug, Default)]
66pub struct ParseTreeStorage {
67    kinds: Vec<NodeKind>,
68    child_starts: Vec<u32>,
69    child_lens: Vec<u32>,
70    payload_a: Vec<u32>,
71    payload_b: Vec<u32>,
72    starts: Vec<u32>,
73    stops: Vec<u32>,
74    alt_numbers: Vec<u32>,
75    context_alt_numbers: Vec<u32>,
76    extra_ids: Vec<u32>,
77    parents: Vec<u32>,
78    flags: Vec<u8>,
79    children: Vec<NodeId>,
80    extras: Vec<ParseTreeExtra>,
81    child_links: Vec<ChildLink>,
82}
83
84#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
85pub struct ParseTreeStats {
86    pub nodes: usize,
87    pub edges: usize,
88    pub extras: usize,
89    pub scratch_links: usize,
90    pub allocated_bytes: usize,
91}
92
93#[derive(Clone, Copy, Debug, Eq, PartialEq)]
94pub(crate) struct ParseTreeCheckpoint {
95    nodes: usize,
96    children: usize,
97    extras: usize,
98    child_links: usize,
99}
100
101impl ParseTreeStorage {
102    #[must_use]
103    pub const fn new() -> Self {
104        Self {
105            kinds: Vec::new(),
106            child_starts: Vec::new(),
107            child_lens: Vec::new(),
108            payload_a: Vec::new(),
109            payload_b: Vec::new(),
110            starts: Vec::new(),
111            stops: Vec::new(),
112            alt_numbers: Vec::new(),
113            context_alt_numbers: Vec::new(),
114            extra_ids: Vec::new(),
115            parents: Vec::new(),
116            flags: Vec::new(),
117            children: Vec::new(),
118            extras: Vec::new(),
119            child_links: Vec::new(),
120        }
121    }
122
123    #[must_use]
124    pub const fn node_count(&self) -> usize {
125        self.kinds.len()
126    }
127
128    #[must_use]
129    pub const fn edge_count(&self) -> usize {
130        self.children.len()
131    }
132
133    #[must_use]
134    pub const fn extra_count(&self) -> usize {
135        self.extras.len()
136    }
137
138    #[must_use]
139    pub const fn stats(&self) -> ParseTreeStats {
140        ParseTreeStats {
141            nodes: self.node_count(),
142            edges: self.edge_count(),
143            extras: self.extra_count(),
144            scratch_links: self.child_links.len(),
145            allocated_bytes: self.kinds.capacity() * size_of::<NodeKind>()
146                + self.child_starts.capacity() * size_of::<u32>()
147                + self.child_lens.capacity() * size_of::<u32>()
148                + self.payload_a.capacity() * size_of::<u32>()
149                + self.payload_b.capacity() * size_of::<u32>()
150                + self.starts.capacity() * size_of::<u32>()
151                + self.stops.capacity() * size_of::<u32>()
152                + self.alt_numbers.capacity() * size_of::<u32>()
153                + self.context_alt_numbers.capacity() * size_of::<u32>()
154                + self.extra_ids.capacity() * size_of::<u32>()
155                + self.parents.capacity() * size_of::<u32>()
156                + self.flags.capacity() * size_of::<u8>()
157                + self.children.capacity() * size_of::<NodeId>()
158                + self.extras.capacity() * size_of::<ParseTreeExtra>()
159                + self.child_links.capacity() * size_of::<ChildLink>(),
160        }
161    }
162
163    pub(crate) fn reset(&mut self) {
164        self.kinds.clear();
165        self.child_starts.clear();
166        self.child_lens.clear();
167        self.payload_a.clear();
168        self.payload_b.clear();
169        self.starts.clear();
170        self.stops.clear();
171        self.alt_numbers.clear();
172        self.context_alt_numbers.clear();
173        self.extra_ids.clear();
174        self.parents.clear();
175        self.flags.clear();
176        self.children.clear();
177        self.extras.clear();
178        self.child_links.clear();
179    }
180
181    pub(crate) fn release_scratch(&mut self) {
182        self.child_links.clear();
183    }
184
185    pub(crate) fn discard_scratch(&mut self) {
186        self.child_links = Vec::new();
187    }
188
189    pub(crate) const fn checkpoint(&self) -> ParseTreeCheckpoint {
190        ParseTreeCheckpoint {
191            nodes: self.kinds.len(),
192            children: self.children.len(),
193            extras: self.extras.len(),
194            child_links: self.child_links.len(),
195        }
196    }
197
198    pub(crate) fn rollback(&mut self, checkpoint: ParseTreeCheckpoint) {
199        self.kinds.truncate(checkpoint.nodes);
200        self.child_starts.truncate(checkpoint.nodes);
201        self.child_lens.truncate(checkpoint.nodes);
202        self.payload_a.truncate(checkpoint.nodes);
203        self.payload_b.truncate(checkpoint.nodes);
204        self.starts.truncate(checkpoint.nodes);
205        self.stops.truncate(checkpoint.nodes);
206        self.alt_numbers.truncate(checkpoint.nodes);
207        self.context_alt_numbers.truncate(checkpoint.nodes);
208        self.extra_ids.truncate(checkpoint.nodes);
209        self.parents.truncate(checkpoint.nodes);
210        self.flags.truncate(checkpoint.nodes);
211        self.children.truncate(checkpoint.children);
212        self.extras.truncate(checkpoint.extras);
213        self.child_links.truncate(checkpoint.child_links);
214    }
215
216    pub(crate) fn terminal(&mut self, token: TokenId) -> NodeId {
217        self.push_node(NodeRecord {
218            kind: NodeKind::Terminal,
219            payload_a: token.index() as u32,
220            ..NodeRecord::default()
221        })
222    }
223
224    pub(crate) fn error(&mut self, token: TokenId) -> NodeId {
225        self.push_node(NodeRecord {
226            kind: NodeKind::Error,
227            payload_a: token.index() as u32,
228            ..NodeRecord::default()
229        })
230    }
231
232    pub(crate) fn add_child(&mut self, context: &mut ParserRuleContext, child: NodeId) {
233        context.matched_child = true;
234        let link = self.child_links.len_u32("parse-tree scratch child links");
235        self.child_links.push(ChildLink {
236            node: child,
237            next: NONE,
238        });
239        if context.first_child == NONE {
240            context.first_child = link;
241        } else {
242            self.child_links[context.last_child as usize].next = link;
243        }
244        context.last_child = link;
245        context.child_count = context
246            .child_count
247            .checked_add(1)
248            .expect("rule child count exceeds u32");
249    }
250
251    pub(crate) fn finish_rule(&mut self, context: ParserRuleContext) -> NodeId {
252        let parent = NodeId(self.kinds.len_u32("parse-tree node pool"));
253        let child_start = self.children.len_u32("parse-tree child pool");
254        let mut link = context.first_child;
255        while link != NONE {
256            let child = &self.child_links[link as usize];
257            self.children.push(child.node);
258            self.parents[child.node.index()] = parent.0;
259            link = child.next;
260        }
261
262        let extra_id = if context.int_returns.is_empty()
263            && context.exception.is_none()
264            && context.attrs.is_none()
265        {
266            NONE
267        } else {
268            let id = self.extras.len_u32("parse-tree extra pool");
269            self.extras.push(ParseTreeExtra::Rule(RuleExtra {
270                int_returns: context.int_returns,
271                exception: context.exception,
272                attrs: context.attrs,
273            }));
274            id
275        };
276
277        self.push_node(NodeRecord {
278            kind: NodeKind::Rule,
279            child_start,
280            child_len: context.child_count,
281            payload_a: u32::try_from(context.rule_index).expect("rule index exceeds u32"),
282            payload_b: i32::try_from(context.invoking_state)
283                .expect("invoking state exceeds i32")
284                .cast_unsigned(),
285            start: context.start.map_or(NONE, |token| token.index() as u32),
286            stop: context.stop.map_or(NONE, |token| token.index() as u32),
287            alt_number: u32::try_from(context.alt_number).expect("alternative number exceeds u32"),
288            context_alt_number: u32::try_from(context.context_alt_number)
289                .expect("context alternative number exceeds u32"),
290            extra_id,
291            flags: (u8::from(context.matched_child) * FLAG_MATCHED_CHILD)
292                | (u8::from(context.start.is_some()) * FLAG_START_PRESENT)
293                | (u8::from(context.stop.is_some()) * FLAG_STOP_PRESENT),
294        })
295    }
296
297    fn push_node(&mut self, record: NodeRecord) -> NodeId {
298        let id = NodeId(self.kinds.len_u32("parse-tree node pool"));
299        self.kinds.push(record.kind);
300        self.child_starts.push(record.child_start);
301        self.child_lens.push(record.child_len);
302        self.payload_a.push(record.payload_a);
303        self.payload_b.push(record.payload_b);
304        self.starts.push(record.start);
305        self.stops.push(record.stop);
306        self.alt_numbers.push(record.alt_number);
307        if record.context_alt_number == 0 {
308            if !self.context_alt_numbers.is_empty() {
309                self.context_alt_numbers.push(0);
310            }
311        } else {
312            if self.context_alt_numbers.is_empty() {
313                self.context_alt_numbers.resize(id.index(), 0);
314            }
315            self.context_alt_numbers.push(record.context_alt_number);
316        }
317        self.extra_ids.push(record.extra_id);
318        self.parents.push(NONE);
319        self.flags.push(record.flags);
320        id
321    }
322
323    #[must_use]
324    pub fn node<'tree>(&'tree self, tokens: &'tree TokenStore, id: NodeId) -> Option<Node<'tree>> {
325        (id.index() < self.node_count()).then_some(Node {
326            storage: self,
327            tokens,
328            id,
329        })
330    }
331
332    fn kind(&self, id: NodeId) -> NodeKind {
333        self.kinds[id.index()]
334    }
335
336    fn child_ids(&self, id: NodeId) -> &[NodeId] {
337        let index = id.index();
338        let start = self.child_starts[index] as usize;
339        let len = self.child_lens[index] as usize;
340        &self.children[start..start + len]
341    }
342
343    const fn context_child_ids<'a>(
344        &'a self,
345        context: &'a ParserRuleContext,
346    ) -> ContextChildIds<'a> {
347        ContextChildIds {
348            storage: self,
349            next: context.first_child,
350            remaining: context.child_count as usize,
351        }
352    }
353
354    fn token_id(&self, id: NodeId) -> Option<TokenId> {
355        match self.kind(id) {
356            NodeKind::Terminal | NodeKind::Error => {
357                Some(stored_token_id(self.payload_a[id.index()]))
358            }
359            NodeKind::Rule => None,
360        }
361    }
362
363    fn rule_extra(&self, id: NodeId) -> Option<&RuleExtra> {
364        let extra = *self.extra_ids.get(id.index())?;
365        if extra == NONE {
366            return None;
367        }
368        match &self.extras[extra as usize] {
369            ParseTreeExtra::Rule(extra) => Some(extra),
370        }
371    }
372}
373
374#[derive(Clone, Copy)]
375struct NodeRecord {
376    kind: NodeKind,
377    child_start: u32,
378    child_len: u32,
379    payload_a: u32,
380    payload_b: u32,
381    start: u32,
382    stop: u32,
383    alt_number: u32,
384    context_alt_number: u32,
385    extra_id: u32,
386    flags: u8,
387}
388
389impl Default for NodeRecord {
390    fn default() -> Self {
391        Self {
392            kind: NodeKind::Rule,
393            child_start: 0,
394            child_len: 0,
395            payload_a: 0,
396            payload_b: 0,
397            start: NONE,
398            stop: NONE,
399            alt_number: 0,
400            context_alt_number: 0,
401            extra_id: NONE,
402            flags: 0,
403        }
404    }
405}
406
407trait LenU32 {
408    fn len_u32(&self, name: &str) -> u32;
409}
410
411impl<T> LenU32 for Vec<T> {
412    fn len_u32(&self, name: &str) -> u32 {
413        u32::try_from(self.len()).unwrap_or_else(|_| panic!("{name} exceeds u32"))
414    }
415}
416
417#[derive(Clone, Copy, Debug)]
418pub struct Node<'tree> {
419    storage: &'tree ParseTreeStorage,
420    tokens: &'tree TokenStore,
421    id: NodeId,
422}
423
424impl<'tree> Node<'tree> {
425    #[must_use]
426    pub const fn id(self) -> NodeId {
427        self.id
428    }
429
430    #[must_use]
431    pub fn kind(self) -> NodeKind {
432        self.storage.kind(self.id)
433    }
434
435    #[must_use]
436    pub fn as_rule(self) -> Option<RuleNodeView<'tree>> {
437        (self.kind() == NodeKind::Rule).then_some(RuleNodeView { node: self })
438    }
439
440    #[must_use]
441    pub fn as_terminal(self) -> Option<TerminalNodeView<'tree>> {
442        (self.kind() == NodeKind::Terminal).then_some(TerminalNodeView { node: self })
443    }
444
445    #[must_use]
446    pub fn as_error(self) -> Option<ErrorNodeView<'tree>> {
447        (self.kind() == NodeKind::Error).then_some(ErrorNodeView { node: self })
448    }
449
450    #[must_use]
451    pub fn children(self) -> NodeChildren<'tree> {
452        NodeChildren {
453            storage: self.storage,
454            tokens: self.tokens,
455            ids: self.storage.child_ids(self.id).iter(),
456        }
457    }
458
459    #[must_use]
460    pub fn parent(self) -> Option<Self> {
461        let parent = self.storage.parents[self.id.index()];
462        (parent != NONE)
463            .then(|| self.storage.node(self.tokens, NodeId(parent)))
464            .flatten()
465    }
466
467    #[must_use]
468    pub fn descendants(self) -> ParseTreeDescendants<'tree> {
469        ParseTreeDescendants {
470            storage: self.storage,
471            tokens: self.tokens,
472            stack: vec![self.id],
473        }
474    }
475
476    #[must_use]
477    pub fn pre_order(self) -> ParseTreeDescendants<'tree> {
478        self.descendants()
479    }
480
481    #[must_use]
482    pub fn text(self) -> String {
483        match self.kind() {
484            NodeKind::Terminal | NodeKind::Error => self
485                .storage
486                .token_id(self.id)
487                .and_then(|id| self.tokens.text(id))
488                .unwrap_or("")
489                .to_owned(),
490            NodeKind::Rule => {
491                let mut text = String::new();
492                let mut stack = self
493                    .storage
494                    .child_ids(self.id)
495                    .iter()
496                    .rev()
497                    .copied()
498                    .collect::<Vec<_>>();
499                while let Some(id) = stack.pop() {
500                    match self.storage.kind(id) {
501                        NodeKind::Rule => {
502                            stack.extend(self.storage.child_ids(id).iter().rev().copied());
503                        }
504                        NodeKind::Terminal | NodeKind::Error => text.push_str(
505                            self.storage
506                                .token_id(id)
507                                .and_then(|token| self.tokens.text(token))
508                                .unwrap_or(""),
509                        ),
510                    }
511                }
512                text
513            }
514        }
515    }
516
517    #[must_use]
518    pub fn to_string_tree_with_names<S: AsRef<str>>(self, rule_names: &[S]) -> String {
519        match self.kind() {
520            NodeKind::Rule => self
521                .as_rule()
522                .expect("rule node kind checked")
523                .to_string_tree_with_names(rule_names),
524            NodeKind::Terminal | NodeKind::Error => escape_tree_text(
525                self.storage
526                    .token_id(self.id)
527                    .and_then(|id| self.tokens.text(id))
528                    .unwrap_or(""),
529            ),
530        }
531    }
532
533    #[must_use]
534    pub fn to_string_tree<R: Recognizer>(
535        self,
536        recognizer: Option<&R>,
537        _tokens: &TokenStore,
538    ) -> String {
539        recognizer.map_or_else(
540            || self.to_string_tree_with_names::<&str>(&[]),
541            |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
542        )
543    }
544
545    #[must_use]
546    pub fn first_rule(self, rule_index: usize) -> Option<Self> {
547        self.descendants().find(|node| {
548            node.as_rule()
549                .is_some_and(|rule| rule.rule_index() == rule_index)
550        })
551    }
552
553    #[must_use]
554    pub fn first_rule_stop(self, rule_index: usize) -> Option<TokenView<'tree>> {
555        self.first_rule(rule_index)?.as_rule()?.stop()
556    }
557
558    #[must_use]
559    pub fn first_rule_int_return(self, rule_index: usize, name: &str) -> Option<i64> {
560        self.first_rule(rule_index)?.as_rule()?.int_return(name)
561    }
562
563    #[must_use]
564    pub fn rule_attrs<T: Any>(self) -> Option<&'tree T> {
565        self.as_rule()?.generated_attrs::<T>()
566    }
567
568    #[must_use]
569    pub fn first_error_token(self) -> Option<TokenView<'tree>> {
570        self.descendants()
571            .find_map(Node::as_error)
572            .map(ErrorNodeView::symbol)
573    }
574
575    #[must_use]
576    pub fn rule_invocation_stack<S: AsRef<str>>(
577        self,
578        rule_index: usize,
579        rule_names: &[S],
580    ) -> Option<Vec<String>> {
581        let mut stack = vec![(self.id, 0_usize)];
582        let mut names = Vec::new();
583        while let Some((id, child_index)) = stack.last_mut() {
584            if *child_index == 0 {
585                let Some(rule) = self.storage.node(self.tokens, *id).and_then(Node::as_rule) else {
586                    stack.pop();
587                    continue;
588                };
589                names.push(
590                    rule_names
591                        .get(rule.rule_index())
592                        .map_or("<unknown>", |name| name.as_ref())
593                        .to_owned(),
594                );
595                if rule.rule_index() == rule_index {
596                    names.reverse();
597                    return Some(names);
598                }
599            }
600            let children = self.storage.child_ids(*id);
601            let next = children.get(*child_index).copied();
602            *child_index += 1;
603            if let Some(child) = next {
604                if self.storage.kind(child) == NodeKind::Rule {
605                    stack.push((child, 0));
606                }
607            } else {
608                stack.pop();
609                names.pop();
610            }
611        }
612        None
613    }
614}
615
616#[derive(Clone, Debug)]
617pub struct NodeChildren<'tree> {
618    storage: &'tree ParseTreeStorage,
619    tokens: &'tree TokenStore,
620    ids: std::slice::Iter<'tree, NodeId>,
621}
622
623impl<'tree> Iterator for NodeChildren<'tree> {
624    type Item = Node<'tree>;
625
626    fn next(&mut self) -> Option<Self::Item> {
627        self.ids
628            .next()
629            .and_then(|id| self.storage.node(self.tokens, *id))
630    }
631
632    fn size_hint(&self) -> (usize, Option<usize>) {
633        self.ids.size_hint()
634    }
635}
636
637impl DoubleEndedIterator for NodeChildren<'_> {
638    fn next_back(&mut self) -> Option<Self::Item> {
639        self.ids
640            .next_back()
641            .and_then(|id| self.storage.node(self.tokens, *id))
642    }
643}
644
645impl ExactSizeIterator for NodeChildren<'_> {}
646
647#[derive(Clone, Debug)]
648pub struct ParseTreeDescendants<'tree> {
649    storage: &'tree ParseTreeStorage,
650    tokens: &'tree TokenStore,
651    stack: Vec<NodeId>,
652}
653
654impl<'tree> Iterator for ParseTreeDescendants<'tree> {
655    type Item = Node<'tree>;
656
657    fn next(&mut self) -> Option<Self::Item> {
658        let id = self.stack.pop()?;
659        self.stack
660            .extend(self.storage.child_ids(id).iter().rev().copied());
661        Some(Node {
662            storage: self.storage,
663            tokens: self.tokens,
664            id,
665        })
666    }
667}
668
669#[derive(Clone, Copy, Debug)]
670pub struct RuleNodeView<'tree> {
671    node: Node<'tree>,
672}
673
674impl<'tree> RuleNodeView<'tree> {
675    #[must_use]
676    pub const fn node(self) -> Node<'tree> {
677        self.node
678    }
679
680    #[must_use]
681    pub fn rule_index(self) -> usize {
682        self.node.storage.payload_a[self.node.id.index()] as usize
683    }
684
685    #[must_use]
686    pub fn invoking_state(self) -> isize {
687        self.node.storage.payload_b[self.node.id.index()].cast_signed() as isize
688    }
689
690    #[must_use]
691    pub fn alt_number(self) -> usize {
692        self.node.storage.alt_numbers[self.node.id.index()] as usize
693    }
694
695    #[doc(hidden)]
696    #[must_use]
697    pub fn context_alt_number(self) -> usize {
698        self.node
699            .storage
700            .context_alt_numbers
701            .get(self.node.id.index())
702            .copied()
703            .unwrap_or_default() as usize
704    }
705
706    #[must_use]
707    pub fn start(self) -> Option<TokenView<'tree>> {
708        self.start_id().and_then(|id| self.node.tokens.view(id))
709    }
710
711    #[must_use]
712    pub fn start_id(self) -> Option<TokenId> {
713        let index = self.node.id.index();
714        (self.node.storage.flags[index] & FLAG_START_PRESENT != 0)
715            .then(|| stored_token_id(self.node.storage.starts[index]))
716    }
717
718    #[must_use]
719    pub fn stop(self) -> Option<TokenView<'tree>> {
720        self.stop_id().and_then(|id| self.node.tokens.view(id))
721    }
722
723    #[must_use]
724    pub fn stop_id(self) -> Option<TokenId> {
725        let index = self.node.id.index();
726        (self.node.storage.flags[index] & FLAG_STOP_PRESENT != 0)
727            .then(|| stored_token_id(self.node.storage.stops[index]))
728    }
729
730    #[must_use]
731    pub fn children(self) -> NodeChildren<'tree> {
732        self.node.children()
733    }
734
735    #[must_use]
736    pub fn child_count(self) -> usize {
737        self.node.storage.child_lens[self.node.id.index()] as usize
738    }
739
740    #[must_use]
741    pub fn child_rule(self, rule_index: usize) -> Option<Self> {
742        self.child_rules(rule_index).next()
743    }
744
745    pub fn child_rules(self, rule_index: usize) -> impl DoubleEndedIterator<Item = Self> + 'tree {
746        self.children().filter_map(move |child| {
747            let rule = child.as_rule()?;
748            (rule.rule_index() == rule_index).then_some(rule)
749        })
750    }
751
752    pub fn child_rule_trees(
753        self,
754        rule_index: usize,
755    ) -> impl DoubleEndedIterator<Item = Node<'tree>> + 'tree {
756        self.child_rules(rule_index).map(Self::node)
757    }
758
759    #[must_use]
760    pub fn child_token(self, token_type: i32) -> Option<TerminalNodeView<'tree>> {
761        self.child_tokens(token_type).next()
762    }
763
764    pub fn child_tokens(
765        self,
766        token_type: i32,
767    ) -> impl DoubleEndedIterator<Item = TerminalNodeView<'tree>> + 'tree {
768        self.children().filter_map(move |child| {
769            let terminal = match child.kind() {
770                NodeKind::Terminal => child.as_terminal(),
771                NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
772                NodeKind::Rule => None,
773            }?;
774            (terminal.symbol().token_type() == token_type).then_some(terminal)
775        })
776    }
777
778    pub fn terminal_children(
779        self,
780    ) -> impl DoubleEndedIterator<Item = TerminalNodeView<'tree>> + 'tree {
781        self.children().filter_map(|child| match child.kind() {
782            NodeKind::Terminal => child.as_terminal(),
783            NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
784            NodeKind::Rule => None,
785        })
786    }
787
788    #[must_use]
789    pub fn has_token(self, token_type: i32) -> bool {
790        self.child_token(token_type).is_some()
791    }
792
793    #[must_use]
794    pub fn text(self) -> String {
795        self.node.text()
796    }
797
798    #[must_use]
799    pub fn int_return(self, name: &str) -> Option<i64> {
800        self.node
801            .storage
802            .rule_extra(self.node.id)?
803            .int_returns
804            .get(name)
805            .copied()
806    }
807
808    #[must_use]
809    pub fn generated_attrs<T: Any>(self) -> Option<&'tree T> {
810        self.node
811            .storage
812            .rule_extra(self.node.id)?
813            .attrs
814            .as_ref()?
815            .downcast_ref::<T>()
816    }
817
818    #[must_use]
819    pub fn exception(self) -> Option<&'tree AntlrError> {
820        self.node
821            .storage
822            .rule_extra(self.node.id)?
823            .exception
824            .as_ref()
825    }
826
827    #[must_use]
828    pub fn downcast_ref<T: FromRuleNode<'tree>>(self) -> Option<T> {
829        T::from_rule_node(self)
830    }
831
832    pub fn invocation_states(self) -> impl Iterator<Item = isize> + 'tree {
833        std::iter::successors(Some(self), |rule| rule.node.parent()?.as_rule())
834            .take_while(|rule| rule.node.parent().is_some() && rule.invoking_state() >= 0)
835            .map(Self::invoking_state)
836    }
837
838    #[must_use]
839    pub fn to_string_tree_with_names<S: AsRef<str>>(self, rule_names: &[S]) -> String {
840        let name = rule_names
841            .get(self.rule_index())
842            .map_or("<unknown>", |name| name.as_ref());
843        let display_name = if self.alt_number() == 0 {
844            name.to_owned()
845        } else {
846            format!("{name}:{}", self.alt_number())
847        };
848        if self.child_count() == 0 {
849            return display_name;
850        }
851        let children = self
852            .children()
853            .map(|child| child.to_string_tree_with_names(rule_names))
854            .collect::<Vec<_>>()
855            .join(" ");
856        format!("({display_name} {children})")
857    }
858
859    #[must_use]
860    pub fn to_string_tree<R: Recognizer>(self, recognizer: Option<&R>) -> String {
861        recognizer.map_or_else(
862            || self.to_string_tree_with_names::<&str>(&[]),
863            |recognizer| self.to_string_tree_with_names(recognizer.data().rule_names()),
864        )
865    }
866}
867
868#[derive(Clone, Copy, Debug)]
869pub struct TerminalNodeView<'tree> {
870    node: Node<'tree>,
871}
872
873impl<'tree> TerminalNodeView<'tree> {
874    #[must_use]
875    pub const fn node(self) -> Node<'tree> {
876        self.node
877    }
878
879    #[must_use]
880    pub fn token_id(self) -> TokenId {
881        self.node
882            .storage
883            .token_id(self.node.id)
884            .expect("terminal node should contain a token ID")
885    }
886
887    #[must_use]
888    pub fn symbol(self) -> TokenView<'tree> {
889        self.node
890            .tokens
891            .view(self.token_id())
892            .expect("terminal node token ID should remain valid")
893    }
894
895    #[must_use]
896    pub fn text(self) -> &'tree str {
897        self.node.tokens.text(self.token_id()).unwrap_or("")
898    }
899}
900
901#[derive(Clone, Copy, Debug)]
902pub struct ErrorNodeView<'tree> {
903    node: Node<'tree>,
904}
905
906impl<'tree> ErrorNodeView<'tree> {
907    #[must_use]
908    pub const fn node(self) -> Node<'tree> {
909        self.node
910    }
911
912    #[must_use]
913    pub const fn terminal(self) -> TerminalNodeView<'tree> {
914        TerminalNodeView { node: self.node }
915    }
916
917    #[must_use]
918    pub fn token_id(self) -> TokenId {
919        self.terminal().token_id()
920    }
921
922    #[must_use]
923    pub fn symbol(self) -> TokenView<'tree> {
924        self.terminal().symbol()
925    }
926
927    #[must_use]
928    pub fn text(self) -> &'tree str {
929        self.terminal().text()
930    }
931}
932
933#[derive(Debug)]
934struct ContextChildIds<'a> {
935    storage: &'a ParseTreeStorage,
936    next: u32,
937    remaining: usize,
938}
939
940impl Iterator for ContextChildIds<'_> {
941    type Item = NodeId;
942
943    fn next(&mut self) -> Option<Self::Item> {
944        if self.next == NONE {
945            return None;
946        }
947        let link = &self.storage.child_links[self.next as usize];
948        self.next = link.next;
949        self.remaining -= 1;
950        Some(link.node)
951    }
952
953    fn size_hint(&self) -> (usize, Option<usize>) {
954        (self.remaining, Some(self.remaining))
955    }
956}
957
958impl ExactSizeIterator for ContextChildIds<'_> {}
959
960/// Transient builder for one open rule.
961///
962/// This value owns no tree nodes or child vector. Child IDs are appended to
963/// parser-owned scratch links and are copied once into the global child pool
964/// when the rule completes.
965#[derive(Debug)]
966pub struct ParserRuleContext {
967    rule_index: usize,
968    invoking_state: isize,
969    alt_number: usize,
970    context_alt_number: usize,
971    start: Option<TokenId>,
972    stop: Option<TokenId>,
973    int_returns: BTreeMap<String, i64>,
974    first_child: u32,
975    last_child: u32,
976    child_count: u32,
977    matched_child: bool,
978    exception: Option<AntlrError>,
979    attrs: Option<GeneratedAttrs>,
980}
981
982impl ParserRuleContext {
983    #[must_use]
984    pub const fn new(rule_index: usize, invoking_state: isize) -> Self {
985        Self {
986            rule_index,
987            invoking_state,
988            alt_number: 0,
989            context_alt_number: 0,
990            start: None,
991            stop: None,
992            int_returns: BTreeMap::new(),
993            first_child: NONE,
994            last_child: NONE,
995            child_count: 0,
996            matched_child: false,
997            exception: None,
998            attrs: None,
999        }
1000    }
1001
1002    pub(crate) const fn with_child_capacity(
1003        rule_index: usize,
1004        invoking_state: isize,
1005        _capacity: usize,
1006    ) -> Self {
1007        Self::new(rule_index, invoking_state)
1008    }
1009
1010    #[must_use]
1011    pub const fn rule_index(&self) -> usize {
1012        self.rule_index
1013    }
1014
1015    #[must_use]
1016    pub const fn invoking_state(&self) -> isize {
1017        self.invoking_state
1018    }
1019
1020    #[must_use]
1021    pub const fn alt_number(&self) -> usize {
1022        self.alt_number
1023    }
1024
1025    pub const fn set_alt_number(&mut self, alt_number: usize) {
1026        self.alt_number = alt_number;
1027    }
1028
1029    #[doc(hidden)]
1030    #[must_use]
1031    pub const fn context_alt_number(&self) -> usize {
1032        self.context_alt_number
1033    }
1034
1035    #[doc(hidden)]
1036    pub const fn set_context_alt_number(&mut self, alt_number: usize) {
1037        self.context_alt_number = alt_number;
1038    }
1039
1040    pub fn start<'a>(&self, tokens: &'a TokenStore) -> Option<TokenView<'a>> {
1041        self.start.and_then(|id| tokens.view(id))
1042    }
1043
1044    pub(crate) const fn start_id(&self) -> Option<TokenId> {
1045        self.start
1046    }
1047
1048    pub fn stop<'a>(&self, tokens: &'a TokenStore) -> Option<TokenView<'a>> {
1049        self.stop.and_then(|id| tokens.view(id))
1050    }
1051
1052    pub(crate) const fn set_start_id(&mut self, token: TokenId) {
1053        self.start = Some(token);
1054    }
1055
1056    pub(crate) const fn set_stop_id(&mut self, token: TokenId) {
1057        self.stop = Some(token);
1058    }
1059
1060    pub(crate) const fn set_start_from_context(&mut self, other: &Self) {
1061        self.start = other.start;
1062    }
1063
1064    pub fn set_int_return(&mut self, name: impl Into<String>, value: i64) {
1065        self.int_returns.insert(name.into(), value);
1066    }
1067
1068    #[must_use]
1069    pub fn int_return(&self, name: &str) -> Option<i64> {
1070        self.int_returns.get(name).copied()
1071    }
1072
1073    pub fn set_generated_attrs(&mut self, attrs: GeneratedAttrs) {
1074        self.attrs = Some(attrs);
1075    }
1076
1077    #[must_use]
1078    pub fn generated_attrs<T: Any>(&self) -> Option<&T> {
1079        self.attrs.as_ref().and_then(GeneratedAttrs::downcast_ref)
1080    }
1081
1082    #[must_use]
1083    pub const fn exception(&self) -> Option<&AntlrError> {
1084        self.exception.as_ref()
1085    }
1086
1087    pub fn set_exception(&mut self, error: AntlrError) {
1088        self.exception = Some(error);
1089    }
1090
1091    #[must_use]
1092    pub const fn child_count(&self) -> usize {
1093        self.child_count as usize
1094    }
1095
1096    #[must_use]
1097    pub const fn has_matched_child(&self) -> bool {
1098        self.matched_child
1099    }
1100
1101    pub const fn note_matched_child(&mut self) {
1102        self.matched_child = true;
1103    }
1104
1105    pub fn child_nodes<'a>(
1106        &'a self,
1107        storage: &'a ParseTreeStorage,
1108        tokens: &'a TokenStore,
1109    ) -> impl Iterator<Item = Node<'a>> + 'a {
1110        storage
1111            .context_child_ids(self)
1112            .filter_map(move |id| storage.node(tokens, id))
1113    }
1114
1115    pub fn child_rules<'a>(
1116        &'a self,
1117        storage: &'a ParseTreeStorage,
1118        tokens: &'a TokenStore,
1119        rule_index: usize,
1120    ) -> impl Iterator<Item = RuleNodeView<'a>> + 'a {
1121        self.child_nodes(storage, tokens).filter_map(move |child| {
1122            let rule = child.as_rule()?;
1123            (rule.rule_index() == rule_index).then_some(rule)
1124        })
1125    }
1126
1127    pub fn child_rule_trees<'a>(
1128        &'a self,
1129        storage: &'a ParseTreeStorage,
1130        tokens: &'a TokenStore,
1131        rule_index: usize,
1132    ) -> impl Iterator<Item = Node<'a>> + 'a {
1133        self.child_rules(storage, tokens, rule_index)
1134            .map(RuleNodeView::node)
1135    }
1136
1137    pub fn child_tokens<'a>(
1138        &'a self,
1139        storage: &'a ParseTreeStorage,
1140        tokens: &'a TokenStore,
1141        token_type: i32,
1142    ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1143        self.child_nodes(storage, tokens).filter_map(move |child| {
1144            let terminal = match child.kind() {
1145                NodeKind::Terminal => child.as_terminal(),
1146                NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
1147                NodeKind::Rule => None,
1148            }?;
1149            (terminal.symbol().token_type() == token_type).then_some(terminal)
1150        })
1151    }
1152
1153    pub fn terminal_children<'a>(
1154        &'a self,
1155        storage: &'a ParseTreeStorage,
1156        tokens: &'a TokenStore,
1157    ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1158        self.child_nodes(storage, tokens)
1159            .filter_map(|child| match child.kind() {
1160                NodeKind::Terminal => child.as_terminal(),
1161                NodeKind::Error => child.as_error().map(ErrorNodeView::terminal),
1162                NodeKind::Rule => None,
1163            })
1164    }
1165
1166    /// Terminal children as a *grammar-positional* sequence: deleted input tokens
1167    /// are skipped while inserted missing tokens are kept.
1168    ///
1169    /// A generated label read derives its index from the grammar, which knows
1170    /// nothing about error recovery. A deleted token still occupies a child slot, so
1171    /// indexing [`Self::terminal_children`] would shift every later position on
1172    /// recovered input; an *inserted* token, by contrast, is the value ANTLR assigns
1173    /// to the label and must stay. This matches the labeled-token accessors the
1174    /// generator emits.
1175    pub fn labeled_terminal_children<'a>(
1176        &'a self,
1177        storage: &'a ParseTreeStorage,
1178        tokens: &'a TokenStore,
1179    ) -> impl Iterator<Item = TerminalNodeView<'a>> + 'a {
1180        self.child_nodes(storage, tokens)
1181            .filter_map(|child| match child.kind() {
1182                NodeKind::Terminal => child.as_terminal(),
1183                NodeKind::Error => {
1184                    let terminal = child.as_error().map(ErrorNodeView::terminal)?;
1185                    terminal.symbol().is_synthetic().then_some(terminal)
1186                }
1187                NodeKind::Rule => None,
1188            })
1189    }
1190
1191    #[must_use]
1192    pub fn text(&self, storage: &ParseTreeStorage, tokens: &TokenStore) -> String {
1193        self.child_nodes(storage, tokens).map(Node::text).collect()
1194    }
1195
1196    #[must_use]
1197    pub fn to_string_tree_with_names<S: AsRef<str>>(
1198        &self,
1199        storage: &ParseTreeStorage,
1200        tokens: &TokenStore,
1201        rule_names: &[S],
1202    ) -> String {
1203        let name = rule_names
1204            .get(self.rule_index)
1205            .map_or("<unknown>", |name| name.as_ref());
1206        let display_name = if self.alt_number == 0 {
1207            name.to_owned()
1208        } else {
1209            format!("{name}:{}", self.alt_number)
1210        };
1211        if self.child_count == 0 {
1212            return display_name;
1213        }
1214        let children = self
1215            .child_nodes(storage, tokens)
1216            .map(|child| child.to_string_tree_with_names(rule_names))
1217            .collect::<Vec<_>>()
1218            .join(" ");
1219        format!("({display_name} {children})")
1220    }
1221
1222    #[must_use]
1223    pub fn to_string_tree<R: Recognizer>(
1224        &self,
1225        recognizer: Option<&R>,
1226        storage: &ParseTreeStorage,
1227        tokens: &TokenStore,
1228    ) -> String {
1229        recognizer.map_or_else(
1230            || self.to_string_tree_with_names::<&str>(storage, tokens, &[]),
1231            |recognizer| {
1232                self.to_string_tree_with_names(storage, tokens, recognizer.data().rule_names())
1233            },
1234        )
1235    }
1236}
1237
1238/// Type-erased generated-rule attributes stored only for rules that use them.
1239pub struct GeneratedAttrs(Box<dyn Any>);
1240
1241impl GeneratedAttrs {
1242    #[must_use]
1243    pub fn new<T: Any>(attrs: T) -> Self {
1244        Self(Box::new(attrs))
1245    }
1246
1247    #[must_use]
1248    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
1249        self.0.downcast_ref::<T>()
1250    }
1251}
1252
1253impl fmt::Debug for GeneratedAttrs {
1254    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1255        f.write_str("GeneratedAttrs(..)")
1256    }
1257}
1258
1259pub trait FromRuleNode<'tree>: Sized {
1260    fn from_rule_node(node: RuleNodeView<'tree>) -> Option<Self>;
1261}
1262
1263/// Exposes the stored rule node behind a completed generated context.
1264pub trait AsRuleNode<'tree> {
1265    fn as_rule_node(&self) -> RuleNodeView<'tree>;
1266}
1267
1268impl<'tree> AsRuleNode<'tree> for RuleNodeView<'tree> {
1269    fn as_rule_node(&self) -> Self {
1270        *self
1271    }
1272}
1273
1274/// A required grammar child was absent from a recovered parse tree.
1275#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1276pub struct MissingChildError {
1277    context: &'static str,
1278    child: &'static str,
1279}
1280
1281impl MissingChildError {
1282    #[must_use]
1283    pub const fn new(context: &'static str, child: &'static str) -> Self {
1284        Self { context, child }
1285    }
1286
1287    #[must_use]
1288    pub const fn context(self) -> &'static str {
1289        self.context
1290    }
1291
1292    #[must_use]
1293    pub const fn child(self) -> &'static str {
1294        self.child
1295    }
1296}
1297
1298impl fmt::Display for MissingChildError {
1299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1300        write!(
1301            f,
1302            "required child {} is missing from {}",
1303            self.child, self.context
1304        )
1305    }
1306}
1307
1308impl std::error::Error for MissingChildError {}
1309
1310pub trait ParseTreeListener {
1311    fn enter_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1312        Ok(())
1313    }
1314
1315    fn exit_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1316        Ok(())
1317    }
1318
1319    fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1320        Ok(())
1321    }
1322
1323    fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Result<(), AntlrError> {
1324        Ok(())
1325    }
1326}
1327
1328/// Value-returning, caller-directed traversal over a completed parse tree.
1329///
1330/// Generated grammar visitors adapt typed rule and alternative callbacks to
1331/// this runtime contract. The default traversal returns the latest child's
1332/// result, matching ANTLR's base visitor behavior.
1333pub trait ParseTreeVisitor {
1334    type Result;
1335
1336    fn default_result(&mut self) -> Self::Result;
1337
1338    fn visit(&mut self, tree: Node<'_>) -> Self::Result {
1339        match tree.kind() {
1340            NodeKind::Rule => self.visit_rule(tree.as_rule().expect("rule node kind checked")),
1341            NodeKind::Terminal => {
1342                self.visit_terminal(tree.as_terminal().expect("terminal node kind checked"))
1343            }
1344            NodeKind::Error => {
1345                self.visit_error_node(tree.as_error().expect("error node kind checked"))
1346            }
1347        }
1348    }
1349
1350    fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1351        self.visit_children(node)
1352    }
1353
1354    fn visit_children(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1355        stacker::maybe_grow(VISITOR_STACK_RED_ZONE, VISITOR_STACK_SIZE, || {
1356            let mut result = self.default_result();
1357            for child in node.children() {
1358                if !self.should_visit_next_child(node, &result) {
1359                    break;
1360                }
1361                let child_result = self.visit(child);
1362                result = self.aggregate_result(result, child_result);
1363            }
1364            result
1365        })
1366    }
1367
1368    fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1369        self.default_result()
1370    }
1371
1372    fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1373        self.default_result()
1374    }
1375
1376    fn aggregate_result(
1377        &mut self,
1378        _aggregate: Self::Result,
1379        next_result: Self::Result,
1380    ) -> Self::Result {
1381        next_result
1382    }
1383
1384    fn should_visit_next_child(
1385        &mut self,
1386        _node: RuleNodeView<'_>,
1387        _current_result: &Self::Result,
1388    ) -> bool {
1389        true
1390    }
1391}
1392
1393#[derive(Debug, Default)]
1394pub struct ParseTreeWalker;
1395
1396impl ParseTreeWalker {
1397    pub fn walk<L: ParseTreeListener>(listener: &mut L, tree: Node<'_>) -> Result<(), AntlrError> {
1398        enum Event {
1399            Enter(NodeId),
1400            Exit(NodeId),
1401        }
1402
1403        let storage = tree.storage;
1404        let tokens = tree.tokens;
1405        let mut stack = vec![Event::Enter(tree.id)];
1406        while let Some(event) = stack.pop() {
1407            match event {
1408                Event::Enter(id) => {
1409                    let node = storage
1410                        .node(tokens, id)
1411                        .expect("walker node ID should remain valid");
1412                    match node.kind() {
1413                        NodeKind::Rule => {
1414                            let rule = node.as_rule().expect("rule node kind checked");
1415                            listener.enter_every_rule(rule)?;
1416                            stack.push(Event::Exit(id));
1417                            stack.extend(
1418                                storage
1419                                    .child_ids(id)
1420                                    .iter()
1421                                    .rev()
1422                                    .copied()
1423                                    .map(Event::Enter),
1424                            );
1425                        }
1426                        NodeKind::Terminal => listener.visit_terminal(
1427                            node.as_terminal().expect("terminal node kind checked"),
1428                        )?,
1429                        NodeKind::Error => {
1430                            listener.visit_error_node(
1431                                node.as_error().expect("error node kind checked"),
1432                            )?;
1433                        }
1434                    }
1435                }
1436                Event::Exit(id) => {
1437                    let rule = storage
1438                        .node(tokens, id)
1439                        .and_then(Node::as_rule)
1440                        .expect("walker exit node should remain a rule");
1441                    listener.exit_every_rule(rule)?;
1442                }
1443            }
1444        }
1445        Ok(())
1446    }
1447}
1448
1449#[derive(Debug)]
1450pub struct ParsedFile {
1451    tokens: TokenStore,
1452    tree: ParseTreeStorage,
1453    root: NodeId,
1454}
1455
1456impl ParsedFile {
1457    #[must_use]
1458    pub fn new(tokens: TokenStore, mut tree: ParseTreeStorage, root: NodeId) -> Self {
1459        tree.discard_scratch();
1460        Self { tokens, tree, root }
1461    }
1462
1463    #[must_use]
1464    pub const fn tokens(&self) -> &TokenStore {
1465        &self.tokens
1466    }
1467
1468    #[must_use]
1469    pub const fn storage(&self) -> &ParseTreeStorage {
1470        &self.tree
1471    }
1472
1473    #[must_use]
1474    pub const fn root_id(&self) -> NodeId {
1475        self.root
1476    }
1477
1478    #[must_use]
1479    pub fn tree(&self) -> Node<'_> {
1480        self.tree
1481            .node(&self.tokens, self.root)
1482            .expect("parsed file root ID should remain valid")
1483    }
1484
1485    #[must_use]
1486    pub fn node(&self, id: NodeId) -> Option<Node<'_>> {
1487        self.tree.node(&self.tokens, id)
1488    }
1489
1490    #[must_use]
1491    pub fn into_parts(self) -> (TokenStore, ParseTreeStorage, NodeId) {
1492        (self.tokens, self.tree, self.root)
1493    }
1494}
1495
1496fn escape_tree_text(text: &str) -> String {
1497    let mut escaped = String::with_capacity(text.len());
1498    for ch in text.chars() {
1499        match ch {
1500            '\n' => escaped.push_str("\\n"),
1501            '\r' => escaped.push_str("\\r"),
1502            '\t' => escaped.push_str("\\t"),
1503            _ => escaped.push(ch),
1504        }
1505    }
1506    escaped
1507}
1508
1509fn stored_token_id(raw: u32) -> TokenId {
1510    TokenId::try_from(raw as usize).expect("stored token ID should fit in u32")
1511}
1512
1513#[cfg(test)]
1514#[allow(clippy::disallowed_methods)] // insta assertion macros unwrap internal I/O.
1515mod tests {
1516    use super::*;
1517    use crate::token::TokenSpec;
1518
1519    fn token(store: &mut TokenStore, token_type: i32, text: &str) -> TokenId {
1520        store
1521            .push(TokenSpec::explicit(token_type, text))
1522            .expect("test token should fit")
1523    }
1524
1525    #[test]
1526    fn stores_rule_children_in_one_pooled_range() {
1527        let mut tokens = TokenStore::new(None, "");
1528        let first = token(&mut tokens, 1, "a");
1529        let second = token(&mut tokens, 2, "b");
1530        let mut storage = ParseTreeStorage::new();
1531        let first = storage.terminal(first);
1532        let second = storage.error(second);
1533        let mut context = ParserRuleContext::new(0, -1);
1534        storage.add_child(&mut context, first);
1535        storage.add_child(&mut context, second);
1536        let root = storage.finish_rule(context);
1537        let parsed = ParsedFile::new(tokens, storage, root);
1538
1539        assert_eq!(parsed.tree().text(), "ab");
1540        assert_eq!(parsed.tree().children().count(), 2);
1541        assert_eq!(parsed.storage().stats().edges, 2);
1542        assert_eq!(parsed.storage().stats().scratch_links, 0);
1543        assert_eq!(
1544            parsed.tree().to_string_tree_with_names(&["root"]),
1545            "(root a b)"
1546        );
1547    }
1548
1549    #[test]
1550    fn labeled_terminal_children_keep_inserted_tokens_and_skip_deleted_ones() {
1551        let mut tokens = TokenStore::new(None, "");
1552        let deleted = token(&mut tokens, 1, "x");
1553        let inserted = tokens
1554            .push(TokenSpec::explicit(2, "<missing B>").with_span(usize::MAX, usize::MAX))
1555            .expect("test token should fit");
1556        let kept = token(&mut tokens, 3, "c");
1557        let mut storage = ParseTreeStorage::new();
1558        let deleted = storage.error(deleted);
1559        let inserted = storage.error(inserted);
1560        let kept = storage.terminal(kept);
1561        let mut context = ParserRuleContext::new(0, -1);
1562        storage.add_child(&mut context, deleted);
1563        storage.add_child(&mut context, inserted);
1564        storage.add_child(&mut context, kept);
1565
1566        // `terminal_children` is the raw CST view: every error node counts, so a
1567        // deleted token shifts the positions a grammar-derived index relies on.
1568        let raw = context
1569            .terminal_children(&storage, &tokens)
1570            .map(|terminal| terminal.text().to_owned())
1571            .collect::<Vec<_>>();
1572        let labeled = context
1573            .labeled_terminal_children(&storage, &tokens)
1574            .map(|terminal| terminal.text().to_owned())
1575            .collect::<Vec<_>>();
1576
1577        insta::assert_debug_snapshot!("terminal_children_raw_vs_labeled", (raw, labeled));
1578    }
1579
1580    #[test]
1581    fn context_alt_number_does_not_change_public_tree_rendering() {
1582        let tokens = TokenStore::new(None, "");
1583        let mut storage = ParseTreeStorage::new();
1584        let mut context = ParserRuleContext::new(0, -1);
1585        context.set_context_alt_number(2);
1586
1587        assert_eq!(context.alt_number(), 0);
1588        assert_eq!(context.context_alt_number(), 2);
1589        assert_eq!(
1590            context.to_string_tree_with_names(&storage, &tokens, &["root"]),
1591            "root"
1592        );
1593
1594        let root = storage.finish_rule(context);
1595        let parsed = ParsedFile::new(tokens, storage, root);
1596        let rule = parsed.tree().as_rule().expect("root rule");
1597        assert_eq!(rule.alt_number(), 0);
1598        assert_eq!(rule.context_alt_number(), 2);
1599        assert_eq!(parsed.tree().to_string_tree_with_names(&["root"]), "root");
1600    }
1601
1602    #[test]
1603    fn descendants_and_walker_preserve_antlr_order() {
1604        let mut tokens = TokenStore::new(None, "");
1605        let a = token(&mut tokens, 1, "a");
1606        let b = token(&mut tokens, 2, "b");
1607        let mut storage = ParseTreeStorage::new();
1608        let a = storage.terminal(a);
1609        let b = storage.terminal(b);
1610        let mut child = ParserRuleContext::new(1, 7);
1611        storage.add_child(&mut child, b);
1612        let child = storage.finish_rule(child);
1613        let mut root = ParserRuleContext::new(0, -1);
1614        storage.add_child(&mut root, a);
1615        storage.add_child(&mut root, child);
1616        let root = storage.finish_rule(root);
1617        let parsed = ParsedFile::new(tokens, storage, root);
1618
1619        let visited = parsed
1620            .tree()
1621            .descendants()
1622            .map(|node| match node.kind() {
1623                NodeKind::Rule => format!(
1624                    "r{}",
1625                    node.as_rule().expect("rule node kind checked").rule_index()
1626                ),
1627                NodeKind::Terminal => node
1628                    .as_terminal()
1629                    .expect("terminal node kind checked")
1630                    .text()
1631                    .to_owned(),
1632                NodeKind::Error => node
1633                    .as_error()
1634                    .expect("error node kind checked")
1635                    .text()
1636                    .to_owned(),
1637            })
1638            .collect::<Vec<_>>();
1639        assert_eq!(visited, ["r0", "a", "r1", "b"]);
1640
1641        #[derive(Default)]
1642        struct Listener(Vec<String>);
1643        impl ParseTreeListener for Listener {
1644            fn enter_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1645                self.0.push(format!("enter{}", ctx.rule_index()));
1646                Ok(())
1647            }
1648
1649            fn exit_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1650                self.0.push(format!("exit{}", ctx.rule_index()));
1651                Ok(())
1652            }
1653
1654            fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1655                self.0.push(node.text().to_owned());
1656                Ok(())
1657            }
1658        }
1659        let mut listener = Listener::default();
1660        ParseTreeWalker::walk(&mut listener, parsed.tree())
1661            .expect("test listener should accept every node");
1662        assert_eq!(listener.0, ["enter0", "a", "enter1", "b", "exit1", "exit0"]);
1663    }
1664
1665    fn visitor_test_tree() -> ParsedFile {
1666        let mut tokens = TokenStore::new(None, "");
1667        let a = token(&mut tokens, 1, "a");
1668        let b = token(&mut tokens, 2, "b");
1669        let error = token(&mut tokens, 3, "!");
1670        let mut storage = ParseTreeStorage::new();
1671        let a = storage.terminal(a);
1672        let b = storage.terminal(b);
1673        let error = storage.error(error);
1674        let mut child = ParserRuleContext::new(1, 7);
1675        storage.add_child(&mut child, b);
1676        let child = storage.finish_rule(child);
1677        let mut root = ParserRuleContext::new(0, -1);
1678        storage.add_child(&mut root, a);
1679        storage.add_child(&mut root, child);
1680        storage.add_child(&mut root, error);
1681        let root = storage.finish_rule(root);
1682        ParsedFile::new(tokens, storage, root)
1683    }
1684
1685    #[test]
1686    fn visitor_dispatches_and_aggregates_all_node_kinds() {
1687        #[derive(Default)]
1688        struct Visitor(Vec<String>);
1689
1690        impl ParseTreeVisitor for Visitor {
1691            type Result = Vec<String>;
1692
1693            fn default_result(&mut self) -> Self::Result {
1694                Vec::new()
1695            }
1696
1697            fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1698                self.0.push(format!("rule{}", node.rule_index()));
1699                self.visit_children(node)
1700            }
1701
1702            fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1703                vec![format!("terminal:{}", node.text())]
1704            }
1705
1706            fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1707                vec![format!("error:{}", node.text())]
1708            }
1709
1710            fn aggregate_result(
1711                &mut self,
1712                mut aggregate: Self::Result,
1713                next_result: Self::Result,
1714            ) -> Self::Result {
1715                aggregate.extend(next_result);
1716                aggregate
1717            }
1718        }
1719
1720        let parsed = visitor_test_tree();
1721        let mut visitor = Visitor::default();
1722        assert_eq!(
1723            visitor.visit(parsed.tree()),
1724            ["terminal:a", "terminal:b", "error:!"]
1725        );
1726        assert_eq!(visitor.0, ["rule0", "rule1"]);
1727    }
1728
1729    #[test]
1730    fn visitor_default_aggregation_returns_the_latest_child() {
1731        struct Visitor;
1732
1733        impl ParseTreeVisitor for Visitor {
1734            type Result = String;
1735
1736            fn default_result(&mut self) -> Self::Result {
1737                String::new()
1738            }
1739
1740            fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1741                node.text().to_owned()
1742            }
1743
1744            fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1745                node.text().to_owned()
1746            }
1747        }
1748
1749        let parsed = visitor_test_tree();
1750        assert_eq!(Visitor.visit(parsed.tree()), "!");
1751    }
1752
1753    #[test]
1754    fn visitor_can_short_circuit_before_any_or_later_children() {
1755        struct Visitor {
1756            limit: usize,
1757            visited: usize,
1758        }
1759
1760        impl ParseTreeVisitor for Visitor {
1761            type Result = usize;
1762
1763            fn default_result(&mut self) -> Self::Result {
1764                0
1765            }
1766
1767            fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1768                self.visited += 1;
1769                1
1770            }
1771
1772            fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1773                self.visited += 1;
1774                1
1775            }
1776
1777            fn aggregate_result(
1778                &mut self,
1779                aggregate: Self::Result,
1780                next_result: Self::Result,
1781            ) -> Self::Result {
1782                aggregate + next_result
1783            }
1784
1785            fn should_visit_next_child(
1786                &mut self,
1787                _node: RuleNodeView<'_>,
1788                current_result: &Self::Result,
1789            ) -> bool {
1790                *current_result < self.limit
1791            }
1792        }
1793
1794        let parsed = visitor_test_tree();
1795        let mut none = Visitor {
1796            limit: 0,
1797            visited: 0,
1798        };
1799        assert_eq!(none.visit(parsed.tree()), 0);
1800        assert_eq!(none.visited, 0);
1801
1802        let mut one = Visitor {
1803            limit: 1,
1804            visited: 0,
1805        };
1806        assert_eq!(one.visit(parsed.tree()), 1);
1807        assert_eq!(one.visited, 1);
1808    }
1809
1810    #[test]
1811    fn visitor_grows_the_stack_for_deep_rule_trees() {
1812        const DEPTH: usize = 20_000;
1813        const STACK_SIZE: usize = 256 * 1024;
1814
1815        std::thread::Builder::new()
1816            .name("visitor-stack-growth".to_owned())
1817            .stack_size(STACK_SIZE)
1818            .spawn(|| {
1819                let tokens = TokenStore::new(None, "");
1820                let mut storage = ParseTreeStorage::new();
1821                let mut child = storage.finish_rule(ParserRuleContext::new(DEPTH, -1));
1822                for rule_index in (0..DEPTH).rev() {
1823                    let mut parent = ParserRuleContext::new(rule_index, -1);
1824                    storage.add_child(&mut parent, child);
1825                    child = storage.finish_rule(parent);
1826                }
1827                let parsed = ParsedFile::new(tokens, storage, child);
1828
1829                struct Visitor;
1830                impl ParseTreeVisitor for Visitor {
1831                    type Result = usize;
1832
1833                    fn default_result(&mut self) -> Self::Result {
1834                        0
1835                    }
1836
1837                    fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1838                        self.visit_children(node) + 1
1839                    }
1840                }
1841
1842                assert_eq!(Visitor.visit(parsed.tree()), DEPTH + 1);
1843            })
1844            .expect("small-stack thread should start")
1845            .join()
1846            .expect("visitor should not overflow its stack");
1847    }
1848
1849    #[test]
1850    fn invocation_states_exclude_a_nonnegative_root_frame() {
1851        let tokens = TokenStore::new(None, "");
1852        let mut storage = ParseTreeStorage::new();
1853        let grandchild = storage.finish_rule(ParserRuleContext::new(2, 13));
1854        let mut child = ParserRuleContext::new(1, 7);
1855        storage.add_child(&mut child, grandchild);
1856        let child = storage.finish_rule(child);
1857        let mut root = ParserRuleContext::new(0, 4);
1858        storage.add_child(&mut root, child);
1859        let root = storage.finish_rule(root);
1860        let parsed = ParsedFile::new(tokens, storage, root);
1861
1862        let root = parsed
1863            .node(root)
1864            .and_then(Node::as_rule)
1865            .expect("root rule should be stored");
1866        let child = parsed
1867            .node(child)
1868            .and_then(Node::as_rule)
1869            .expect("child rule should be stored");
1870        let grandchild = parsed
1871            .node(grandchild)
1872            .and_then(Node::as_rule)
1873            .expect("grandchild rule should be stored");
1874
1875        assert_eq!(root.invocation_states().collect::<Vec<_>>(), []);
1876        assert_eq!(child.invocation_states().collect::<Vec<_>>(), [7]);
1877        assert_eq!(grandchild.invocation_states().collect::<Vec<_>>(), [13, 7]);
1878    }
1879
1880    #[test]
1881    fn uncommon_rule_payloads_live_in_sparse_extras() {
1882        let tokens = TokenStore::new(None, "");
1883        let mut storage = ParseTreeStorage::new();
1884        let plain = storage.finish_rule(ParserRuleContext::new(0, -1));
1885        let mut rich = ParserRuleContext::new(1, 3);
1886        rich.set_int_return("value", 42);
1887        let rich = storage.finish_rule(rich);
1888        let parsed = ParsedFile::new(tokens, storage, rich);
1889
1890        assert_eq!(parsed.storage().extra_count(), 1);
1891        assert_eq!(
1892            parsed
1893                .node(rich)
1894                .expect("rich rule should be stored")
1895                .as_rule()
1896                .expect("rich node should be a rule")
1897                .int_return("value"),
1898            Some(42)
1899        );
1900        assert!(
1901            parsed
1902                .node(plain)
1903                .expect("plain rule should be stored")
1904                .as_rule()
1905                .expect("plain node should be a rule")
1906                .int_return("value")
1907                .is_none()
1908        );
1909    }
1910
1911    #[test]
1912    fn preserves_maximum_token_id_in_nodes_and_rule_spans() {
1913        let max = TokenId::try_from(u32::MAX as usize).expect("maximum token ID should fit");
1914        let tokens = TokenStore::new(None, "");
1915        let mut storage = ParseTreeStorage::new();
1916        let terminal = storage.terminal(max);
1917        assert_eq!(storage.token_id(terminal), Some(max));
1918
1919        let mut context = ParserRuleContext::new(0, -1);
1920        context.set_start_id(max);
1921        context.set_stop_id(max);
1922        let rule = storage.finish_rule(context);
1923        let rule = storage
1924            .node(&tokens, rule)
1925            .and_then(Node::as_rule)
1926            .expect("rule should be stored");
1927        assert_eq!(rule.start_id(), Some(max));
1928        assert_eq!(rule.stop_id(), Some(max));
1929    }
1930}