verilization_compiler/
model.rs

1use num_bigint::{ BigUint, BigInt };
2use num_traits::{Zero, One};
3use std::collections::{HashMap, HashSet};
4use std::fmt;
5use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
6use lazy_static::lazy_static;
7use std::marker::PhantomData;
8
9/// A dot-separated package.
10#[derive(PartialEq, Eq, Hash, Debug, Clone)]
11pub struct PackageName {
12	pub package: Vec<String>,
13}
14
15impl PackageName {
16	pub fn new() -> PackageName {
17		PackageName {
18			package: Vec::new(),
19		}
20	}
21	
22	pub fn from_str(pkg: &str) -> PackageName {
23		PackageName {
24			package: 
25				if pkg.is_empty() {
26					Vec::new()	
27				}
28				else {
29					pkg.split(".").map(str::to_string).collect()
30				},
31		}
32	}
33
34	pub fn from_parts(parts: &[&str]) -> PackageName {
35		PackageName {
36			package: parts.iter().map(|x| String::from(*x)).collect::<Vec<_>>(),
37		}
38	}
39}
40
41impl fmt::Display for PackageName {
42	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43		for_sep!(item, &self.package, { write!(f, ".")?; }, {
44			write!(f, "{}", item)?;
45		});
46		Ok(())
47	}
48}
49
50impl Ord for PackageName {
51	fn cmp(&self, other: &Self) -> Ordering {
52		let mut i1 = self.package.iter();
53		let mut i2 = other.package.iter();
54
55		loop {
56			match (i1.next(), i2.next()) {
57				(Some(p1), Some(p2)) => {
58					let ord = p1.cmp(p2);
59					if ord != Ordering::Equal {
60						return ord
61					}
62				},
63				(Some(_), None) => return Ordering::Greater,
64				(None, Some(_)) => return Ordering::Less,
65				(None, None) => return Ordering::Equal,
66			}
67		}
68	}
69}
70
71impl PartialOrd for PackageName {
72	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
73		Some(self.cmp(other))
74	}
75}
76
77/// A name that exists within a package.
78#[derive(PartialEq, Eq, Hash, Debug, Clone)]
79pub struct QualifiedName {
80	pub package: PackageName,
81	pub name: String,
82}
83
84impl QualifiedName {
85	pub fn from_str(name: &str) -> Option<QualifiedName> {
86		let mut iter = name.split(".");
87		if let Some(part) = iter.next() {
88			let mut pkg_parts = Vec::new();
89			let mut name = String::from(part);
90
91			while let Some(part) = iter.next() {
92				pkg_parts.push(name);
93				name = String::from(part);
94			}
95
96			Some(QualifiedName {
97				package: PackageName {
98					package: pkg_parts,
99				},
100				name: name,
101			})
102		}
103		else {
104			None
105		}
106	}
107
108	pub fn from_parts(package: &[&str], name: &str) -> QualifiedName {
109		QualifiedName {
110			package: PackageName::from_parts(package),
111			name: String::from(name),
112		}
113	}
114}
115
116impl fmt::Display for QualifiedName {
117	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118		if self.package.package.is_empty() {
119			write!(f, "{}", self.name)
120		}
121		else {
122			write!(f, "{}.{}", self.package, self.name)
123		}
124	}
125}
126
127impl Ord for QualifiedName {
128	fn cmp(&self, other: &Self) -> Ordering {
129		let ord = self.package.cmp(&other.package);
130		if ord != Ordering::Equal {
131			return ord
132		}
133
134		self.name.cmp(&other.name)
135	}
136}
137
138impl PartialOrd for QualifiedName {
139	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
140		Some(self.cmp(other))
141	}
142}
143
144#[derive(Debug)]
145pub enum ModelError {
146	DuplicateConstant(QualifiedName),
147	DuplicateType(QualifiedName),
148	DuplicateVersion(QualifiedName, BigUint),
149	DuplicateField(QualifiedName, BigUint, String),
150	DuplicateLiteralInteger(QualifiedName),
151	DuplicateLiteralString(QualifiedName),
152	DuplicateLiteralSequence(QualifiedName),
153	DuplicateLiteralCase(QualifiedName, String),
154	DuplicateLiteralRecord(QualifiedName),
155	DuplicateLiteralRecordField(QualifiedName, String),
156	DuplicateFieldValue(String),
157}
158
159impl fmt::Display for ModelError {
160	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161		match self {
162			ModelError::DuplicateConstant(name) => write!(f, "Cannot declare constant {}. Name is already defined.", name),
163			ModelError::DuplicateType(name) => write!(f, "Cannot declare type {}. Name is already defined.", name),
164			ModelError::DuplicateVersion(name, version) => write!(f, "Version {} of type {} is already defined.", version, name),
165			ModelError::DuplicateField(name, version, field) => write!(f, "Version {} of type {} already has a field named {}.", version, name, field),
166			ModelError::DuplicateLiteralInteger(type_name) => write!(f, "Type {} already has an integer literal.", type_name),
167			ModelError::DuplicateLiteralString(type_name) => write!(f, "Type {} already has a string literal.", type_name),
168			ModelError::DuplicateLiteralSequence(type_name) => write!(f, "Type {} already has a sequence literal.", type_name),
169			ModelError::DuplicateLiteralCase(type_name, name) => write!(f, "Type {} already has a literal for case {}.", type_name, name),
170			ModelError::DuplicateLiteralRecord(type_name) => write!(f, "Type {} already has a record literal.", type_name),
171			ModelError::DuplicateLiteralRecordField(type_name, field) => write!(f, "Record literal for type {} already has a field named {}.", type_name, field),
172			ModelError::DuplicateFieldValue(name) => write!(f, "Record constant already has a field named {}.", name),
173		}
174	}
175}
176
177/// A data type. This includes the name of the type and the type arguments.
178#[derive(Clone, Debug)]
179pub struct Type {
180	pub name: QualifiedName,
181	pub args: Vec<Type>,
182}
183
184// Attaches a name to something.
185pub struct Named<'a, A> {
186	model: &'a Verilization,
187	name: &'a QualifiedName,
188	value: &'a A,
189}
190
191impl <'a, A: fmt::Debug> fmt::Debug for Named<'a, A> {
192	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
193		f.debug_struct("Named")
194			.field("name", &self.name)
195			.field("value", &self.value)
196			.finish()
197	}
198}
199
200impl <'a, A> Clone for Named<'a, A> {
201	fn clone(&self) -> Self {
202		Named {
203			model: self.model,
204			name: self.name,
205			value: self.value,
206		}
207	}
208}
209
210impl <'a, A> Copy for Named<'a, A> {}
211
212impl <'a, A> Named<'a, A> {
213	fn new(model: &'a Verilization, name: &'a QualifiedName, value: &'a A) -> Named<'a, A> {
214		Named {
215			model: model,
216			name: name,
217			value: value,
218		}
219	}
220
221	/// Gets the name of this named value.
222	pub fn name(&self) -> &'a QualifiedName {
223		self.name
224	}
225}
226
227/// The value of a constant.
228#[derive(Clone, Debug)]
229pub enum ConstantValue {
230	Integer(BigInt),
231	String(String),
232	Sequence(Vec<ConstantValue>),
233	Case(String, Vec<ConstantValue>),
234	Record(ConstantValueRecord),
235	Constant(QualifiedName),
236}
237
238#[derive(Clone, Debug)]
239pub struct ConstantValueRecord {
240	field_values: HashMap<String, ConstantValue>,
241}
242
243impl ConstantValueRecord {
244	pub fn field_values<'a>(&'a self) -> &'a HashMap<String, ConstantValue> {
245		&self.field_values
246	}
247
248	pub fn into_field_values(self) -> HashMap<String, ConstantValue> {
249		self.field_values
250	}
251}
252
253pub struct ConstantValueRecordBuilder {
254	field_names: HashSet<String>,
255	record: ConstantValueRecord,
256}
257
258impl ConstantValueRecordBuilder {
259	pub fn new() -> Self {
260		ConstantValueRecordBuilder {
261			field_names: HashSet::new(),
262			record: ConstantValueRecord {
263				field_values: HashMap::new(),
264			},
265		}
266	}
267
268	pub fn add_field(&mut self, name: String, value: ConstantValue) -> Result<(), ModelError> {
269		if self.field_names.insert(name.to_ascii_uppercase()) {
270			self.record.field_values.insert(name, value);
271			Ok(())
272		}
273		else {
274			Err(ModelError::DuplicateFieldValue(name))
275		}
276	}
277
278	pub fn build(self) -> ConstantValueRecord {
279		self.record
280	}
281}
282
283
284/// The result of looking up a constant for a specific format version.
285/// If value is None, then the value was defined in a previous version.
286pub struct ConstantVersionInfo<'a> {
287	pub version: BigUint,
288	pub value: Option<&'a ConstantValue>,
289
290	dummy: PhantomData<()>,
291}
292
293/// A constant definition.
294/// 
295/// See accessor methods for [`Named`] constants.
296pub struct Constant {
297	imports: HashMap<String, ScopeLookup>,
298	value_type: Type,
299	versions: HashMap<BigUint, ConstantValue>,
300}
301
302pub struct ConstantBuilder {
303	name: QualifiedName,
304	constant: Constant,
305}
306
307impl ConstantBuilder {
308	pub fn new(name: QualifiedName, value_type: Type, imports: HashMap<String, ScopeLookup>) -> Self {
309		ConstantBuilder {
310			name: name,
311			constant: Constant {
312				imports: imports,
313				value_type: value_type,
314				versions: HashMap::new(),
315			},
316		}
317	}
318
319	pub fn add_version(&mut self, version: BigUint, value: ConstantValue) -> Result<(), ModelError> {
320		if self.constant.versions.contains_key(&version) {
321			Err(ModelError::DuplicateVersion(self.name.clone(), version.clone()))
322		}
323		else {
324			self.constant.versions.insert(version, value);
325			Ok(())
326		}
327	}
328}
329
330impl <'a> Named<'a, Constant> {
331
332	/// The type of the constant.
333	pub fn value_type(self) -> &'a Type {
334		&self.value.value_type
335	}
336
337	/// Iterates over types referenced in the type of the constant.
338	pub fn referenced_types(self) -> ReferencedTypeIterator<'a> {
339		ReferencedTypeIterator::from_type(&self.value.value_type)
340	}
341
342	/// Iterates over the versions of the constant from the first version to the latest version of the model.
343	pub fn versions(self) -> ConstantVersionIterator<'a> {
344		ConstantVersionIterator {
345			constant: self,
346			version: BigUint::one(),
347			has_prev_version: false,
348			max_version: self.model.metadata.latest_version.clone(),
349		}
350	}
351
352	/// Gets a scope for this constant element.
353	pub fn scope(self) -> Scope<'a> {
354		Scope {
355			model: self.model,
356			current_pkg: Some(&self.name.package),
357			imports: Some(&self.value.imports),
358			type_params: None,
359		}
360	}
361
362}
363
364/// A field of a struct or enum. An enum field represents a single case.
365#[derive(Debug)]
366pub struct FieldInfo {
367	pub field_type: Type,
368}
369
370/// A versioned type defines the contents of a type for a specific format version.
371#[derive(Debug)]
372pub struct TypeVersionDefinition {
373	fields: Vec<(String, FieldInfo)>,
374}
375
376impl TypeVersionDefinition {
377	pub fn fields(&self) -> &Vec<(String, FieldInfo)> {
378		&self.fields
379	}
380}
381
382pub struct TypeVersionDefinitionBuilder<'a> {
383	name: &'a QualifiedName,
384	version: BigUint,
385	field_names: HashSet<String>,
386	ver_type: &'a mut TypeVersionDefinition,
387}
388
389impl <'a> TypeVersionDefinitionBuilder<'a> {
390	pub fn add_field(&mut self, name: String, field: FieldInfo) -> Result<(), ModelError> {
391		if self.field_names.insert(name.to_ascii_uppercase()) {
392			self.ver_type.fields.push((name, field));
393			Ok(())
394		}
395		else {
396			Err(ModelError::DuplicateField(self.name.clone(), self.version.clone(), name))
397		}
398	}
399}
400
401/// The result of looking up a version of a type.
402#[derive(Debug)]
403pub struct TypeVersionInfo<'a> {
404	pub version: BigUint,
405	pub explicit_version: bool,
406	pub ver_type: &'a TypeVersionDefinition,
407
408	dummy: PhantomData<()>,
409}
410
411impl <'a> Clone for TypeVersionInfo<'a> {
412	fn clone(&self) -> Self {
413		TypeVersionInfo {
414			version: self.version.clone(),
415			explicit_version: self.explicit_version,
416			ver_type: self.ver_type,
417
418			dummy: PhantomData {}
419		}
420	}
421}
422
423/// Defines a versioned type. Could be a struct or enum.
424#[derive(Debug)]
425pub struct VersionedTypeDefinitionData {
426	imports: HashMap<String, ScopeLookup>,
427	type_params: Vec<String>,
428	versions: HashMap<BigUint, TypeVersionDefinition>,
429	is_final: bool,
430}
431
432pub struct VersionedTypeDefinitionBuilder {
433	name: QualifiedName,
434	t: VersionedTypeDefinitionData,
435}
436
437impl VersionedTypeDefinitionBuilder {
438	pub fn new(name: QualifiedName, type_params: Vec<String>, is_final: bool, imports: HashMap<String, ScopeLookup>) -> Self {
439		VersionedTypeDefinitionBuilder {
440			name: name,
441			t: VersionedTypeDefinitionData {
442				imports: imports,
443				type_params: type_params,
444				is_final: is_final,
445				versions: HashMap::new(),
446			},
447		}
448	}
449
450	pub fn add_version<'a>(&'a mut self, version: BigUint) -> Result<TypeVersionDefinitionBuilder<'a>, ModelError> {
451		match self.t.versions.entry(version.clone()) {
452			std::collections::hash_map::Entry::Occupied(_) => Err(ModelError::DuplicateVersion(self.name.clone(), version)),
453			std::collections::hash_map::Entry::Vacant(entry) => {
454				let ver_type = entry.insert(TypeVersionDefinition {
455					fields: Vec::new(),
456				});
457
458				Ok(TypeVersionDefinitionBuilder {
459					name: &self.name,
460					version: version,
461					field_names: HashSet::new(),
462					ver_type: ver_type,
463				})
464			}
465		}
466	}
467}
468
469impl <'a> Named<'a, VersionedTypeDefinitionData> {
470
471	// Gets whether this type is final.
472	pub fn is_final(&self) -> bool {
473		self.value.is_final
474	}
475
476	/// Gets a version of this type.
477	pub fn versioned(self, version: &BigUint) -> Option<TypeVersionInfo<'a>> {
478		self.value.versions.iter()
479			.filter(|(ver, _)| ver <= &version)
480			.max_by_key(|(ver, _)| ver.clone())
481			.map(|(actual_ver, ver_type)| {
482
483				let ver =
484					if self.value.is_final && !self.value.versions.keys().any(|other_ver| other_ver > actual_ver) {
485						actual_ver.clone()
486					}
487					else {
488						version.clone()
489					};
490
491				TypeVersionInfo {
492					version: ver,
493					explicit_version: version == actual_ver,
494					ver_type: ver_type,
495					dummy: PhantomData {},
496				}
497			})
498	}
499
500	/// Finds the last explicitly defined version of this type.
501	pub fn last_explicit_version(self) -> Option<&'a BigUint> {
502		self.value.versions.keys().max()
503	}
504
505	/// Iterates over types referenced in the field types of this type.
506	pub fn referenced_types(self) -> ReferencedTypeIterator<'a> {
507		ReferencedTypeIterator::from_versions(&self.value.versions)
508	}
509
510	/// Iterates over the versions of this type.
511	/// 
512	/// Starts at the first version of the type.
513	/// If the type is final, ends at the last explicitly defined version.
514	/// If the type is not final, ends at the latest version of the model.
515	pub fn versions(self) -> TypeVersionIterator<'a> {
516		TypeVersionIterator {
517			type_def: self,
518			version: BigUint::one(),
519			max_version:
520				if self.value.is_final {
521					self.last_explicit_version().map(|ver| ver.clone()).unwrap_or(BigUint::zero())
522				}
523				else {
524					self.model.metadata.latest_version.clone()
525				},
526
527			last_seen_version: None,
528		}
529	}
530
531	/// Gets a scope for the type.
532	pub fn scope(self) -> Scope<'a> {
533		Scope {
534			model: self.model,
535			current_pkg: Some(&self.name.package),
536			imports: Some(&self.value.imports),
537			type_params: Some(&self.value.type_params),
538		}
539	}
540
541	/// Gets the parameters of the type.
542	pub fn type_params(self) -> &'a Vec<String> {
543		&self.value.type_params
544	}
545}
546
547/// Defines an extern type.
548#[derive(Debug)]
549pub struct ExternTypeDefinitionData {
550	imports: HashMap<String, ScopeLookup>,
551	type_params: Vec<String>,
552	literals: Vec<ExternLiteralSpecifier>,
553}
554
555pub struct ExternTypeDefinitionBuilder {
556	name: QualifiedName,
557	has_integer: bool,
558	has_string: bool,
559	has_sequence: bool,
560	cases: HashSet<String>,
561	has_record: bool,
562	t: ExternTypeDefinitionData,
563}
564
565pub struct ExternLiteralRecordBuilder<'a> {
566	name: &'a QualifiedName,
567	field_names: HashSet<String>,
568	fields: &'a mut Vec<(String, FieldInfo)>,
569}
570
571impl ExternTypeDefinitionBuilder {
572	pub fn new(name: QualifiedName, type_params: Vec<String>, imports: HashMap<String, ScopeLookup>) -> Self {
573		ExternTypeDefinitionBuilder {
574			name: name,
575			has_integer: false,
576			has_string: false,
577			has_sequence: false,
578			cases: HashSet::new(),
579			has_record: false,
580			t: ExternTypeDefinitionData {
581				imports: imports,
582				type_params: type_params,
583				literals: Vec::new(),
584			},
585		}
586	}
587	
588	pub fn add_integer_literal(&mut self, lower_type: ExternLiteralIntBound, lower: Option<BigInt>, upper_type: ExternLiteralIntBound, upper: Option<BigInt>) -> Result<(), ModelError> {
589		if self.has_integer {
590			Err(ModelError::DuplicateLiteralInteger(self.name.clone()))
591		}
592		else {
593			self.t.literals.push(ExternLiteralSpecifier::Integer(lower_type, lower, upper_type, upper));
594			self.has_integer = true;
595			Ok(())
596		}
597	}
598	
599	pub fn add_string_literal(&mut self) -> Result<(), ModelError> {
600		if self.has_string {
601			Err(ModelError::DuplicateLiteralString(self.name.clone()))
602		}
603		else {
604			self.t.literals.push(ExternLiteralSpecifier::String);
605			self.has_string = true;
606			Ok(())
607		}
608	}
609	
610	pub fn add_sequence_literal(&mut self, element_type: Type) -> Result<(), ModelError> {
611		if self.has_sequence {
612			Err(ModelError::DuplicateLiteralSequence(self.name.clone()))
613		}
614		else {
615			self.t.literals.push(ExternLiteralSpecifier::Sequence(element_type));
616			self.has_sequence = true;
617			Ok(())
618		}
619	}
620	
621	pub fn add_case_literal(&mut self, case_name: String, params: Vec<Type>) -> Result<(), ModelError> {
622		if self.cases.insert(case_name.to_ascii_uppercase()) {
623			self.t.literals.push(ExternLiteralSpecifier::Case(case_name, params));
624			Ok(())
625		}
626		else {
627			Err(ModelError::DuplicateLiteralCase(self.name.clone(), case_name))
628		}
629	}
630	
631	pub fn add_record_literal<'a>(&'a mut self) -> Result<ExternLiteralRecordBuilder<'a>, ModelError> {
632		if self.has_record {
633			Err(ModelError::DuplicateLiteralRecord(self.name.clone()))
634		}
635		else {
636			self.has_record = true;
637			self.t.literals.push(ExternLiteralSpecifier::Record(Vec::new()));
638			let fields = match self.t.literals.last_mut() {
639				Some(ExternLiteralSpecifier::Record(fields)) => fields,
640				_ => panic!("Last element should have been a record"),
641			};
642			Ok(ExternLiteralRecordBuilder {
643				name: &self.name,
644				field_names: HashSet::new(),
645				fields: fields,
646			})
647		}
648	}
649
650
651}
652
653impl <'a> ExternLiteralRecordBuilder<'a> {
654	pub fn add_field(&mut self, name: String, field: FieldInfo) -> Result<(), ModelError> {
655		if self.field_names.insert(name.to_ascii_uppercase()) {
656			self.fields.push((name, field));
657			Ok(())
658		}
659		else {
660			Err(ModelError::DuplicateLiteralRecordField(self.name.clone(), name))
661		}
662	}
663}
664
665/// Defines a bound for an integer literal definition.
666#[derive(Copy, Clone, Debug, PartialEq, Eq)]
667pub enum ExternLiteralIntBound {
668	Inclusive,
669	Exclusive,
670}
671
672/// Defines a literal for an extern type.
673#[derive(Debug)]
674pub enum ExternLiteralSpecifier {
675	Integer(ExternLiteralIntBound, Option<BigInt>, ExternLiteralIntBound, Option<BigInt>),
676	String,
677	Sequence(Type),
678	Case(String, Vec<Type>),
679	Record(Vec<(String, FieldInfo)>),
680}
681
682impl <'a> Named<'a, ExternTypeDefinitionData> {
683	/// Get the literals defined by the type.
684	pub fn literals(self) -> &'a Vec<ExternLiteralSpecifier> {
685		&self.value.literals
686	}
687
688	/// Gets a scope for the type.
689	pub fn scope(self) -> Scope<'a> {
690		Scope {
691			model: self.model,
692			current_pkg: Some(&self.name.package),
693			imports: Some(&self.value.imports),
694			type_params: Some(&self.value.type_params),
695		}
696	}
697
698	/// Gets the parameters for the type.
699	pub fn type_params(self) -> &'a Vec<String> {
700		&self.value.type_params
701	}
702}
703
704
705
706/// A definition of a type.
707pub enum TypeDefinition {
708	StructType(VersionedTypeDefinitionData),
709	EnumType(VersionedTypeDefinitionData),
710	ExternType(ExternTypeDefinitionData),
711}
712
713/// A named definition of a type.
714#[derive(Copy, Clone)]
715pub enum NamedTypeDefinition<'a> {
716	StructType(Named<'a, VersionedTypeDefinitionData>),
717	EnumType(Named<'a, VersionedTypeDefinitionData>),
718	ExternType(Named<'a, ExternTypeDefinitionData>),
719}
720
721impl <'a> NamedTypeDefinition<'a> {
722	/// Get the name of the type.
723	pub fn name(&self) -> &'a QualifiedName {
724		match self {
725			NamedTypeDefinition::StructType(t) => t.name,
726			NamedTypeDefinition::EnumType(t) => t.name,
727			NamedTypeDefinition::ExternType(t) => t.name,
728		}
729	}
730
731	/// Gets the parameters of the type.
732	pub fn type_params(&self) -> &'a Vec<String> {
733		match self {
734			NamedTypeDefinition::StructType(t) => &t.value.type_params,
735			NamedTypeDefinition::EnumType(t) => &t.value.type_params,
736			NamedTypeDefinition::ExternType(t) => &t.value.type_params,
737		}
738	}
739
740	/// Gets the number of parameters of the type.
741	pub fn arity(&self) -> usize {
742		self.type_params().len()
743	}
744
745	/// Returns true if the type exists in the specified version.
746	pub fn has_version(self, version: &BigUint) -> bool {
747		match self {
748			NamedTypeDefinition::StructType(t) => t.versioned(version).is_some(),
749			NamedTypeDefinition::EnumType(t) => t.versioned(version).is_some(),
750			NamedTypeDefinition::ExternType(_) => true,
751		}
752	}
753}
754
755/// Metadata about the format.
756pub struct VerilizationMetadata {
757	pub latest_version: BigUint,
758}
759
760/// Defines a versioned serialization format.
761pub struct Verilization {
762	metadata: VerilizationMetadata,
763	constants: HashMap<QualifiedName, Constant>,
764	type_definitions: HashMap<QualifiedName, TypeDefinition>,
765	names: HashSet<QualifiedName>,
766}
767
768/// The result of looking up a name.
769#[derive(Clone, Debug)]
770pub enum ScopeLookup {
771	NamedType(QualifiedName),
772	TypeParameter(String),
773}
774
775/// A Scope allows looking up names.
776/// 
777/// It can identify names that are type parameters, names in the current package, etc.
778pub struct Scope<'a> {
779	model: &'a Verilization,
780	current_pkg: Option<&'a PackageName>,
781	imports: Option<&'a HashMap<String, ScopeLookup>>,
782	type_params: Option<&'a Vec<String>>,
783}
784
785impl <'a> Scope<'a> {
786	pub fn empty(model: &'a Verilization) -> Self {
787		Scope {
788			model: model,
789			current_pkg: None,
790			imports: None,
791			type_params: None,
792		}
793	}
794
795	pub fn lookup(&self, mut name: QualifiedName) -> ScopeLookup {
796		if name.package.package.is_empty() {
797			if let Some(type_params) = self.type_params {
798				if type_params.contains(&name.name) {
799					return ScopeLookup::TypeParameter(name.name);
800				}
801			}
802
803			if let Some(import) = self.imports.and_then(|imports| imports.get(&name.name)) {
804				return import.clone();
805			}
806
807			if let Some(current_pkg) = self.current_pkg {
808				let current_pkg_name = QualifiedName {
809					package: current_pkg.clone(),
810					name: name.name,
811				};
812	
813				if self.model.has_type(&current_pkg_name) {
814					return ScopeLookup::NamedType(current_pkg_name);
815				}
816	
817				name.name = current_pkg_name.name; // restore name because current_pkg_name is not a type
818			}
819		}
820
821		ScopeLookup::NamedType(name)
822	}
823
824	pub fn type_params(&self) -> Vec<String> {
825		match self.type_params {
826			Some(params) => params.clone(),
827			None => Vec::new(),
828		}
829	}
830}
831
832fn make_name_uppercase(name: &mut QualifiedName) {
833	for part in &mut name.package.package {
834		part.make_ascii_uppercase();
835	}
836
837	name.name.make_ascii_uppercase();
838}
839
840impl Verilization {
841
842	/// Creates a new versioned format.
843	pub fn new(metadata: VerilizationMetadata) -> Self {
844		Verilization {
845			metadata: metadata,
846			constants: HashMap::new(),
847			type_definitions: HashMap::new(),
848			names: HashSet::new(),
849		}
850	}
851
852	/// Adds a constant to the serialization format.
853	pub fn add_constant(&mut self, constant: ConstantBuilder) -> Result<(), ModelError> {
854		let mut case_name = constant.name.clone();
855		make_name_uppercase(&mut case_name);
856		if self.names.insert(case_name) {
857			self.constants.insert(constant.name, constant.constant);
858			Ok(())
859		}
860		else {
861			Err(ModelError::DuplicateConstant(constant.name))
862		}
863	}
864
865	/// Adds a struct to the serialization format.
866	pub fn add_struct_type(&mut self, type_def: VersionedTypeDefinitionBuilder) -> Result<(), ModelError> {
867		let mut case_name = type_def.name.clone();
868		make_name_uppercase(&mut case_name);
869		if self.names.insert(case_name) {
870			self.type_definitions.insert(type_def.name, TypeDefinition::StructType(type_def.t));
871			Ok(())
872		}
873		else {
874			Err(ModelError::DuplicateType(type_def.name))
875		}
876	}
877
878	/// Adds an enum to the serialization format.
879	pub fn add_enum_type(&mut self, type_def: VersionedTypeDefinitionBuilder) -> Result<(), ModelError> {
880		let mut case_name = type_def.name.clone();
881		make_name_uppercase(&mut case_name);
882		if self.names.insert(case_name) {
883			self.type_definitions.insert(type_def.name, TypeDefinition::EnumType(type_def.t));
884			Ok(())
885		}
886		else {
887			Err(ModelError::DuplicateType(type_def.name))
888		}
889	}
890
891	/// Adds an extern to the serialization format.
892	pub fn add_extern_type(&mut self, type_def: ExternTypeDefinitionBuilder) -> Result<(), ModelError> {
893		let mut case_name = type_def.name.clone();
894		make_name_uppercase(&mut case_name);
895		if self.names.insert(case_name) {
896			self.type_definitions.insert(type_def.name, TypeDefinition::ExternType(type_def.t));
897			Ok(())
898		}
899		else {
900			Err(ModelError::DuplicateType(type_def.name))
901		}
902	}
903
904	/// Finds a constant in the model.
905	pub fn get_constant<'a>(&'a self, name: &QualifiedName) -> Option<Named<'a, Constant>> {
906		let (name, constant) = self.constants.get_key_value(name)?;
907
908		Some(Named::new(self, name, constant))
909	}
910
911	/// Finds a type in the model.
912	pub fn get_type<'a>(&'a self, name: &QualifiedName) -> Option<NamedTypeDefinition<'a>> {
913		let (name, t) = self.type_definitions.get_key_value(name)?;
914
915		Some(match t {
916			TypeDefinition::StructType(t) => NamedTypeDefinition::StructType(Named::new(self, name, t)),
917			TypeDefinition::EnumType(t) => NamedTypeDefinition::EnumType(Named::new(self, name, t)),
918			TypeDefinition::ExternType(t) => NamedTypeDefinition::ExternType(Named::new(self, name,  t)),
919		})
920	}
921
922	/// Determines whether a type with this name exists.
923	pub fn has_type<'a>(&'a self, name: &QualifiedName) -> bool {
924		self.type_definitions.contains_key(name)
925	}
926
927	/// Merges two serialization formats.
928	pub fn merge(&mut self, other: Verilization) -> Result<(), ModelError> {
929		if self.metadata.latest_version < other.metadata.latest_version {
930			self.metadata.latest_version = other.metadata.latest_version
931		}
932
933		other.constants.into_iter().try_for_each(|(name, constant)| self.add_constant(ConstantBuilder { name: name, constant: constant }))?;
934		other.type_definitions.into_iter().try_for_each(|(name, t)| match t {
935			TypeDefinition::StructType(type_def) => self.add_struct_type(VersionedTypeDefinitionBuilder { name: name, t: type_def }),
936			TypeDefinition::EnumType(type_def) => self.add_enum_type(VersionedTypeDefinitionBuilder { name: name, t: type_def }),
937			TypeDefinition::ExternType(type_def) => self.add_extern_type(ExternTypeDefinitionBuilder { name: name, t: type_def, has_integer: false, has_string: false, has_sequence: false, cases: HashSet::new(), has_record: false, }),
938		})?;
939
940		Ok(())
941	}
942
943
944	/// Iterate over constants defined in the model.
945	pub fn constants<'a>(&'a self) -> ConstantIterator<'a> {
946		ConstantIterator {
947			model: self,
948			iter: self.constants.iter(),
949		}
950	}
951
952	/// Iterate over types defined in the model.
953	pub fn types<'a>(&'a self) -> TypeIterator<'a> {
954		TypeIterator {
955			model: self,
956			iter: self.type_definitions.iter(),
957		}
958	}
959
960}
961
962
963
964// Iterators
965
966pub struct ConstantIterator<'a> {
967	model: &'a Verilization,
968	iter: std::collections::hash_map::Iter<'a, QualifiedName, Constant>,
969}
970
971impl <'a> Iterator for ConstantIterator<'a> {
972	type Item = Named<'a, Constant>;
973
974	fn next(&mut self) -> Option<Self::Item> {
975		self.iter.next().map(|(name, constant)| Named::new(self.model, name, constant))
976	}
977}
978
979pub struct ConstantVersionIterator<'a> {
980	constant: Named<'a, Constant>,
981	version: BigUint,
982	max_version: BigUint,
983	has_prev_version: bool,
984}
985
986impl <'a> Iterator for ConstantVersionIterator<'a> {
987	type Item = ConstantVersionInfo<'a>;
988
989	fn next(&mut self) -> Option<Self::Item> {
990		while self.version <= self.max_version {
991			let version = self.version.clone();
992			self.version += BigUint::one();
993			
994			if let Some(ver_type) = self.constant.value.versions.get(&version) {
995				self.has_prev_version = true;
996				return Some(ConstantVersionInfo {
997					version: version,
998					value: Some(ver_type),
999					dummy: PhantomData {},
1000				});
1001			}
1002			else if self.has_prev_version {
1003				return Some(ConstantVersionInfo {
1004					version: version,
1005					value: None,
1006					dummy: PhantomData {},
1007				});
1008			}
1009		}
1010
1011		None
1012	}
1013}
1014
1015pub struct TypeIterator<'a> {
1016	model: &'a Verilization,
1017	iter: std::collections::hash_map::Iter<'a, QualifiedName, TypeDefinition>,
1018}
1019
1020impl <'a> Iterator for TypeIterator<'a> {
1021	type Item = NamedTypeDefinition<'a>;
1022
1023	fn next(&mut self) -> Option<Self::Item> {
1024		self.iter.next().map(|(name, t)| match t {
1025			TypeDefinition::StructType(t) => NamedTypeDefinition::StructType(Named::new(self.model, name, t)),
1026			TypeDefinition::EnumType(t) => NamedTypeDefinition::EnumType(Named::new(self.model, name, t)),
1027			TypeDefinition::ExternType(t) => NamedTypeDefinition::ExternType(Named::new(self.model, name, t)),
1028		})
1029	}
1030}
1031
1032pub struct TypeVersionIterator<'a> {
1033	type_def: Named<'a, VersionedTypeDefinitionData>,
1034	version: BigUint,
1035	max_version: BigUint,
1036	last_seen_version: Option<&'a TypeVersionDefinition>,
1037}
1038
1039impl <'a> Iterator for TypeVersionIterator<'a> {
1040	type Item = TypeVersionInfo<'a>;
1041
1042	fn next(&mut self) -> Option<Self::Item> {
1043		while self.version <= self.max_version {
1044			let version = self.version.clone();
1045			self.version += BigUint::one();
1046			
1047			if let Some(ver_type) = self.type_def.value.versions.get(&version) {
1048				self.last_seen_version = Some(ver_type);
1049				return Some(TypeVersionInfo {
1050					version: version,
1051					explicit_version: true,
1052					ver_type: ver_type,
1053					dummy: PhantomData {},
1054				});
1055			}
1056			else if let Some(ver_type) = self.last_seen_version {
1057				return Some(TypeVersionInfo {
1058					version: version,
1059					explicit_version: false,
1060					ver_type: ver_type,
1061					dummy: PhantomData {},
1062				});
1063			}
1064		}
1065
1066		None
1067	}
1068}
1069
1070
1071pub struct ReferencedTypeIterator<'a> {
1072	seen_types: HashSet<&'a QualifiedName>,
1073	ver_iter: std::collections::hash_map::Values<'a, BigUint, TypeVersionDefinition>,
1074	field_iter: std::slice::Iter<'a, (String, FieldInfo)>,
1075	arg_iters: Vec<std::slice::Iter<'a, Type>>,
1076}
1077
1078lazy_static! {
1079	static ref REF_TYPE_ITER_EMPTY_VER_MAP: HashMap<BigUint, TypeVersionDefinition> = HashMap::new();
1080}
1081const REF_TYPE_ITER_EMPTY_FIELD_SLICE: &[(String, FieldInfo)] = &[];
1082
1083impl <'a> Iterator for ReferencedTypeIterator<'a> {
1084	type Item = &'a QualifiedName;
1085
1086	fn next(&mut self) -> Option<Self::Item> {
1087		loop {
1088			while let Some(arg_iter) = self.arg_iters.last_mut() {
1089				if let Some(arg) = arg_iter.next() {
1090					self.arg_iters.push(arg.args.iter());
1091					if self.seen_types.insert(&arg.name) {
1092						return Some(&arg.name);
1093					}
1094			}
1095				else {
1096					self.arg_iters.pop();
1097				}
1098			}
1099
1100			if let Some((_, field)) = self.field_iter.next() {
1101				self.arg_iters.push(std::slice::from_ref(&field.field_type).iter());
1102			}
1103			else if let Some(ver_type) = self.ver_iter.next() {
1104				self.field_iter = ver_type.fields.iter();
1105			}
1106			else {
1107				return None;
1108			}
1109		}
1110	}
1111}
1112
1113impl <'a> ReferencedTypeIterator<'a> {
1114	fn from_versions(versions: &'a HashMap<BigUint, TypeVersionDefinition>) -> ReferencedTypeIterator<'a> {
1115		ReferencedTypeIterator {
1116			seen_types: HashSet::new(),
1117			ver_iter: versions.values(),
1118			field_iter: REF_TYPE_ITER_EMPTY_FIELD_SLICE.iter(),
1119			arg_iters: Vec::new(),
1120		}
1121	}
1122
1123	fn from_type(t: &'a Type) -> ReferencedTypeIterator<'a> {
1124		ReferencedTypeIterator {
1125			seen_types: HashSet::new(),
1126			ver_iter: REF_TYPE_ITER_EMPTY_VER_MAP.values(),
1127			field_iter: REF_TYPE_ITER_EMPTY_FIELD_SLICE.iter(),
1128			arg_iters: vec!(std::slice::from_ref(t).iter()),
1129		}
1130	}
1131}