Skip to content

Commit 534cba8

Browse files
committed
Add toplevel.rs
1 parent bbe21e3 commit 534cba8

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

xml-schema/src/toplevel.rs

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//! Collects named entities and global information from the root of the AST.
2+
use std::collections::hash_map::{Entry, HashMap};
3+
4+
use names::FullName;
5+
use parser::xs;
6+
7+
fn insert_unique<'ast, 'input: 'ast, T>(
8+
type_name: &'static str,
9+
map: &mut HashMap<FullName<'input>, T>,
10+
name: FullName<'input>,
11+
sub_ast: T,
12+
) {
13+
let entry = map.entry(name);
14+
match entry {
15+
Entry::Occupied(_) => panic!("Duplicate {}: {:?}", type_name, name),
16+
Entry::Vacant(e) => {
17+
e.insert(sub_ast);
18+
}
19+
}
20+
}
21+
22+
#[derive(Debug)]
23+
pub struct Toplevel<'ast, 'input: 'ast> {
24+
pub target_namespace: Option<&'input str>,
25+
pub element_form_default_qualified: bool,
26+
pub attribute_form_default_qualified: bool,
27+
pub elements: HashMap<FullName<'input>, &'ast xs::Element<'input>>,
28+
pub simple_types: HashMap<FullName<'input>, &'ast xs::SimpleType<'input>>,
29+
pub complex_types: HashMap<FullName<'input>, &'ast xs::ComplexType<'input>>,
30+
pub groups: HashMap<FullName<'input>, &'ast xs::Group<'input>>,
31+
pub attribute_groups: HashMap<FullName<'input>, &'ast xs::AttributeGroup<'input>>,
32+
}
33+
34+
impl<'ast, 'input: 'ast> Toplevel<'ast, 'input> {
35+
pub fn new(ast: &'ast xs::Schema<'input>) -> Toplevel<'ast, 'input> {
36+
let target_namespace = ast.attr_target_namespace.as_ref().map(|t| t.0);
37+
let element_form_default_qualified =
38+
match ast.attr_element_form_default.as_ref().map(|x| ((x.0).0).0) {
39+
Some("qualified") => true,
40+
Some("unqualified") | None => false,
41+
_ => unreachable!(),
42+
};
43+
let attribute_form_default_qualified = match ast
44+
.attr_attribute_form_default
45+
.as_ref()
46+
.map(|x| ((x.0).0).0)
47+
{
48+
Some("qualified") => true,
49+
Some("unqualified") | None => false,
50+
_ => unreachable!(),
51+
};
52+
let mut toplevel = Toplevel {
53+
target_namespace,
54+
element_form_default_qualified,
55+
attribute_form_default_qualified,
56+
elements: HashMap::new(),
57+
simple_types: HashMap::new(),
58+
complex_types: HashMap::new(),
59+
groups: HashMap::new(),
60+
attribute_groups: HashMap::new(),
61+
};
62+
toplevel.process_ast(ast);
63+
toplevel
64+
}
65+
66+
pub fn process_ast(&mut self, ast: &'ast xs::Schema<'input>) {
67+
for top_level_item in ast.sequence_schema_top_annotation.iter() {
68+
match top_level_item.schema_top {
69+
xs::SchemaTop::Redefinable(ref r) => self.process_redefinable(r),
70+
xs::SchemaTop::Element(ref e) => self.process_element(e),
71+
xs::SchemaTop::Attribute(_) => unimplemented!("top-level attribute"),
72+
xs::SchemaTop::Notation(_) => unimplemented!("notation"),
73+
}
74+
}
75+
}
76+
77+
fn process_redefinable(&mut self, r: &'ast xs::Redefinable<'input>) {
78+
match r {
79+
xs::Redefinable::SimpleType(ref e) => self.process_simple_type(e),
80+
xs::Redefinable::ComplexType(e) => self.process_complex_type(e),
81+
xs::Redefinable::Group(e) => self.process_named_group(e),
82+
xs::Redefinable::AttributeGroup(e) => self.process_attribute_group(e),
83+
}
84+
}
85+
86+
fn process_element(&mut self, element: &'ast xs::Element<'input>) {
87+
let name = FullName::new(self.target_namespace, element.attr_name.0);
88+
insert_unique("element", &mut self.elements, name, element);
89+
}
90+
91+
fn process_simple_type(&mut self, simple_type: &'ast xs::SimpleType<'input>) {
92+
let name = FullName::new(self.target_namespace, simple_type.attr_name.0.clone());
93+
self.simple_types.insert(name, simple_type);
94+
}
95+
96+
fn process_complex_type(&mut self, complex_type: &'ast xs::ComplexType<'input>) {
97+
let name = FullName::new(self.target_namespace, complex_type.attr_name.0.clone());
98+
self.complex_types.insert(name, complex_type);
99+
}
100+
101+
fn process_named_group(&mut self, group: &'ast xs::Group<'input>) {
102+
let name = FullName::new(self.target_namespace, group.attr_name.0.clone());
103+
self.groups.insert(name, group);
104+
}
105+
106+
fn process_attribute_group(&mut self, attribute_group: &'ast xs::AttributeGroup<'input>) {
107+
let name = FullName::new(self.target_namespace, attribute_group.attr_name.0.clone());
108+
self.attribute_groups.insert(name, attribute_group);
109+
}
110+
}

0 commit comments

Comments
 (0)