1mod constraints;
5mod information_object;
6mod types;
7mod utils;
8
9use std::{
10 borrow::{BorrowMut, Cow},
11 collections::BTreeMap,
12};
13
14use crate::{
15 common::INTERNAL_NESTED_TYPE_NAME_PREFIX,
16 intermediate::{error::*, information_object::*, types::*, utils::*, *},
17 validator::{
18 linking::utils::bit_string_to_octet_string,
19 parameterization::{Parameterization, ParameterizationArgument},
20 },
21};
22
23use self::{
24 parameterization::ParameterGovernor,
25 utils::{find_tld_or_enum_value_by_name, octet_string_to_bit_string},
26};
27
28use super::{Constraint, Parameter, TableConstraint};
29
30macro_rules! grammar_error {
31 ($kind:ident, $($arg:tt)*) => {
32 GrammarError::new(&format!($($arg)*), GrammarErrorType::$kind)
33 };
34}
35
36impl ToplevelDefinition {
37 pub(crate) fn is_parameterized(&self) -> bool {
38 match self {
39 ToplevelDefinition::Information(ToplevelInformationDefinition {
40 parameterization: Some(_),
41 ..
42 })
43 | ToplevelDefinition::Type(ToplevelTypeDefinition {
44 parameterization: Some(_),
45 ..
46 })
47 | ToplevelDefinition::Value(ToplevelValueDefinition {
48 parameterization: Some(_),
49 ..
50 }) => true,
51 ToplevelDefinition::Type(ToplevelTypeDefinition {
52 ty: ASN1Type::Sequence(s),
53 ..
54 })
55 | ToplevelDefinition::Type(ToplevelTypeDefinition {
56 ty: ASN1Type::Set(s),
57 ..
58 }) => s.members.iter().any(|m| {
59 m.constraints
60 .iter()
61 .any(|c| matches!(c, Constraint::Parameter(_)))
62 }),
63 ToplevelDefinition::Type(ToplevelTypeDefinition {
64 ty: ASN1Type::SequenceOf(s),
65 ..
66 })
67 | ToplevelDefinition::Type(ToplevelTypeDefinition {
68 ty: ASN1Type::SetOf(s),
69 ..
70 }) => s.element_type.constraints().map_or(false, |constraints| {
71 constraints
72 .iter()
73 .any(|c| matches!(c, Constraint::Parameter(_)))
74 }),
75 _ => false,
76 }
77 }
78
79 pub(crate) fn get_distinguished_or_enum_value(
80 &self,
81 type_name: Option<&String>,
82 identifier: &String,
83 ) -> Option<ASN1Value> {
84 if let ToplevelDefinition::Type(t) = self {
85 if type_name.is_some() && Some(&t.name) != type_name {
86 return None;
87 }
88 match &t.ty {
89 ASN1Type::Enumerated(e) => {
90 return e
91 .members
92 .iter()
93 .find_map(|m| (&m.name == identifier).then(|| ASN1Value::Integer(m.index)))
94 }
95 ASN1Type::Integer(i) => {
96 return i.distinguished_values.as_ref().and_then(|dv| {
97 dv.iter().find_map(|d| {
98 (&d.name == identifier).then(|| ASN1Value::Integer(d.value))
99 })
100 })
101 }
102 _ => (),
103 }
104 }
105 None
106 }
107
108 pub fn is_class_with_name(&self, name: &String) -> Option<&InformationObjectClass> {
109 match self {
110 ToplevelDefinition::Information(info) => match &info.value {
111 ASN1Information::ObjectClass(class) => (&info.name == name).then_some(class),
112 _ => None,
113 },
114 _ => None,
115 }
116 }
117
118 pub fn has_constraint_reference(&self) -> bool {
131 match self {
132 ToplevelDefinition::Type(t) => t.ty.contains_constraint_reference(),
133 _ => false,
135 }
136 }
137
138 pub fn link_constraint_reference(
172 &mut self,
173 tlds: &BTreeMap<String, ToplevelDefinition>,
174 ) -> Result<bool, GrammarError> {
175 match self {
176 ToplevelDefinition::Type(t) => {
177 if let Some(replacement) = t.ty.link_constraint_reference(&t.name, tlds)? {
178 t.ty = replacement;
179 }
180 Ok(true)
181 }
182 _ => Ok(false),
184 }
185 }
186
187 pub fn mark_recursive(&mut self) -> Result<(), GrammarError> {
189 match self {
190 ToplevelDefinition::Type(t) => {
191 let _ = t.ty.mark_recursive(&t.name)?;
192 Ok(())
193 }
194 ToplevelDefinition::Value(_v) => Ok(()), ToplevelDefinition::Information(_i) => Ok(()), }
197 }
198
199 pub fn collect_supertypes(
201 &mut self,
202 tlds: &BTreeMap<String, ToplevelDefinition>,
203 ) -> Result<(), GrammarError> {
204 match self {
205 ToplevelDefinition::Type(t) => t.ty.collect_supertypes(tlds),
206 ToplevelDefinition::Value(v) => v.collect_supertypes(tlds),
207 ToplevelDefinition::Information(i) => i.collect_supertypes(tlds),
208 }
209 }
210}
211
212impl ToplevelValueDefinition {
213 pub fn collect_supertypes(
225 &mut self,
226 tlds: &BTreeMap<String, ToplevelDefinition>,
227 ) -> Result<(), GrammarError> {
228 if let Some(ToplevelDefinition::Type(tld)) =
229 tlds.get(self.associated_type.as_str().as_ref())
230 {
231 self.value.link_with_type(tlds, &tld.ty, Some(&tld.name))
232 } else {
233 self.value.link_with_type(tlds, &self.associated_type, None)
234 }
235 }
236}
237
238impl ASN1Type {
239 pub fn collect_supertypes(
243 &mut self,
244 tlds: &BTreeMap<String, ToplevelDefinition>,
245 ) -> Result<(), GrammarError> {
246 match self {
247 ASN1Type::Set(ref mut s) | ASN1Type::Sequence(ref mut s) => {
248 s.members.iter_mut().try_for_each(|m| {
249 m.ty.collect_supertypes(tlds)?;
250 m.default_value
251 .as_mut()
252 .map(|d| d.link_with_type(tlds, &m.ty, Some(&m.ty.as_str().into_owned())))
253 .unwrap_or(Ok(()))
254 })
255 }
256 ASN1Type::Choice(ref mut c) => c
257 .options
258 .iter_mut()
259 .try_for_each(|o| o.ty.collect_supertypes(tlds)),
260 _ => Ok(()),
261 }
262 }
263
264 pub fn has_choice_selection_type(&self) -> bool {
265 match self {
266 ASN1Type::ChoiceSelectionType(_) => true,
267 ASN1Type::Sequence(s) | ASN1Type::Set(s) => s
268 .members
269 .iter()
270 .map(|m| m.ty.has_choice_selection_type())
271 .any(|b| b),
272 ASN1Type::Choice(c) => c
273 .options
274 .iter()
275 .map(|o| o.ty.has_choice_selection_type())
276 .any(|b| b),
277 ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => {
278 s.element_type.has_choice_selection_type()
279 }
280 _ => false,
281 }
282 }
283
284 pub fn link_choice_selection_type(
285 &mut self,
286 tlds: &BTreeMap<String, ToplevelDefinition>,
287 ) -> Result<(), GrammarError> {
288 match self {
289 ASN1Type::ChoiceSelectionType(c) => {
290 if let Some(ToplevelDefinition::Type(parent)) = tlds.get(&c.choice_name) {
291 *self = parent.ty.clone();
292 Ok(())
293 } else {
294 Err(grammar_error!(
295 LinkerError,
296 "Could not find Choice {} of selection type.",
297 c.choice_name
298 ))
299 }
300 }
301 ASN1Type::Sequence(s) | ASN1Type::Set(s) => s
302 .members
303 .iter_mut()
304 .try_for_each(|m| m.ty.link_choice_selection_type(tlds)),
305 ASN1Type::Choice(c) => c
306 .options
307 .iter_mut()
308 .try_for_each(|o: &mut ChoiceOption| o.ty.link_choice_selection_type(tlds)),
309 ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => {
310 s.element_type.link_choice_selection_type(tlds)
311 }
312 _ => Ok(()),
313 }
314 }
315
316 pub fn contains_components_of_notation(&self) -> bool {
317 match self {
318 ASN1Type::Choice(c) => c
319 .options
320 .iter()
321 .any(|o| o.ty.contains_components_of_notation()),
322 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
323 !s.components_of.is_empty()
324 || s.members
325 .iter()
326 .any(|m| m.ty.contains_components_of_notation())
327 }
328 ASN1Type::SequenceOf(so) => so.element_type.contains_components_of_notation(),
329 _ => false,
330 }
331 }
332
333 pub fn link_components_of_notation(
334 &mut self,
335 tlds: &BTreeMap<String, ToplevelDefinition>,
336 ) -> bool {
337 match self {
338 ASN1Type::Choice(c) => c
339 .options
340 .iter_mut()
341 .any(|o| o.ty.link_components_of_notation(tlds)),
342 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
343 let mut member_linking = s
344 .members
345 .iter_mut()
346 .any(|m| m.ty.link_components_of_notation(tlds));
347 for comp_link in &s.components_of {
350 if let Some(ToplevelDefinition::Type(linked)) = tlds.get(comp_link) {
351 if let ASN1Type::Sequence(linked_seq) = &linked.ty {
352 linked_seq
353 .members
354 .iter()
355 .enumerate()
356 .for_each(|(index, member)| {
357 if index < linked_seq.extensible.unwrap_or(usize::MAX) {
358 if let Some(index_of_first_ext) = s.extensible {
359 s.extensible = Some(index_of_first_ext + 1)
360 }
361 s.members.push(member.clone());
362 }
363 });
364 member_linking = true;
365 }
366 }
367 }
368 member_linking
369 }
370 ASN1Type::SequenceOf(so) => so.element_type.link_components_of_notation(tlds),
371 _ => false,
372 }
373 }
374
375 pub fn link_constraint_reference(
376 &mut self,
377 name: &String,
378 tlds: &BTreeMap<String, ToplevelDefinition>,
379 ) -> Result<Option<ASN1Type>, GrammarError> {
380 let mut self_replacement = None;
381 match self {
382 ASN1Type::Null => (),
383 ASN1Type::Choice(c) => {
384 for b in c.constraints.iter_mut() {
385 b.link_cross_reference(name, tlds)?;
386 }
387 for opt in c.options.iter_mut() {
388 if let Some(replacement) = opt.ty.link_constraint_reference(name, tlds)? {
389 opt.ty = replacement;
390 }
391 for c in opt.constraints.iter_mut() {
392 c.link_cross_reference(name, tlds)?;
393 }
394 for c in opt.ty.constraints_mut().unwrap_or(&mut vec![]).iter_mut() {
395 c.link_cross_reference(name, tlds)?;
396 }
397 }
398 }
399 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
400 for b in s.constraints.iter_mut() {
401 b.link_cross_reference(name, tlds)?;
402 }
403 for m in s.members.iter_mut() {
404 if let Some(replacement) = m.ty.link_constraint_reference(name, tlds)? {
405 m.ty = replacement;
406 }
407 }
408 }
409 ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => {
410 for b in s.constraints.iter_mut() {
411 b.link_cross_reference(name, tlds)?;
412 }
413 if let Some(replacement) = s.element_type.link_constraint_reference(name, tlds)? {
414 s.element_type = Box::new(replacement);
415 }
416 }
417 ASN1Type::ElsewhereDeclaredType(e) => {
418 if let Some(Constraint::Parameter(args)) = e
419 .constraints()
420 .iter()
421 .find(|c| matches![c, Constraint::Parameter(_)])
422 {
423 self_replacement = Some(Self::resolve_parameters(
424 &e.identifier,
425 e.parent.as_ref(),
426 tlds,
427 args,
428 )?);
429 } else {
430 let id_clone = e.identifier.clone();
431 for c in e.constraints_mut() {
432 c.link_cross_reference(&id_clone, tlds)?;
433 }
434 }
435 }
436 ASN1Type::InformationObjectFieldReference(iofr) => {
437 if let Some(ToplevelDefinition::Information(ToplevelInformationDefinition {
438 value: ASN1Information::ObjectClass(clazz),
439 ..
440 })) = tlds.get(&iofr.class)
441 {
442 if let Some(InformationObjectClassField { ty: Some(ty), .. }) =
443 clazz.get_field(&iofr.field_path)
444 {
445 self_replacement = Some(ty.clone());
446 }
447 }
448 }
449 ty => {
450 if let Some(c) = ty.constraints_mut() {
451 for c in c.iter_mut() {
452 c.link_cross_reference(name, tlds)?;
453 }
454 }
455 }
456 }
457 Ok(self_replacement)
458 }
459
460 pub(crate) fn resolve_parameters(
461 identifier: &String,
462 _parent: Option<&String>,
463 tlds: &BTreeMap<String, ToplevelDefinition>,
464 args: &[Parameter],
465 ) -> Result<ASN1Type, GrammarError> {
466 match tlds.get(identifier) {
467 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
468 ty,
469 parameterization: Some(Parameterization { parameters }),
470 ..
471 })) => {
472 let mut impl_template = ty.clone();
473 let mut impl_tlds = tlds.clone();
474 let mut table_constraint_replacements = BTreeMap::new();
475 for (
476 index,
477 ParameterizationArgument {
478 dummy_reference,
479 param_governor,
480 },
481 ) in parameters.iter().enumerate()
482 {
483 let arg = args.get(index).ok_or_else(|| grammar_error!(LinkerError, "Did not find an argument for parameter {dummy_reference} of {identifier}"))?;
484 match (arg, param_governor) {
485 (Parameter::ValueParameter(v), ParameterGovernor::TypeOrClass(gov)) => {
486 impl_tlds.insert(
487 dummy_reference.clone(),
488 ToplevelDefinition::Value(ToplevelValueDefinition::from((
489 dummy_reference.as_str(),
490 v.clone(),
491 gov.clone(),
492 ))),
493 );
494 }
495 (Parameter::TypeParameter(t), _) => {
496 impl_tlds.insert(
497 dummy_reference.clone(),
498 ToplevelDefinition::Type(ToplevelTypeDefinition::from((
499 dummy_reference.as_str(),
500 t.clone(),
501 ))),
502 );
503 }
504 (Parameter::InformationObjectParameter(_), _) => todo!(),
505 (Parameter::ObjectSetParameter(o), ParameterGovernor::Class(c)) => {
506 match &o.values.first() {
507 Some(osv) if o.values.len() == 1 => {
508 #[allow(suspicious_double_ref_op)]
509 table_constraint_replacements.insert(dummy_reference, osv.clone());
510 }
511 _ => return Err(grammar_error!(LinkerError, "Expected object set value argument to contain single object set value!"))
512 }
513 let mut info = ASN1Information::ObjectSet(o.clone());
514 info.link_object_set_reference(tlds);
515 let mut tld = ToplevelInformationDefinition::from((
516 dummy_reference.as_str(),
517 info,
518 c.as_str(),
519 ));
520 tld = tld.resolve_class_reference(tlds);
521 impl_tlds.insert(
522 dummy_reference.clone(),
523 ToplevelDefinition::Information(tld),
524 );
525 }
526 _ => {
527 return Err(grammar_error!(
528 LinkerError,
529 "Mismatching argument for parameter {dummy_reference} of {identifier}"
530 ))
531 }
532 }
533 }
534 impl_template.link_elsewhere_declared(&impl_tlds)?;
535 if let Some(replacement) =
536 impl_template.link_constraint_reference(identifier, &impl_tlds)?
537 {
538 impl_template = replacement;
539 };
540 impl_template
541 .collect_supertypes(&impl_tlds)
542 .or_else(|_| impl_template.collect_supertypes(tlds))?;
543 for (dummy_reference, osv) in table_constraint_replacements {
544 impl_template.reassign_table_constraint(dummy_reference, osv)?;
545 }
546 Ok(impl_template)
547 }
548 _ => Err(grammar_error!(
549 LinkerError,
550 "Failed to resolve supertype {identifier} of parameterized implementation."
551 )),
552 }
553 }
554
555 pub fn mark_recursive(&mut self, name: &str) -> Result<Vec<Cow<str>>, GrammarError> {
557 match self {
558 ASN1Type::Choice(choice) => {
559 let mut children = Vec::new();
560 for option in &mut choice.options {
561 match &option.ty {
562 ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
563 identifier,
564 ..
565 }) if identifier == name => {
566 option.is_recursive = true;
567 continue;
568 }
569 _ => (),
570 }
571 let opt_ty_name = option.ty.as_str().into_owned();
572 let mut opt_children = option.ty.mark_recursive(&opt_ty_name)?;
573 if opt_children.iter().any(|id: &Cow<'_, str>| id == name) {
574 option.is_recursive = true;
575 } else {
576 children.append(&mut opt_children);
577 }
578 }
579 Ok(children)
580 }
581 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
582 let mut children = Vec::new();
583 for member in &mut s.members {
584 match &member.ty {
585 ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
586 identifier,
587 ..
588 }) if identifier == name => {
589 member.is_recursive = true;
590 continue;
591 }
592 _ => (),
593 }
594 let mem_ty_name = member.ty.as_str().into_owned();
595 let mut mem_children = member.ty.mark_recursive(&mem_ty_name)?;
596 if mem_children.iter().any(|id: &Cow<'_, str>| id == name) {
597 member.is_recursive = true;
598 } else {
599 children.append(&mut mem_children);
600 }
601 }
602 Ok(children)
603 }
604 ASN1Type::SequenceOf(_) | ASN1Type::SetOf(_) => Ok(Vec::new()),
606 ASN1Type::ChoiceSelectionType(_) => Err(grammar_error!(
607 LinkerError,
608 "Choice selection types should be resolved by now"
609 )),
610 ASN1Type::InformationObjectFieldReference(_information_object_field_reference) => {
611 Ok(Vec::new())
612 } n => Ok(vec![n.as_str()]),
614 }
615 }
616
617 fn reassign_table_constraint(
637 &mut self,
638 reference_id_before: &str,
639 replacement: &ObjectSetValue,
640 ) -> Result<(), GrammarError> {
641 match self {
642 ASN1Type::Sequence(s) | ASN1Type::Set(s) => {
643 for m in &mut s.members {
644 if let Some(constraints) = m.ty.constraints_mut() {
645 for c in constraints {
646 if let Constraint::TableConstraint(TableConstraint {
647 object_set: ObjectSet { values, .. },
648 ..
649 }) = c
650 {
651 for value in values {
652 match value {
653 ObjectSetValue::Reference(r)
654 if r == reference_id_before =>
655 {
656 *value = replacement.clone();
657 }
658 _ => (),
659 }
660 }
661 }
662 }
663 }
664 }
665 Ok(())
666 }
667 ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => s
668 .element_type
669 .reassign_table_constraint(reference_id_before, replacement),
670 _ => Ok(()),
671 }
672 }
673
674 fn link_elsewhere_declared(
675 &mut self,
676 tlds: &BTreeMap<String, ToplevelDefinition>,
677 ) -> Result<(), GrammarError> {
678 match self {
679 ASN1Type::Choice(c) => c
680 .options
681 .iter_mut()
682 .try_for_each(|o| o.ty.link_elsewhere_declared(tlds)),
683 ASN1Type::Set(s) | ASN1Type::Sequence(s) => s
684 .members
685 .iter_mut()
686 .try_for_each(|o| o.ty.link_elsewhere_declared(tlds)),
687 ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => {
688 s.element_type.link_elsewhere_declared(tlds)
689 }
690 ASN1Type::ElsewhereDeclaredType(e) => {
691 if let Some(ToplevelDefinition::Type(tld)) = tlds.get(&e.identifier) {
692 *self = tld.ty.clone();
693 Ok(())
694 } else {
695 Err(grammar_error!(
696 LinkerError,
697 "Failed to resolve argument {} of parameterized implementation.",
698 e.identifier
699 ))
700 }
701 }
702 ASN1Type::InformationObjectFieldReference(iofr) => {
703 if let Some(ToplevelDefinition::Information(ToplevelInformationDefinition {
704 value: ASN1Information::ObjectClass(c),
705 ..
706 })) = tlds.get(&iofr.class)
707 {
708 if let Some(field) = c.get_field(&iofr.field_path) {
709 if let Some(ref ty) = field.ty {
710 *self = ty.clone();
711 }
712 return Ok(());
713 }
714 }
715 Err(grammar_error!(
716 LinkerError,
717 "Failed to resolve argument {}.{} of parameterized implementation.",
718 iofr.class,
719 iofr.field_path
720 .iter()
721 .map(|f| f.identifier().clone())
722 .collect::<Vec<_>>()
723 .join(".")
724 ))
725 }
726 ASN1Type::ChoiceSelectionType(_) => Err(grammar_error!(
727 LinkerError,
728 "Linking choice selection type is not yet supported!"
729 )),
730 _ => Ok(()),
731 }
732 }
733
734 pub fn contains_constraint_reference(&self) -> bool {
735 match self {
736 ASN1Type::Null => false,
737 ASN1Type::Boolean(b) => b.constraints.iter().any(|c| c.has_cross_reference()),
738 ASN1Type::ObjectIdentifier(o) => o.constraints.iter().any(|c| c.has_cross_reference()),
739 ASN1Type::Integer(i) => i.constraints.iter().any(|c| c.has_cross_reference()),
740 ASN1Type::BitString(b) => b.constraints.iter().any(|c| c.has_cross_reference()),
741 ASN1Type::OctetString(o) => o.constraints.iter().any(|c| c.has_cross_reference()),
742 ASN1Type::CharacterString(c) => c.constraints.iter().any(|c| c.has_cross_reference()),
743 ASN1Type::Enumerated(e) => e.constraints.iter().any(|c| c.has_cross_reference()),
744 ASN1Type::Choice(c) => {
745 c.constraints.iter().any(|c| c.has_cross_reference())
746 || c.options.iter().any(|o| {
747 o.ty.contains_constraint_reference()
748 || o.constraints.iter().any(|c| c.has_cross_reference())
749 })
750 }
751 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
752 s.constraints.iter().any(|c| c.has_cross_reference())
753 || s.members.iter().any(|m| {
754 m.ty.contains_constraint_reference()
755 || m.default_value
756 .as_ref()
757 .map_or(false, |d| d.is_elsewhere_declared())
758 || m.constraints.iter().any(|c| c.has_cross_reference())
759 })
760 }
761 ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => {
762 s.constraints.iter().any(|c| c.has_cross_reference())
763 || s.element_type.contains_constraint_reference()
764 }
765 ASN1Type::ElsewhereDeclaredType(e) => {
766 e.constraints.iter().any(|c| c.has_cross_reference())
767 }
768 _ => false,
769 }
770 }
771
772 pub fn references_class_by_name(&self) -> bool {
773 match self {
774 ASN1Type::Choice(c) => c.options.iter().any(|o| o.ty.references_class_by_name()),
775 ASN1Type::Sequence(s) => s.members.iter().any(|m| m.ty.references_class_by_name()),
776 ASN1Type::SequenceOf(so) => so.element_type.references_class_by_name(),
777 ASN1Type::InformationObjectFieldReference(io_ref) => {
778 matches!(
779 io_ref.field_path.last(),
780 Some(ObjectFieldIdentifier::SingleValue(_))
781 )
782 }
783 _ => false,
784 }
785 }
786
787 pub fn resolve_class_reference(self, tlds: &BTreeMap<String, ToplevelDefinition>) -> Self {
788 match self {
789 ASN1Type::Choice(c) => ASN1Type::Choice(Choice {
790 extensible: c.extensible,
791 options: c
792 .options
793 .into_iter()
794 .map(|option| ChoiceOption {
795 is_recursive: false,
796 name: option.name,
797 tag: option.tag,
798 ty: option.ty.resolve_class_reference(tlds),
799 constraints: vec![],
800 })
801 .collect(),
802 constraints: c.constraints,
803 }),
804 ASN1Type::Sequence(s) => ASN1Type::Sequence(SequenceOrSet {
805 extensible: s.extensible,
806 constraints: s.constraints,
807 components_of: s.components_of,
808 members: s
809 .members
810 .into_iter()
811 .map(|mut member| {
812 member.constraints = vec![];
813 member.ty = member.ty.resolve_class_reference(tlds);
814 member
815 })
816 .collect(),
817 }),
818 ASN1Type::InformationObjectFieldReference(_) => self.reassign_type_for_ref(tlds),
819 _ => self,
820 }
821 }
822
823 fn reassign_type_for_ref(mut self, tlds: &BTreeMap<String, ToplevelDefinition>) -> Self {
824 if let Self::InformationObjectFieldReference(ref ior) = self {
825 if let Some(t) = tlds
826 .iter()
827 .find_map(|(_, c)| {
828 c.is_class_with_name(&ior.class)
829 .map(|clazz| clazz.get_field(&ior.field_path))
830 })
831 .flatten()
832 .and_then(|class_field| class_field.ty.clone())
833 {
834 self = t;
835 }
836 }
837 self
838 }
839
840 pub fn link_subtype_constraint(
841 &mut self,
842 tlds: &BTreeMap<String, ToplevelDefinition>,
843 ) -> Result<(), GrammarError> {
844 if let Self::ElsewhereDeclaredType(e) = self {
845 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
846 *self = t.ty.clone();
847 }
848 }
849 Ok(())
850 }
851}
852
853impl ASN1Value {
854 pub fn link_with_type(
855 &mut self,
856 tlds: &BTreeMap<String, ToplevelDefinition>,
857 ty: &ASN1Type,
858 type_name: Option<&String>,
859 ) -> Result<(), GrammarError> {
860 #[allow(clippy::useless_asref)] match (ty, self.as_mut()) {
862 (
863 ASN1Type::ElsewhereDeclaredType(e),
864 ASN1Value::LinkedNestedValue { supertypes, value },
865 ) => {
866 supertypes.push(e.identifier.clone());
867 if let ASN1Value::LinkedIntValue { integer_type, .. } = value.borrow_mut() {
868 let int_type = e.constraints.iter().fold(IntegerType::Unbounded, |acc, c| {
869 c.integer_constraints().max_restrictive(acc)
870 });
871 *integer_type = int_type;
872 }
873 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
874 self.link_with_type(tlds, &t.ty, Some(&t.name))
875 } else {
876 Err(grammar_error!(
877 LinkerError,
878 "Failed to link value with '{}'",
879 e.identifier
880 ))
881 }
882 }
883 (
884 ASN1Type::ElsewhereDeclaredType(e),
885 ASN1Value::ElsewhereDeclaredValue { identifier, parent },
886 ) => {
887 if let Some(value) = Self::link_enum_or_distinguished(
888 tlds,
889 e,
890 identifier,
891 vec![e.identifier.clone()],
892 )? {
893 *self = value;
894 return Ok(());
895 } else if let Some((ToplevelDefinition::Type(ty), ToplevelDefinition::Value(val))) =
896 tlds.get(&e.identifier).zip(tlds.get(identifier))
897 {
898 if ty.name != val.associated_type.as_str() {
899 *self = val.clone().value;
912 self.link_with_type(
913 tlds,
914 &ASN1Type::ElsewhereDeclaredType(e.clone()),
915 None,
916 )?;
917 return Ok(());
918 }
919 }
920 *self = ASN1Value::LinkedElsewhereDefinedValue {
921 parent: parent.clone(),
922 identifier: identifier.clone(),
923 can_be_const: e.root(tlds)?.is_const_type(),
924 };
925 Ok(())
926 }
927 (ASN1Type::ElsewhereDeclaredType(e), val) => {
928 *self = ASN1Value::LinkedNestedValue {
929 supertypes: vec![e.identifier.clone()],
930 value: Box::new((*val).clone()),
931 };
932 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
933 self.link_with_type(tlds, &t.ty, Some(&t.name))
934 } else {
935 Err(grammar_error!(
936 LinkerError,
937 "Failed to link value with '{}'",
938 e.identifier
939 ))
940 }
941 }
942 (
943 ASN1Type::Choice(c),
944 ASN1Value::Choice {
945 type_name: tn,
946 variant_name,
947 inner_value,
948 },
949 ) => {
950 if let Some(option) = c.options.iter().find(|o| &o.name == variant_name) {
951 *tn = type_name.cloned();
952 inner_value.link_with_type(
953 tlds,
954 &option.ty,
955 Some(&option.ty.as_str().into_owned()),
956 )
957 } else {
958 Err(grammar_error!(
959 LinkerError,
960 "Failed to link value with '{}'",
961 variant_name
962 ))
963 }
964 }
965 (ASN1Type::Choice(c), ASN1Value::LinkedNestedValue { supertypes, value })
966 if matches![**value, ASN1Value::Choice { .. }] =>
967 {
968 let enum_name = supertypes.pop();
969 if let ASN1Value::Choice {
970 type_name,
971 variant_name,
972 inner_value,
973 } = &mut **value
974 {
975 if let Some(option) = c.options.iter().find(|o| &o.name == variant_name) {
976 *type_name = enum_name;
977 inner_value.link_with_type(
978 tlds,
979 &option.ty,
980 Some(&option.ty.as_str().into_owned()),
981 )
982 } else {
983 Err(grammar_error!(
984 LinkerError,
985 "Failed to link value with '{}'",
986 variant_name
987 ))
988 }
989 } else {
990 Ok(())
991 }
992 }
993 (ASN1Type::Set(s), ASN1Value::SequenceOrSet(val))
994 | (ASN1Type::Sequence(s), ASN1Value::SequenceOrSet(val)) => {
995 *self = Self::link_struct_like(val, s, tlds, type_name)?;
996 Ok(())
997 }
998 (ASN1Type::Set(s), ASN1Value::LinkedNestedValue { value, .. })
999 | (ASN1Type::Sequence(s), ASN1Value::LinkedNestedValue { value, .. })
1000 if matches![**value, ASN1Value::SequenceOrSet(_)] =>
1001 {
1002 if let ASN1Value::SequenceOrSet(val) = &mut **value {
1003 *value = Box::new(Self::link_struct_like(val, s, tlds, type_name)?);
1004 }
1005 Ok(())
1006 }
1007 (ASN1Type::SetOf(s), ASN1Value::SequenceOrSet(val))
1008 | (ASN1Type::SequenceOf(s), ASN1Value::SequenceOrSet(val)) => {
1009 *self = Self::link_array_like(val, s, tlds)?;
1010 Ok(())
1011 }
1012 (ASN1Type::SetOf(s), ASN1Value::LinkedNestedValue { value, .. })
1013 | (ASN1Type::SequenceOf(s), ASN1Value::LinkedNestedValue { value, .. })
1014 if matches![**value, ASN1Value::SequenceOrSet(_)] =>
1015 {
1016 if let ASN1Value::SequenceOrSet(val) = &mut **value {
1017 *value = Box::new(Self::link_array_like(val, s, tlds)?);
1018 }
1019 Ok(())
1020 }
1021 (ASN1Type::Integer(i), ASN1Value::Integer(val)) => {
1022 *self = ASN1Value::LinkedIntValue {
1023 integer_type: i.int_type(),
1024 value: *val,
1025 };
1026 Ok(())
1027 }
1028 (ASN1Type::CharacterString(t), ASN1Value::String(s)) => {
1029 *self = ASN1Value::LinkedCharStringValue(t.ty, s.clone());
1030 Ok(())
1031 }
1032 (ASN1Type::CharacterString(t), ASN1Value::LinkedNestedValue { value, .. })
1033 if matches![**value, ASN1Value::String(_)] =>
1034 {
1035 if let ASN1Value::String(s) = &**value {
1036 *value = Box::new(ASN1Value::LinkedCharStringValue(t.ty, s.clone()));
1037 }
1038 Ok(())
1039 }
1040 (ASN1Type::BitString(_), ASN1Value::OctetString(o)) => {
1041 *self = ASN1Value::BitString(octet_string_to_bit_string(o));
1042 Ok(())
1043 }
1044 (
1045 ASN1Type::BitString(BitString {
1046 distinguished_values: Some(_),
1047 ..
1048 }),
1049 ASN1Value::SequenceOrSet(o),
1050 ) => {
1051 *self = ASN1Value::BitStringNamedBits(
1052 o.iter()
1053 .filter_map(|(_, v)| match &**v {
1054 ASN1Value::ElsewhereDeclaredValue { identifier, .. } => {
1055 Some(identifier.clone())
1056 }
1057 ASN1Value::EnumeratedValue { enumerable, .. } => {
1058 Some(enumerable.clone())
1059 }
1060 _ => None,
1061 })
1062 .collect(),
1063 );
1064 self.link_with_type(tlds, ty, type_name)
1065 }
1066 (
1067 ASN1Type::BitString(BitString {
1068 distinguished_values: Some(_),
1069 ..
1070 }),
1071 ASN1Value::LinkedNestedValue { value, .. },
1072 ) if matches![**value, ASN1Value::SequenceOrSet(_)] => {
1073 if let ASN1Value::SequenceOrSet(o) = &**value {
1074 *value = Box::new(ASN1Value::BitStringNamedBits(
1075 o.iter()
1076 .filter_map(|(_, v)| match &**v {
1077 ASN1Value::ElsewhereDeclaredValue { identifier, .. } => {
1078 Some(identifier.clone())
1079 }
1080 ASN1Value::EnumeratedValue { enumerable, .. } => {
1081 Some(enumerable.clone())
1082 }
1083 _ => None,
1084 })
1085 .collect(),
1086 ));
1087 self.link_with_type(tlds, ty, type_name)?;
1088 }
1089 Ok(())
1090 }
1091 (
1092 ASN1Type::BitString(BitString {
1093 distinguished_values: Some(_),
1094 ..
1095 }),
1096 ASN1Value::ObjectIdentifier(o),
1097 ) => {
1098 *self = ASN1Value::BitStringNamedBits(
1099 o.0.iter().filter_map(|arc| arc.name.clone()).collect(),
1100 );
1101 self.link_with_type(tlds, ty, type_name)
1102 }
1103 (
1104 ASN1Type::BitString(BitString {
1105 distinguished_values: Some(_),
1106 ..
1107 }),
1108 ASN1Value::LinkedNestedValue { value, .. },
1109 ) if matches![**value, ASN1Value::ObjectIdentifier(_)] => {
1110 if let ASN1Value::ObjectIdentifier(o) = &**value {
1111 *value = Box::new(ASN1Value::BitStringNamedBits(
1112 o.0.iter().filter_map(|arc| arc.name.clone()).collect(),
1113 ));
1114 self.link_with_type(tlds, ty, type_name)?;
1115 }
1116 Ok(())
1117 }
1118 (
1119 ASN1Type::BitString(BitString {
1120 distinguished_values: Some(distinguished),
1121 ..
1122 }),
1123 ASN1Value::BitStringNamedBits(o),
1124 ) => {
1125 if let Some(highest_distinguished_bit) = distinguished.iter().map(|d| d.value).max()
1126 {
1127 *self = ASN1Value::BitString(bit_string_value_from_named_bits(
1128 highest_distinguished_bit,
1129 o,
1130 distinguished,
1131 ));
1132 Ok(())
1133 } else {
1134 Err(GrammarError {
1135 details: format!("Failed to resolve BIT STRING value {o:?}"),
1136 kind: GrammarErrorType::LinkerError,
1137 pdu: None,
1138 })
1139 }
1140 }
1141 (
1142 ASN1Type::BitString(BitString {
1143 distinguished_values: Some(distinguished),
1144 ..
1145 }),
1146 ASN1Value::LinkedNestedValue { value, .. },
1147 ) if matches![**value, ASN1Value::BitStringNamedBits(_)] => {
1148 if let (ASN1Value::BitStringNamedBits(o), Some(highest_distinguished_bit)) =
1149 (&**value, distinguished.iter().map(|d| d.value).max())
1150 {
1151 *value = Box::new(ASN1Value::BitString(bit_string_value_from_named_bits(
1152 highest_distinguished_bit,
1153 o,
1154 distinguished,
1155 )));
1156 Ok(())
1157 } else {
1158 Err(GrammarError {
1159 details: format!("Failed to resolve BIT STRING value {value:?}"),
1160 kind: GrammarErrorType::LinkerError,
1161 pdu: None,
1162 })
1163 }
1164 }
1165 (ASN1Type::BitString(_), ASN1Value::LinkedNestedValue { value, .. })
1166 if matches![**value, ASN1Value::OctetString(_)] =>
1167 {
1168 if let ASN1Value::OctetString(o) = &**value {
1169 *value = Box::new(ASN1Value::BitString(octet_string_to_bit_string(o)));
1170 }
1171 Ok(())
1172 }
1173 (ASN1Type::OctetString(_), ASN1Value::BitString(b)) => {
1174 *self = ASN1Value::OctetString(bit_string_to_octet_string(b)?);
1175 Ok(())
1176 }
1177 (ASN1Type::OctetString(_), ASN1Value::LinkedNestedValue { value, .. })
1178 if matches![**value, ASN1Value::BitString(_)] =>
1179 {
1180 if let ASN1Value::BitString(b) = &**value {
1181 *value = Box::new(ASN1Value::OctetString(bit_string_to_octet_string(b)?));
1182 }
1183 Ok(())
1184 }
1185 (ASN1Type::Integer(i), ASN1Value::LinkedIntValue { integer_type, .. }) => {
1186 let int_type = i.int_type().max_restrictive(*integer_type);
1187 *integer_type = int_type;
1188 Ok(())
1189 }
1190 (ASN1Type::Integer(i), ASN1Value::LinkedNestedValue { value, .. })
1191 if matches![**value, ASN1Value::ElsewhereDeclaredValue { .. }] =>
1192 {
1193 if let ASN1Value::ElsewhereDeclaredValue { identifier, .. } = &**value {
1194 if let Some(distinguished_value) =
1195 i.distinguished_values.as_ref().and_then(|dist_vals| {
1196 dist_vals
1197 .iter()
1198 .find_map(|d| (&d.name == identifier).then_some(d.value))
1199 })
1200 {
1201 *value = Box::new(ASN1Value::LinkedIntValue {
1202 integer_type: i.int_type(),
1203 value: distinguished_value,
1204 });
1205 }
1206 }
1207 Ok(())
1208 }
1209 (ASN1Type::Integer(i), ASN1Value::LinkedNestedValue { value, .. })
1210 if matches![**value, ASN1Value::Integer(_)] =>
1211 {
1212 if let ASN1Value::Integer(v) = &**value {
1213 let int_type = i.constraints.iter().fold(IntegerType::Unbounded, |acc, c| {
1214 c.integer_constraints().max_restrictive(acc)
1215 });
1216 *value = Box::new(ASN1Value::LinkedIntValue {
1217 integer_type: int_type,
1218 value: *v,
1219 });
1220 }
1221 Ok(())
1222 }
1223 (ASN1Type::Integer(i), ASN1Value::ElsewhereDeclaredValue { identifier, .. }) => {
1224 if let Some(value) = i.distinguished_values.as_ref().and_then(|dist_vals| {
1225 dist_vals
1226 .iter()
1227 .find_map(|d| (&d.name == identifier).then_some(d.value))
1228 }) {
1229 *self = ASN1Value::LinkedIntValue {
1230 integer_type: i.int_type(),
1231 value,
1232 };
1233 }
1234 Ok(())
1235 }
1236 (ASN1Type::Enumerated(_), ASN1Value::LinkedNestedValue { value, .. })
1237 if matches![**value, ASN1Value::ElsewhereDeclaredValue { .. }] =>
1238 {
1239 if let ASN1Value::ElsewhereDeclaredValue { identifier, .. } = &**value {
1240 if let Some((_, tld)) = tlds
1241 .iter()
1242 .find(|(_, tld)| tld.has_enum_value(None, identifier))
1243 {
1244 *value = Box::new(ASN1Value::EnumeratedValue {
1245 enumerated: tld.name().clone(),
1246 enumerable: identifier.clone(),
1247 });
1248 }
1249 }
1250 Ok(())
1251 }
1252 (ASN1Type::Enumerated(_), ASN1Value::ElsewhereDeclaredValue { identifier, .. }) => {
1253 if let Some((_, tld)) = tlds
1254 .iter()
1255 .find(|(_, tld)| tld.has_enum_value(None, identifier))
1256 {
1257 *self = ASN1Value::EnumeratedValue {
1258 enumerated: tld.name().clone(),
1259 enumerable: identifier.clone(),
1260 };
1261 }
1262 Ok(())
1263 }
1264 (
1265 _,
1266 ASN1Value::ElsewhereDeclaredValue {
1267 parent: None,
1268 identifier,
1269 },
1270 ) => {
1271 if let Some(ToplevelDefinition::Value(tld)) = tlds.get(identifier) {
1272 *self = tld.value.clone();
1273 self.link_with_type(tlds, ty, type_name)?;
1274 }
1275 Ok(())
1276 }
1277 (_, ASN1Value::ElsewhereDeclaredValue { .. }) => Err(GrammarError::todo()),
1278 _ => Ok(()),
1279 }
1280 }
1281
1282 fn link_enum_or_distinguished(
1283 tlds: &BTreeMap<String, ToplevelDefinition>,
1284 e: &DeclarationElsewhere,
1285 identifier: &mut String,
1286 mut supertypes: Vec<String>,
1287 ) -> Result<Option<ASN1Value>, GrammarError> {
1288 match tlds.get(&e.identifier) {
1289 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1290 ty: ASN1Type::Enumerated(enumerated),
1291 ..
1292 })) => {
1293 if enumerated
1294 .members
1295 .iter()
1296 .any(|enumeral| &enumeral.name == identifier)
1297 {
1298 Ok(Some(ASN1Value::EnumeratedValue {
1299 enumerated: e.identifier.clone(),
1300 enumerable: identifier.clone(),
1301 }))
1302 } else {
1303 Ok(None)
1304 }
1305 }
1306 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1307 ty:
1308 ASN1Type::Integer(Integer {
1309 distinguished_values: Some(distinguished),
1310 constraints,
1311 }),
1312 ..
1313 })) => {
1314 if let Some(distinguished_value) =
1315 distinguished.iter().find(|d| &d.name == identifier)
1316 {
1317 Ok(Some(ASN1Value::LinkedNestedValue {
1318 supertypes,
1319 value: Box::new(ASN1Value::LinkedIntValue {
1320 integer_type: constraints
1321 .iter()
1322 .fold(IntegerType::Unbounded, |acc, c| {
1323 c.integer_constraints().max_restrictive(acc)
1324 }),
1325 value: distinguished_value.value,
1326 }),
1327 }))
1328 } else {
1329 Ok(None)
1330 }
1331 }
1332 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1333 ty: ASN1Type::ElsewhereDeclaredType(elsewhere),
1334 ..
1335 })) => {
1336 supertypes.push(elsewhere.identifier.clone());
1337 Self::link_enum_or_distinguished(tlds, elsewhere, identifier, supertypes)
1338 }
1339 _ => Ok(None),
1340 }
1341 }
1342
1343 fn link_array_like(
1344 val: &mut [(Option<String>, Box<ASN1Value>)],
1345 s: &SequenceOrSetOf,
1346 tlds: &BTreeMap<String, ToplevelDefinition>,
1347 ) -> Result<ASN1Value, GrammarError> {
1348 let _ = val.iter_mut().try_for_each(|v| {
1349 v.1.link_with_type(
1350 tlds,
1351 &s.element_type,
1352 Some(&s.element_type.as_str().into_owned()),
1353 )
1354 });
1355 Ok(ASN1Value::LinkedArrayLikeValue(
1356 val.iter().map(|v| v.1.clone()).collect(),
1357 ))
1358 }
1359
1360 fn link_struct_like(
1361 val: &mut [(Option<String>, Box<ASN1Value>)],
1362 s: &SequenceOrSet,
1363 tlds: &BTreeMap<String, ToplevelDefinition>,
1364 type_name: Option<&String>,
1365 ) -> Result<ASN1Value, GrammarError> {
1366 val.iter_mut().try_for_each(|v| {
1367 if let Some(member) = s.members.iter().find(|m| Some(&m.name) == v.0.as_ref()) {
1368 let type_name = match (member.ty.is_builtin_type(), type_name) {
1369 (true, Some(parent)) => Some(
1370 INTERNAL_NESTED_TYPE_NAME_PREFIX.to_owned() + &member.name + "$" + parent,
1371 ),
1372 (false, _) => Some(member.ty.as_str().into_owned()),
1373 _ => {
1374 return Err(grammar_error!(
1375 LinkerError,
1376 "Failed to determine parent name of field {}",
1377 member.name
1378 ))
1379 }
1380 };
1381 v.1.link_with_type(tlds, &member.ty, type_name.as_ref())
1382 } else {
1383 Err(grammar_error!(
1384 LinkerError,
1385 "Failed to link value with '{:?}'",
1386 v.0
1387 ))
1388 }
1389 })?;
1390
1391 s.members
1392 .iter()
1393 .map(|member| {
1394 val.iter()
1395 .find_map(|(name, value)| {
1396 (name.as_ref() == Some(&member.name))
1397 .then_some(StructLikeFieldValue::Explicit(value.clone()))
1398 })
1399 .or(member
1400 .default_value
1401 .as_ref()
1402 .map(|d| StructLikeFieldValue::Implicit(Box::new(d.clone()))))
1403 .ok_or_else(|| {
1404 grammar_error!(LinkerError, "No value for field {} found!", member.name)
1405 })
1406 .map(|field_value| (member.name.clone(), member.ty.clone(), field_value))
1407 })
1408 .collect::<Result<Vec<_>, _>>()
1409 .map(ASN1Value::LinkedStructLikeValue)
1410 }
1411
1412 pub fn is_elsewhere_declared(&self) -> bool {
1413 let is = matches!(
1414 self,
1415 Self::ElsewhereDeclaredValue { .. }
1416 | Self::EnumeratedValue {
1417 enumerated: _,
1418 enumerable: _,
1419 }
1420 );
1421 is
1422 }
1423
1424 pub fn resolve_elsewhere_with_parent(
1439 &mut self,
1440 tlds: &BTreeMap<String, ToplevelDefinition>,
1441 ) -> Result<(), GrammarError> {
1442 if let Self::ElsewhereDeclaredValue {
1443 parent: Some(object_name),
1444 identifier,
1445 } = self
1446 {
1447 if object_name.contains('.') {
1448 return Err(grammar_error!(NotYetInplemented, "Value references of path length > 2 are not yet supported! Found reference {object_name}.{identifier}"));
1449 }
1450 let object = get_declaration![
1451 tlds,
1452 object_name,
1453 Information,
1454 ASN1Information::Object
1455 ]
1456 .ok_or_else(|| grammar_error!(LinkerError, "No information object found for identifier {object_name}, parent of {identifier}"))?;
1457 match &object.fields {
1458 InformationObjectFields::DefaultSyntax(d) => {
1459 match d.iter().find(|elem| elem.identifier() == identifier) {
1460 Some(InformationObjectField::FixedValueField(FixedValueField { value, .. })) => {
1461 *self = value.clone();
1462 return Ok(())
1463 }
1464 _ => return Err(grammar_error!(
1465 LinkerError,
1466 "No matching value field for identifier {identifier} found in object {object_name}"
1467 ))
1468 }
1469 }
1470 InformationObjectFields::CustomSyntax(c) => {
1471 let class_name = &object.class_name;
1472 let class = get_declaration![
1473 tlds,
1474 class_name,
1475 Information,
1476 ASN1Information::ObjectClass
1477 ]
1478 .ok_or_else(|| {
1479 grammar_error!(
1480 LinkerError,
1481 "No information object class found for identifier {class_name}"
1482 )
1483 })?;
1484 let syntax = class.syntax.as_ref().ok_or_else(|| {
1485 grammar_error!(LinkerError, "No syntax info found for class {class_name}")
1486 })?;
1487 let tokens = syntax.flatten();
1488 let (mut before, mut after) = (None, None);
1489 'iter_syntax: for i in 0..tokens.len() {
1490 let expr = tokens.get(i);
1491 match expr {
1492 Some((
1493 _,
1494 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(id)),
1495 )) if id == identifier => {
1496 before = tokens.get(i - 1).map(|(_, token)| token);
1497 after = tokens.get(i + 1).map(|(_, token)| token);
1498 break 'iter_syntax;
1499 }
1500 _ => {}
1501 };
1502 }
1503 for i in 0..c.len() {
1504 if let Some(SyntaxApplication::ValueReference(val)) = c.get(i) {
1505 match (c.get(i - 1), before, c.get(i + 1), after) {
1506 (Some(a), Some(b), _, _) if a.matches(b, &tokens, i) => {
1507 *self = val.clone();
1508 return Ok(());
1509 }
1510 (_, _, Some(c), Some(d)) if c.matches(d, &tokens, i) => {
1511 *self = val.clone();
1512 return Ok(());
1513 }
1514 _ => {}
1515 };
1516 }
1517 }
1518 return Err(grammar_error!(
1519 LinkerError,
1520 "Failed to match expression to syntax of class {class_name}"
1521 ));
1522 }
1523 }
1524 }
1525 Ok(())
1526 }
1527
1528 pub fn link_elsewhere_declared(
1529 &mut self,
1530 identifier: &String,
1531 tlds: &BTreeMap<String, ToplevelDefinition>,
1532 ) -> Result<(), GrammarError> {
1533 match self {
1534 Self::ElsewhereDeclaredValue {
1535 parent: Some(_), ..
1536 } => {
1537 return self.resolve_elsewhere_with_parent(tlds);
1538 }
1539 Self::ElsewhereDeclaredValue {
1540 identifier: e,
1541 parent: _,
1542 }
1543 | Self::EnumeratedValue {
1544 enumerated: _,
1545 enumerable: e,
1546 } => {
1547 if let Some(v) = find_tld_or_enum_value_by_name(identifier, e, tlds) {
1548 *self = v;
1549 }
1550 }
1551 _ => {}
1552 }
1553 Ok(())
1554 }
1555}
1556
1557fn bit_string_value_from_named_bits(
1558 highest_distinguished_bit: i128,
1559 named_bits: &[String],
1560 distinguished: &[DistinguishedValue],
1561) -> Vec<bool> {
1562 (0..=highest_distinguished_bit)
1563 .map(|i| {
1564 named_bits.iter().any(|bit| {
1565 Some(bit)
1566 == distinguished
1567 .iter()
1568 .find_map(|d| (d.value == i).then_some(&d.name))
1569 })
1570 })
1571 .collect()
1572}
1573
1574#[cfg(test)]
1575mod tests {
1576 use std::collections::BTreeMap;
1577
1578 use crate::intermediate::{types::*, *};
1579
1580 macro_rules! tld {
1581 ($name:literal, $ty:expr) => {
1582 ToplevelTypeDefinition {
1583 comments: String::new(),
1584 tag: None,
1585 index: None,
1586 name: $name.into(),
1587 ty: $ty,
1588 parameterization: None,
1589 }
1590 };
1591 }
1592
1593 #[test]
1594 fn links_asn1_value() {
1595 let tlds: BTreeMap<String, ToplevelDefinition> = {
1596 let mut map = BTreeMap::new();
1597 map.insert(
1598 "RootBool".into(),
1599 ToplevelDefinition::Type(tld!(
1600 "RootBool",
1601 ASN1Type::Boolean(Boolean {
1602 constraints: vec![]
1603 })
1604 )),
1605 );
1606 map.insert(
1607 "IntermediateBool".into(),
1608 ToplevelDefinition::Type(tld!(
1609 "IntermediateBool",
1610 ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1611 parent: None,
1612 identifier: String::from("RootBool"),
1613 constraints: vec![]
1614 })
1615 )),
1616 );
1617 map.insert(
1618 "BaseChoice".into(),
1619 ToplevelDefinition::Type(tld!(
1620 "BaseChoice",
1621 ASN1Type::Choice(Choice {
1622 extensible: None,
1623 constraints: vec![],
1624 options: vec![ChoiceOption {
1625 is_recursive: false,
1626 name: String::from("first"),
1627 constraints: vec![],
1628 tag: None,
1629 ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1630 parent: None,
1631 identifier: String::from("IntermediateBool"),
1632 constraints: vec![]
1633 })
1634 }]
1635 })
1636 )),
1637 );
1638 map
1639 };
1640 let mut example_value = ToplevelValueDefinition {
1641 comments: String::new(),
1642 name: "exampleValue".into(),
1643 parameterization: None,
1644 associated_type: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1645 parent: None,
1646 identifier: "BaseChoice".into(),
1647 constraints: vec![],
1648 }),
1649 index: None,
1650 value: ASN1Value::Choice {
1651 type_name: None,
1652 variant_name: "first".into(),
1653 inner_value: Box::new(ASN1Value::Boolean(true)),
1654 },
1655 };
1656 example_value.collect_supertypes(&tlds).unwrap();
1657 assert_eq!(
1658 example_value,
1659 ToplevelValueDefinition {
1660 comments: "".into(),
1661 name: "exampleValue".into(),
1662 associated_type: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1663 parent: None,
1664 identifier: "BaseChoice".into(),
1665 constraints: vec![]
1666 }),
1667 parameterization: None,
1668 value: ASN1Value::Choice {
1669 type_name: Some("BaseChoice".into()),
1670 variant_name: "first".into(),
1671 inner_value: Box::new(ASN1Value::LinkedNestedValue {
1672 supertypes: vec!["IntermediateBool".into(), "RootBool".into()],
1673 value: Box::new(ASN1Value::Boolean(true))
1674 })
1675 },
1676 index: None
1677 }
1678 )
1679 }
1680}