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