Skip to main content

dbt_antlr4/
arena.rs

1#![allow(clippy::mut_from_ref)]
2use crate::{token::Token, tree::RuleNode};
3
4#[derive(Debug)]
5pub struct Arena {
6    tokens: bumpalo::Bump,
7    contexts: bumpalo::Bump,
8    payloads: bumpalo::Bump,
9}
10
11impl Arena {
12    /// Invoke the callback function with a reference to a local Arena.
13    ///
14    /// The arena will be dropped when the callback returns.
15    pub fn with<F, R>(f: F) -> R
16    where
17        F: for<'a> FnOnce(&'a Arena) -> R,
18    {
19        let arena = Arena::new();
20        f(&arena)
21    }
22
23    pub(crate) fn new() -> Self {
24        Self {
25            tokens: bumpalo::Bump::new(),
26            contexts: bumpalo::Bump::new(),
27            payloads: bumpalo::Bump::new(),
28        }
29    }
30
31    pub(crate) fn children_arena(&self) -> &bumpalo::Bump {
32        &self.payloads
33    }
34
35    pub fn alloc_token<T>(&self, value: T) -> &mut T
36    where
37        T: Token,
38    {
39        self.tokens.alloc(value)
40    }
41
42    pub fn alloc_context<'input, 'a, T>(&'a self, value: T) -> &'a mut T
43    where
44        'input: 'a,
45        T: RuleNode<'input, 'a>,
46    {
47        let res = self.contexts.alloc(value);
48        let self_ref: *const T = res;
49        unsafe {
50            res.set_self_ref(self_ref);
51        }
52        res
53    }
54
55    pub fn alloc_exception<'a, T>(&'a self, value: T) -> bumpalo::boxed::Box<'a, T> {
56        bumpalo::boxed::Box::new_in(value, &self.payloads)
57    }
58
59    pub fn alloc_payload<T>(&self, value: T) -> &mut T {
60        self.payloads.alloc(value)
61    }
62
63    pub fn alloc<T>(&self, value: T) -> &mut T {
64        self.payloads.alloc(value)
65    }
66}