use crate::{
RawSyntaxKind,
Syntax,
build::GreenNodeBuilder,
interning::{Resolver, TokenKey},
syntax::{ResolvedNode, SyntaxNode},
traversal::WalkEvent,
util::NodeOrToken,
};
use serde::{
Deserialize,
Serialize,
de::{Error, SeqAccess, Visitor},
ser::SerializeTuple,
};
use std::{collections::VecDeque, fmt, marker::PhantomData};
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::into_raw(node.kind()), has_data))
}
WalkEvent::Enter(NodeOrToken::Token(tok)) => Some(Event::Token($l::into_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(RawSyntaxKind, bool),
Token(RawSyntaxKind, &'text str),
LeaveNode,
}
pub(crate) struct SerializeWithResolver<'node, 'resolver, S: Syntax, D: 'static, R: ?Sized> {
pub(crate) node: &'node SyntaxNode<S, D>,
pub(crate) resolver: &'resolver R,
}
pub(crate) struct SerializeWithData<'node, 'resolver, S: Syntax, D: 'static, R: ?Sized> {
pub(crate) node: &'node SyntaxNode<S, D>,
pub(crate) resolver: &'resolver R,
}
impl<S, D, R> Serialize for SerializeWithData<'_, '_, S, D, R>
where
S: Syntax,
R: Resolver<TokenKey> + ?Sized,
D: Serialize,
{
fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
where
Ser: serde::Serializer,
{
let mut data_list = Vec::new();
gen_serialize!(S, self.node, self.resolver, serializer, data_list)
}
}
impl<S, D, R> Serialize for SerializeWithResolver<'_, '_, S, D, R>
where
S: Syntax,
R: Resolver<TokenKey> + ?Sized,
{
fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
where
Ser: serde::Serializer,
{
gen_serialize!(S, self.node, self.resolver, serializer,)
}
}
impl<S, D> Serialize for ResolvedNode<S, D>
where
S: Syntax,
D: Serialize,
{
fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
where
Ser: serde::Serializer,
{
let node = SerializeWithResolver {
node: self,
resolver: self.resolver().as_ref(),
};
node.serialize(serializer)
}
}
impl<'de, S, D> Deserialize<'de> for ResolvedNode<S, D>
where
S: Syntax,
D: Deserialize<'de>,
{
fn deserialize<De>(deserializer: De) -> Result<Self, De::Error>
where
De: serde::Deserializer<'de>,
{
struct EventVisitor<S: Syntax, D: 'static> {
_marker: PhantomData<fn() -> ResolvedNode<S, D>>,
}
impl<'de, S, D> Visitor<'de> for EventVisitor<S, D>
where
S: Syntax,
D: Deserialize<'de>,
{
type Value = (ResolvedNode<S, D>, 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<S> = 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(S::from_raw(kind));
data_indices.push_back(has_data);
}
Event::Token(kind, text) => builder.token(S::from_raw(kind), text),
Event::LeaveNode => builder.finish_node(),
}
}
let (tree, cache) = builder.finish();
let tree = ResolvedNode::new_root_with_resolver(tree, cache.unwrap().into_interner().unwrap());
Ok((tree, data_indices))
}
}
struct ProcessedEvents<S: Syntax, D: 'static>(ResolvedNode<S, D>, VecDeque<bool>);
impl<'de, S, D> Deserialize<'de> for ProcessedEvents<S, D>
where
S: Syntax,
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<S, 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 RawSyntaxKind {
fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
where
Ser: serde::Serializer,
{
serializer.serialize_u32(self.0)
}
}
impl<'de> Deserialize<'de> for RawSyntaxKind {
fn deserialize<De>(deserializer: De) -> Result<Self, De::Error>
where
De: serde::Deserializer<'de>,
{
Ok(Self(u32::deserialize(deserializer)?))
}
}