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#[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#[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#[derive(Clone, Debug)]
179pub struct Type {
180 pub name: QualifiedName,
181 pub args: Vec<Type>,
182}
183
184pub 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 pub fn name(&self) -> &'a QualifiedName {
223 self.name
224 }
225}
226
227#[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
284pub struct ConstantVersionInfo<'a> {
287 pub version: BigUint,
288 pub value: Option<&'a ConstantValue>,
289
290 dummy: PhantomData<()>,
291}
292
293pub 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 pub fn value_type(self) -> &'a Type {
334 &self.value.value_type
335 }
336
337 pub fn referenced_types(self) -> ReferencedTypeIterator<'a> {
339 ReferencedTypeIterator::from_type(&self.value.value_type)
340 }
341
342 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 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#[derive(Debug)]
366pub struct FieldInfo {
367 pub field_type: Type,
368}
369
370#[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#[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#[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 pub fn is_final(&self) -> bool {
473 self.value.is_final
474 }
475
476 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 pub fn last_explicit_version(self) -> Option<&'a BigUint> {
502 self.value.versions.keys().max()
503 }
504
505 pub fn referenced_types(self) -> ReferencedTypeIterator<'a> {
507 ReferencedTypeIterator::from_versions(&self.value.versions)
508 }
509
510 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 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 pub fn type_params(self) -> &'a Vec<String> {
543 &self.value.type_params
544 }
545}
546
547#[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#[derive(Copy, Clone, Debug, PartialEq, Eq)]
667pub enum ExternLiteralIntBound {
668 Inclusive,
669 Exclusive,
670}
671
672#[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 pub fn literals(self) -> &'a Vec<ExternLiteralSpecifier> {
685 &self.value.literals
686 }
687
688 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 pub fn type_params(self) -> &'a Vec<String> {
700 &self.value.type_params
701 }
702}
703
704
705
706pub enum TypeDefinition {
708 StructType(VersionedTypeDefinitionData),
709 EnumType(VersionedTypeDefinitionData),
710 ExternType(ExternTypeDefinitionData),
711}
712
713#[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 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 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 pub fn arity(&self) -> usize {
742 self.type_params().len()
743 }
744
745 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
755pub struct VerilizationMetadata {
757 pub latest_version: BigUint,
758}
759
760pub struct Verilization {
762 metadata: VerilizationMetadata,
763 constants: HashMap<QualifiedName, Constant>,
764 type_definitions: HashMap<QualifiedName, TypeDefinition>,
765 names: HashSet<QualifiedName>,
766}
767
768#[derive(Clone, Debug)]
770pub enum ScopeLookup {
771 NamedType(QualifiedName),
772 TypeParameter(String),
773}
774
775pub 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(¤t_pkg_name) {
814 return ScopeLookup::NamedType(current_pkg_name);
815 }
816
817 name.name = current_pkg_name.name; }
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 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 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 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 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 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 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 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 pub fn has_type<'a>(&'a self, name: &QualifiedName) -> bool {
924 self.type_definitions.contains_key(name)
925 }
926
927 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 pub fn constants<'a>(&'a self) -> ConstantIterator<'a> {
946 ConstantIterator {
947 model: self,
948 iter: self.constants.iter(),
949 }
950 }
951
952 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
964pub 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}