1use std::collections::{BTreeMap, BTreeSet};
2use std::sync::Arc;
3use maplit::btreeset;
4use crate::availability::Availability;
5use crate::ast::config::Config;
6use crate::ast::decorator::Decorator;
7use crate::ast::empty_decorator::EmptyDecorator;
8use crate::ast::import::Import;
9use crate::ast::namespace::Namespace;
10use crate::ast::node::Node;
11use crate::format::Writer;
12use crate::traits::write::Write;
13
14#[derive(Debug)]
15pub struct Source {
16 pub id: usize,
17 pub builtin: bool,
18 pub file_path: String,
19 pub children: BTreeMap<usize, Node>,
20 pub references: SourceReferences,
21}
22
23impl Source {
24
25 pub fn new(id: usize, builtin: bool, file_path: String, children: BTreeMap<usize, Node>, references: SourceReferences) -> Self {
26 Self {
27 id,
28 builtin,
29 file_path,
30 children,
31 references,
32 }
33 }
34
35 pub fn children(&self) -> Vec<&Node> {
36 self.children.values().collect()
37 }
38
39 pub fn imports(&self) -> Vec<&Import> {
40 self.references.imports.iter().map(|id| self.children.get(id).unwrap().as_import().unwrap()).collect()
41 }
42
43 pub fn namespaces(&self) -> Vec<&Namespace> {
44 self.references.namespaces.iter().map(|m| self.get_namespace(*m).unwrap()).collect()
45 }
46
47 pub fn unattached_decorators(&self) -> Vec<&Decorator> {
48 self.references.unattached_decorators.iter().map(|m| self.get_unattached_decorator(*m).unwrap()).collect()
49 }
50
51 pub fn empty_decorators(&self) -> Vec<&EmptyDecorator> {
52 self.references.empty_decorators.iter().map(|m| self.children.get(m).unwrap().as_empty_decorator().unwrap()).collect()
53 }
54
55 pub fn get_connector(&self) -> Option<&Config> {
56 self.references.connector.map(|id| self.children.get(&id).unwrap().as_config().unwrap())
57 }
58
59 pub fn get_namespace(&self, id: usize) -> Option<&Namespace> {
60 self.children.get(&id).unwrap().as_namespace()
61 }
62
63 pub fn get_unattached_decorator(&self, id: usize) -> Option<&Decorator> {
64 self.children.get(&id).unwrap().as_decorator()
65 }
66
67 pub fn find_top_by_id(&self, id: usize) -> Option<&Node> {
68 self.children.get(&id)
69 }
70
71 pub fn find_top_by_name(&self, name: &str, filter: &Arc<dyn Fn(&Node) -> bool>, availability: Availability) -> Option<&Node> {
72 self.children().iter().find(|t| {
73 if let Some(n) = t.name() {
74 (n == name) && filter(t) && t.available_test(availability)
75 } else {
76 false
77 }
78 }).map(|t| *t)
79 }
80
81 pub fn find_top_by_path(&self, path: &Vec<usize>) -> Option<&Node> {
82 if *path.first().unwrap() != self.id {
83 return None;
84 }
85 if path.len() < 2 {
86 return None;
87 } else if path.len() == 2 {
88 self.find_top_by_id(*path.get(1).unwrap())
89 } else {
90 let mut path_for_ns = path.clone();
91 path_for_ns.remove(path_for_ns.len() - 1);
92 let child_ns = self.find_child_namespace_by_path(&path_for_ns);
93 if let Some(child_ns) = child_ns {
94 child_ns.find_top_by_id(*path.last().unwrap())
95 } else {
96 None
97 }
98 }
99 }
100
101 pub fn find_node_by_string_path(&self, path: &Vec<&str>, filter: &Arc<dyn Fn(&Node) -> bool>, availability: Availability) -> Option<&Node> {
102 if path.len() == 0 {
103 return None;
104 } else if path.len() == 1 {
105 self.find_top_by_name(path.get(0).unwrap(), filter, availability)
106 } else {
107 let mut path_for_ns = path.clone();
108 path_for_ns.remove(path_for_ns.len() - 1);
109 let child_ns = self.find_child_namespace_by_string_path(&path_for_ns);
110 if let Some(child_ns) = child_ns {
111 child_ns.find_top_by_name(path.last().unwrap(), filter, availability)
112 } else {
113 None
114 }
115 }
116 }
117
118 pub fn parent_namespace_for_namespace(&self, namespace: &Namespace) -> Option<&Namespace> {
119 self.find_child_namespace_by_string_path(&namespace.parent_str_path())
120 }
121
122 pub fn find_child_namespace_by_path(&self, path: &Vec<usize>) -> Option<&Namespace> {
123 if *path.first().unwrap() != self.id {
124 return None;
125 }
126 let mut ns = self.get_namespace(*path.get(1).unwrap());
127 for (index, item) in path.iter().enumerate() {
128 if index > 1 {
129 if let Some(ns_ref) = ns {
130 ns = ns_ref.get_namespace(*item);
131 } else {
132 return None;
133 }
134 }
135 }
136 ns
137 }
138
139 pub fn find_child_namespace_by_string_path(&self, path: &Vec<&str>) -> Option<&Namespace> {
140 if path.len() == 0 { return None }
141 let mut ns = self.namespaces().iter().find(|n| n.identifier().name() == *path.get(0).unwrap()).map(|r| *r);
142 for (index, item) in path.iter().enumerate() {
143 if index > 0 {
144 if let Some(ns_ref) = ns {
145 ns = ns_ref.namespaces().iter().find(|n| n.identifier().name() == *item).map(|r| *r);
146 } else {
147 return None;
148 }
149 }
150 }
151 ns
152 }
153}
154
155#[derive(Debug)]
156pub struct SourceReferences {
157 pub imports: BTreeSet<usize>,
158 pub connector: Option<usize>,
159 pub constants: BTreeSet<usize>,
160 pub configs: BTreeSet<usize>,
161 pub enums: BTreeSet<usize>,
162 pub models: BTreeSet<usize>,
163 pub data_sets: BTreeSet<usize>,
164 pub interfaces: BTreeSet<usize>,
165 pub namespaces: BTreeSet<usize>,
166 pub config_declarations: BTreeSet<usize>,
167 pub decorator_declarations: BTreeSet<usize>,
168 pub pipeline_item_declarations: BTreeSet<usize>,
169 pub middlewares: BTreeSet<usize>,
170 pub handlers: BTreeSet<usize>,
171 pub handler_groups: BTreeSet<usize>,
172 pub use_middlewares_block: Option<usize>,
173 pub empty_decorators: BTreeSet<usize>,
174 pub unattached_decorators: BTreeSet<usize>,
175 pub synthesized_shape_declarations: BTreeSet<usize>,
176 pub handler_template_declarations: BTreeSet<usize>,
177}
178
179impl SourceReferences {
180
181 pub fn new() -> Self {
182 Self {
183 imports: btreeset!{},
184 connector: None,
185 constants: btreeset!{},
186 configs: btreeset!{},
187 enums: btreeset!{},
188 models: btreeset!{},
189 namespaces: btreeset!{},
190 interfaces: btreeset!{},
191 data_sets: btreeset!{},
192 config_declarations: btreeset!{},
193 decorator_declarations: btreeset!{},
194 pipeline_item_declarations: btreeset!{},
195 middlewares: btreeset!{},
196 handlers: btreeset!{},
197 handler_groups: btreeset!{},
198 use_middlewares_block: None,
199 empty_decorators: btreeset! {},
200 unattached_decorators: btreeset! {},
201 synthesized_shape_declarations: btreeset! {},
202 handler_template_declarations: btreeset! {},
203 }
204 }
205}
206
207impl Write for Source {
208 fn write<'a>(&'a self, writer: &mut Writer<'a>) {
209 writer.write_children(self, self.children.values())
210 }
211}