asn1_compiler/resolver/
int.rs

1//! Resolver Struct and it's implementation
2
3use std::collections::{BTreeMap, HashMap};
4
5use anyhow::Result;
6
7use crate::parser::asn::structs::{defs::Asn1Definition, module::Asn1Module};
8
9use crate::resolver::asn::structs::{
10    defs::Asn1ResolvedDefinition, types::Asn1ResolvedType, values::Asn1ResolvedValue,
11};
12
13use crate::resolver::asn::defs::resolve_definition;
14
15#[derive(Debug, Clone)]
16pub(crate) struct Resolver {
17    // Resolved definitions
18    pub(crate) resolved_defs: BTreeMap<String, Asn1ResolvedDefinition>,
19
20    // Unresolved Parameterized Definitions used by individual 'Type's to resolve themselves.
21    pub(crate) parameterized_defs: HashMap<String, Asn1Definition>,
22
23    // Object Classes: Used by Objects and Object Sets to resolves themselves.
24    pub(crate) classes: HashMap<String, Asn1Definition>,
25}
26
27impl Resolver {
28    pub fn new() -> Self {
29        Resolver {
30            resolved_defs: BTreeMap::new(),
31            parameterized_defs: HashMap::new(),
32            classes: HashMap::new(),
33        }
34    }
35
36    // Resolve Definitions: Algorithm
37    //
38    // First we need to resolve classes in the current module, because we need to resolve Object
39    // and ObjectSets before we can process definitions. The Objects and ObjectSets need to be
40    // handled before other definitions because Objects may refer to some Types that may be
41    // required later on while resolving some other Types and if those 'Type's remain hidden within
42    // Objects, we can always end up having some missing definition(s).
43    //
44    // These first two steps are actually part of parsing, which can only be done when all Class
45    // definitions are avaiable (Think of it as macro invocation in Rust, which is before the Type
46    // resolution, but after an individual file is parsed!).
47    //
48    // After that we resolve definitions in a Topologically sorted order. Fairly straight forward.
49    // We do not need to do any `Pending` definitions, as we were doing before.
50    pub(crate) fn resolve_definitions(&mut self, module: &mut Asn1Module) -> Result<()> {
51        log::debug!(
52            "Resolving Definitions in module: {}",
53            module.get_module_name()
54        );
55        // We need to first get Classes in the current module - resolved
56        self.resolve_classes_in_current_module(module);
57
58        module.resolve_object_classes(&self.classes)?;
59
60        let definitions_sorted = module.definitions_sorted();
61        for k in definitions_sorted {
62            let parsed_def = module.get_definition_mut(&k);
63            if parsed_def.is_none() {
64                log::warn!(
65                    "Warning!! Definition '{}' in module '{}' Not found! It's Okay for certain Dummy References",
66                    k,
67                    module.get_module_name()
68                );
69                continue;
70            }
71            let parsed_def = parsed_def.unwrap();
72            if parsed_def.params.is_some() {
73                log::trace!("Resolving definition with params : {:#?}", parsed_def);
74                self.parameterized_defs
75                    .insert(k.to_string(), parsed_def.clone());
76            } else if parsed_def.is_class_assignment() {
77                log::trace!("Resolving Class Assignment Definition : {:#?}", parsed_def);
78                self.classes.insert(k.to_string(), parsed_def.clone());
79            } else {
80                log::trace!("Resolving definition : {:#?}", parsed_def);
81                let resolved_def = resolve_definition(parsed_def, self)?;
82                self.resolved_defs.insert(k.clone(), resolved_def);
83            }
84            parsed_def.resolved = true;
85        }
86
87        for k in module.definitions_sorted() {
88            let parsed_def = module.get_definition_mut(&k);
89            if parsed_def.is_none() {
90                eprintln!(
91                    "Warning!! Definition '{}' Not found! It's Okay for certain Dummy References",
92                    k
93                );
94                continue;
95            }
96            let parsed_def = parsed_def.unwrap();
97            if !parsed_def.resolved {
98                println!(
99                    "UNRESOLVED: Definition: {} in module : {} not resolved!",
100                    k,
101                    module.get_module_name()
102                );
103            }
104        }
105
106        Ok(())
107    }
108
109    pub(crate) fn get_resolved_types(&self) -> Vec<(&String, &Asn1ResolvedType)> {
110        self.resolved_defs
111            .iter()
112            .filter_map(|(k, v)| match v {
113                Asn1ResolvedDefinition::Type(ref t) => Some((k, t)),
114                _ => None,
115            })
116            .collect::<Vec<(&String, &Asn1ResolvedType)>>()
117    }
118
119    pub(crate) fn get_resolved_values(&self) -> Vec<(&String, &Asn1ResolvedValue)> {
120        self.resolved_defs
121            .iter()
122            .filter_map(|(k, v)| match v {
123                Asn1ResolvedDefinition::Value(ref v) => Some((k, v)),
124                _ => None,
125            })
126            .collect::<Vec<(&String, &Asn1ResolvedValue)>>()
127    }
128
129    fn resolve_classes_in_current_module(&mut self, module: &Asn1Module) {
130        for (k, def) in module.get_definitions() {
131            if def.is_class_assignment() {
132                self.classes.insert(k.clone(), def.clone());
133            }
134        }
135    }
136}