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    #[must_use]
1167    pub fn text(&self, storage: &ParseTreeStorage, tokens: &TokenStore) -> String {
1168        self.child_nodes(storage, tokens).map(Node::text).collect()
1169    }
1170
1171    #[must_use]
1172    pub fn to_string_tree_with_names<S: AsRef<str>>(
1173        &self,
1174        storage: &ParseTreeStorage,
1175        tokens: &TokenStore,
1176        rule_names: &[S],
1177    ) -> String {
1178        let name = rule_names
1179            .get(self.rule_index)
1180            .map_or("<unknown>", |name| name.as_ref());
1181        let display_name = if self.alt_number == 0 {
1182            name.to_owned()
1183        } else {
1184            format!("{name}:{}", self.alt_number)
1185        };
1186        if self.child_count == 0 {
1187            return display_name;
1188        }
1189        let children = self
1190            .child_nodes(storage, tokens)
1191            .map(|child| child.to_string_tree_with_names(rule_names))
1192            .collect::<Vec<_>>()
1193            .join(" ");
1194        format!("({display_name} {children})")
1195    }
1196
1197    #[must_use]
1198    pub fn to_string_tree<R: Recognizer>(
1199        &self,
1200        recognizer: Option<&R>,
1201        storage: &ParseTreeStorage,
1202        tokens: &TokenStore,
1203    ) -> String {
1204        recognizer.map_or_else(
1205            || self.to_string_tree_with_names::<&str>(storage, tokens, &[]),
1206            |recognizer| {
1207                self.to_string_tree_with_names(storage, tokens, recognizer.data().rule_names())
1208            },
1209        )
1210    }
1211}
1212
1213/// Type-erased generated-rule attributes stored only for rules that use them.
1214pub struct GeneratedAttrs(Box<dyn Any>);
1215
1216impl GeneratedAttrs {
1217    #[must_use]
1218    pub fn new<T: Any>(attrs: T) -> Self {
1219        Self(Box::new(attrs))
1220    }
1221
1222    #[must_use]
1223    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
1224        self.0.downcast_ref::<T>()
1225    }
1226}
1227
1228impl fmt::Debug for GeneratedAttrs {
1229    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1230        f.write_str("GeneratedAttrs(..)")
1231    }
1232}
1233
1234pub trait FromRuleNode<'tree>: Sized {
1235    fn from_rule_node(node: RuleNodeView<'tree>) -> Option<Self>;
1236}
1237
1238/// Exposes the stored rule node behind a completed generated context.
1239pub trait AsRuleNode<'tree> {
1240    fn as_rule_node(&self) -> RuleNodeView<'tree>;
1241}
1242
1243impl<'tree> AsRuleNode<'tree> for RuleNodeView<'tree> {
1244    fn as_rule_node(&self) -> Self {
1245        *self
1246    }
1247}
1248
1249/// A required grammar child was absent from a recovered parse tree.
1250#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1251pub struct MissingChildError {
1252    context: &'static str,
1253    child: &'static str,
1254}
1255
1256impl MissingChildError {
1257    #[must_use]
1258    pub const fn new(context: &'static str, child: &'static str) -> Self {
1259        Self { context, child }
1260    }
1261
1262    #[must_use]
1263    pub const fn context(self) -> &'static str {
1264        self.context
1265    }
1266
1267    #[must_use]
1268    pub const fn child(self) -> &'static str {
1269        self.child
1270    }
1271}
1272
1273impl fmt::Display for MissingChildError {
1274    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1275        write!(
1276            f,
1277            "required child {} is missing from {}",
1278            self.child, self.context
1279        )
1280    }
1281}
1282
1283impl std::error::Error for MissingChildError {}
1284
1285pub trait ParseTreeListener {
1286    fn enter_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1287        Ok(())
1288    }
1289
1290    fn exit_every_rule(&mut self, _ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1291        Ok(())
1292    }
1293
1294    fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1295        Ok(())
1296    }
1297
1298    fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Result<(), AntlrError> {
1299        Ok(())
1300    }
1301}
1302
1303/// Value-returning, caller-directed traversal over a completed parse tree.
1304///
1305/// Generated grammar visitors adapt typed rule and alternative callbacks to
1306/// this runtime contract. The default traversal returns the latest child's
1307/// result, matching ANTLR's base visitor behavior.
1308pub trait ParseTreeVisitor {
1309    type Result;
1310
1311    fn default_result(&mut self) -> Self::Result;
1312
1313    fn visit(&mut self, tree: Node<'_>) -> Self::Result {
1314        match tree.kind() {
1315            NodeKind::Rule => self.visit_rule(tree.as_rule().expect("rule node kind checked")),
1316            NodeKind::Terminal => {
1317                self.visit_terminal(tree.as_terminal().expect("terminal node kind checked"))
1318            }
1319            NodeKind::Error => {
1320                self.visit_error_node(tree.as_error().expect("error node kind checked"))
1321            }
1322        }
1323    }
1324
1325    fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1326        self.visit_children(node)
1327    }
1328
1329    fn visit_children(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1330        stacker::maybe_grow(VISITOR_STACK_RED_ZONE, VISITOR_STACK_SIZE, || {
1331            let mut result = self.default_result();
1332            for child in node.children() {
1333                if !self.should_visit_next_child(node, &result) {
1334                    break;
1335                }
1336                let child_result = self.visit(child);
1337                result = self.aggregate_result(result, child_result);
1338            }
1339            result
1340        })
1341    }
1342
1343    fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1344        self.default_result()
1345    }
1346
1347    fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1348        self.default_result()
1349    }
1350
1351    fn aggregate_result(
1352        &mut self,
1353        _aggregate: Self::Result,
1354        next_result: Self::Result,
1355    ) -> Self::Result {
1356        next_result
1357    }
1358
1359    fn should_visit_next_child(
1360        &mut self,
1361        _node: RuleNodeView<'_>,
1362        _current_result: &Self::Result,
1363    ) -> bool {
1364        true
1365    }
1366}
1367
1368#[derive(Debug, Default)]
1369pub struct ParseTreeWalker;
1370
1371impl ParseTreeWalker {
1372    pub fn walk<L: ParseTreeListener>(listener: &mut L, tree: Node<'_>) -> Result<(), AntlrError> {
1373        enum Event {
1374            Enter(NodeId),
1375            Exit(NodeId),
1376        }
1377
1378        let storage = tree.storage;
1379        let tokens = tree.tokens;
1380        let mut stack = vec![Event::Enter(tree.id)];
1381        while let Some(event) = stack.pop() {
1382            match event {
1383                Event::Enter(id) => {
1384                    let node = storage
1385                        .node(tokens, id)
1386                        .expect("walker node ID should remain valid");
1387                    match node.kind() {
1388                        NodeKind::Rule => {
1389                            let rule = node.as_rule().expect("rule node kind checked");
1390                            listener.enter_every_rule(rule)?;
1391                            stack.push(Event::Exit(id));
1392                            stack.extend(
1393                                storage
1394                                    .child_ids(id)
1395                                    .iter()
1396                                    .rev()
1397                                    .copied()
1398                                    .map(Event::Enter),
1399                            );
1400                        }
1401                        NodeKind::Terminal => listener.visit_terminal(
1402                            node.as_terminal().expect("terminal node kind checked"),
1403                        )?,
1404                        NodeKind::Error => {
1405                            listener.visit_error_node(
1406                                node.as_error().expect("error node kind checked"),
1407                            )?;
1408                        }
1409                    }
1410                }
1411                Event::Exit(id) => {
1412                    let rule = storage
1413                        .node(tokens, id)
1414                        .and_then(Node::as_rule)
1415                        .expect("walker exit node should remain a rule");
1416                    listener.exit_every_rule(rule)?;
1417                }
1418            }
1419        }
1420        Ok(())
1421    }
1422}
1423
1424#[derive(Debug)]
1425pub struct ParsedFile {
1426    tokens: TokenStore,
1427    tree: ParseTreeStorage,
1428    root: NodeId,
1429}
1430
1431impl ParsedFile {
1432    #[must_use]
1433    pub fn new(tokens: TokenStore, mut tree: ParseTreeStorage, root: NodeId) -> Self {
1434        tree.discard_scratch();
1435        Self { tokens, tree, root }
1436    }
1437
1438    #[must_use]
1439    pub const fn tokens(&self) -> &TokenStore {
1440        &self.tokens
1441    }
1442
1443    #[must_use]
1444    pub const fn storage(&self) -> &ParseTreeStorage {
1445        &self.tree
1446    }
1447
1448    #[must_use]
1449    pub const fn root_id(&self) -> NodeId {
1450        self.root
1451    }
1452
1453    #[must_use]
1454    pub fn tree(&self) -> Node<'_> {
1455        self.tree
1456            .node(&self.tokens, self.root)
1457            .expect("parsed file root ID should remain valid")
1458    }
1459
1460    #[must_use]
1461    pub fn node(&self, id: NodeId) -> Option<Node<'_>> {
1462        self.tree.node(&self.tokens, id)
1463    }
1464
1465    #[must_use]
1466    pub fn into_parts(self) -> (TokenStore, ParseTreeStorage, NodeId) {
1467        (self.tokens, self.tree, self.root)
1468    }
1469}
1470
1471fn escape_tree_text(text: &str) -> String {
1472    let mut escaped = String::with_capacity(text.len());
1473    for ch in text.chars() {
1474        match ch {
1475            '\n' => escaped.push_str("\\n"),
1476            '\r' => escaped.push_str("\\r"),
1477            '\t' => escaped.push_str("\\t"),
1478            _ => escaped.push(ch),
1479        }
1480    }
1481    escaped
1482}
1483
1484fn stored_token_id(raw: u32) -> TokenId {
1485    TokenId::try_from(raw as usize).expect("stored token ID should fit in u32")
1486}
1487
1488#[cfg(test)]
1489mod tests {
1490    use super::*;
1491    use crate::token::TokenSpec;
1492
1493    fn token(store: &mut TokenStore, token_type: i32, text: &str) -> TokenId {
1494        store
1495            .push(TokenSpec::explicit(token_type, text))
1496            .expect("test token should fit")
1497    }
1498
1499    #[test]
1500    fn stores_rule_children_in_one_pooled_range() {
1501        let mut tokens = TokenStore::new(None, "");
1502        let first = token(&mut tokens, 1, "a");
1503        let second = token(&mut tokens, 2, "b");
1504        let mut storage = ParseTreeStorage::new();
1505        let first = storage.terminal(first);
1506        let second = storage.error(second);
1507        let mut context = ParserRuleContext::new(0, -1);
1508        storage.add_child(&mut context, first);
1509        storage.add_child(&mut context, second);
1510        let root = storage.finish_rule(context);
1511        let parsed = ParsedFile::new(tokens, storage, root);
1512
1513        assert_eq!(parsed.tree().text(), "ab");
1514        assert_eq!(parsed.tree().children().count(), 2);
1515        assert_eq!(parsed.storage().stats().edges, 2);
1516        assert_eq!(parsed.storage().stats().scratch_links, 0);
1517        assert_eq!(
1518            parsed.tree().to_string_tree_with_names(&["root"]),
1519            "(root a b)"
1520        );
1521    }
1522
1523    #[test]
1524    fn context_alt_number_does_not_change_public_tree_rendering() {
1525        let tokens = TokenStore::new(None, "");
1526        let mut storage = ParseTreeStorage::new();
1527        let mut context = ParserRuleContext::new(0, -1);
1528        context.set_context_alt_number(2);
1529
1530        assert_eq!(context.alt_number(), 0);
1531        assert_eq!(context.context_alt_number(), 2);
1532        assert_eq!(
1533            context.to_string_tree_with_names(&storage, &tokens, &["root"]),
1534            "root"
1535        );
1536
1537        let root = storage.finish_rule(context);
1538        let parsed = ParsedFile::new(tokens, storage, root);
1539        let rule = parsed.tree().as_rule().expect("root rule");
1540        assert_eq!(rule.alt_number(), 0);
1541        assert_eq!(rule.context_alt_number(), 2);
1542        assert_eq!(parsed.tree().to_string_tree_with_names(&["root"]), "root");
1543    }
1544
1545    #[test]
1546    fn descendants_and_walker_preserve_antlr_order() {
1547        let mut tokens = TokenStore::new(None, "");
1548        let a = token(&mut tokens, 1, "a");
1549        let b = token(&mut tokens, 2, "b");
1550        let mut storage = ParseTreeStorage::new();
1551        let a = storage.terminal(a);
1552        let b = storage.terminal(b);
1553        let mut child = ParserRuleContext::new(1, 7);
1554        storage.add_child(&mut child, b);
1555        let child = storage.finish_rule(child);
1556        let mut root = ParserRuleContext::new(0, -1);
1557        storage.add_child(&mut root, a);
1558        storage.add_child(&mut root, child);
1559        let root = storage.finish_rule(root);
1560        let parsed = ParsedFile::new(tokens, storage, root);
1561
1562        let visited = parsed
1563            .tree()
1564            .descendants()
1565            .map(|node| match node.kind() {
1566                NodeKind::Rule => format!(
1567                    "r{}",
1568                    node.as_rule().expect("rule node kind checked").rule_index()
1569                ),
1570                NodeKind::Terminal => node
1571                    .as_terminal()
1572                    .expect("terminal node kind checked")
1573                    .text()
1574                    .to_owned(),
1575                NodeKind::Error => node
1576                    .as_error()
1577                    .expect("error node kind checked")
1578                    .text()
1579                    .to_owned(),
1580            })
1581            .collect::<Vec<_>>();
1582        assert_eq!(visited, ["r0", "a", "r1", "b"]);
1583
1584        #[derive(Default)]
1585        struct Listener(Vec<String>);
1586        impl ParseTreeListener for Listener {
1587            fn enter_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1588                self.0.push(format!("enter{}", ctx.rule_index()));
1589                Ok(())
1590            }
1591
1592            fn exit_every_rule(&mut self, ctx: RuleNodeView<'_>) -> Result<(), AntlrError> {
1593                self.0.push(format!("exit{}", ctx.rule_index()));
1594                Ok(())
1595            }
1596
1597            fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Result<(), AntlrError> {
1598                self.0.push(node.text().to_owned());
1599                Ok(())
1600            }
1601        }
1602        let mut listener = Listener::default();
1603        ParseTreeWalker::walk(&mut listener, parsed.tree())
1604            .expect("test listener should accept every node");
1605        assert_eq!(listener.0, ["enter0", "a", "enter1", "b", "exit1", "exit0"]);
1606    }
1607
1608    fn visitor_test_tree() -> ParsedFile {
1609        let mut tokens = TokenStore::new(None, "");
1610        let a = token(&mut tokens, 1, "a");
1611        let b = token(&mut tokens, 2, "b");
1612        let error = token(&mut tokens, 3, "!");
1613        let mut storage = ParseTreeStorage::new();
1614        let a = storage.terminal(a);
1615        let b = storage.terminal(b);
1616        let error = storage.error(error);
1617        let mut child = ParserRuleContext::new(1, 7);
1618        storage.add_child(&mut child, b);
1619        let child = storage.finish_rule(child);
1620        let mut root = ParserRuleContext::new(0, -1);
1621        storage.add_child(&mut root, a);
1622        storage.add_child(&mut root, child);
1623        storage.add_child(&mut root, error);
1624        let root = storage.finish_rule(root);
1625        ParsedFile::new(tokens, storage, root)
1626    }
1627
1628    #[test]
1629    fn visitor_dispatches_and_aggregates_all_node_kinds() {
1630        #[derive(Default)]
1631        struct Visitor(Vec<String>);
1632
1633        impl ParseTreeVisitor for Visitor {
1634            type Result = Vec<String>;
1635
1636            fn default_result(&mut self) -> Self::Result {
1637                Vec::new()
1638            }
1639
1640            fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1641                self.0.push(format!("rule{}", node.rule_index()));
1642                self.visit_children(node)
1643            }
1644
1645            fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1646                vec![format!("terminal:{}", node.text())]
1647            }
1648
1649            fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1650                vec![format!("error:{}", node.text())]
1651            }
1652
1653            fn aggregate_result(
1654                &mut self,
1655                mut aggregate: Self::Result,
1656                next_result: Self::Result,
1657            ) -> Self::Result {
1658                aggregate.extend(next_result);
1659                aggregate
1660            }
1661        }
1662
1663        let parsed = visitor_test_tree();
1664        let mut visitor = Visitor::default();
1665        assert_eq!(
1666            visitor.visit(parsed.tree()),
1667            ["terminal:a", "terminal:b", "error:!"]
1668        );
1669        assert_eq!(visitor.0, ["rule0", "rule1"]);
1670    }
1671
1672    #[test]
1673    fn visitor_default_aggregation_returns_the_latest_child() {
1674        struct Visitor;
1675
1676        impl ParseTreeVisitor for Visitor {
1677            type Result = String;
1678
1679            fn default_result(&mut self) -> Self::Result {
1680                String::new()
1681            }
1682
1683            fn visit_terminal(&mut self, node: TerminalNodeView<'_>) -> Self::Result {
1684                node.text().to_owned()
1685            }
1686
1687            fn visit_error_node(&mut self, node: ErrorNodeView<'_>) -> Self::Result {
1688                node.text().to_owned()
1689            }
1690        }
1691
1692        let parsed = visitor_test_tree();
1693        assert_eq!(Visitor.visit(parsed.tree()), "!");
1694    }
1695
1696    #[test]
1697    fn visitor_can_short_circuit_before_any_or_later_children() {
1698        struct Visitor {
1699            limit: usize,
1700            visited: usize,
1701        }
1702
1703        impl ParseTreeVisitor for Visitor {
1704            type Result = usize;
1705
1706            fn default_result(&mut self) -> Self::Result {
1707                0
1708            }
1709
1710            fn visit_terminal(&mut self, _node: TerminalNodeView<'_>) -> Self::Result {
1711                self.visited += 1;
1712                1
1713            }
1714
1715            fn visit_error_node(&mut self, _node: ErrorNodeView<'_>) -> Self::Result {
1716                self.visited += 1;
1717                1
1718            }
1719
1720            fn aggregate_result(
1721                &mut self,
1722                aggregate: Self::Result,
1723                next_result: Self::Result,
1724            ) -> Self::Result {
1725                aggregate + next_result
1726            }
1727
1728            fn should_visit_next_child(
1729                &mut self,
1730                _node: RuleNodeView<'_>,
1731                current_result: &Self::Result,
1732            ) -> bool {
1733                *current_result < self.limit
1734            }
1735        }
1736
1737        let parsed = visitor_test_tree();
1738        let mut none = Visitor {
1739            limit: 0,
1740            visited: 0,
1741        };
1742        assert_eq!(none.visit(parsed.tree()), 0);
1743        assert_eq!(none.visited, 0);
1744
1745        let mut one = Visitor {
1746            limit: 1,
1747            visited: 0,
1748        };
1749        assert_eq!(one.visit(parsed.tree()), 1);
1750        assert_eq!(one.visited, 1);
1751    }
1752
1753    #[test]
1754    fn visitor_grows_the_stack_for_deep_rule_trees() {
1755        const DEPTH: usize = 20_000;
1756        const STACK_SIZE: usize = 256 * 1024;
1757
1758        std::thread::Builder::new()
1759            .name("visitor-stack-growth".to_owned())
1760            .stack_size(STACK_SIZE)
1761            .spawn(|| {
1762                let tokens = TokenStore::new(None, "");
1763                let mut storage = ParseTreeStorage::new();
1764                let mut child = storage.finish_rule(ParserRuleContext::new(DEPTH, -1));
1765                for rule_index in (0..DEPTH).rev() {
1766                    let mut parent = ParserRuleContext::new(rule_index, -1);
1767                    storage.add_child(&mut parent, child);
1768                    child = storage.finish_rule(parent);
1769                }
1770                let parsed = ParsedFile::new(tokens, storage, child);
1771
1772                struct Visitor;
1773                impl ParseTreeVisitor for Visitor {
1774                    type Result = usize;
1775
1776                    fn default_result(&mut self) -> Self::Result {
1777                        0
1778                    }
1779
1780                    fn visit_rule(&mut self, node: RuleNodeView<'_>) -> Self::Result {
1781                        self.visit_children(node) + 1
1782                    }
1783                }
1784
1785                assert_eq!(Visitor.visit(parsed.tree()), DEPTH + 1);
1786            })
1787            .expect("small-stack thread should start")
1788            .join()
1789            .expect("visitor should not overflow its stack");
1790    }
1791
1792    #[test]
1793    fn invocation_states_exclude_a_nonnegative_root_frame() {
1794        let tokens = TokenStore::new(None, "");
1795        let mut storage = ParseTreeStorage::new();
1796        let grandchild = storage.finish_rule(ParserRuleContext::new(2, 13));
1797        let mut child = ParserRuleContext::new(1, 7);
1798        storage.add_child(&mut child, grandchild);
1799        let child = storage.finish_rule(child);
1800        let mut root = ParserRuleContext::new(0, 4);
1801        storage.add_child(&mut root, child);
1802        let root = storage.finish_rule(root);
1803        let parsed = ParsedFile::new(tokens, storage, root);
1804
1805        let root = parsed
1806            .node(root)
1807            .and_then(Node::as_rule)
1808            .expect("root rule should be stored");
1809        let child = parsed
1810            .node(child)
1811            .and_then(Node::as_rule)
1812            .expect("child rule should be stored");
1813        let grandchild = parsed
1814            .node(grandchild)
1815            .and_then(Node::as_rule)
1816            .expect("grandchild rule should be stored");
1817
1818        assert_eq!(root.invocation_states().collect::<Vec<_>>(), []);
1819        assert_eq!(child.invocation_states().collect::<Vec<_>>(), [7]);
1820        assert_eq!(grandchild.invocation_states().collect::<Vec<_>>(), [13, 7]);
1821    }
1822
1823    #[test]
1824    fn uncommon_rule_payloads_live_in_sparse_extras() {
1825        let tokens = TokenStore::new(None, "");
1826        let mut storage = ParseTreeStorage::new();
1827        let plain = storage.finish_rule(ParserRuleContext::new(0, -1));
1828        let mut rich = ParserRuleContext::new(1, 3);
1829        rich.set_int_return("value", 42);
1830        let rich = storage.finish_rule(rich);
1831        let parsed = ParsedFile::new(tokens, storage, rich);
1832
1833        assert_eq!(parsed.storage().extra_count(), 1);
1834        assert_eq!(
1835            parsed
1836                .node(rich)
1837                .expect("rich rule should be stored")
1838                .as_rule()
1839                .expect("rich node should be a rule")
1840                .int_return("value"),
1841            Some(42)
1842        );
1843        assert!(
1844            parsed
1845                .node(plain)
1846                .expect("plain rule should be stored")
1847                .as_rule()
1848                .expect("plain node should be a rule")
1849                .int_return("value")
1850                .is_none()
1851        );
1852    }
1853
1854    #[test]
1855    fn preserves_maximum_token_id_in_nodes_and_rule_spans() {
1856        let max = TokenId::try_from(u32::MAX as usize).expect("maximum token ID should fit");
1857        let tokens = TokenStore::new(None, "");
1858        let mut storage = ParseTreeStorage::new();
1859        let terminal = storage.terminal(max);
1860        assert_eq!(storage.token_id(terminal), Some(max));
1861
1862        let mut context = ParserRuleContext::new(0, -1);
1863        context.set_start_id(max);
1864        context.set_stop_id(max);
1865        let rule = storage.finish_rule(context);
1866        let rule = storage
1867            .node(&tokens, rule)
1868            .and_then(Node::as_rule)
1869            .expect("rule should be stored");
1870        assert_eq!(rule.start_id(), Some(max));
1871        assert_eq!(rule.stop_id(), Some(max));
1872    }
1873}