use std::any::{type_name, Any};
use std::borrow::{Borrow, BorrowMut};
use std::cell::{Ref, RefCell, RefMut};
use std::convert::identity;
use std::fmt::{Debug, Error, Formatter};
use std::marker::PhantomData;
use std::ops::{CoerceUnsized, Deref, DerefMut};
use std::rc::Rc;
use crate::errors::ANTLRError;
use crate::interval_set::Interval;
use crate::parser::ParserNodeType;
use crate::rule_context::{
BaseRuleContext, CustomRuleContext, EmptyCustomRuleContext, RuleContext,
};
use crate::token::Token;
use crate::token_factory::{CommonTokenFactory, TokenFactory};
use crate::tree::{
ErrorNode, ParseTree, ParseTreeListener, ParseTreeVisitor, TerminalNode, Tree, Visitable,
};
use better_any::{Tid, TidAble, TidExt};
pub trait ParserRuleContext<'input>:
ParseTree<'input> + RuleContext<'input> + Debug + Tid<'input>
{
fn set_exception(&self, e: ANTLRError) {}
fn set_start(&self, t: Option<<Self::TF as TokenFactory<'input>>::Tok>) {}
fn start<'a>(&'a self) -> Ref<'a, <Self::TF as TokenFactory<'input>>::Inner>
where
'input: 'a,
{
unimplemented!()
}
fn start_mut<'a>(&'a self) -> RefMut<'a, <Self::TF as TokenFactory<'input>>::Tok>
where
'input: 'a,
{
unimplemented!()
}
fn set_stop(&self, t: Option<<Self::TF as TokenFactory<'input>>::Tok>) {}
fn stop<'a>(&'a self) -> Ref<'a, <Self::TF as TokenFactory<'input>>::Inner>
where
'input: 'a,
{
unimplemented!()
}
fn stop_mut<'a>(&'a self) -> RefMut<'a, <Self::TF as TokenFactory<'input>>::Tok>
where
'input: 'a,
{
unimplemented!()
}
fn add_child(&self, child: Rc<<Self::Ctx as ParserNodeType<'input>>::Type>) {}
fn remove_last_child(&self) {}
fn child_of_type<T>(&self, pos: usize) -> Option<Rc<T>>
where
T: ParserRuleContext<'input, TF = Self::TF, Ctx = Self::Ctx> + 'input,
Self: Sized,
{
self.get_children()
.filter(|it| it.deref().self_id() == T::id())
.nth(pos)
.and_then(|it| it.downcast_rc().ok())
}
fn children_of_type<T>(&self) -> Vec<Rc<T>>
where
T: ParserRuleContext<'input, TF = Self::TF, Ctx = Self::Ctx> + 'input,
Self: Sized,
{
self.get_children()
.filter_map(|it| it.downcast_rc().ok())
.collect()
}
fn get_token(&self, ttype: isize, pos: usize) -> Option<Rc<TerminalNode<'input, Self::Ctx>>> {
self.get_children()
.filter_map(|it| it.downcast_rc::<TerminalNode<'input, Self::Ctx>>().ok())
.filter(|it| it.symbol.borrow().get_token_type() == ttype)
.nth(pos)
}
fn get_tokens(&self, ttype: isize) -> Vec<Rc<TerminalNode<'input, Self::Ctx>>> {
self.get_children()
.filter_map(|it| it.downcast_rc::<TerminalNode<'input, Self::Ctx>>().ok())
.filter(|it| it.symbol.borrow().get_token_type() == ttype)
.collect()
}
}
pub trait RuleContextExt<'input>: ParserRuleContext<'input> {
fn to_string<Z>(self: &Rc<Self>, rule_names: Option<&[&str]>, stop: Option<Rc<Z>>) -> String
where
Z: ParserRuleContext<'input, Ctx = Self::Ctx, TF = Self::TF> + ?Sized + 'input,
Self::Ctx: ParserNodeType<'input, Type = Z>,
Rc<Self>: CoerceUnsized<Rc<Z>>;
fn accept_children<V>(&self, visitor: &mut V)
where
V: ParseTreeVisitor<'input, Self::Ctx> + ?Sized,
<Self::Ctx as ParserNodeType<'input>>::Type: Visitable<V>;
}
impl<'input, T: ParserRuleContext<'input> + ?Sized + 'input> RuleContextExt<'input> for T {
fn to_string<Z>(self: &Rc<Self>, rule_names: Option<&[&str]>, stop: Option<Rc<Z>>) -> String
where
Z: ParserRuleContext<'input, Ctx = T::Ctx, TF = T::TF> + ?Sized + 'input,
T::Ctx: ParserNodeType<'input, Type = Z>,
Rc<T>: CoerceUnsized<Rc<Z>>,
{
let mut result = String::from("[");
let mut next: Option<Rc<Z>> = Some(self.clone() as Rc<Z>);
while let Some(ref p) = next {
if stop.is_some() && (stop.is_none() || Rc::ptr_eq(p, stop.as_ref().unwrap())) {
break;
}
if let Some(rule_names) = rule_names {
let rule_index = p.get_rule_index();
let rule_name = rule_names
.get(rule_index)
.map(|&it| it.to_owned())
.unwrap_or_else(|| rule_index.to_string());
result.extend(rule_name.chars());
result.push(' ');
} else {
if !p.is_empty() {
result.extend(p.get_invoking_state().to_string().chars());
result.push(' ');
}
}
next = p.get_parent().clone();
}
if result.chars().last() == Some(' ') {
result.pop();
}
result.push(']');
return result;
}
fn accept_children<V>(&self, visitor: &mut V)
where
V: ParseTreeVisitor<'input, Self::Ctx> + ?Sized,
<Self::Ctx as ParserNodeType<'input>>::Type: Visitable<V>,
{
self.get_children().for_each(|child| child.accept(visitor))
}
}
#[inline]
#[doc(hidden)]
pub fn cast<'a, T, Result>(ctx: &T) -> &Result
where
T: ParserRuleContext<'a> + 'a + ?Sized,
Result: ParserRuleContext<'a, Ctx = T::Ctx> + 'a,
{
ctx.downcast_ref().unwrap()
}
#[inline]
#[doc(hidden)]
pub fn cast_mut<'a, T: ParserRuleContext<'a> + 'a + ?Sized, Result: 'a>(
ctx: &mut Rc<T>,
) -> &mut Result {
unsafe { &mut *(Rc::get_mut_unchecked(ctx) as *mut T as *mut Result) }
}
#[derive(Tid)]
pub struct BaseParserRuleContext<'input, Ctx: CustomRuleContext<'input>> {
base: BaseRuleContext<'input, Ctx>,
start: RefCell<<Ctx::TF as TokenFactory<'input>>::Tok>,
stop: RefCell<<Ctx::TF as TokenFactory<'input>>::Tok>,
exception: Option<Box<ANTLRError>>,
pub(crate) children: RefCell<Vec<Rc<<Ctx::Ctx as ParserNodeType<'input>>::Type>>>,
}
impl<'input, Ctx: CustomRuleContext<'input>> Debug for BaseParserRuleContext<'input, Ctx> {
default fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
f.write_str(type_name::<Self>())
}
}
impl<'input, Ctx: CustomRuleContext<'input>> RuleContext<'input>
for BaseParserRuleContext<'input, Ctx>
{
fn get_invoking_state(&self) -> isize { self.base.get_invoking_state() }
fn set_invoking_state(&self, t: isize) { self.base.set_invoking_state(t) }
fn get_parent_ctx(&self) -> Option<Rc<<Ctx::Ctx as ParserNodeType<'input>>::Type>> {
self.base.get_parent_ctx()
}
fn set_parent(&self, parent: &Option<Rc<<Ctx::Ctx as ParserNodeType<'input>>::Type>>) {
self.base.set_parent(parent)
}
}
impl<'input, Ctx: CustomRuleContext<'input>> CustomRuleContext<'input>
for BaseParserRuleContext<'input, Ctx>
{
type TF = Ctx::TF;
type Ctx = Ctx::Ctx;
fn get_rule_index(&self) -> usize { self.base.ext.get_rule_index() }
}
impl<'input, Ctx: CustomRuleContext<'input>> Deref for BaseParserRuleContext<'input, Ctx> {
type Target = Ctx;
fn deref(&self) -> &Self::Target { &self.base.ext }
}
impl<'input, Ctx: CustomRuleContext<'input>> DerefMut for BaseParserRuleContext<'input, Ctx> {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.base.ext }
}
impl<'input, Ctx: CustomRuleContext<'input>> Borrow<Ctx> for BaseParserRuleContext<'input, Ctx> {
fn borrow(&self) -> &Ctx { &self.base.ext }
}
impl<'input, Ctx: CustomRuleContext<'input>> BorrowMut<Ctx> for BaseParserRuleContext<'input, Ctx> {
fn borrow_mut(&mut self) -> &mut Ctx { &mut self.base.ext }
}
impl<'input, Ctx: CustomRuleContext<'input> + TidAble<'input>> ParserRuleContext<'input>
for BaseParserRuleContext<'input, Ctx>
{
fn set_exception(&self, _e: ANTLRError) {
unimplemented!()
}
fn set_start(&self, t: Option<<Ctx::TF as TokenFactory<'input>>::Tok>) {
*self.start.borrow_mut() = t.unwrap_or(Ctx::TF::create_invalid().clone());
}
fn start<'a>(&'a self) -> Ref<'a, <Ctx::TF as TokenFactory<'input>>::Inner>
where
'input: 'a,
{
Ref::map(self.start.borrow(), |t| t.borrow())
}
fn start_mut<'a>(&'a self) -> RefMut<'a, <Self::TF as TokenFactory<'input>>::Tok>
where
'input: 'a,
{
self.start.borrow_mut()
}
fn set_stop(&self, t: Option<<Ctx::TF as TokenFactory<'input>>::Tok>) {
*self.stop.borrow_mut() = t.unwrap_or(Ctx::TF::create_invalid().clone());
}
fn stop<'a>(&'a self) -> Ref<'a, <Ctx::TF as TokenFactory<'input>>::Inner>
where
'input: 'a,
{
Ref::map(self.stop.borrow(), |t| t.borrow())
}
fn stop_mut<'a>(&'a self) -> RefMut<'a, <Self::TF as TokenFactory<'input>>::Tok>
where
'input: 'a,
{
self.stop.borrow_mut()
}
fn add_child(&self, child: Rc<<Ctx::Ctx as ParserNodeType<'input>>::Type>) {
self.children.borrow_mut().push(child);
}
fn remove_last_child(&self) { self.children.borrow_mut().pop(); }
}
impl<'input, Ctx: CustomRuleContext<'input>> Tree<'input> for BaseParserRuleContext<'input, Ctx> {
fn get_parent(&self) -> Option<Rc<<Ctx::Ctx as ParserNodeType<'input>>::Type>> {
self.get_parent_ctx()
}
fn has_parent(&self) -> bool { self.base.parent_ctx.borrow().is_some() }
fn get_payload(&self) -> Box<dyn Any> { unimplemented!() }
fn get_child(&self, i: usize) -> Option<Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> {
self.children.borrow().get(i).cloned()
}
fn get_child_count(&self) -> usize { self.children.borrow().len() }
}
impl<'input, Ctx: CustomRuleContext<'input> + TidAble<'input>> ParseTree<'input>
for BaseParserRuleContext<'input, Ctx>
{
fn get_source_interval(&self) -> Interval {
Interval {
a: self.start().get_token_index(),
b: self.stop().get_token_index(),
}
}
default fn get_text(&self) -> String {
let children = self.get_children();
let mut result = String::new();
for child in children {
result += &child.get_text()
}
result
}
}
impl<'input, Ctx: CustomRuleContext<'input> + 'input> BaseParserRuleContext<'input, Ctx> {
pub fn new_parser_ctx(
parent_ctx: Option<Rc<<Ctx::Ctx as ParserNodeType<'input>>::Type>>,
invoking_state: isize,
ext: Ctx,
) -> Self {
Self {
base: BaseRuleContext::new_ctx(parent_ctx, invoking_state, ext),
start: RefCell::new(Ctx::TF::create_invalid()),
stop: RefCell::new(Ctx::TF::create_invalid()),
exception: None,
children: RefCell::new(vec![]),
}
}
pub fn copy_from<T: ParserRuleContext<'input, TF = Ctx::TF, Ctx = Ctx::Ctx> + ?Sized>(
ctx: &T,
ext: Ctx,
) -> Self {
Self {
base: BaseRuleContext::new_ctx(ctx.get_parent_ctx(), ctx.get_invoking_state(), ext),
start: RefCell::new(ctx.start_mut().clone()),
stop: RefCell::new(ctx.stop_mut().clone()),
exception: None,
children: RefCell::new(ctx.get_children().collect()),
}
}
}
#[doc(hidden)]
pub trait DerefSeal: Deref {}
impl<'input, T, I> ParserRuleContext<'input> for T
where
T: DerefSeal<Target = I> + 'input + Debug + Tid<'input>,
I: ParserRuleContext<'input> + 'input + ?Sized,
{
fn set_exception(&self, e: ANTLRError) { self.deref().set_exception(e) }
fn set_start(&self, t: Option<<Self::TF as TokenFactory<'input>>::Tok>) {
self.deref().set_start(t)
}
fn start<'a>(&'a self) -> Ref<'a, <Self::TF as TokenFactory<'input>>::Inner>
where
'input: 'a,
{
self.deref().start()
}
fn start_mut<'a>(&'a self) -> RefMut<'a, <Self::TF as TokenFactory<'input>>::Tok>
where
'input: 'a,
{
self.deref().start_mut()
}
fn set_stop(&self, t: Option<<Self::TF as TokenFactory<'input>>::Tok>) {
self.deref().set_stop(t)
}
fn stop<'a>(&'a self) -> Ref<'a, <Self::TF as TokenFactory<'input>>::Inner>
where
'input: 'a,
{
self.deref().stop()
}
fn stop_mut<'a>(&'a self) -> RefMut<'a, <Self::TF as TokenFactory<'input>>::Tok>
where
'input: 'a,
{
self.deref().stop_mut()
}
fn add_child(&self, child: Rc<<I::Ctx as ParserNodeType<'input>>::Type>) {
self.deref().add_child(child)
}
fn remove_last_child(&self) { self.deref().remove_last_child() }
}
impl<'input, T, I> RuleContext<'input> for T
where
T: DerefSeal<Target = I> + 'input + Debug + Tid<'input>,
I: ParserRuleContext<'input> + 'input + ?Sized,
{
fn get_invoking_state(&self) -> isize { self.deref().get_invoking_state() }
fn set_invoking_state(&self, t: isize) { self.deref().set_invoking_state(t) }
fn is_empty(&self) -> bool { self.deref().is_empty() }
fn get_parent_ctx(&self) -> Option<Rc<<I::Ctx as ParserNodeType<'input>>::Type>> {
self.deref().get_parent_ctx()
}
fn set_parent(&self, parent: &Option<Rc<<I::Ctx as ParserNodeType<'input>>::Type>>) {
self.deref().set_parent(parent)
}
}
impl<'input, T, I> ParseTree<'input> for T
where
T: DerefSeal<Target = I> + 'input + Debug + Tid<'input>,
I: ParserRuleContext<'input> + 'input + ?Sized,
{
fn get_source_interval(&self) -> Interval { self.deref().get_source_interval() }
fn get_text(&self) -> String { self.deref().get_text() }
}
impl<'input, T, I> Tree<'input> for T
where
T: DerefSeal<Target = I> + 'input + Debug + Tid<'input>,
I: ParserRuleContext<'input> + 'input + ?Sized,
{
fn get_parent(&self) -> Option<Rc<<I::Ctx as ParserNodeType<'input>>::Type>> {
self.deref().get_parent()
}
fn has_parent(&self) -> bool { self.deref().has_parent() }
fn get_payload(&self) -> Box<dyn Any> { self.deref().get_payload() }
fn get_child(&self, i: usize) -> Option<Rc<<I::Ctx as ParserNodeType<'input>>::Type>> {
self.deref().get_child(i)
}
fn get_child_count(&self) -> usize { self.deref().get_child_count() }
fn get_children<'a>(
&'a self,
) -> Box<dyn Iterator<Item = Rc<<Self::Ctx as ParserNodeType<'input>>::Type>> + 'a>
where
'input: 'a,
{
self.deref().get_children()
}
}
impl<'input, T, I> CustomRuleContext<'input> for T
where
T: DerefSeal<Target = I> + 'input + Debug + Tid<'input>,
I: ParserRuleContext<'input> + 'input + ?Sized,
{
type TF = I::TF;
type Ctx = I::Ctx;
fn get_rule_index(&self) -> usize { self.deref().get_rule_index() }
fn get_alt_number(&self) -> isize { self.deref().get_alt_number() }
fn set_alt_number(&self, _alt_number: isize) { self.deref().set_alt_number(_alt_number) }
}