static_graph/resolver/
mod.rs

1pub mod rir;
2
3use std::{str::FromStr, sync::Arc};
4
5use fxhash::FxHashMap;
6
7use crate::{
8    index::Idx,
9    parser::document::Document,
10    symbol::{DefId, Ident, Symbol, TagId},
11    tags::Annotation,
12    tags::{Construct, Editable, Tags},
13};
14
15use self::rir::{Field, Graph, Node, Path, Type};
16
17pub struct Resolver {
18    graphs: FxHashMap<DefId, Arc<Graph>>,
19    nodes: FxHashMap<DefId, Arc<Node>>,
20    fields: FxHashMap<DefId, Arc<Field>>,
21    tags: FxHashMap<TagId, Arc<Tags>>,
22    did_counter: DefId,
23    tid_counter: TagId,
24    symbol_table: FxHashMap<Symbol, DefId>,
25}
26
27impl Default for Resolver {
28    fn default() -> Self {
29        Self {
30            graphs: Default::default(),
31            nodes: Default::default(),
32            fields: Default::default(),
33            tags: Default::default(),
34            did_counter: DefId::from_usize(0),
35            tid_counter: TagId::from_usize(0),
36            symbol_table: Default::default(),
37        }
38    }
39}
40
41pub struct ResolveResult {
42    pub graphs: FxHashMap<DefId, Arc<Graph>>,
43    pub nodes: FxHashMap<DefId, Arc<Node>>,
44    pub fields: FxHashMap<DefId, Arc<Field>>,
45    pub tags: FxHashMap<TagId, Arc<Tags>>,
46    pub entrys: Vec<DefId>,
47}
48
49impl Resolver {
50    pub fn resolve_document(mut self, document: Document) -> ResolveResult {
51        let _ = document
52            .nodes
53            .iter()
54            .map(|node| self.lower_node(node))
55            .collect::<Vec<_>>();
56        let entrys: Vec<_> = document
57            .graphs
58            .iter()
59            .map(|graph| self.lower_graph(graph))
60            .collect();
61        ResolveResult {
62            graphs: self.graphs,
63            nodes: self.nodes,
64            fields: self.fields,
65            tags: self.tags,
66            entrys,
67        }
68    }
69
70    fn lower_node(&mut self, n: &crate::parser::node::Node) -> Arc<Node> {
71        let name = self.lower_ident(&n.name);
72        let def_id = self.get_did(&name);
73        let to_nodes = n
74            .to_nodes
75            .iter()
76            .map(|n| {
77                let ident = self.lower_ident(n);
78                self.get_did(&ident)
79            })
80            .collect();
81        let fields = n
82            .fields
83            .iter()
84            .map(|field| self.lower_field(field))
85            .collect();
86
87        let node = Arc::from(Node {
88            name,
89            to_nodes,
90            fields,
91        });
92
93        self.nodes.insert(def_id, node.clone());
94
95        node
96    }
97
98    fn get_did(&mut self, name: &Ident) -> DefId {
99        *self
100            .symbol_table
101            .entry(name.clone().sym)
102            .or_insert(self.did_counter.inc_one())
103    }
104
105    fn lower_graph(&mut self, g: &crate::parser::graph::Graph) -> DefId {
106        let name = self.lower_ident(&g.name);
107        let def_id = self.get_did(&name);
108
109        let entry_node_name = self.lower_ident(&g.entry_node);
110        let entry_node_def_id = self.get_did(&entry_node_name);
111
112        let graph = Arc::from(Graph {
113            name,
114            entry_node: entry_node_def_id,
115        });
116
117        self.graphs.insert(def_id, graph);
118
119        def_id
120    }
121
122    fn lower_field(&mut self, f: &crate::parser::field::Field) -> Arc<Field> {
123        let tag_id = self.tid_counter.inc_one();
124        let tags = self.extract_tags(&f.annotations);
125
126        let name = self.lower_ident(&f.name);
127        let def_id = self.get_did(&name);
128        let ty = self.lower_type(&f.ty);
129        let ty = self.modify_ty_by_tags(ty, &tags);
130
131        self.tags.insert(tag_id, tags.into());
132
133        let field = Arc::from(Field { name, ty, tag_id });
134
135        self.fields.insert(def_id, field.clone());
136
137        field
138    }
139
140    fn modify_ty_by_tags(&mut self, ty: Type, tags: &Tags) -> Type {
141        if let Some(Editable(true)) = tags.get::<Editable>() {
142            Type::ArcSwap(Arc::from(ty))
143        } else {
144            ty
145        }
146    }
147
148    fn extract_tags(&mut self, annotations: &crate::parser::annotations::Annotations) -> Tags {
149        let mut tags = Tags::default();
150        macro_rules! with_tags {
151            ($annotation: tt -> $($key: ty)|+) => {
152                match $annotation.key.as_str()  {
153                    $(<$key>::KEY => {
154                        tags.insert(<$key>::from_str(&$annotation.value).unwrap());
155                    }),+
156                    _ => {},
157                }
158            };
159        }
160
161        annotations
162            .iter()
163            .for_each(|annotation| with_tags!(annotation -> Construct | Editable));
164
165        tags
166    }
167
168    fn lower_type(&mut self, ty: &crate::parser::ty::Type) -> Type {
169        match ty {
170            crate::parser::ty::Type::String => Type::String,
171            crate::parser::ty::Type::Void => Type::Void,
172            crate::parser::ty::Type::Byte => Type::U8,
173            crate::parser::ty::Type::Bool => Type::Bool,
174            crate::parser::ty::Type::Binary => Type::Bytes,
175            crate::parser::ty::Type::I8 => Type::I8,
176            crate::parser::ty::Type::I16 => Type::I16,
177            crate::parser::ty::Type::I32 => Type::I32,
178            crate::parser::ty::Type::I64 => Type::I64,
179            crate::parser::ty::Type::Double => Type::F64,
180            crate::parser::ty::Type::List { value } => Type::Vec(Arc::from(self.lower_type(value))),
181            crate::parser::ty::Type::Set { value } => Type::Set(Arc::from(self.lower_type(value))),
182            crate::parser::ty::Type::Map { key, value } => Type::Map(
183                Arc::from(self.lower_type(key)),
184                Arc::from(self.lower_type(value)),
185            ),
186            crate::parser::ty::Type::Path(path) => Type::Path(self.lower_path(path)),
187        }
188    }
189
190    fn lower_ident(&mut self, ident: &crate::parser::ident::Ident) -> Ident {
191        Ident::from(ident.0.clone())
192    }
193
194    fn lower_path(&mut self, path: &crate::parser::path::Path) -> Path {
195        Path {
196            segments: Arc::from_iter(path.segments.iter().map(|i| self.lower_ident(i))),
197        }
198    }
199}