1use std::collections::HashMap;
2
3use crate::ast::{Interface, QualifiedIdentifier};
4
5#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
6pub struct InterfaceDefId(usize);
7
8pub struct Database {
9 imports: HashMap<String, Module>,
10 local: Module,
11 mproto_db: mproto_codegen::Database,
12}
13
14impl Database {
15 pub fn new(mproto_db: mproto_codegen::Database) -> Self {
16 Self {
17 imports: HashMap::new(),
18 local: Module::new(),
19 mproto_db,
20 }
21 }
22
23 pub fn local(&mut self) -> &mut Module {
24 &mut self.local
25 }
26 pub fn mproto_db(&self) -> &mproto_codegen::Database {
27 &self.mproto_db
28 }
29 pub fn mproto_db_mut(&mut self) -> &mut mproto_codegen::Database {
30 &mut self.mproto_db
31 }
32
33 pub fn add_module(&mut self, name: String, module: Module) {
34 self.imports.insert(name, module);
35 }
36
37 pub fn lookup_interface<'a>(
38 &'a self,
39 identifier: &QualifiedIdentifier,
40 ) -> Option<&'a Interface> {
41 if let Some(ref module_name) = identifier.module {
42 let module = self.imports.get(module_name)?;
44 module.interface_by_name(&identifier.name)
45 } else {
46 self.local.interface_by_name(&identifier.name)
48 }
49 }
50}
51
52#[derive(Debug)]
53pub struct Module {
54 interfaces: Vec<Interface>,
55 interfaces_by_name: HashMap<String, InterfaceDefId>,
56}
57
58impl Module {
59 pub fn new() -> Self {
60 Self {
61 interfaces: Vec::new(),
62 interfaces_by_name: HashMap::new(),
63 }
64 }
65
66 pub fn add_interface(&mut self, interface: Interface) -> InterfaceDefId {
67 let id = InterfaceDefId(self.interfaces.len());
68
69 self.interfaces_by_name.insert(interface.name.clone(), id);
70 self.interfaces.push(interface);
71
72 id
73 }
74
75 pub fn interface(&self, id: InterfaceDefId) -> &Interface {
76 &self.interfaces[id.0]
77 }
78
79 pub fn interface_by_name<'a>(&'a self, name: &str) -> Option<&'a Interface> {
80 let id = self.interfaces_by_name.get(name)?;
81 Some(self.interface(*id))
82 }
83}