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