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