1use ::lex;
2
3use super::*;
4
5pub fn parse_lexed(lexed: lex::Ast) -> (Ir, Counts) {
6 let lex::Ast {
7 aut_nums,
8 as_sets,
9 route_sets,
10 peering_sets,
11 filter_sets,
12 as_routes,
13 } = lexed;
14 let (aut_nums, an_counts) = parse_lexed_aut_nums(aut_nums);
15 let (as_sets, as_counts) = parse_lexed_as_sets(as_sets);
16 let (route_sets, rs_counts) = parse_lexed_route_sets(route_sets);
17 let (peering_sets, ps_counts) = parse_lexed_peering_sets(peering_sets);
18 let (filter_sets, fs_counts) = parse_lexed_filter_sets(filter_sets);
19 let (as_routes, ar_counts) = parse_lexed_as_routes(as_routes);
20 let ir = Ir {
21 aut_nums,
22 as_sets,
23 route_sets,
24 peering_sets,
25 filter_sets,
26 as_routes,
27 };
28 let counts = an_counts + as_counts + rs_counts + ps_counts + fs_counts + ar_counts;
29 (ir, counts)
30}
31
32pub fn parse_lexed_aut_nums(lexed: Vec<lex::AutNum>) -> (BTreeMap<u32, AutNum>, Counts) {
33 par_process_map_counts(
34 lexed,
35 |(mut acc, mut counts), lexed| match parse_lexed_aut_num(lexed, &mut counts) {
36 Ok((num, aut_num)) => {
37 acc.insert(num, aut_num);
38 (acc, counts)
39 }
40 Err(e) => {
41 counts.parse_aut_num += 1;
42 error!("{e:?}");
43 (acc, counts)
44 }
45 },
46 )
47}
48
49pub fn parse_lexed_aut_num(aut_num: lex::AutNum, counts: &mut Counts) -> Result<(u32, AutNum)> {
50 let num = parse_aut_num_name(&aut_num.name).context(format!("parsing {aut_num:?}"))?;
51 let lex::AutNum {
52 name: _,
53 body,
54 n_import,
55 n_export,
56 imports,
57 exports,
58 } = aut_num;
59 let imports = parse_imports(imports, counts);
60 let exports = parse_imports(exports, counts);
61 Ok((
62 num,
63 AutNum {
64 body,
65 n_import,
66 n_export,
67 imports,
68 exports,
69 },
70 ))
71}
72
73pub fn parse_lexed_as_sets(lexed: Vec<lex::AsOrRouteSet>) -> (BTreeMap<String, AsSet>, Counts) {
74 par_process_map_counts(
75 lexed,
76 |(mut acc, mut counts), lexed| match parse_lexed_as_set(lexed) {
77 Ok((name, as_set)) => {
78 acc.insert(name, as_set);
79 (acc, counts)
80 }
81 Err(e) => {
82 counts.parse_as_set += 1;
83 error!("{e:?}");
84 (acc, counts)
85 }
86 },
87 )
88}
89
90pub fn parse_lexed_as_set(lexed: lex::AsOrRouteSet) -> Result<(String, AsSet)> {
91 if !is_as_set(&lexed.name) && !is_pseudo_set(&lexed.name) {
92 bail!("invalid AS Set name in {lexed:?}");
93 }
94 let max_length = lexed.members.len();
95 let mut members = Vec::with_capacity(max_length);
96 let mut set_members = Vec::with_capacity(max_length);
97 for member in lexed.members {
98 let member = parse_as_name(member)
99 .with_context(|| format!("parsing AS Set {}\n{}", lexed.name, lexed.body))?;
100 match member {
101 AsName::Any => return Ok((lexed.name, AsSet::new_any(lexed.body))),
102 AsName::Num(n) => members.push(n),
103 AsName::Set(set) => set_members.push(set),
104 AsName::Invalid(reason) => {
105 bail!("{reason} parsing AS Set {}\n{}", lexed.name, lexed.body)
106 }
107 }
108 }
109 let as_set = AsSet::new(lexed.body, members, set_members);
110 Ok((lexed.name, as_set))
111}
112
113pub fn parse_lexed_route_sets(
114 lexed: Vec<lex::AsOrRouteSet>,
115) -> (BTreeMap<String, RouteSet>, Counts) {
116 par_process_map_counts(
117 lexed,
118 |(mut acc, mut counts), lexed| match parse_lexed_route_set(lexed) {
119 Ok((name, route_set)) => {
120 acc.insert(name, route_set);
121 (acc, counts)
122 }
123 Err(e) => {
124 counts.parse_route_set += 1;
125 error!("{e:?}");
126 (acc, counts)
127 }
128 },
129 )
130}
131
132pub fn parse_lexed_route_set(lexed: lex::AsOrRouteSet) -> Result<(String, RouteSet)> {
133 if !is_route_set_name(&lexed.name) && !is_pseudo_set(&lexed.name) {
134 bail!(
135 "{} is an invalid route set name—parsing {lexed:?}",
136 lexed.name
137 );
138 }
139 let members = lexed
140 .members
141 .into_iter()
142 .map(|member| member.into())
143 .collect();
144
145 Ok((
146 lexed.name,
147 RouteSet {
148 body: lexed.body,
149 members,
150 },
151 ))
152}
153
154pub fn parse_lexed_peering_sets(
155 lexed: Vec<lex::PeeringSet>,
156) -> (BTreeMap<String, PeeringSet>, Counts) {
157 par_process_map_counts(
158 lexed,
159 |(mut acc, mut counts), lexed| match parse_lexed_peering_set(lexed) {
160 Ok((name, peering_set)) => {
161 acc.insert(name, peering_set);
162 (acc, counts)
163 }
164 Err(e) => {
165 counts.parse_peering_set += 1;
166 error!("{e:?}");
167 (acc, counts)
168 }
169 },
170 )
171}
172
173pub fn parse_lexed_peering_set(lexed: lex::PeeringSet) -> Result<(String, PeeringSet)> {
174 if !is_peering_set(&lexed.name) {
175 bail!(
176 "{} is an invalid peering set name—parsing {lexed:?}",
177 lexed.name
178 );
179 }
180 Ok((
181 lexed.name,
182 PeeringSet {
183 body: lexed.body,
184 peerings: lexed.peerings.into_iter().map(parse_mp_peering).collect(),
185 },
186 ))
187}
188
189pub fn parse_lexed_filter_sets(
190 lexed: Vec<lex::FilterSet>,
191) -> (BTreeMap<String, FilterSet>, Counts) {
192 par_process_map_counts(
193 lexed,
194 |(mut acc, mut counts), lexed| match parse_lexed_filter_set(lexed, &mut counts) {
195 Ok((name, filter_set)) => {
196 acc.insert(name, filter_set);
197 (acc, counts)
198 }
199 Err(e) => {
200 counts.parse_filter_set += 1;
201 error!("{e:?}");
202 (acc, counts)
203 }
204 },
205 )
206}
207
208pub fn parse_lexed_filter_set(
209 lexed: lex::FilterSet,
210 counts: &mut Counts,
211) -> Result<(String, FilterSet)> {
212 if !is_filter_set(&lexed.name) {
213 bail!(
214 "{} is an invalid filter set name—parsing {lexed:?}",
215 lexed.name
216 );
217 }
218 let filter_set = FilterSet {
219 body: lexed.body,
220 filters: lexed
221 .filters
222 .into_iter()
223 .map(|f| parse_filter(f, counts))
224 .collect(),
225 };
226 Ok((lexed.name, filter_set))
227}
228
229pub fn parse_lexed_as_routes(
230 as_routes: BTreeMap<String, Vec<String>>,
231) -> (BTreeMap<u32, Vec<IpNet>>, Counts) {
232 par_process_map_counts(
233 as_routes,
234 |(mut acc, mut counts), lexed| match parse_lexed_as_route(&lexed) {
235 Ok((num, routes)) => {
236 acc.insert(num, routes);
237 (acc, counts)
238 }
239 Err(e) => {
240 counts.parse_as_route += 1;
241 error!("Parsing routes for {lexed:?}: {e}.");
242 (acc, counts)
243 }
244 },
245 )
246}
247
248pub fn par_process_map_counts<I, In, F, K, V>(input: I, transform: F) -> (BTreeMap<K, V>, Counts)
249where
250 I: IntoParallelIterator<Item = In>,
251 F: Fn((BTreeMap<K, V>, Counts), In) -> (BTreeMap<K, V>, Counts) + Send + Sync,
252 K: Ord + Send + Sync,
253 V: Send + Sync,
254{
255 input
256 .into_par_iter()
257 .fold(|| (BTreeMap::new(), Counts::default()), transform)
258 .reduce(
259 || (BTreeMap::new(), Counts::default()),
260 |(mut map0, counts0), (map1, counts1)| {
261 map0.extend(map1);
262 (map0, counts0 + counts1)
263 },
264 )
265}
266
267pub fn parse_lexed_as_route((name, routes): &(String, Vec<String>)) -> Result<(u32, Vec<IpNet>)> {
268 let num = parse_aut_num_name(name)?;
269 let routes: Result<_> = routes.iter().map(|r| Ok(r.parse()?)).collect();
270 let mut routes: Vec<_> = routes?;
271 routes.sort_unstable();
272 Ok((num, routes))
273}