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 = Box::new(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 { identifier, parent },
907 ) => {
908 if let Some(value) = Self::link_enum_or_distinguished(
909 tlds,
910 e,
911 identifier,
912 vec![e.identifier.clone()],
913 )? {
914 *self = value;
915 return Ok(());
916 } else if let Some((ToplevelDefinition::Type(ty), ToplevelDefinition::Value(val))) =
917 tlds.get(&e.identifier).zip(tlds.get(identifier))
918 {
919 if ty.name != val.associated_type.as_str() {
920 *self = val.clone().value;
933 self.link_with_type(
934 tlds,
935 &ASN1Type::ElsewhereDeclaredType(e.clone()),
936 None,
937 )?;
938 return Ok(());
939 }
940 }
941 *self = ASN1Value::LinkedElsewhereDefinedValue {
942 parent: parent.clone(),
943 identifier: identifier.clone(),
944 can_be_const: e.root(tlds)?.is_const_type(),
945 };
946 Ok(())
947 }
948 (ASN1Type::ElsewhereDeclaredType(e), val) => {
949 *self = ASN1Value::LinkedNestedValue {
950 supertypes: vec![e.identifier.clone()],
951 value: Box::new((*val).clone()),
952 };
953 if let Some(ToplevelDefinition::Type(t)) = tlds.get(&e.identifier) {
954 self.link_with_type(tlds, &t.ty, Some(&t.name))
955 } else {
956 Err(grammar_error!(
957 LinkerError,
958 "Failed to link value with '{}'",
959 e.identifier
960 ))
961 }
962 }
963 (
964 ASN1Type::Choice(c),
965 ASN1Value::Choice {
966 type_name: tn,
967 variant_name,
968 inner_value,
969 },
970 ) => {
971 if let Some(option) = c.options.iter().find(|o| &o.name == variant_name) {
972 *tn = type_name.cloned();
973 inner_value.link_with_type(
974 tlds,
975 &option.ty,
976 Some(&option.ty.as_str().into_owned()),
977 )
978 } else {
979 Err(grammar_error!(
980 LinkerError,
981 "Failed to link value with '{}'",
982 variant_name
983 ))
984 }
985 }
986 (ASN1Type::Choice(c), ASN1Value::LinkedNestedValue { supertypes, value })
987 if matches![**value, ASN1Value::Choice { .. }] =>
988 {
989 let enum_name = supertypes.pop();
990 if let ASN1Value::Choice {
991 type_name,
992 variant_name,
993 inner_value,
994 } = &mut **value
995 {
996 if let Some(option) = c.options.iter().find(|o| &o.name == variant_name) {
997 *type_name = enum_name;
998 inner_value.link_with_type(
999 tlds,
1000 &option.ty,
1001 Some(&option.ty.as_str().into_owned()),
1002 )
1003 } else {
1004 Err(grammar_error!(
1005 LinkerError,
1006 "Failed to link value with '{}'",
1007 variant_name
1008 ))
1009 }
1010 } else {
1011 Ok(())
1012 }
1013 }
1014 (ASN1Type::SetOf(_), ASN1Value::ObjectIdentifier(val))
1015 | (ASN1Type::SequenceOf(_), ASN1Value::ObjectIdentifier(val))
1016 | (ASN1Type::Set(_), ASN1Value::ObjectIdentifier(val))
1017 | (ASN1Type::Sequence(_), ASN1Value::ObjectIdentifier(val)) => {
1018 let mut pseudo_arcs = std::mem::take(&mut val.0);
1020 let struct_value = pseudo_arcs
1021 .chunks_mut(2)
1022 .map(|chunk| {
1023 let err = || GrammarError {
1024 pdu: None,
1025 details:
1026 "Failed to interpret object identifier value as sequence value!"
1027 .into(),
1028 kind: GrammarErrorType::LinkerError,
1029 };
1030 if let [id, val] = chunk {
1031 val.number
1032 .and_then(|n| <u128 as TryInto<i128>>::try_into(n).ok())
1033 .ok_or_else(err)
1034 .map(|number| {
1035 (id.name.take(), Box::new(ASN1Value::Integer(number)))
1036 })
1037 } else {
1038 Err(err())
1039 }
1040 })
1041 .collect::<Result<Vec<_>, _>>()?;
1042 *self = ASN1Value::SequenceOrSet(struct_value);
1043 self.link_with_type(tlds, ty, type_name)
1044 }
1045 (ASN1Type::Set(s), ASN1Value::SequenceOrSet(val))
1046 | (ASN1Type::Sequence(s), ASN1Value::SequenceOrSet(val)) => {
1047 *self = Self::link_struct_like(val, s, tlds, type_name)?;
1048 Ok(())
1049 }
1050 (ASN1Type::Set(s), ASN1Value::LinkedNestedValue { value, .. })
1051 | (ASN1Type::Sequence(s), ASN1Value::LinkedNestedValue { value, .. })
1052 if matches![**value, ASN1Value::SequenceOrSet(_)] =>
1053 {
1054 if let ASN1Value::SequenceOrSet(val) = &mut **value {
1055 *value = Box::new(Self::link_struct_like(val, s, tlds, type_name)?);
1056 }
1057 Ok(())
1058 }
1059 (ASN1Type::SetOf(s), ASN1Value::SequenceOrSet(val))
1060 | (ASN1Type::SequenceOf(s), ASN1Value::SequenceOrSet(val)) => {
1061 *self = Self::link_array_like(val, s, tlds)?;
1062 Ok(())
1063 }
1064 (ASN1Type::SetOf(s), ASN1Value::LinkedNestedValue { value, .. })
1065 | (ASN1Type::SequenceOf(s), ASN1Value::LinkedNestedValue { value, .. })
1066 if matches![**value, ASN1Value::SequenceOrSet(_)] =>
1067 {
1068 if let ASN1Value::SequenceOrSet(val) = &mut **value {
1069 *value = Box::new(Self::link_array_like(val, s, tlds)?);
1070 }
1071 Ok(())
1072 }
1073 (ASN1Type::Integer(i), ASN1Value::Integer(val)) => {
1074 *self = ASN1Value::LinkedIntValue {
1075 integer_type: i.int_type(),
1076 value: *val,
1077 };
1078 Ok(())
1079 }
1080 (ASN1Type::CharacterString(t), ASN1Value::String(s)) => {
1081 *self = ASN1Value::LinkedCharStringValue(t.ty, s.clone());
1082 Ok(())
1083 }
1084 (ASN1Type::CharacterString(t), ASN1Value::LinkedNestedValue { value, .. })
1085 if matches![**value, ASN1Value::String(_)] =>
1086 {
1087 if let ASN1Value::String(s) = &**value {
1088 *value = Box::new(ASN1Value::LinkedCharStringValue(t.ty, s.clone()));
1089 }
1090 Ok(())
1091 }
1092 (ASN1Type::BitString(_), ASN1Value::OctetString(o)) => {
1093 *self = ASN1Value::BitString(octet_string_to_bit_string(o));
1094 Ok(())
1095 }
1096 (
1097 ASN1Type::BitString(BitString {
1098 distinguished_values: Some(_),
1099 ..
1100 }),
1101 ASN1Value::SequenceOrSet(o),
1102 ) => {
1103 *self = ASN1Value::BitStringNamedBits(
1104 o.iter()
1105 .filter_map(|(_, v)| match &**v {
1106 ASN1Value::ElsewhereDeclaredValue { identifier, .. } => {
1107 Some(identifier.clone())
1108 }
1109 ASN1Value::EnumeratedValue { enumerable, .. } => {
1110 Some(enumerable.clone())
1111 }
1112 _ => None,
1113 })
1114 .collect(),
1115 );
1116 self.link_with_type(tlds, ty, type_name)
1117 }
1118 (
1119 ASN1Type::BitString(BitString {
1120 distinguished_values: Some(_),
1121 ..
1122 }),
1123 ASN1Value::LinkedNestedValue { value, .. },
1124 ) if matches![**value, ASN1Value::SequenceOrSet(_)] => {
1125 if let ASN1Value::SequenceOrSet(o) = &**value {
1126 *value = Box::new(ASN1Value::BitStringNamedBits(
1127 o.iter()
1128 .filter_map(|(_, v)| match &**v {
1129 ASN1Value::ElsewhereDeclaredValue { identifier, .. } => {
1130 Some(identifier.clone())
1131 }
1132 ASN1Value::EnumeratedValue { enumerable, .. } => {
1133 Some(enumerable.clone())
1134 }
1135 _ => None,
1136 })
1137 .collect(),
1138 ));
1139 self.link_with_type(tlds, ty, type_name)?;
1140 }
1141 Ok(())
1142 }
1143 (
1144 ASN1Type::BitString(BitString {
1145 distinguished_values: Some(_),
1146 ..
1147 }),
1148 ASN1Value::ObjectIdentifier(o),
1149 ) => {
1150 *self = ASN1Value::BitStringNamedBits(
1151 o.0.iter().filter_map(|arc| arc.name.clone()).collect(),
1152 );
1153 self.link_with_type(tlds, ty, type_name)
1154 }
1155 (
1156 ASN1Type::BitString(BitString {
1157 distinguished_values: Some(_),
1158 ..
1159 }),
1160 ASN1Value::LinkedNestedValue { value, .. },
1161 ) if matches![**value, ASN1Value::ObjectIdentifier(_)] => {
1162 if let ASN1Value::ObjectIdentifier(o) = &**value {
1163 *value = Box::new(ASN1Value::BitStringNamedBits(
1164 o.0.iter().filter_map(|arc| arc.name.clone()).collect(),
1165 ));
1166 self.link_with_type(tlds, ty, type_name)?;
1167 }
1168 Ok(())
1169 }
1170 (
1171 ASN1Type::BitString(BitString {
1172 distinguished_values: Some(distinguished),
1173 ..
1174 }),
1175 ASN1Value::BitStringNamedBits(o),
1176 ) => {
1177 if let Some(highest_distinguished_bit) = distinguished.iter().map(|d| d.value).max()
1178 {
1179 *self = ASN1Value::BitString(bit_string_value_from_named_bits(
1180 highest_distinguished_bit,
1181 o,
1182 distinguished,
1183 ));
1184 Ok(())
1185 } else {
1186 Err(GrammarError {
1187 details: format!("Failed to resolve BIT STRING value {o:?}"),
1188 kind: GrammarErrorType::LinkerError,
1189 pdu: None,
1190 })
1191 }
1192 }
1193 (
1194 ASN1Type::BitString(BitString {
1195 distinguished_values: Some(distinguished),
1196 ..
1197 }),
1198 ASN1Value::LinkedNestedValue { value, .. },
1199 ) if matches![**value, ASN1Value::BitStringNamedBits(_)] => {
1200 if let (ASN1Value::BitStringNamedBits(o), Some(highest_distinguished_bit)) =
1201 (&**value, distinguished.iter().map(|d| d.value).max())
1202 {
1203 *value = Box::new(ASN1Value::BitString(bit_string_value_from_named_bits(
1204 highest_distinguished_bit,
1205 o,
1206 distinguished,
1207 )));
1208 Ok(())
1209 } else {
1210 Err(GrammarError {
1211 details: format!("Failed to resolve BIT STRING value {value:?}"),
1212 kind: GrammarErrorType::LinkerError,
1213 pdu: None,
1214 })
1215 }
1216 }
1217 (ASN1Type::BitString(_), ASN1Value::LinkedNestedValue { value, .. })
1218 if matches![**value, ASN1Value::OctetString(_)] =>
1219 {
1220 if let ASN1Value::OctetString(o) = &**value {
1221 *value = Box::new(ASN1Value::BitString(octet_string_to_bit_string(o)));
1222 }
1223 Ok(())
1224 }
1225 (ASN1Type::OctetString(_), ASN1Value::BitString(b)) => {
1226 *self = ASN1Value::OctetString(bit_string_to_octet_string(b)?);
1227 Ok(())
1228 }
1229 (ASN1Type::OctetString(_), ASN1Value::LinkedNestedValue { value, .. })
1230 if matches![**value, ASN1Value::BitString(_)] =>
1231 {
1232 if let ASN1Value::BitString(b) = &**value {
1233 *value = Box::new(ASN1Value::OctetString(bit_string_to_octet_string(b)?));
1234 }
1235 Ok(())
1236 }
1237 (ASN1Type::Integer(i), ASN1Value::LinkedIntValue { integer_type, .. }) => {
1238 let int_type = i.int_type().max_restrictive(*integer_type);
1239 *integer_type = int_type;
1240 Ok(())
1241 }
1242 (ASN1Type::Integer(i), ASN1Value::LinkedNestedValue { value, .. })
1243 if matches![**value, ASN1Value::ElsewhereDeclaredValue { .. }] =>
1244 {
1245 if let ASN1Value::ElsewhereDeclaredValue { identifier, .. } = &**value {
1246 if let Some(distinguished_value) =
1247 i.distinguished_values.as_ref().and_then(|dist_vals| {
1248 dist_vals
1249 .iter()
1250 .find_map(|d| (&d.name == identifier).then_some(d.value))
1251 })
1252 {
1253 *value = Box::new(ASN1Value::LinkedIntValue {
1254 integer_type: i.int_type(),
1255 value: distinguished_value,
1256 });
1257 }
1258 }
1259 Ok(())
1260 }
1261 (ASN1Type::Integer(i), ASN1Value::LinkedNestedValue { value, .. })
1262 if matches![**value, ASN1Value::Integer(_)] =>
1263 {
1264 if let ASN1Value::Integer(v) = &**value {
1265 let int_type = i.constraints.iter().fold(IntegerType::Unbounded, |acc, c| {
1266 c.integer_constraints().max_restrictive(acc)
1267 });
1268 *value = Box::new(ASN1Value::LinkedIntValue {
1269 integer_type: int_type,
1270 value: *v,
1271 });
1272 }
1273 Ok(())
1274 }
1275 (ASN1Type::Integer(i), ASN1Value::ElsewhereDeclaredValue { identifier, .. }) => {
1276 if let Some(value) = i.distinguished_values.as_ref().and_then(|dist_vals| {
1277 dist_vals
1278 .iter()
1279 .find_map(|d| (&d.name == identifier).then_some(d.value))
1280 }) {
1281 *self = ASN1Value::LinkedIntValue {
1282 integer_type: i.int_type(),
1283 value,
1284 };
1285 }
1286 Ok(())
1287 }
1288 (ASN1Type::Enumerated(_), ASN1Value::LinkedNestedValue { value, .. })
1289 if matches![**value, ASN1Value::ElsewhereDeclaredValue { .. }] =>
1290 {
1291 if let ASN1Value::ElsewhereDeclaredValue { identifier, .. } = &**value {
1292 if let Some((_, tld)) = tlds
1293 .iter()
1294 .find(|(_, tld)| tld.has_enum_value(None, identifier))
1295 {
1296 *value = Box::new(ASN1Value::EnumeratedValue {
1297 enumerated: tld.name().clone(),
1298 enumerable: identifier.clone(),
1299 });
1300 }
1301 }
1302 Ok(())
1303 }
1304 (ASN1Type::Enumerated(_), ASN1Value::ElsewhereDeclaredValue { identifier, .. }) => {
1305 if let Some((_, tld)) = tlds
1306 .iter()
1307 .find(|(_, tld)| tld.has_enum_value(None, identifier))
1308 {
1309 *self = ASN1Value::EnumeratedValue {
1310 enumerated: tld.name().clone(),
1311 enumerable: identifier.clone(),
1312 };
1313 }
1314 Ok(())
1315 }
1316 (
1317 _,
1318 ASN1Value::ElsewhereDeclaredValue {
1319 parent: None,
1320 identifier,
1321 },
1322 ) => {
1323 if let Some(ToplevelDefinition::Value(tld)) = tlds.get(identifier) {
1324 *self = tld.value.clone();
1325 self.link_with_type(tlds, ty, type_name)?;
1326 }
1327 Ok(())
1328 }
1329 (_, ASN1Value::ElsewhereDeclaredValue { .. }) => Err(GrammarError::todo()),
1330 _ => Ok(()),
1331 }
1332 }
1333
1334 fn link_enum_or_distinguished(
1335 tlds: &BTreeMap<String, ToplevelDefinition>,
1336 e: &DeclarationElsewhere,
1337 identifier: &mut String,
1338 mut supertypes: Vec<String>,
1339 ) -> Result<Option<ASN1Value>, GrammarError> {
1340 match tlds.get(&e.identifier) {
1341 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1342 ty: ASN1Type::Enumerated(enumerated),
1343 ..
1344 })) => {
1345 if enumerated
1346 .members
1347 .iter()
1348 .any(|enumeral| &enumeral.name == identifier)
1349 {
1350 Ok(Some(ASN1Value::EnumeratedValue {
1351 enumerated: e.identifier.clone(),
1352 enumerable: identifier.clone(),
1353 }))
1354 } else {
1355 Ok(None)
1356 }
1357 }
1358 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1359 ty:
1360 ASN1Type::Integer(Integer {
1361 distinguished_values: Some(distinguished),
1362 constraints,
1363 }),
1364 ..
1365 })) => {
1366 if let Some(distinguished_value) =
1367 distinguished.iter().find(|d| &d.name == identifier)
1368 {
1369 Ok(Some(ASN1Value::LinkedNestedValue {
1370 supertypes,
1371 value: Box::new(ASN1Value::LinkedIntValue {
1372 integer_type: constraints
1373 .iter()
1374 .fold(IntegerType::Unbounded, |acc, c| {
1375 c.integer_constraints().max_restrictive(acc)
1376 }),
1377 value: distinguished_value.value,
1378 }),
1379 }))
1380 } else {
1381 Ok(None)
1382 }
1383 }
1384 Some(ToplevelDefinition::Type(ToplevelTypeDefinition {
1385 ty: ASN1Type::ElsewhereDeclaredType(elsewhere),
1386 ..
1387 })) => {
1388 supertypes.push(elsewhere.identifier.clone());
1389 Self::link_enum_or_distinguished(tlds, elsewhere, identifier, supertypes)
1390 }
1391 _ => Ok(None),
1392 }
1393 }
1394
1395 fn link_array_like(
1396 val: &mut [(Option<String>, Box<ASN1Value>)],
1397 s: &SequenceOrSetOf,
1398 tlds: &BTreeMap<String, ToplevelDefinition>,
1399 ) -> Result<ASN1Value, GrammarError> {
1400 let _ = val.iter_mut().try_for_each(|v| {
1401 v.1.link_with_type(
1402 tlds,
1403 &s.element_type,
1404 Some(&s.element_type.as_str().into_owned()),
1405 )
1406 });
1407 Ok(ASN1Value::LinkedArrayLikeValue(
1408 val.iter().map(|v| v.1.clone()).collect(),
1409 ))
1410 }
1411
1412 fn link_struct_like(
1413 val: &mut [(Option<String>, Box<ASN1Value>)],
1414 s: &SequenceOrSet,
1415 tlds: &BTreeMap<String, ToplevelDefinition>,
1416 type_name: Option<&String>,
1417 ) -> Result<ASN1Value, GrammarError> {
1418 val.iter_mut().try_for_each(|v| {
1419 if let Some(member) = s.members.iter().find(|m| Some(&m.name) == v.0.as_ref()) {
1420 let type_name = match (member.ty.is_builtin_type(), type_name) {
1421 (true, Some(parent)) => Some(
1422 INTERNAL_NESTED_TYPE_NAME_PREFIX.to_owned() + &member.name + "$" + parent,
1423 ),
1424 (false, _) => Some(member.ty.as_str().into_owned()),
1425 _ => {
1426 return Err(grammar_error!(
1427 LinkerError,
1428 "Failed to determine parent name of field {}",
1429 member.name
1430 ))
1431 }
1432 };
1433 v.1.link_with_type(tlds, &member.ty, type_name.as_ref())
1434 } else {
1435 Err(grammar_error!(
1436 LinkerError,
1437 "Failed to link value with '{:?}'",
1438 v.0
1439 ))
1440 }
1441 })?;
1442
1443 s.members
1444 .iter()
1445 .map(|member| {
1446 val.iter()
1447 .find_map(|(name, value)| {
1448 (name.as_ref() == Some(&member.name))
1449 .then_some(StructLikeFieldValue::Explicit(value.clone()))
1450 })
1451 .or(member
1452 .optionality
1453 .default()
1454 .map(|d| StructLikeFieldValue::Implicit(Box::new(d.clone()))))
1455 .ok_or_else(|| {
1456 grammar_error!(LinkerError, "No value for field {} found!", member.name)
1457 })
1458 .map(|field_value| (member.name.clone(), member.ty.clone(), field_value))
1459 })
1460 .collect::<Result<Vec<_>, _>>()
1461 .map(ASN1Value::LinkedStructLikeValue)
1462 }
1463
1464 pub fn is_elsewhere_declared(&self) -> bool {
1465 let is = matches!(
1466 self,
1467 Self::ElsewhereDeclaredValue { .. }
1468 | Self::EnumeratedValue {
1469 enumerated: _,
1470 enumerable: _,
1471 }
1472 );
1473 is
1474 }
1475
1476 pub fn resolve_elsewhere_with_parent(
1491 &mut self,
1492 tlds: &BTreeMap<String, ToplevelDefinition>,
1493 ) -> Result<(), GrammarError> {
1494 if let Self::ElsewhereDeclaredValue {
1495 parent: Some(object_name),
1496 identifier,
1497 } = self
1498 {
1499 if object_name.contains('.') {
1500 return Err(grammar_error!(NotYetInplemented, "Value references of path length > 2 are not yet supported! Found reference {object_name}.{identifier}"));
1501 }
1502 let object = get_declaration![
1503 tlds,
1504 object_name,
1505 Object,
1506 ASN1Information::Object
1507 ]
1508 .ok_or_else(|| grammar_error!(LinkerError, "No information object found for identifier {object_name}, parent of {identifier}"))?;
1509 match &object.fields {
1510 InformationObjectFields::DefaultSyntax(d) => {
1511 match d.iter().find(|elem| elem.identifier() == identifier) {
1512 Some(InformationObjectField::FixedValueField(FixedValueField { value, .. })) => {
1513 *self = value.clone();
1514 return Ok(())
1515 }
1516 _ => return Err(grammar_error!(
1517 LinkerError,
1518 "No matching value field for identifier {identifier} found in object {object_name}"
1519 ))
1520 }
1521 }
1522 InformationObjectFields::CustomSyntax(c) => {
1523 let class_name = &object.class_name;
1524 let Some(tld) = tlds.get(class_name) else {
1525 return Err(grammar_error!(
1526 LinkerError,
1527 "No top level definition found for identifier {class_name}"
1528 ));
1529 };
1530 let ToplevelDefinition::Class(class) = tld else {
1531 return Err(grammar_error!(
1532 LinkerError,
1533 "Identifier {class_name} is not a CLASS definition"
1534 ));
1535 };
1536 let syntax = class.definition.syntax.as_ref().ok_or_else(|| {
1537 grammar_error!(LinkerError, "No syntax info found for class {class_name}")
1538 })?;
1539 let tokens = syntax.flatten();
1540 let (mut before, mut after) = (None, None);
1541 'iter_syntax: for i in 0..tokens.len() {
1542 let expr = tokens.get(i);
1543 match expr {
1544 Some((
1545 _,
1546 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(id)),
1547 )) if id == identifier => {
1548 before = tokens.get(i - 1).map(|(_, token)| token);
1549 after = tokens.get(i + 1).map(|(_, token)| token);
1550 break 'iter_syntax;
1551 }
1552 _ => {}
1553 };
1554 }
1555 for i in 0..c.len() {
1556 if let Some(SyntaxApplication::ValueReference(val)) = c.get(i) {
1557 match (c.get(i - 1), before, c.get(i + 1), after) {
1558 (Some(a), Some(b), _, _) if a.matches(b, &tokens, i) => {
1559 *self = val.clone();
1560 return Ok(());
1561 }
1562 (_, _, Some(c), Some(d)) if c.matches(d, &tokens, i) => {
1563 *self = val.clone();
1564 return Ok(());
1565 }
1566 _ => {}
1567 };
1568 }
1569 }
1570 return Err(grammar_error!(
1571 LinkerError,
1572 "Failed to match expression to syntax of class {class_name}"
1573 ));
1574 }
1575 }
1576 }
1577 Ok(())
1578 }
1579
1580 pub fn link_elsewhere_declared(
1581 &mut self,
1582 identifier: &String,
1583 tlds: &BTreeMap<String, ToplevelDefinition>,
1584 ) -> Result<(), GrammarError> {
1585 match self {
1586 Self::ElsewhereDeclaredValue {
1587 parent: Some(_), ..
1588 } => {
1589 return self.resolve_elsewhere_with_parent(tlds);
1590 }
1591 Self::ElsewhereDeclaredValue {
1592 identifier: e,
1593 parent: _,
1594 }
1595 | Self::EnumeratedValue {
1596 enumerated: _,
1597 enumerable: e,
1598 } => {
1599 if let Some(v) = find_tld_or_enum_value_by_name(identifier, e, tlds) {
1600 *self = v;
1601 }
1602 }
1603 _ => {}
1604 }
1605 Ok(())
1606 }
1607}
1608
1609fn bit_string_value_from_named_bits(
1610 highest_distinguished_bit: i128,
1611 named_bits: &[String],
1612 distinguished: &[DistinguishedValue],
1613) -> Vec<bool> {
1614 (0..=highest_distinguished_bit)
1615 .map(|i| {
1616 named_bits.iter().any(|bit| {
1617 Some(bit)
1618 == distinguished
1619 .iter()
1620 .find_map(|d| (d.value == i).then_some(&d.name))
1621 })
1622 })
1623 .collect()
1624}
1625
1626#[cfg(test)]
1627mod tests {
1628 use std::collections::BTreeMap;
1629
1630 use crate::intermediate::{types::*, *};
1631
1632 macro_rules! tld {
1633 ($name:literal, $ty:expr) => {
1634 ToplevelTypeDefinition {
1635 comments: String::new(),
1636 tag: None,
1637 module_header: None,
1638 name: $name.into(),
1639 ty: $ty,
1640 parameterization: None,
1641 }
1642 };
1643 }
1644
1645 #[test]
1646 fn links_asn1_value() {
1647 let tlds: BTreeMap<String, ToplevelDefinition> = {
1648 let mut map = BTreeMap::new();
1649 map.insert(
1650 "RootBool".into(),
1651 ToplevelDefinition::Type(tld!(
1652 "RootBool",
1653 ASN1Type::Boolean(Boolean {
1654 constraints: vec![]
1655 })
1656 )),
1657 );
1658 map.insert(
1659 "IntermediateBool".into(),
1660 ToplevelDefinition::Type(tld!(
1661 "IntermediateBool",
1662 ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1663 parent: None,
1664 module: None,
1665 identifier: String::from("RootBool"),
1666 constraints: vec![]
1667 })
1668 )),
1669 );
1670 map.insert(
1671 "BaseChoice".into(),
1672 ToplevelDefinition::Type(tld!(
1673 "BaseChoice",
1674 ASN1Type::Choice(Choice {
1675 extensible: None,
1676 constraints: vec![],
1677 options: vec![ChoiceOption {
1678 is_recursive: false,
1679 name: String::from("first"),
1680 constraints: vec![],
1681 tag: None,
1682 ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1683 parent: None,
1684 module: None,
1685 identifier: String::from("IntermediateBool"),
1686 constraints: vec![]
1687 })
1688 }]
1689 })
1690 )),
1691 );
1692 map
1693 };
1694 let mut example_value = ToplevelValueDefinition {
1695 comments: String::new(),
1696 name: "exampleValue".into(),
1697 parameterization: None,
1698 associated_type: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1699 parent: None,
1700 module: None,
1701 identifier: "BaseChoice".into(),
1702 constraints: vec![],
1703 }),
1704 module_header: None,
1705 value: ASN1Value::Choice {
1706 type_name: None,
1707 variant_name: "first".into(),
1708 inner_value: Box::new(ASN1Value::Boolean(true)),
1709 },
1710 };
1711 example_value.collect_supertypes(&tlds).unwrap();
1712 assert_eq!(
1713 example_value,
1714 ToplevelValueDefinition {
1715 comments: "".into(),
1716 name: "exampleValue".into(),
1717 associated_type: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
1718 parent: None,
1719 module: None,
1720 identifier: "BaseChoice".into(),
1721 constraints: vec![]
1722 }),
1723 parameterization: None,
1724 value: ASN1Value::Choice {
1725 type_name: Some("BaseChoice".into()),
1726 variant_name: "first".into(),
1727 inner_value: Box::new(ASN1Value::LinkedNestedValue {
1728 supertypes: vec!["IntermediateBool".into(), "RootBool".into()],
1729 value: Box::new(ASN1Value::Boolean(true))
1730 })
1731 },
1732 module_header: None
1733 }
1734 )
1735 }
1736}