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}