use crate::{
interning::{IntoResolver, Resolver},
GreenNodeBuilder, Language, NodeOrToken, SyntaxKind, SyntaxNode, WalkEvent,
};
use serde::{
de::{Error, SeqAccess, Visitor},
ser::SerializeTuple,
Deserialize, Serialize,
};
use std::{collections::VecDeque, fmt, marker::PhantomData};
type Rodeo = lasso::Rodeo<lasso::Spur, fxhash::FxBuildHasher>;
type RodeoResolver = lasso::RodeoResolver<lasso::Spur>;
macro_rules! data_list {
($_:expr, $list:expr) => {
$list
};
($list:expr,) => {
$list
};
}
macro_rules! gen_serialize {
($l:ident, $node:expr, $resolver:expr, $ser:ident, $($data_list:ident)?) => {{
#[allow(unused_variables)]
let events = $node.preorder_with_tokens().filter_map(|event| match event {
WalkEvent::Enter(NodeOrToken::Node(node)) => {
let has_data = false;
$(let has_data = node
.get_data()
.map(|data| {
$data_list.push(data);
true
})
.unwrap_or(false);)?
Some(Event::EnterNode($l::kind_to_raw(node.kind()), has_data))
}
WalkEvent::Enter(NodeOrToken::Token(tok)) => Some(Event::Token($l::kind_to_raw(tok.kind()), tok.resolve_text($resolver))),
WalkEvent::Leave(NodeOrToken::Node(_)) => Some(Event::LeaveNode),
WalkEvent::Leave(NodeOrToken::Token(_)) => None,
});
let mut tuple = $ser.serialize_tuple(2)?;
tuple.serialize_element(&events.collect::<Vec<_>>())?;
tuple.serialize_element(&data_list!(Vec::<()>::new(), $($data_list)?))?;
tuple.end()
}};
}
#[derive(Deserialize, Serialize)]
#[serde(tag = "t", content = "c")]
enum Event<'text> {
EnterNode(SyntaxKind, bool),
Token(SyntaxKind, &'text str),
LeaveNode,
}
pub(crate) struct SerializeWithResolver<'node, 'resolver, L: Language, D: 'static, RN: 'static, R> {
pub(crate) node: &'node SyntaxNode<L, D, RN>,
pub(crate) resolver: &'resolver R,
}
pub(crate) struct SerializeWithData<'node, 'resolver, L: Language, D: 'static, RN: 'static, R> {
pub(crate) node: &'node SyntaxNode<L, D, RN>,
pub(crate) resolver: &'resolver R,
}
impl<L, D, RN, R> Serialize for SerializeWithData<'_, '_, L, D, RN, R>
where
L: Language,
R: Resolver,
D: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut data_list = Vec::new();
gen_serialize!(L, self.node, self.resolver, serializer, data_list)
}
}
impl<L, D, RN, R> Serialize for SerializeWithResolver<'_, '_, L, D, RN, R>
where
L: Language,
R: Resolver,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
gen_serialize!(L, self.node, self.resolver, serializer,)
}
}
impl<L, D, R> Serialize for SyntaxNode<L, D, R>
where
L: Language,
D: Serialize,
R: Resolver,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let node = SerializeWithResolver {
node: self,
resolver: self.resolver().as_ref(),
};
node.serialize(serializer)
}
}
impl<'de, L, D> Deserialize<'de> for SyntaxNode<L, D, RodeoResolver>
where
L: Language,
D: Deserialize<'de>,
{
fn deserialize<DE>(deserializer: DE) -> Result<Self, DE::Error>
where
DE: serde::Deserializer<'de>,
{
struct EventVisitor<L: Language, D: 'static> {
_marker: PhantomData<SyntaxNode<L, D, Rodeo>>,
}
impl<'de, L, D> Visitor<'de> for EventVisitor<L, D>
where
L: Language,
D: Deserialize<'de>,
{
type Value = (SyntaxNode<L, D, RodeoResolver>, VecDeque<bool>);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a list of tree events")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut builder = GreenNodeBuilder::new();
let mut data_indices = VecDeque::new();
while let Some(next) = seq.next_element::<Event<'_>>()? {
match next {
Event::EnterNode(kind, has_data) => {
builder.start_node(kind);
data_indices.push_back(has_data);
}
Event::Token(kind, text) => builder.token(kind, text),
Event::LeaveNode => builder.finish_node(),
}
}
let (tree, resolver) = builder.finish();
let tree = SyntaxNode::new_root_with_resolver(tree, resolver.unwrap().into_resolver());
Ok((tree, data_indices))
}
}
struct ProcessedEvents<L: Language, D: 'static>(SyntaxNode<L, D, RodeoResolver>, VecDeque<bool>);
impl<'de, L, D> Deserialize<'de> for ProcessedEvents<L, D>
where
L: Language,
D: Deserialize<'de>,
{
fn deserialize<DE>(deserializer: DE) -> Result<Self, DE::Error>
where
DE: serde::Deserializer<'de>,
{
let (tree, ids) = deserializer.deserialize_seq(EventVisitor { _marker: PhantomData })?;
Ok(Self(tree, ids))
}
}
let (ProcessedEvents(tree, data_indices), mut data) =
<(ProcessedEvents<L, D>, VecDeque<D>)>::deserialize(deserializer)?;
tree.descendants().zip(data_indices).try_for_each(|(node, has_data)| {
if has_data {
let data = data
.pop_front()
.ok_or_else(|| DE::Error::custom("invalid serialized tree"))?;
node.set_data(data);
}
<Result<(), DE::Error>>::Ok(())
})?;
if !data.is_empty() {
Err(DE::Error::custom(
"serialized SyntaxNode contained too many data elements",
))
} else {
Ok(tree)
}
}
}
impl Serialize for SyntaxKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u16(self.0)
}
}
impl<'de> Deserialize<'de> for SyntaxKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Self(u16::deserialize(deserializer)?))
}
}