diff --git a/rasn-compiler/src/generator/rasn/builder.rs b/rasn-compiler/src/generator/rasn/builder.rs index fa7df9ad..feee80fa 100644 --- a/rasn-compiler/src/generator/rasn/builder.rs +++ b/rasn-compiler/src/generator/rasn/builder.rs @@ -17,6 +17,7 @@ use super::{ TaggingEnvironment, }; use crate::generator::error::{GeneratorError, GeneratorErrorType}; +use crate::prelude::ir::SequenceComponent; pub(crate) const INNER_ARRAY_LIKE_PREFIX: &str = "Anonymous_"; @@ -681,17 +682,11 @@ impl Rasn { match tld.ty { ASN1Type::Sequence(ref seq) | ASN1Type::Set(ref seq) => { let name = self.to_rust_title_case(&tld.name); - let extensible = seq - .extensible - .or( - (self.extensibility_environment == ExtensibilityEnvironment::Implied) - .then_some(seq.members.len()), - ) - .map(|_| { - quote! { - #[non_exhaustive]} - }) - .unwrap_or_default(); + let extensible = if seq.extensible || self.extensibility_environment == ExtensibilityEnvironment::Implied { + quote! {#[non_exhaustive]} + } else { + TokenStream::new() + }; let set_annotation = if let ASN1Type::Set(_) = tld.ty { quote!(set) } else { @@ -700,7 +695,8 @@ impl Rasn { let class_fields = if self.config.opaque_open_types { TokenStream::new() } else { - seq.members.iter().fold( + seq.direct_members() + .fold( TokenStream::new(), |mut acc, m| { [ @@ -747,7 +743,7 @@ impl Rasn { self.format_tag( tld.tag.as_ref(), self.tagging_environment == TaggingEnvironment::Automatic - && !seq.members.iter().any(|m| m.tag.is_some()), + && !seq.direct_members().any(|m| m.tag.is_some()), ), ]; if name.to_string() != tld.name { @@ -764,7 +760,7 @@ impl Rasn { formatted_members.struct_body, formatted_members.nested_anonymous_types, self.join_annotations(annotations, false, true)?, - self.format_default_methods(&seq.members, &name.to_string())?, + self.format_default_methods(&seq.direct_members().cloned().collect(), &name.to_string())?, self.format_new_impl(&name, formatted_members.name_types), class_fields, )) diff --git a/rasn-compiler/src/generator/rasn/utils.rs b/rasn-compiler/src/generator/rasn/utils.rs index eb73dfbb..0036dde4 100644 --- a/rasn-compiler/src/generator/rasn/utils.rs +++ b/rasn-compiler/src/generator/rasn/utils.rs @@ -331,9 +331,8 @@ impl Rasn { sequence_or_set: &SequenceOrSet, parent_name: &String, ) -> Result { - let first_extension_index = sequence_or_set.extensible; - - sequence_or_set.members.iter().enumerate().try_fold( + let extension_range = sequence_or_set.extension_range(); + sequence_or_set.direct_members().enumerate().try_fold( FormattedMembers::default(), |mut acc, (i, m)| { let nested = if Self::needs_unnesting(&m.ty) { @@ -351,11 +350,11 @@ impl Rasn { } else { Ok(None) }; - let extension_annotation = if i >= first_extension_index.unwrap_or(usize::MAX) + let extension_annotation = if extension_range.contains(&i) && m.name.starts_with(INTERNAL_EXTENSION_GROUP_NAME_PREFIX) { quote!(extension_addition_group) - } else if i >= first_extension_index.unwrap_or(usize::MAX) { + } else if extension_range.contains(&i) { quote!(extension_addition) } else { TokenStream::new() @@ -1096,7 +1095,7 @@ impl Rasn { const REQUIRED_DERIVES: [&'static str; 6] = ["Debug", "AsnType", "Encode", "Decode", "PartialEq", "Clone"]; - const COPY_DERIVE: &str = "Copy"; + const COPY_DERIVE: &'static str = "Copy"; const RUST_KEYWORDS: [&'static str; 53] = [ "as", "break", @@ -1321,8 +1320,7 @@ impl ASN1Type { .iter() .fold(true, |acc, opt| opt.ty.is_const_type() && acc), ASN1Type::Set(s) | ASN1Type::Sequence(s) => s - .members - .iter() + .direct_members() .fold(true, |acc, m| m.ty.is_const_type() && acc), ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => s.element_type.is_const_type(), _ => false, @@ -1361,7 +1359,7 @@ mod tests { types::{Boolean, Enumeral, Integer}, AsnTag, }; - + use crate::prelude::ir::SequenceComponent; use super::*; #[test] @@ -1430,11 +1428,10 @@ mod tests { generator .format_sequence_or_set_members( &SequenceOrSet { - components_of: vec![], - extensible: Some(1), + extensible: true, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "testMember0".into(), tag: None, @@ -1444,28 +1441,31 @@ mod tests { default_value: None, is_optional: true, constraints: vec![] - }, - SequenceOrSetMember { + }) + ], + extension_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "testMember1".into(), tag: None, ty: ASN1Type::Integer(Integer { distinguished_values: None, constraints: vec![Constraint::SubtypeConstraint(ElementSet { - extensible: false, - set: crate::intermediate::constraints::ElementOrSetOperation::Element( - crate::intermediate::constraints::SubtypeElement::SingleValue { - value: ASN1Value::Integer(4), - extensible: true - } - ) - })] + extensible: false, + set: crate::intermediate::constraints::ElementOrSetOperation::Element( + crate::intermediate::constraints::SubtypeElement::SingleValue { + value: ASN1Value::Integer(4), + extensible: true + } + ) + })] }), default_value: Some(ASN1Value::Integer(4)), is_optional: true, constraints: vec![] - } - ] + }), + ], + suffix_components: vec![], }, &"Parent".into(), ) diff --git a/rasn-compiler/src/generator/typescript/utils.rs b/rasn-compiler/src/generator/typescript/utils.rs index 53c44572..2426780e 100644 --- a/rasn-compiler/src/generator/typescript/utils.rs +++ b/rasn-compiler/src/generator/typescript/utils.rs @@ -1,7 +1,6 @@ use num::pow::Pow; use crate::generator::error::GeneratorError; - use super::{ types::{BitString, Choice, SequenceOrSet}, ASN1Type, ASN1Value, @@ -62,8 +61,7 @@ pub fn format_sequence_or_set_members(se: &SequenceOrSet) -> String { r#"{{ {}{} }}"#, - se.members - .iter() + se.direct_members() .map(|m| format!( r#"{}{}: {},"#, to_jer_identifier(&m.name), @@ -72,8 +70,11 @@ pub fn format_sequence_or_set_members(se: &SequenceOrSet) -> String { )) .collect::>() .join("\n"), - se.extensible - .map_or(String::new(), |_| String::from("\n\t[key: string]: any")) + if se.extensible { + String::from("\n\t[key: string]: any") + } else { + String::new() + } ) } diff --git a/rasn-compiler/src/intermediate/mod.rs b/rasn-compiler/src/intermediate/mod.rs index 7d8154d2..5e4fdaff 100644 --- a/rasn-compiler/src/intermediate/mod.rs +++ b/rasn-compiler/src/intermediate/mod.rs @@ -578,13 +578,20 @@ impl ToplevelDefinition { id: t.id, }); match &mut ty.ty { - ASN1Type::Sequence(s) | ASN1Type::Set(s) => s.members.iter_mut().for_each(|m| { - m.tag = m.tag.as_ref().map(|t| AsnTag { - environment: env + &t.environment, - tag_class: t.tag_class, - id: t.id, - }); - }), + ASN1Type::Sequence(s) | ASN1Type::Set(s) => { + for s in [&mut s.fixed_components, &mut s.suffix_components, &mut s.extension_components] { + s.iter_mut().for_each(|m| { + if let SequenceComponent::Member(m) = m { + m.tag = m.tag.as_ref().map(|t| AsnTag { + environment: env + &t.environment, + tag_class: t.tag_class, + id: t.id, + }); + } + }) + + } + }, ASN1Type::Choice(c) => c.options.iter_mut().for_each(|o| { o.tag = o.tag.as_ref().map(|t| AsnTag { environment: env + &t.environment, @@ -950,6 +957,7 @@ impl ASN1Type { ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => Some(s.constraints()), ASN1Type::ElsewhereDeclaredType(e) => Some(e.constraints()), ASN1Type::InformationObjectFieldReference(f) => Some(f.constraints()), + ASN1Type::ObjectIdentifier(o) => Some(&o.constraints), _ => None, } } @@ -969,6 +977,7 @@ impl ASN1Type { ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => Some(s.constraints_mut()), ASN1Type::ElsewhereDeclaredType(e) => Some(e.constraints_mut()), ASN1Type::InformationObjectFieldReference(f) => Some(f.constraints_mut()), + ASN1Type::ObjectIdentifier(o) => Some(&mut o.constraints), _ => None, } } diff --git a/rasn-compiler/src/intermediate/types.rs b/rasn-compiler/src/intermediate/types.rs index 2c129f97..71709e97 100644 --- a/rasn-compiler/src/intermediate/types.rs +++ b/rasn-compiler/src/intermediate/types.rs @@ -315,15 +315,49 @@ impl From<(Option>, (Option, ASN1Type))> for SequenceOrS /// *As defined in Rec. ITU-T X.680 (02/2021) §25 and §27* #[derive(Debug, Clone, PartialEq)] pub struct SequenceOrSet { - pub components_of: Vec, - pub extensible: Option, + pub fixed_components: Vec, + pub extension_components: Vec, + pub suffix_components: Vec, + pub extensible: bool, pub constraints: Vec, - pub members: Vec, +} + +impl SequenceOrSet { + pub fn direct_members(&self) -> impl Iterator { + [&self.fixed_components, &self.extension_components, &self.suffix_components] + .into_iter() + .flat_map(|x| x) + .flat_map(|x| { + if let SequenceComponent::Member(m) = x { + Some(m) + } else { + None + } + }) + } + + pub fn direct_members_mut(&mut self) -> impl Iterator { + [&mut self.fixed_components, &mut self.extension_components, &mut self.suffix_components] + .into_iter() + .flat_map(|x| x) + .flat_map(|x| { + if let SequenceComponent::Member(m) = x { + Some(m) + } else { + None + } + }) + } + + pub fn extension_range(&self) -> std::ops::Range { + self.fixed_components.len() .. self.fixed_components.len() + self.extension_components.len() + } } impl IterNameTypes for SequenceOrSet { fn iter_name_types(&self) -> impl Iterator { - self.members.iter().map(|m| (m.name.as_str(), &m.ty)) + self.direct_members() + .map(|m| (m.name.as_str(), &m.ty)) } } @@ -331,8 +365,10 @@ impl From<( ( Vec, - Option, - Option>, + Option<( + Vec, + Vec, + )>, ), Option>, )> for SequenceOrSet @@ -341,27 +377,23 @@ impl mut value: ( ( Vec, - Option, - Option>, + Option<( + Vec, + Vec, + )>, ), Option>, ), ) -> Self { - let index_of_first_extension = value.0 .0.len(); - value.0 .0.append(&mut value.0 .2.unwrap_or_default()); - let mut components_of = vec![]; - let mut members = vec![]; - for comp in value.0 .0 { - match comp { - SequenceComponent::Member(m) => members.push(m), - SequenceComponent::ComponentsOf(c) => components_of.push(c), - } - } + let extensible = value.0 .1.is_some(); + let (extension_components, suffix_components) = value.0 .1.unwrap_or_default(); + SequenceOrSet { - components_of, + fixed_components: value.0 .0, + extension_components, + suffix_components, constraints: value.1.unwrap_or_default(), - extensible: value.0 .1.map(|_| index_of_first_extension), - members, + extensible, } } } @@ -369,9 +401,9 @@ impl impl From<( ( - Vec, + Vec, Option, - Option>, + Option>, ), Option>, )> for SequenceOrSet @@ -379,20 +411,19 @@ impl fn from( mut value: ( ( - Vec, + Vec, Option, - Option>, + Option>, ), Option>, ), ) -> Self { - let index_of_first_extension = value.0 .0.len(); - value.0 .0.append(&mut value.0 .2.unwrap_or_default()); SequenceOrSet { - components_of: vec![], + fixed_components: value.0 .0.into_iter().collect(), + extension_components: value.0 .2.into_iter().flat_map(|x| x).collect(), + suffix_components: vec![], constraints: value.1.unwrap_or_default(), - extensible: value.0 .1.map(|_| index_of_first_extension), - members: value.0 .0, + extensible: value.0 .1.is_some(), } } } diff --git a/rasn-compiler/src/lexer/constraint.rs b/rasn-compiler/src/lexer/constraint.rs index 7142f430..901d24ce 100644 --- a/rasn-compiler/src/lexer/constraint.rs +++ b/rasn-compiler/src/lexer/constraint.rs @@ -59,7 +59,7 @@ pub fn set_operator(input: Input<'_>) -> ParserResult<'_, SetOperator> { )))(input) } -fn element_set(input: Input<'_>) -> ParserResult<'_, ElementSet> { +pub fn element_set(input: Input<'_>) -> ParserResult<'_, ElementSet> { into(pair( alt(( map(set_operation, ElementOrSetOperation::SetOperation), diff --git a/rasn-compiler/src/lexer/mod.rs b/rasn-compiler/src/lexer/mod.rs index a3039cd2..6226d4be 100644 --- a/rasn-compiler/src/lexer/mod.rs +++ b/rasn-compiler/src/lexer/mod.rs @@ -20,7 +20,7 @@ use nom::{ use crate::{ input::{context_boundary, Input}, - intermediate::{information_object::*, *}, + intermediate::{information_object::*, constraints::Constraint, *}, }; use self::{ @@ -94,6 +94,7 @@ pub(crate) fn asn_module( ToplevelDefinition::Information, ), map(top_level_type_declaration, ToplevelDefinition::Type), + map(top_level_valueset_declaration, ToplevelDefinition::Type), map(top_level_value_declaration, ToplevelDefinition::Value), )))), context_boundary(skip_ws_and_comments(alt((end, encoding_control)))), @@ -231,6 +232,32 @@ fn top_level_value_declaration(input: Input<'_>) -> ParserResult<'_, ToplevelVal ))(input) } +fn top_level_valueset_declaration(input: Input<'_>) -> ParserResult<'_, ToplevelTypeDefinition> { + map( + tuple(( + skip_ws(many0(comment)), + skip_ws(context_boundary(title_case_identifier)), + skip_ws_and_comments(opt(parameterization)), + skip_ws_and_comments(asn1_type), + preceded(assignment, in_braces(element_set)) + )), + |mut value| { + if let Some(constraints) = value.3.constraints_mut() { + constraints.push(Constraint::SubtypeConstraint(value.4)) + } else { + eprintln!("{name}: unable to push constraints to {ty:?}", name=value.1, ty=value.3); + } + ToplevelTypeDefinition{ + comments: value.0.join("\n"), + tag: None, + name: value.1.to_string(), + ty: value.3, + parameterization: value.2, + index: None, + } + } + )(input) +} fn top_level_information_object_declaration( input: Input<'_>, ) -> ParserResult<'_, ToplevelInformationDefinition> { diff --git a/rasn-compiler/src/lexer/sequence.rs b/rasn-compiler/src/lexer/sequence.rs index 5735cd14..f8aa7094 100644 --- a/rasn-compiler/src/lexer/sequence.rs +++ b/rasn-compiler/src/lexer/sequence.rs @@ -5,12 +5,12 @@ use nom::{ multi::{many0, separated_list0, separated_list1}, sequence::{terminated, tuple}, }; - +use nom::combinator::value; use crate::{ common::INTERNAL_EXTENSION_GROUP_NAME_PREFIX, intermediate::{types::*, *}, }; - +use crate::lexer::util::opt_delimited; use super::{common::optional_comma, constraint::constraint, *}; pub fn sequence_value(input: Input<'_>) -> ParserResult<'_, ASN1Value> { @@ -33,6 +33,7 @@ pub fn sequence_value(input: Input<'_>) -> ParserResult<'_, ASN1Value> { )(input) } + /// Tries to parse an ASN1 SEQUENCE /// /// *`input` - [Input]-wrapped string slice to be matched against @@ -48,17 +49,38 @@ pub fn sequence(input: Input<'_>) -> ParserResult<'_, ASN1Type> { preceded( skip_ws_and_comments(tag(SEQUENCE)), pair( - in_braces(tuple(( - many0(terminated( - skip_ws_and_comments(sequence_component), - optional_comma, - )), - opt(terminated(extension_marker, opt(char(COMMA)))), - opt(many0(terminated( - skip_ws_and_comments(alt((extension_group, sequence_component))), - optional_comma, - ))), - ))), + in_braces( + pair( + separated_list0( + skip_ws_and_comments(char(COMMA)), + sequence_component + ), + opt(preceded( + pair( + skip_ws_and_comments(char(COMMA)), + extension_marker + ), + pair( + many0( + preceded( + skip_ws_and_comments(char(COMMA)), + alt((sequence_component, extension_group)), + ) + ), + map( + opt( + preceded( + pair(skip_ws_and_comments(char(COMMA)), extension_marker), + many0( + preceded(skip_ws_and_comments(char(COMMA)), sequence_component)) + ) + ), + |suf| suf.unwrap_or_default() + ) + ) + )) + ), + ), opt(constraint), ), ), @@ -79,24 +101,26 @@ fn extension_group(input: Input<'_>) -> ParserResult<'_, SequenceComponent> { ))), )), |ext_group| { - let mut components_of = vec![]; - let mut members = vec![]; - for comp in ext_group { - match comp { - SequenceComponent::Member(m) => members.push(m), - SequenceComponent::ComponentsOf(c) => components_of.push(c), - } - } + // TODO: Make this None, so that generators can choose their own names + let name = + String::from(INTERNAL_EXTENSION_GROUP_NAME_PREFIX) + + ext_group.iter().find_map(|c| { + if let SequenceComponent::Member(m) = c { + Some(m.name.as_str()) + } else { + None + } + }).unwrap_or(""); SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, - name: String::from(INTERNAL_EXTENSION_GROUP_NAME_PREFIX) - + &members.first().unwrap().name, + name, tag: None, ty: ASN1Type::Sequence(SequenceOrSet { - components_of, - extensible: None, + fixed_components: ext_group, + extension_components: vec![], + suffix_components: vec![], + extensible: false, constraints: vec![], - members, }), default_value: None, is_optional: false, @@ -213,10 +237,10 @@ mod tests { .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![],extensible: Some(1), + extensible: true, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "clusterBoundingBoxShape".into(), tag: None, @@ -226,8 +250,10 @@ is_recursive: false, default_value: None, is_optional: true, constraints: vec![], - } - ] + }) + ], + extension_components: vec![], + suffix_components: vec![], }) ) } @@ -245,11 +271,10 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "value".into(), tag: None, @@ -261,8 +286,8 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![] - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "confidence".into(), @@ -275,8 +300,10 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![], - } - ] + }), + ], + extension_components: vec![], + suffix_components: vec![], }) ) } @@ -296,11 +323,10 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "xCoordinate".into(), @@ -313,8 +339,8 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "yCoordinate".into(), tag: None, @@ -326,8 +352,8 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "zCoordinate".into(), tag: None, @@ -339,8 +365,10 @@ is_recursive: false, default_value: None, is_optional: true, constraints: vec![], - } - ] + }), + ], + extension_components: vec![], + suffix_components: vec![], }) ) } @@ -361,11 +389,10 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: Some(3), + extensible: true, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "horizontalPositionConfidence".into(), tag: None, @@ -377,8 +404,8 @@ is_recursive: false, default_value: None, is_optional: true, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "deltaAltitude".into(), tag: None, @@ -393,8 +420,8 @@ is_recursive: false, }), is_optional: true, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "altitudeConfidence".into(), tag: None, @@ -409,8 +436,10 @@ is_recursive: false, }), is_optional: true, constraints: vec![], - } - ] + }) + ], + extension_components: vec![], + suffix_components: vec![], }) ) } @@ -430,11 +459,10 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: Some(3), + extensible: true, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "unNumber".into(), tag: None, @@ -452,8 +480,8 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "limitedQuantity".into(), tag: None, @@ -463,8 +491,8 @@ is_recursive: false, default_value: Some(ASN1Value::Boolean(false)), is_optional: true, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "emergencyActionCode".into(), tag: None, @@ -487,8 +515,10 @@ is_recursive: false, default_value: None, is_optional: true, constraints: vec![], - } - ] + }) + ], + extension_components: vec![], + suffix_components: vec![], }) ) } @@ -515,20 +545,18 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: Some(1), + extensible: true, constraints: vec![], - members: vec![SequenceOrSetMember { + fixed_components: vec![SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "nested".into(), tag: None, ty: ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: Some(3), + extensible: true, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "wow".into(), @@ -541,8 +569,8 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "this-is-annoying".into(), @@ -553,17 +581,16 @@ is_recursive: false, default_value: Some(ASN1Value::Boolean(true)), is_optional: true, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "another".into(), tag: None, ty: ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![SequenceOrSetMember { + fixed_components: vec![SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "inner".into(), @@ -589,18 +616,24 @@ is_recursive: false, default_value: Some(ASN1Value::BitString(vec![false])), is_optional: true, constraints: vec![], - }] + })], + extension_components: vec![], + suffix_components: vec![], }), default_value: None, is_optional: true, constraints: vec![], - } - ] + }) + ], + extension_components: vec![], + suffix_components: vec![] }), default_value: None, is_optional: false, constraints: vec![], - }] + })], + extension_components: vec![], + suffix_components: vec![] }) ) } @@ -645,11 +678,10 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: Some(1), + extensible: true, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "item-code".into(), tag: None, @@ -667,17 +699,17 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![] - }, - SequenceOrSetMember { + })], + extension_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "ext_group_alternate-item-code".into(), tag: None, ty: ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "alternate-item-code".into(), tag: None, @@ -699,8 +731,8 @@ is_recursive: false, default_value: None, is_optional: false, constraints: vec![] - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "and-another".into(), tag: None, @@ -710,14 +742,17 @@ is_recursive: false, default_value: Some(ASN1Value::Boolean(true)), is_optional: true, constraints: vec![] - } - ] + }) + ], + extension_components: vec![], + suffix_components: vec![] }), default_value: None, is_optional: false, constraints: vec![] - } - ] + }) + ], + suffix_components: vec![] }) ) } @@ -735,22 +770,26 @@ is_recursive: false, .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec!["TypeA".into()], - extensible: None, + extensible: false, constraints: vec![], - members: vec![SequenceOrSetMember { - is_recursive: false, - name: "bilateral-information".into(), - tag: None, - ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere { - parent: None, - identifier: "TypeB".into(), + fixed_components: vec![ + SequenceComponent::ComponentsOf("TypeA".into()), + SequenceComponent::Member(SequenceOrSetMember { + is_recursive: false, + name: "bilateral-information".into(), + tag: None, + ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere { + parent: None, + identifier: "TypeB".into(), + constraints: vec![] + }), + default_value: None, + is_optional: false, constraints: vec![] }), - default_value: None, - is_optional: false, - constraints: vec![] - }] + ], + extension_components: vec![], + suffix_components: vec![], }) ) } @@ -842,10 +881,9 @@ integrityCheckValue ICV OPTIONAL .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![SequenceOrSetMember { + fixed_components: vec![SequenceComponent::Member(SequenceOrSetMember { name: "ages".into(), tag: None, ty: ASN1Type::SequenceOf(SequenceOrSetOf { @@ -868,7 +906,9 @@ integrityCheckValue ICV OPTIONAL is_optional: false, is_recursive: false, constraints: vec![], - }], + })], + extension_components: vec![], + suffix_components: vec![], },) ) } @@ -888,10 +928,9 @@ integrityCheckValue ICV OPTIONAL .unwrap() .1, ASN1Type::Sequence(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![SequenceOrSetMember { + fixed_components: vec![SequenceComponent::Member(SequenceOrSetMember { name: "member".into(), tag: None, ty: ASN1Type::SequenceOf(SequenceOrSetOf { @@ -911,7 +950,9 @@ integrityCheckValue ICV OPTIONAL is_optional: false, is_recursive: false, constraints: vec![], - },], + })], + extension_components: vec![], + suffix_components: vec![], },) ) } diff --git a/rasn-compiler/src/lexer/set.rs b/rasn-compiler/src/lexer/set.rs index 75f9b2ff..fd8e4fd7 100644 --- a/rasn-compiler/src/lexer/set.rs +++ b/rasn-compiler/src/lexer/set.rs @@ -46,7 +46,7 @@ pub fn set(input: Input<'_>) -> ParserResult<'_, ASN1Type> { #[cfg(test)] mod tests { use set::types::{CharacterString, SequenceOrSet, SequenceOrSetMember, SequenceOrSetOf}; - + use crate::intermediate::types::SequenceComponent; use super::*; #[test] @@ -60,11 +60,10 @@ mod tests { .unwrap() .1, ASN1Type::Set(SequenceOrSet { - components_of: vec![], - extensible: None, + extensible: false, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "title".into(), tag: None, @@ -75,8 +74,8 @@ mod tests { default_value: None, is_optional: false, constraints: vec![], - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "children".into(), tag: None, @@ -92,8 +91,10 @@ mod tests { default_value: Some(ASN1Value::SequenceOrSet(vec![])), is_optional: true, constraints: vec![] - } - ] + }), + ], + extension_components: vec![], + suffix_components: vec![], }) ); } diff --git a/rasn-compiler/src/lexer/tests/mod.rs b/rasn-compiler/src/lexer/tests/mod.rs index 7fb912c6..e3372627 100644 --- a/rasn-compiler/src/lexer/tests/mod.rs +++ b/rasn-compiler/src/lexer/tests/mod.rs @@ -426,11 +426,10 @@ fn parses_parameterized_declaration() { index: None, name: "RegionalExtension".into(), ty: ASN1Type::Sequence(SequenceOrSet { - extensible: None, - components_of: vec![], + extensible: false, constraints: vec![], - members: vec![ - SequenceOrSetMember { + fixed_components: vec![ + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "regionId".into(), tag: None, @@ -450,8 +449,8 @@ fn parses_parameterized_declaration() { default_value: None, is_optional: false, constraints: vec![] - }, - SequenceOrSetMember { + }), + SequenceComponent::Member(SequenceOrSetMember { is_recursive: false, name: "regExtValue".into(), tag: None, @@ -476,8 +475,10 @@ fn parses_parameterized_declaration() { default_value: None, is_optional: false, constraints: vec![] - } - ] + }) + ], + extension_components: vec![], + suffix_components: vec![], }), parameterization: Some(Parameterization { parameters: vec![ParameterizationArgument { diff --git a/rasn-compiler/src/validator/linking/mod.rs b/rasn-compiler/src/validator/linking/mod.rs index e4f1d881..292cde7d 100644 --- a/rasn-compiler/src/validator/linking/mod.rs +++ b/rasn-compiler/src/validator/linking/mod.rs @@ -55,7 +55,7 @@ impl ToplevelDefinition { | ToplevelDefinition::Type(ToplevelTypeDefinition { ty: ASN1Type::Set(s), .. - }) => s.members.iter().any(|m| { + }) => s.direct_members().any(|m| { m.constraints .iter() .any(|c| matches!(c, Constraint::Parameter(_))) @@ -263,7 +263,7 @@ impl ASN1Type { ) -> Result<(), GrammarError> { match self { ASN1Type::Set(ref mut s) | ASN1Type::Sequence(ref mut s) => { - s.members.iter_mut().try_for_each(|m| { + s.direct_members_mut().try_for_each(|m| { m.ty.collect_supertypes(tlds)?; m.default_value .as_mut() @@ -283,7 +283,7 @@ impl ASN1Type { match self { ASN1Type::ChoiceSelectionType(_) => true, ASN1Type::Sequence(s) | ASN1Type::Set(s) => { - s.members.iter().any(|m| m.ty.has_choice_selection_type()) + s.direct_members().any(|m| m.ty.has_choice_selection_type()) } ASN1Type::Choice(c) => c.options.iter().any(|o| o.ty.has_choice_selection_type()), ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => { @@ -311,8 +311,7 @@ impl ASN1Type { } } ASN1Type::Sequence(s) | ASN1Type::Set(s) => s - .members - .iter_mut() + .direct_members_mut() .try_for_each(|m| m.ty.link_choice_selection_type(tlds)), ASN1Type::Choice(c) => c .options @@ -332,10 +331,16 @@ impl ASN1Type { .iter() .any(|o| o.ty.contains_components_of_notation()), ASN1Type::Set(s) | ASN1Type::Sequence(s) => { - !s.components_of.is_empty() - || s.members - .iter() - .any(|m| m.ty.contains_components_of_notation()) + fn contains_components_of(members: &Vec) -> bool { + members.iter() + .any(|m| match m { + SequenceComponent::Member(m) => m.ty.contains_components_of_notation(), + SequenceComponent::ComponentsOf(_) => true, + }) + } + [&s.fixed_components, &s.extension_components, &s.suffix_components] + .into_iter() + .any(contains_components_of) } ASN1Type::SequenceOf(so) => so.element_type.contains_components_of_notation(), _ => false, @@ -352,32 +357,38 @@ impl ASN1Type { .iter_mut() .any(|o| o.ty.link_components_of_notation(tlds)), ASN1Type::Set(s) | ASN1Type::Sequence(s) => { - let mut member_linking = s - .members - .iter_mut() - .any(|m| m.ty.link_components_of_notation(tlds)); - // TODO: properly link components of in extensions - // TODO: link components of Class field, such as COMPONENTS OF BILATERAL.&id - for comp_link in &s.components_of { - if let Some(ToplevelDefinition::Type(linked)) = tlds.get(comp_link) { - if let ASN1Type::Sequence(linked_seq) = &linked.ty { - linked_seq - .members - .iter() - .enumerate() - .for_each(|(index, member)| { - if index < linked_seq.extensible.unwrap_or(usize::MAX) { - if let Some(index_of_first_ext) = s.extensible { - s.extensible = Some(index_of_first_ext + 1) - } - s.members.push(member.clone()); + let mut changed = false; + for part in [&mut s.fixed_components, &mut s.extension_components, &mut s.suffix_components] { + let old_part = std::mem::replace(part, vec![]); + // TODO: properly link components of in extensions + for member in old_part { + match member { + SequenceComponent::Member(mut m) => { + changed = changed || m.ty.link_components_of_notation(tlds); + part.push(SequenceComponent::Member(m)) + }, + SequenceComponent::ComponentsOf(comp_link) => { + // TODO: ensure that COMPONENTS OF in the included type are correctly handled. + if let Some(ToplevelDefinition::Type(linked)) = tlds.get(&comp_link) { + if let ASN1Type::Sequence(linked_seq) = &linked.ty { + let ext_range = linked_seq.extension_range(); + linked_seq + .direct_members() + .enumerate() + .for_each(|(index, member)| { + if !ext_range.contains(&index) { + part.push(SequenceComponent::Member(member.clone())); + } + }); + changed = true; } - }); - member_linking = true; + } + } } } } - member_linking + // TODO: link components of Class field, such as COMPONENTS OF BILATERAL.&id + changed } ASN1Type::SequenceOf(so) => so.element_type.link_components_of_notation(tlds), _ => false, @@ -412,7 +423,7 @@ impl ASN1Type { for b in s.constraints.iter_mut() { b.link_cross_reference(name, tlds)?; } - for m in s.members.iter_mut() { + for m in s.direct_members_mut() { if let Some(replacement) = m.ty.link_constraint_reference(name, tlds)? { m.ty = replacement; } @@ -588,7 +599,7 @@ impl ASN1Type { // it will be boxed and constitute a recursion // boundary between `self` and the option type !opt.is_recursive && opt.ty.recurses(name, tlds, reference_graph.clone())), - ASN1Type::Sequence(s) | ASN1Type::Set(s) => s.members.iter().any(|m| + ASN1Type::Sequence(s) | ASN1Type::Set(s) => s.direct_members().any(|m| // if a member is already marked recursive, // it will be boxed and thus constitutes a recursion // boundary between `self` and the member type @@ -620,7 +631,7 @@ impl ASN1Type { } ASN1Type::Set(s) | ASN1Type::Sequence(s) => { let mut children = Vec::new(); - for member in &mut s.members { + for member in s.direct_members_mut() { member.is_recursive = member.ty.recurses(name, tlds, Vec::new()); let mem_ty_name = member.ty.as_str().into_owned(); let mut mem_children = member.ty.mark_recursive(&mem_ty_name, tlds)?; @@ -671,7 +682,7 @@ impl ASN1Type { ) -> Result<(), GrammarError> { match self { ASN1Type::Sequence(s) | ASN1Type::Set(s) => { - for m in &mut s.members { + for m in s.direct_members_mut() { if let Some(constraints) = m.ty.constraints_mut() { for c in constraints { if let Constraint::TableConstraint(TableConstraint { @@ -712,8 +723,7 @@ impl ASN1Type { .iter_mut() .try_for_each(|o| o.ty.link_elsewhere_declared(tlds)), ASN1Type::Set(s) | ASN1Type::Sequence(s) => s - .members - .iter_mut() + .direct_members_mut() .try_for_each(|o| o.ty.link_elsewhere_declared(tlds)), ASN1Type::SequenceOf(s) | ASN1Type::SetOf(s) => { s.element_type.link_elsewhere_declared(tlds) @@ -781,7 +791,7 @@ impl ASN1Type { } ASN1Type::Set(s) | ASN1Type::Sequence(s) => { s.constraints.iter().any(|c| c.has_cross_reference()) - || s.members.iter().any(|m| { + || s.direct_members().any(|m| { m.ty.contains_constraint_reference() || m.default_value .as_ref() @@ -803,7 +813,7 @@ impl ASN1Type { pub fn references_class_by_name(&self) -> bool { match self { ASN1Type::Choice(c) => c.options.iter().any(|o| o.ty.references_class_by_name()), - ASN1Type::Sequence(s) => s.members.iter().any(|m| m.ty.references_class_by_name()), + ASN1Type::Sequence(s) => s.direct_members().any(|m| m.ty.references_class_by_name()), ASN1Type::SequenceOf(so) => so.element_type.references_class_by_name(), ASN1Type::InformationObjectFieldReference(io_ref) => { matches!( @@ -832,20 +842,15 @@ impl ASN1Type { .collect(), constraints: c.constraints, }), - ASN1Type::Sequence(s) => ASN1Type::Sequence(SequenceOrSet { - extensible: s.extensible, - constraints: s.constraints, - components_of: s.components_of, - members: s - .members - .into_iter() - .map(|mut member| { - member.constraints = vec![]; - member.ty = member.ty.resolve_class_reference(tlds); - member - }) - .collect(), - }), + ASN1Type::Sequence(mut s) => { + for member in s.direct_members_mut() { + // TODO: document why the constraints are being removed here + member.constraints = vec![]; + let old_ty = std::mem::replace(&mut member.ty, ASN1Type::EmbeddedPdv); + member.ty = old_ty.resolve_class_reference(tlds); + } + ASN1Type::Sequence(s) + }, ASN1Type::InformationObjectFieldReference(_) => self.reassign_type_for_ref(tlds), _ => self, } @@ -1395,7 +1400,7 @@ impl ASN1Value { type_name: Option<&String>, ) -> Result { val.iter_mut().try_for_each(|v| { - if let Some(member) = s.members.iter().find(|m| Some(&m.name) == v.0.as_ref()) { + if let Some(member) = s.direct_members().find(|m| Some(&m.name) == v.0.as_ref()) { let type_name = match (member.ty.is_builtin_type(), type_name) { (true, Some(parent)) => Some( INTERNAL_NESTED_TYPE_NAME_PREFIX.to_owned() + &member.name + "$" + parent, @@ -1419,8 +1424,7 @@ impl ASN1Value { } })?; - s.members - .iter() + s.direct_members() .map(|member| { val.iter() .find_map(|(name, value)| {