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