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|
578 !opt.is_recursive && opt.ty.recurses(name, tlds)),
582 ASN1Type::Sequence(s) | ASN1Type::Set(s) => s.members.iter().any(|m|
583 !m.is_recursive && m.ty.recurses(name, tlds)),
587 _ => false,
588 }
589 }
590
591 pub fn mark_recursive(
593 &mut self,
594 name: &str,
595 tlds: &BTreeMap<String, ToplevelDefinition>,
596 ) -> Result<Vec<Cow<str>>, GrammarError> {
597 match self {
598 ASN1Type::Choice(choice) => {
599 let mut children = Vec::new();
600 for option in &mut choice.options {
601 option.is_recursive = option.ty.recurses(name, tlds);
602 let opt_ty_name = option.ty.as_str().into_owned();
603 let mut opt_children = option.ty.mark_recursive(&opt_ty_name, tlds)?;
604 if opt_children.iter().any(|id: &Cow<'_, str>| id == name) {
605 option.is_recursive = true;
606 } else {
607 children.append(&mut opt_children);
608 }
609 }
610 Ok(children)
611 }
612 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
613 let mut children = Vec::new();
614 for member in &mut s.members {
615 member.is_recursive = member.ty.recurses(name, tlds);
616 let mem_ty_name = member.ty.as_str().into_owned();
617 let mut mem_children = member.ty.mark_recursive(&mem_ty_name, tlds)?;
618 if mem_children.iter().any(|id: &Cow<'_, str>| id == name) {
619 member.is_recursive = true;
620 } else {
621 children.append(&mut mem_children);
622 }
623 }
624 Ok(children)
625 }
626 ASN1Type::SequenceOf(_) | ASN1Type::SetOf(_) => Ok(Vec::new()),
628 ASN1Type::ChoiceSelectionType(_) => Err(grammar_error!(
629 LinkerError,
630 "Choice selection types should be resolved by now"
631 )),
632 ASN1Type::InformationObjectFieldReference(_information_object_field_reference) => {
633 Ok(Vec::new())
634 } n => Ok(vec![n.as_str()]),
636 }
637 }
638
639 fn reassign_table_constraint(
659 &mut self,
660 reference_id_before: &str,
661 replacement: &ObjectSetValue,
662 ) -> Result<(), GrammarError> {
663 match self {
664 ASN1Type::Sequence(s) | ASN1Type::Set(s) => {
665 for m in &mut s.members {
666 if let Some(constraints) = m.ty.constraints_mut() {
667 for c in constraints {
668 if let Constraint::TableConstraint(TableConstraint {
669 object_set: ObjectSet { values, .. },
670 ..
671 }) = c
672 {
673 for value in values {
674 match value {
675 ObjectSetValue::Reference(r)
676 if r == reference_id_before =>
677 {
678 *value = replacement.clone();
679 }
680 _ => (),
681 }
682 }
683 }
684 }
685 }
686 }
687 Ok(())
688 }
689 ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => s
690 .element_type
691 .reassign_table_constraint(reference_id_before, replacement),
692 _ => Ok(()),
693 }
694 }
695
696 fn link_elsewhere_declared(
697 &mut self,
698 tlds: &BTreeMap<String, ToplevelDefinition>,
699 ) -> Result<(), GrammarError> {
700 match self {
701 ASN1Type::Choice(c) => c
702 .options
703 .iter_mut()
704 .try_for_each(|o| o.ty.link_elsewhere_declared(tlds)),
705 ASN1Type::Set(s) | ASN1Type::Sequence(s) => s
706 .members
707 .iter_mut()
708 .try_for_each(|o| o.ty.link_elsewhere_declared(tlds)),
709 ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => {
710 s.element_type.link_elsewhere_declared(tlds)
711 }
712 ASN1Type::ElsewhereDeclaredType(e) => {
713 if let Some(ToplevelDefinition::Type(tld)) = tlds.get(&e.identifier) {
714 *self = tld.ty.clone();
715 Ok(())
716 } else {
717 Err(grammar_error!(
718 LinkerError,
719 "Failed to resolve argument {} of parameterized implementation.",
720 e.identifier
721 ))
722 }
723 }
724 ASN1Type::InformationObjectFieldReference(iofr) => {
725 if let Some(ToplevelDefinition::Information(ToplevelInformationDefinition {
726 value: ASN1Information::ObjectClass(c),
727 ..
728 })) = tlds.get(&iofr.class)
729 {
730 if let Some(field) = c.get_field(&iofr.field_path) {
731 if let Some(ref ty) = field.ty {
732 *self = ty.clone();
733 }
734 return Ok(());
735 }
736 }
737 Err(grammar_error!(
738 LinkerError,
739 "Failed to resolve argument {}.{} of parameterized implementation.",
740 iofr.class,
741 iofr.field_path
742 .iter()
743 .map(|f| f.identifier().clone())
744 .collect::<Vec<_>>()
745 .join(".")
746 ))
747 }
748 ASN1Type::ChoiceSelectionType(_) => Err(grammar_error!(
749 LinkerError,
750 "Linking choice selection type is not yet supported!"
751 )),
752 _ => Ok(()),
753 }
754 }
755
756 pub fn contains_constraint_reference(&self) -> bool {
757 match self {
758 ASN1Type::Null => false,
759 ASN1Type::Boolean(b) => b.constraints.iter().any(|c| c.has_cross_reference()),
760 ASN1Type::ObjectIdentifier(o) => o.constraints.iter().any(|c| c.has_cross_reference()),
761 ASN1Type::Integer(i) => i.constraints.iter().any(|c| c.has_cross_reference()),
762 ASN1Type::BitString(b) => b.constraints.iter().any(|c| c.has_cross_reference()),
763 ASN1Type::OctetString(o) => o.constraints.iter().any(|c| c.has_cross_reference()),
764 ASN1Type::CharacterString(c) => c.constraints.iter().any(|c| c.has_cross_reference()),
765 ASN1Type::Enumerated(e) => e.constraints.iter().any(|c| c.has_cross_reference()),
766 ASN1Type::Choice(c) => {
767 c.constraints.iter().any(|c| c.has_cross_reference())
768 || c.options.iter().any(|o| {
769 o.ty.contains_constraint_reference()
770 || o.constraints.iter().any(|c| c.has_cross_reference())
771 })
772 }
773 ASN1Type::Set(s) | ASN1Type::Sequence(s) => {
774 s.constraints.iter().any(|c| c.has_cross_reference())
775 || s.members.iter().any(|m| {
776 m.ty.contains_constraint_reference()
777 || m.default_value
778 .as_ref()
779 .map_or(false, |d| d.is_elsewhere_declared())
780 || m.constraints.iter().any(|c| c.has_cross_reference())
781 })
782 }
783 ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => {
784 s.constraints.iter().any(|c| c.has_cross_reference())
785 || s.element_type.contains_constraint_reference()
786 }
787 ASN1Type::ElsewhereDeclaredType(e) => {
788 e.constraints.iter().any(|c| c.has_cross_reference())
789 }
790 _ => false,
791 }
792 }
793
794 pub fn references_class_by_name(&self) -> bool {
795 match self {
796 ASN1Type::Choice(c) => c.options.iter().any(|o| o.ty.references_class_by_name()),
797 ASN1Type::Sequence(s) => s.members.iter().any(|m| m.ty.references_class_by_name()),
798 ASN1Type::SequenceOf(so) => so.element_type.references_class_by_name(),
799 ASN1Type::InformationObjectFieldReference(io_ref) => {
800 matches!(
801 io_ref.field_path.last(),
802 Some(ObjectFieldIdentifier::SingleValue(_))
803 )
804 }
805 _ => false,
806 }
807 }
808
809 pub fn resolve_class_reference(self, tlds: &BTreeMap<String, ToplevelDefinition>) -> Self {
810 match self {
811 ASN1Type::Choice(c) => ASN1Type::Choice(Choice {
812 extensible: c.extensible,
813 options: c
814 .options
815 .into_iter()
816 .map(|option| ChoiceOption {
817 is_recursive: false,
818 name: option.name,
819 tag: option.tag,
820 ty: option.ty.resolve_class_reference(tlds),
821 constraints: vec![],
822 })
823 .collect(),
824 constraints: c.constraints,
825 }),
826 ASN1Type::Sequence(s) => ASN1Type::Sequence(SequenceOrSet {
827 extensible: s.extensible,
828 constraints: s.constraints,
829 components_of: s.components_of,
830 members: s
831 .members
832 .into_iter()
833 .map(|mut member| {
834 member.constraints = vec![];
835 member.ty = member.ty.resolve_class_reference(tlds);
836 member
837 })
838 .collect(),
839 }),
840 ASN1Type::InformationObjectFieldReference(_) => self.reassign_type_for_ref(tlds),
841 _ => self,
842 }
843 }
844
845 fn reassign_type_for_ref(mut self, tlds: &BTreeMap<String, ToplevelDefinition>) -> Self {
846 if let Self::InformationObjectFieldReference(ref ior) = self {
847 if let Some(t) = tlds
848 .iter()
849 .find_map(|(_, c)| {
850 c.is_class_with_name(&ior.class)
851 .map(|clazz| clazz.get_field(&ior.field_path))
852 })
853 .flatten()
854 .and_then(|class_field| class_field.ty.clone())
855 {
856 self = t;
857 }
858 }
859 self
860 }
861
862 pub fn link_subtype_constraint(
863 &mut self,
864 tlds: &BTreeMap<String, ToplevelDefinition>,
865 ) -> Result<(), GrammarError> {
866 if let Self::ElsewhereDeclaredType(e) = self {
867 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
868 *self = t.ty.clone();
869 }
870 }
871 Ok(())
872 }
873}
874
875impl ASN1Value {
876 pub fn link_with_type(
877 &mut self,
878 tlds: &BTreeMap<String, ToplevelDefinition>,
879 ty: &ASN1Type,
880 type_name: Option<&String>,
881 ) -> Result<(), GrammarError> {
882 #[allow(clippy::useless_asref)] match (ty, self.as_mut()) {
884 (
885 ASN1Type::ElsewhereDeclaredType(e),
886 ASN1Value::LinkedNestedValue { supertypes, value },
887 ) => {
888 supertypes.push(e.identifier.clone());
889 if let ASN1Value::LinkedIntValue { integer_type, .. } = value.borrow_mut() {
890 let int_type = e.constraints.iter().fold(IntegerType::Unbounded, |acc, c| {
891 c.integer_constraints().max_restrictive(acc)
892 });
893 *integer_type = int_type;
894 }
895 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
896 self.link_with_type(tlds, &t.ty, Some(&t.name))
897 } else {
898 Err(grammar_error!(
899 LinkerError,
900 "Failed to link value with '{}'",
901 e.identifier
902 ))
903 }
904 }
905 (
906 ASN1Type::ElsewhereDeclaredType(e),
907 ASN1Value::ElsewhereDeclaredValue { identifier, parent },
908 ) => {
909 if let Some(value) = Self::link_enum_or_distinguished(
910 tlds,
911 e,
912 identifier,
913 vec![e.identifier.clone()],
914 )? {
915 *self = value;
916 return Ok(());
917 } else if let Some((ToplevelDefinition::Type(ty), ToplevelDefinition::Value(val))) =
918 tlds.get(&e.identifier).zip(tlds.get(identifier))
919 {
920 if ty.name != val.associated_type.as_str() {
921 *self = val.clone().value;
934 self.link_with_type(
935 tlds,
936 &ASN1Type::ElsewhereDeclaredType(e.clone()),
937 None,
938 )?;
939 return Ok(());
940 }
941 }
942 *self = ASN1Value::LinkedElsewhereDefinedValue {
943 parent: parent.clone(),
944 identifier: identifier.clone(),
945 can_be_const: e.root(tlds)?.is_const_type(),
946 };
947 Ok(())
948 }
949 (ASN1Type::ElsewhereDeclaredType(e), val) => {
950 *self = ASN1Value::LinkedNestedValue {
951 supertypes: vec![e.identifier.clone()],
952 value: Box::new((*val).clone()),
953 };
954 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
955 self.link_with_type(tlds, &t.ty, Some(&t.name))
956 } else {
957 Err(grammar_error!(
958 LinkerError,
959 "Failed to link value with '{}'",
960 e.identifier
961 ))
962 }
963 }
964 (
965 ASN1Type::Choice(c),
966 ASN1Value::Choice {
967 type_name: tn,
968 variant_name,
969 inner_value,
970 },
971 ) => {
972 if let Some(option) = c.options.iter().find(|o| &o.name == variant_name) {
973 *tn = type_name.cloned();
974 inner_value.link_with_type(
975 tlds,
976 &option.ty,
977 Some(&option.ty.as_str().into_owned()),
978 )
979 } else {
980 Err(grammar_error!(
981 LinkerError,
982 "Failed to link value with '{}'",
983 variant_name
984 ))
985 }
986 }
987 (ASN1Type::Choice(c), ASN1Value::LinkedNestedValue { supertypes, value })
988 if matches![**value, ASN1Value::Choice { .. }] =>
989 {
990 let enum_name = supertypes.pop();
991 if let ASN1Value::Choice {
992 type_name,
993 variant_name,
994 inner_value,
995 } = &mut **value
996 {
997 if let Some(option) = c.options.iter().find(|o| &o.name == variant_name) {
998 *type_name = enum_name;
999 inner_value.link_with_type(
1000 tlds,
1001 &option.ty,
1002 Some(&option.ty.as_str().into_owned()),
1003 )
1004 } else {
1005 Err(grammar_error!(
1006 LinkerError,
1007 "Failed to link value with '{}'",
1008 variant_name
1009 ))
1010 }
1011 } else {
1012 Ok(())
1013 }
1014 }
1015 (ASN1Type::Set(s), ASN1Value::SequenceOrSet(val))
1016 | (ASN1Type::Sequence(s), ASN1Value::SequenceOrSet(val)) => {
1017 *self = Self::link_struct_like(val, s, tlds, type_name)?;
1018 Ok(())
1019 }
1020 (ASN1Type::Set(s), ASN1Value::LinkedNestedValue { value, .. })
1021 | (ASN1Type::Sequence(s), ASN1Value::LinkedNestedValue { value, .. })
1022 if matches![**value, ASN1Value::SequenceOrSet(_)] =>
1023 {
1024 if let ASN1Value::SequenceOrSet(val) = &mut **value {
1025 *value = Box::new(Self::link_struct_like(val, s, tlds, type_name)?);
1026 }
1027 Ok(())
1028 }
1029 (ASN1Type::SetOf(s), ASN1Value::SequenceOrSet(val))
1030 | (ASN1Type::SequenceOf(s), ASN1Value::SequenceOrSet(val)) => {
1031 *self = Self::link_array_like(val, s, tlds)?;
1032 Ok(())
1033 }
1034 (ASN1Type::SetOf(s), ASN1Value::LinkedNestedValue { value, .. })
1035 | (ASN1Type::SequenceOf(s), ASN1Value::LinkedNestedValue { value, .. })
1036 if matches![**value, ASN1Value::SequenceOrSet(_)] =>
1037 {
1038 if let ASN1Value::SequenceOrSet(val) = &mut **value {
1039 *value = Box::new(Self::link_array_like(val, s, tlds)?);
1040 }
1041 Ok(())
1042 }
1043 (ASN1Type::Integer(i), ASN1Value::Integer(val)) => {
1044 *self = ASN1Value::LinkedIntValue {
1045 integer_type: i.int_type(),
1046 value: *val,
1047 };
1048 Ok(())
1049 }
1050 (ASN1Type::CharacterString(t), ASN1Value::String(s)) => {
1051 *self = ASN1Value::LinkedCharStringValue(t.ty, s.clone());
1052 Ok(())
1053 }
1054 (ASN1Type::CharacterString(t), ASN1Value::LinkedNestedValue { value, .. })
1055 if matches![**value, ASN1Value::String(_)] =>
1056 {
1057 if let ASN1Value::String(s) = &**value {
1058 *value = Box::new(ASN1Value::LinkedCharStringValue(t.ty, s.clone()));
1059 }
1060 Ok(())
1061 }
1062 (ASN1Type::BitString(_), ASN1Value::OctetString(o)) => {
1063 *self = ASN1Value::BitString(octet_string_to_bit_string(o));
1064 Ok(())
1065 }
1066 (
1067 ASN1Type::BitString(BitString {
1068 distinguished_values: Some(_),
1069 ..
1070 }),
1071 ASN1Value::SequenceOrSet(o),
1072 ) => {
1073 *self = ASN1Value::BitStringNamedBits(
1074 o.iter()
1075 .filter_map(|(_, v)| match &**v {
1076 ASN1Value::ElsewhereDeclaredValue { identifier, .. } => {
1077 Some(identifier.clone())
1078 }
1079 ASN1Value::EnumeratedValue { enumerable, .. } => {
1080 Some(enumerable.clone())
1081 }
1082 _ => None,
1083 })
1084 .collect(),
1085 );
1086 self.link_with_type(tlds, ty, type_name)
1087 }
1088 (
1089 ASN1Type::BitString(BitString {
1090 distinguished_values: Some(_),
1091 ..
1092 }),
1093 ASN1Value::LinkedNestedValue { value, .. },
1094 ) if matches![**value, ASN1Value::SequenceOrSet(_)] => {
1095 if let ASN1Value::SequenceOrSet(o) = &**value {
1096 *value = Box::new(ASN1Value::BitStringNamedBits(
1097 o.iter()
1098 .filter_map(|(_, v)| match &**v {
1099 ASN1Value::ElsewhereDeclaredValue { identifier, .. } => {
1100 Some(identifier.clone())
1101 }
1102 ASN1Value::EnumeratedValue { enumerable, .. } => {
1103 Some(enumerable.clone())
1104 }
1105 _ => None,
1106 })
1107 .collect(),
1108 ));
1109 self.link_with_type(tlds, ty, type_name)?;
1110 }
1111 Ok(())
1112 }
1113 (
1114 ASN1Type::BitString(BitString {
1115 distinguished_values: Some(_),
1116 ..
1117 }),
1118 ASN1Value::ObjectIdentifier(o),
1119 ) => {
1120 *self = ASN1Value::BitStringNamedBits(
1121 o.0.iter().filter_map(|arc| arc.name.clone()).collect(),
1122 );
1123 self.link_with_type(tlds, ty, type_name)
1124 }
1125 (
1126 ASN1Type::BitString(BitString {
1127 distinguished_values: Some(_),
1128 ..
1129 }),
1130 ASN1Value::LinkedNestedValue { value, .. },
1131 ) if matches![**value, ASN1Value::ObjectIdentifier(_)] => {
1132 if let ASN1Value::ObjectIdentifier(o) = &**value {
1133 *value = Box::new(ASN1Value::BitStringNamedBits(
1134 o.0.iter().filter_map(|arc| arc.name.clone()).collect(),
1135 ));
1136 self.link_with_type(tlds, ty, type_name)?;
1137 }
1138 Ok(())
1139 }
1140 (
1141 ASN1Type::BitString(BitString {
1142 distinguished_values: Some(distinguished),
1143 ..
1144 }),
1145 ASN1Value::BitStringNamedBits(o),
1146 ) => {
1147 if let Some(highest_distinguished_bit) = distinguished.iter().map(|d| d.value).max()
1148 {
1149 *self = ASN1Value::BitString(bit_string_value_from_named_bits(
1150 highest_distinguished_bit,
1151 o,
1152 distinguished,
1153 ));
1154 Ok(())
1155 } else {
1156 Err(GrammarError {
1157 details: format!("Failed to resolve BIT STRING value {o:?}"),
1158 kind: GrammarErrorType::LinkerError,
1159 pdu: None,
1160 })
1161 }
1162 }
1163 (
1164 ASN1Type::BitString(BitString {
1165 distinguished_values: Some(distinguished),
1166 ..
1167 }),
1168 ASN1Value::LinkedNestedValue { value, .. },
1169 ) if matches![**value, ASN1Value::BitStringNamedBits(_)] => {
1170 if let (ASN1Value::BitStringNamedBits(o), Some(highest_distinguished_bit)) =
1171 (&**value, distinguished.iter().map(|d| d.value).max())
1172 {
1173 *value = Box::new(ASN1Value::BitString(bit_string_value_from_named_bits(
1174 highest_distinguished_bit,
1175 o,
1176 distinguished,
1177 )));
1178 Ok(())
1179 } else {
1180 Err(GrammarError {
1181 details: format!("Failed to resolve BIT STRING value {value:?}"),
1182 kind: GrammarErrorType::LinkerError,
1183 pdu: None,
1184 })
1185 }
1186 }
1187 (ASN1Type::BitString(_), ASN1Value::LinkedNestedValue { value, .. })
1188 if matches![**value, ASN1Value::OctetString(_)] =>
1189 {
1190 if let ASN1Value::OctetString(o) = &**value {
1191 *value = Box::new(ASN1Value::BitString(octet_string_to_bit_string(o)));
1192 }
1193 Ok(())
1194 }
1195 (ASN1Type::OctetString(_), ASN1Value::BitString(b)) => {
1196 *self = ASN1Value::OctetString(bit_string_to_octet_string(b)?);
1197 Ok(())
1198 }
1199 (ASN1Type::OctetString(_), ASN1Value::LinkedNestedValue { value, .. })
1200 if matches![**value, ASN1Value::BitString(_)] =>
1201 {
1202 if let ASN1Value::BitString(b) = &**value {
1203 *value = Box::new(ASN1Value::OctetString(bit_string_to_octet_string(b)?));
1204 }
1205 Ok(())
1206 }
1207 (ASN1Type::Integer(i), ASN1Value::LinkedIntValue { integer_type, .. }) => {
1208 let int_type = i.int_type().max_restrictive(*integer_type);
1209 *integer_type = int_type;
1210 Ok(())
1211 }
1212 (ASN1Type::Integer(i), ASN1Value::LinkedNestedValue { value, .. })
1213 if matches![**value, ASN1Value::ElsewhereDeclaredValue { .. }] =>
1214 {
1215 if let ASN1Value::ElsewhereDeclaredValue { identifier, .. } = &**value {
1216 if let Some(distinguished_value) =
1217 i.distinguished_values.as_ref().and_then(|dist_vals| {
1218 dist_vals
1219 .iter()
1220 .find_map(|d| (&d.name == identifier).then_some(d.value))
1221 })
1222 {
1223 *value = Box::new(ASN1Value::LinkedIntValue {
1224 integer_type: i.int_type(),
1225 value: distinguished_value,
1226 });
1227 }
1228 }
1229 Ok(())
1230 }
1231 (ASN1Type::Integer(i), ASN1Value::LinkedNestedValue { value, .. })
1232 if matches![**value, ASN1Value::Integer(_)] =>
1233 {
1234 if let ASN1Value::Integer(v) = &**value {
1235 let int_type = i.constraints.iter().fold(IntegerType::Unbounded, |acc, c| {
1236 c.integer_constraints().max_restrictive(acc)
1237 });
1238 *value = Box::new(ASN1Value::LinkedIntValue {
1239 integer_type: int_type,
1240 value: *v,
1241 });
1242 }
1243 Ok(())
1244 }
1245 (ASN1Type::Integer(i), ASN1Value::ElsewhereDeclaredValue { identifier, .. }) => {
1246 if let Some(value) = i.distinguished_values.as_ref().and_then(|dist_vals| {
1247 dist_vals
1248 .iter()
1249 .find_map(|d| (&d.name == identifier).then_some(d.value))
1250 }) {
1251 *self = ASN1Value::LinkedIntValue {
1252 integer_type: i.int_type(),
1253 value,
1254 };
1255 }
1256 Ok(())
1257 }
1258 (ASN1Type::Enumerated(_), ASN1Value::LinkedNestedValue { value, .. })
1259 if matches![**value, ASN1Value::ElsewhereDeclaredValue { .. }] =>
1260 {
1261 if let ASN1Value::ElsewhereDeclaredValue { identifier, .. } = &**value {
1262 if let Some((_, tld)) = tlds
1263 .iter()
1264 .find(|(_, tld)| tld.has_enum_value(None, identifier))
1265 {
1266 *value = Box::new(ASN1Value::EnumeratedValue {
1267 enumerated: tld.name().clone(),
1268 enumerable: identifier.clone(),
1269 });
1270 }
1271 }
1272 Ok(())
1273 }
1274 (ASN1Type::Enumerated(_), ASN1Value::ElsewhereDeclaredValue { identifier, .. }) => {
1275 if let Some((_, tld)) = tlds
1276 .iter()
1277 .find(|(_, tld)| tld.has_enum_value(None, identifier))
1278 {
1279 *self = ASN1Value::EnumeratedValue {
1280 enumerated: tld.name().clone(),
1281 enumerable: identifier.clone(),
1282 };
1283 }
1284 Ok(())
1285 }
1286 (
1287 _,
1288 ASN1Value::ElsewhereDeclaredValue {
1289 parent: None,
1290 identifier,
1291 },
1292 ) => {
1293 if let Some(ToplevelDefinition::Value(tld)) = tlds.get(identifier) {
1294 *self = tld.value.clone();
1295 self.link_with_type(tlds, ty, type_name)?;
1296 }
1297 Ok(())
1298 }
1299 (_, ASN1Value::ElsewhereDeclaredValue { .. }) => Err(GrammarError::todo()),
1300 _ => Ok(()),
1301 }
1302 }
1303
1304 fn link_enum_or_distinguished(
1305 tlds: &BTreeMap<String, ToplevelDefinition>,
1306 e: &DeclarationElsewhere,
1307 identifier: &mut String,
1308 mut supertypes: Vec<String>,
1309 ) -> Result<Option<ASN1Value>, GrammarError> {
1310 match tlds.get(&e.identifier) {
1311 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1312 ty: ASN1Type::Enumerated(enumerated),
1313 ..
1314 })) => {
1315 if enumerated
1316 .members
1317 .iter()
1318 .any(|enumeral| &enumeral.name == identifier)
1319 {
1320 Ok(Some(ASN1Value::EnumeratedValue {
1321 enumerated: e.identifier.clone(),
1322 enumerable: identifier.clone(),
1323 }))
1324 } else {
1325 Ok(None)
1326 }
1327 }
1328 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1329 ty:
1330 ASN1Type::Integer(Integer {
1331 distinguished_values: Some(distinguished),
1332 constraints,
1333 }),
1334 ..
1335 })) => {
1336 if let Some(distinguished_value) =
1337 distinguished.iter().find(|d| &d.name == identifier)
1338 {
1339 Ok(Some(ASN1Value::LinkedNestedValue {
1340 supertypes,
1341 value: Box::new(ASN1Value::LinkedIntValue {
1342 integer_type: constraints
1343 .iter()
1344 .fold(IntegerType::Unbounded, |acc, c| {
1345 c.integer_constraints().max_restrictive(acc)
1346 }),
1347 value: distinguished_value.value,
1348 }),
1349 }))
1350 } else {
1351 Ok(None)
1352 }
1353 }
1354 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1355 ty: ASN1Type::ElsewhereDeclaredType(elsewhere),
1356 ..
1357 })) => {
1358 supertypes.push(elsewhere.identifier.clone());
1359 Self::link_enum_or_distinguished(tlds, elsewhere, identifier, supertypes)
1360 }
1361 _ => Ok(None),
1362 }
1363 }
1364
1365 fn link_array_like(
1366 val: &mut [(Option<String>, Box<ASN1Value>)],
1367 s: &SequenceOrSetOf,
1368 tlds: &BTreeMap<String, ToplevelDefinition>,
1369 ) -> Result<ASN1Value, GrammarError> {
1370 let _ = val.iter_mut().try_for_each(|v| {
1371 v.1.link_with_type(
1372 tlds,
1373 &s.element_type,
1374 Some(&s.element_type.as_str().into_owned()),
1375 )
1376 });
1377 Ok(ASN1Value::LinkedArrayLikeValue(
1378 val.iter().map(|v| v.1.clone()).collect(),
1379 ))
1380 }
1381
1382 fn link_struct_like(
1383 val: &mut [(Option<String>, Box<ASN1Value>)],
1384 s: &SequenceOrSet,
1385 tlds: &BTreeMap<String, ToplevelDefinition>,
1386 type_name: Option<&String>,
1387 ) -> Result<ASN1Value, GrammarError> {
1388 val.iter_mut().try_for_each(|v| {
1389 if let Some(member) = s.members.iter().find(|m| Some(&m.name) == v.0.as_ref()) {
1390 let type_name = match (member.ty.is_builtin_type(), type_name) {
1391 (true, Some(parent)) => Some(
1392 INTERNAL_NESTED_TYPE_NAME_PREFIX.to_owned() + &member.name + "$" + parent,
1393 ),
1394 (false, _) => Some(member.ty.as_str().into_owned()),
1395 _ => {
1396 return Err(grammar_error!(
1397 LinkerError,
1398 "Failed to determine parent name of field {}",
1399 member.name
1400 ))
1401 }
1402 };
1403 v.1.link_with_type(tlds, &member.ty, type_name.as_ref())
1404 } else {
1405 Err(grammar_error!(
1406 LinkerError,
1407 "Failed to link value with '{:?}'",
1408 v.0
1409 ))
1410 }
1411 })?;
1412
1413 s.members
1414 .iter()
1415 .map(|member| {
1416 val.iter()
1417 .find_map(|(name, value)| {
1418 (name.as_ref() == Some(&member.name))
1419 .then_some(StructLikeFieldValue::Explicit(value.clone()))
1420 })
1421 .or(member
1422 .default_value
1423 .as_ref()
1424 .map(|d| StructLikeFieldValue::Implicit(Box::new(d.clone()))))
1425 .ok_or_else(|| {
1426 grammar_error!(LinkerError, "No value for field {} found!", member.name)
1427 })
1428 .map(|field_value| (member.name.clone(), member.ty.clone(), field_value))
1429 })
1430 .collect::<Result<Vec<_>, _>>()
1431 .map(ASN1Value::LinkedStructLikeValue)
1432 }
1433
1434 pub fn is_elsewhere_declared(&self) -> bool {
1435 let is = matches!(
1436 self,
1437 Self::ElsewhereDeclaredValue { .. }
1438 | Self::EnumeratedValue {
1439 enumerated: _,
1440 enumerable: _,
1441 }
1442 );
1443 is
1444 }
1445
1446 pub fn resolve_elsewhere_with_parent(
1461 &mut self,
1462 tlds: &BTreeMap<String, ToplevelDefinition>,
1463 ) -> Result<(), GrammarError> {
1464 if let Self::ElsewhereDeclaredValue {
1465 parent: Some(object_name),
1466 identifier,
1467 } = self
1468 {
1469 if object_name.contains('.') {
1470 return Err(grammar_error!(NotYetInplemented, "Value references of path length > 2 are not yet supported! Found reference {object_name}.{identifier}"));
1471 }
1472 let object = get_declaration![
1473 tlds,
1474 object_name,
1475 Information,
1476 ASN1Information::Object
1477 ]
1478 .ok_or_else(|| grammar_error!(LinkerError, "No information object found for identifier {object_name}, parent of {identifier}"))?;
1479 match &object.fields {
1480 InformationObjectFields::DefaultSyntax(d) => {
1481 match d.iter().find(|elem| elem.identifier() == identifier) {
1482 Some(InformationObjectField::FixedValueField(FixedValueField { value, .. })) => {
1483 *self = value.clone();
1484 return Ok(())
1485 }
1486 _ => return Err(grammar_error!(
1487 LinkerError,
1488 "No matching value field for identifier {identifier} found in object {object_name}"
1489 ))
1490 }
1491 }
1492 InformationObjectFields::CustomSyntax(c) => {
1493 let class_name = &object.class_name;
1494 let class = get_declaration![
1495 tlds,
1496 class_name,
1497 Information,
1498 ASN1Information::ObjectClass
1499 ]
1500 .ok_or_else(|| {
1501 grammar_error!(
1502 LinkerError,
1503 "No information object class found for identifier {class_name}"
1504 )
1505 })?;
1506 let syntax = class.syntax.as_ref().ok_or_else(|| {
1507 grammar_error!(LinkerError, "No syntax info found for class {class_name}")
1508 })?;
1509 let tokens = syntax.flatten();
1510 let (mut before, mut after) = (None, None);
1511 'iter_syntax: for i in 0..tokens.len() {
1512 let expr = tokens.get(i);
1513 match expr {
1514 Some((
1515 _,
1516 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(id)),
1517 )) if id == identifier => {
1518 before = tokens.get(i - 1).map(|(_, token)| token);
1519 after = tokens.get(i + 1).map(|(_, token)| token);
1520 break 'iter_syntax;
1521 }
1522 _ => {}
1523 };
1524 }
1525 for i in 0..c.len() {
1526 if let Some(SyntaxApplication::ValueReference(val)) = c.get(i) {
1527 match (c.get(i - 1), before, c.get(i + 1), after) {
1528 (Some(a), Some(b), _, _) if a.matches(b, &tokens, i) => {
1529 *self = val.clone();
1530 return Ok(());
1531 }
1532 (_, _, Some(c), Some(d)) if c.matches(d, &tokens, i) => {
1533 *self = val.clone();
1534 return Ok(());
1535 }
1536 _ => {}
1537 };
1538 }
1539 }
1540 return Err(grammar_error!(
1541 LinkerError,
1542 "Failed to match expression to syntax of class {class_name}"
1543 ));
1544 }
1545 }
1546 }
1547 Ok(())
1548 }
1549
1550 pub fn link_elsewhere_declared(
1551 &mut self,
1552 identifier: &String,
1553 tlds: &BTreeMap<String, ToplevelDefinition>,
1554 ) -> Result<(), GrammarError> {
1555 match self {
1556 Self::ElsewhereDeclaredValue {
1557 parent: Some(_), ..
1558 } => {
1559 return self.resolve_elsewhere_with_parent(tlds);
1560 }
1561 Self::ElsewhereDeclaredValue {
1562 identifier: e,
1563 parent: _,
1564 }
1565 | Self::EnumeratedValue {
1566 enumerated: _,
1567 enumerable: e,
1568 } => {
1569 if let Some(v) = find_tld_or_enum_value_by_name(identifier, e, tlds) {
1570 *self = v;
1571 }
1572 }
1573 _ => {}
1574 }
1575 Ok(())
1576 }
1577}
1578
1579fn bit_string_value_from_named_bits(
1580 highest_distinguished_bit: i128,
1581 named_bits: &[String],
1582 distinguished: &[DistinguishedValue],
1583) -> Vec<bool> {
1584 (0..=highest_distinguished_bit)
1585 .map(|i| {
1586 named_bits.iter().any(|bit| {
1587 Some(bit)
1588 == distinguished
1589 .iter()
1590 .find_map(|d| (d.value == i).then_some(&d.name))
1591 })
1592 })
1593 .collect()
1594}
1595
1596#[cfg(test)]
1597mod tests {
1598 use std::collections::BTreeMap;
1599
1600 use crate::intermediate::{types::*, *};
1601
1602 macro_rules! tld {
1603 ($name:literal, $ty:expr) => {
1604 ToplevelTypeDefinition {
1605 comments: String::new(),
1606 tag: None,
1607 index: None,
1608 name: $name.into(),
1609 ty: $ty,
1610 parameterization: None,
1611 }
1612 };
1613 }
1614
1615 #[test]
1616 fn links_asn1_value() {
1617 let tlds: BTreeMap<String, ToplevelDefinition> = {
1618 let mut map = BTreeMap::new();
1619 map.insert(
1620 "RootBool".into(),
1621 ToplevelDefinition::Type(tld!(
1622 "RootBool",
1623 ASN1Type::Boolean(Boolean {
1624 constraints: vec![]
1625 })
1626 )),
1627 );
1628 map.insert(
1629 "IntermediateBool".into(),
1630 ToplevelDefinition::Type(tld!(
1631 "IntermediateBool",
1632 ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1633 parent: None,
1634 identifier: String::from("RootBool"),
1635 constraints: vec![]
1636 })
1637 )),
1638 );
1639 map.insert(
1640 "BaseChoice".into(),
1641 ToplevelDefinition::Type(tld!(
1642 "BaseChoice",
1643 ASN1Type::Choice(Choice {
1644 extensible: None,
1645 constraints: vec![],
1646 options: vec![ChoiceOption {
1647 is_recursive: false,
1648 name: String::from("first"),
1649 constraints: vec![],
1650 tag: None,
1651 ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1652 parent: None,
1653 identifier: String::from("IntermediateBool"),
1654 constraints: vec![]
1655 })
1656 }]
1657 })
1658 )),
1659 );
1660 map
1661 };
1662 let mut example_value = ToplevelValueDefinition {
1663 comments: String::new(),
1664 name: "exampleValue".into(),
1665 parameterization: None,
1666 associated_type: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1667 parent: None,
1668 identifier: "BaseChoice".into(),
1669 constraints: vec![],
1670 }),
1671 index: None,
1672 value: ASN1Value::Choice {
1673 type_name: None,
1674 variant_name: "first".into(),
1675 inner_value: Box::new(ASN1Value::Boolean(true)),
1676 },
1677 };
1678 example_value.collect_supertypes(&tlds).unwrap();
1679 assert_eq!(
1680 example_value,
1681 ToplevelValueDefinition {
1682 comments: "".into(),
1683 name: "exampleValue".into(),
1684 associated_type: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1685 parent: None,
1686 identifier: "BaseChoice".into(),
1687 constraints: vec![]
1688 }),
1689 parameterization: None,
1690 value: ASN1Value::Choice {
1691 type_name: Some("BaseChoice".into()),
1692 variant_name: "first".into(),
1693 inner_value: Box::new(ASN1Value::LinkedNestedValue {
1694 supertypes: vec!["IntermediateBool".into(), "RootBool".into()],
1695 value: Box::new(ASN1Value::Boolean(true))
1696 })
1697 },
1698 index: None
1699 }
1700 )
1701 }
1702}