15. The REF-AS-TYPE Encoding Instruction
The REF-AS-TYPE encoding instruction causes values of the Markup ASN.1 type to be restricted to conform to the content and attributes permitted by a nominated element type declaration and its associated attribute-list declarations in an external DTD subset.
The notation for a REF-AS-TYPE encoding instruction is defined as follows: RefAsTypeInstruction ::= "REF-AS-TYPE" NameValue RefParameters Taken together, the NameValue and the ContextParameter of the RefParameters (if present) MUST reference an element type declaration in an external DTD subset that is conformant with Namespaces in XML 1.0 [XMLNS10]. The referenced element type declaration MUST NOT require the presence of attributes of type ENTITY or ENTITIES. Aside: Entity declarations are not supported by CRXER. Example The product element type declaration can be referenced as a type in an ASN.1 definition: SEQUENCE OF inventoryItem [REF-AS-TYPE "product" CONTEXT "http://www.example.com/inventory"] Markup Here is the ASN.X translation of this definition: <sequenceOf> <element name="inventoryItem"> <type elementType="product" context="http://www.example.com/inventory"/> </element> </sequenceOf> Note that when an element type declaration is referenced as a type, the Name of the element type declaration does not contribute to RXER encodings. For example, child elements in the RXER encoding of values of the above SEQUENCE OF type would resemble the following: <inventoryItem name="hammer" partNumber="1543" quantity="29"/>
16. The SCHEMA-IDENTITY Encoding Instruction
The SCHEMA-IDENTITY encoding instruction associates a unique identifier, a URI [URI], with the ASN.1 module containing the encoding instruction. This encoding instruction has no effect on an RXER encoder but does have an effect on the translation of an ASN.1 specification into an ASN.X representation. The notation for a SCHEMA-IDENTITY encoding instruction is defined as follows: SchemaIdentityInstruction ::= "SCHEMA-IDENTITY" AnyURIValue The character string specified by the AnyURIValue of each SCHEMA-IDENTITY encoding instruction MUST be distinct. In particular, successive versions of an ASN.1 module must each have a different schema identity URI value.17. The SIMPLE-CONTENT Encoding Instruction
The SIMPLE-CONTENT encoding instruction causes an RXER encoder to encode a value of a component of a SEQUENCE or SET type without encapsulation in a child element. The notation for a SIMPLE-CONTENT encoding instruction is defined as follows: SimpleContentInstruction ::= "SIMPLE-CONTENT" A NamedType subject to a SIMPLE-CONTENT encoding instruction SHALL be in a ComponentType in a ComponentTypeList in a RootComponentTypeList. At most one such NamedType of a SEQUENCE or SET type is permitted to be subject to a SIMPLE-CONTENT encoding instruction. If any component is subject to a SIMPLE-CONTENT encoding instruction, then all other components in the same SEQUENCE or SET type definition MUST be attribute components. These tests are applied after the COMPONENTS OF transformation specified in X.680, Clause 24.4 [X.680]. Aside: Child elements and simple content are mutually exclusive. Specification writers should note that use of the SIMPLE-CONTENT encoding instruction on a component of an extensible SEQUENCE or SET type means that all future extensions to the SEQUENCE or SET type are restricted to being attribute components with the limited set of types that are permitted for attribute components. Using an ATTRIBUTE encoding instruction instead of a SIMPLE-CONTENT encoding instruction avoids this limitation.
The base type of the type of a NamedType that is subject to a SIMPLE-CONTENT encoding instruction SHALL NOT be: (1) a SET or SET OF type, or (2) a CHOICE type where the ChoiceType is not subject to a UNION encoding instruction, or (3) a SEQUENCE type other than the one defining the QName type from the AdditionalBasicDefinitions module [RXER] (i.e., QName is allowed), or (4) a SEQUENCE OF type where the SequenceOfType is not subject to a LIST encoding instruction, or (5) an open type. If the type of a NamedType subject to a SIMPLE-CONTENT encoding instruction has abstract values with an empty character data translation [RXER] (i.e., an empty encoding), then the NamedType SHALL NOT be marked OPTIONAL or DEFAULT. Example SEQUENCE { units [ATTRIBUTE] UTF8String, amount [SIMPLE-CONTENT] INTEGER }18. The TARGET-NAMESPACE Encoding Instruction
The TARGET-NAMESPACE encoding instruction associates an XML namespace name [XMLNS10], a URI [URI], with the type, object class, value, object, and object set references defined in the ASN.1 module containing the encoding instruction. In addition, it associates the namespace name with each top-level NamedType in the RXER encoding control section. The notation for a TARGET-NAMESPACE encoding instruction is defined as follows: TargetNamespaceInstruction ::= "TARGET-NAMESPACE" AnyURIValue Prefix ? Prefix ::= "PREFIX" NCNameValue The AnyURIValue SHALL NOT specify an empty string.
Definition (target namespace): If an ASN.1 module contains a TARGET-NAMESPACE encoding instruction, then the target namespace of the module is the character string specified by the AnyURIValue of the TARGET-NAMESPACE encoding instruction; otherwise, the target namespace of the module is said to be absent. Two or more ASN.1 modules MAY have the same non-absent target namespace if and only if the expanded names of the top-level attribute components are distinct across all those modules, the expanded names of the top-level element components are distinct across all those modules, and the defined type, object class, value, object, and object set references are distinct in their category across all those modules. The Prefix, if present, suggests an NCName to use as the namespace prefix in namespace declarations involving the target namespace. An RXER encoder is not obligated to use the nominated namespace prefix. If there are no top-level components, then the RXER encodings produced using a module with a TARGET-NAMESPACE encoding instruction are backward compatible with the RXER encodings produced by the same module without the TARGET-NAMESPACE encoding instruction.19. The TYPE-AS-VERSION Encoding Instruction
The TYPE-AS-VERSION encoding instruction causes an RXER encoder to include an xsi:type attribute in the encoding of a value of the component to which the encoding instruction is applied. This attribute allows an XML Schema [XSD1] validator to select, if available, the appropriate XML Schema translation for the version of the ASN.1 specification used to create the encoding. Aside: Translations of an ASN.1 specification into a compatible XML Schema are expected to be slightly different across versions because of progressive extensions to the ASN.1 specification. Any incompatibilities between these translations can be accommodated if each version uses a different target namespace. The target namespace will be evident in the value of the xsi:type attribute and will cause an XML Schema validator to use the appropriate version. This mechanism also accommodates an ASN.1 type that is renamed in a later version of the ASN.1 specification. The notation for a TYPE-AS-VERSION encoding instruction is defined as follows: TypeAsVersionInstruction ::= "TYPE-AS-VERSION"
The Type in a NamedType that is subject to a TYPE-AS-VERSION encoding instruction MUST be a namespace-qualified reference [RXER]. The addition of a TYPE-AS-VERSION encoding instruction does not affect the backward compatibility of RXER encodings. Aside: In a translation of an ASN.1 specification into XML Schema, any Type in a NamedType that is subject to a TYPE-AS-VERSION encoding instruction is expected to be translated into the XML Schema anyType so that the xsi:type attribute acts as a switch to select the appropriate version.20. The TYPE-REF Encoding Instruction
The TYPE-REF encoding instruction causes values of the Markup ASN.1 type to be restricted to conform to a specific XML Schema named type, RELAX NG named pattern or an ASN.1 defined type. Aside: Referencing an ASN.1 type in a TYPE-REF encoding instruction does not have the effect of imposing a requirement to preserve the Infoset [INFOSET] representation of the RXER encoding of an abstract value of the type. It is still sufficient to preserve just the abstract value. The notation for a TYPE-REF encoding instruction is defined as follows: TypeRefInstruction ::= "TYPE-REF" QNameValue RefParameters Taken together, the QNameValue and the ContextParameter of the RefParameters (if present) MUST reference an XML Schema named type, a RELAX NG named pattern, or an ASN.1 defined type. A referenced XML Schema type MUST NOT require the presence of values for the XML Schema ENTITY or ENTITIES types. Aside: Entity declarations are not supported by CRXER. The QNameValue SHALL NOT be a direct reference to the XML Schema NOTATION type [XSD2] (i.e., the namespace name "http://www.w3.org/2001/XMLSchema" and local name "NOTATION"); however, a reference to an XML Schema type derived from the NOTATION type is permitted. Aside: This restriction is to ensure that the lexical space [XSD2] of the referenced type is actually populated with the names of notations [XSD1].
Example MyDecimal ::= [TYPE-REF { namespace-name "http://www.w3.org/2001/XMLSchema", local-name "decimal" }] Markup Note that the ASN.X translation of this ASN.1 type definition provides a more natural way to reference the XML Schema decimal type: <namedType xmlns:xs="http://www.w3.org/2001/XMLSchema" name="MyDecimal"> <type ref="xs:decimal" embedded="true"/> </namedType>21. The UNION Encoding Instruction
The UNION encoding instruction causes an RXER encoder to encode the value of an alternative of a CHOICE type without encapsulation in a child element. The chosen alternative is optionally indicated with a member attribute. The optional PrecedenceList also allows a specification writer to alter the order in which an RXER decoder will consider the alternatives of the CHOICE as it determines which alternative has been used (if the actual alternative has not been specified through the member attribute). The notation for a UNION encoding instruction is defined as follows: UnionInstruction ::= "UNION" AlternativesPrecedence ? AlternativesPrecedence ::= "PRECEDENCE" PrecedenceList PrecedenceList ::= identifier PrecedenceList ? The Type in the EncodingPrefixedType for a UNION encoding instruction SHALL be either: (1) a BuiltinType that is a ChoiceType, or (2) a ConstrainedType that is not a TypeWithConstraint where the Type in the ConstrainedType is one of (1) to (4), or (3) a BuiltinType that is a PrefixedType that is a TaggedType where the Type in the TaggedType is one of (1) to (4), or
(4) a BuiltinType that is a PrefixedType that is an EncodingPrefixedType where the Type in the EncodingPrefixedType is one of (1) to (4). The ChoiceType in case (1) is said to be "subject to" the UNION encoding instruction. The base type of the type of each alternative of a ChoiceType that is subject to a UNION encoding instruction SHALL NOT be: (1) a CHOICE, SET, or SET OF type, or (2) a SEQUENCE type other than the one defining the QName type from the AdditionalBasicDefinitions module [RXER] (i.e., QName is allowed), or (3) a SEQUENCE OF type where the SequenceOfType is not subject to a LIST encoding instruction, or (4) an open type. Each identifier in the PrecedenceList MUST be the identifier of a NamedType in the ChoiceType. A particular identifier SHALL NOT appear more than once in the same PrecedenceList. Every NamedType in a ChoiceType that is subject to a UNION encoding instruction MUST NOT be subject to an ATTRIBUTE, ATTRIBUTE-REF, COMPONENT-REF, GROUP, ELEMENT-REF, REF-AS-ELEMENT, SIMPLE-CONTENT, or TYPE-AS-VERSION encoding instruction. Example [UNION PRECEDENCE basicName] CHOICE { extendedName UTF8String, basicName PrintableString }22. The VALUES Encoding Instruction
The VALUES encoding instruction causes an RXER encoder to use nominated names instead of the identifiers that would otherwise appear in the encoding of a value of a BIT STRING, ENUMERATED, or INTEGER type.
The notation for a VALUES encoding instruction is defined as follows: ValuesInstruction ::= "VALUES" AllValuesMapped ? ValueMappingList ? AllValuesMapped ::= AllCapitalized | AllUppercased AllCapitalized ::= "ALL" "CAPITALIZED" AllUppercased ::= "ALL" "UPPERCASED" ValueMappingList ::= ValueMapping ValueMappingList ? ValueMapping ::= "," identifier "AS" NCNameValue The Type in the EncodingPrefixedType for a VALUES encoding instruction SHALL be either: (1) a BuiltinType that is a BitStringType with a NamedBitList, or (2) a BuiltinType that is an EnumeratedType, or (3) a BuiltinType that is an IntegerType with a NamedNumberList, or (4) a ConstrainedType that is not a TypeWithConstraint where the Type in the ConstrainedType is one of (1) to (6), or (5) a BuiltinType that is a PrefixedType that is a TaggedType where the Type in the TaggedType is one of (1) to (6), or (6) a BuiltinType that is a PrefixedType that is an EncodingPrefixedType where the Type in the EncodingPrefixedType is one of (1) to (6). The effect of this condition is to force the VALUES encoding instruction to be textually co-located with the type definition to which it applies. The BitStringType, EnumeratedType, or IntegerType in case (1), (2), or (3), respectively, is said to be "subject to" the VALUES encoding instruction. A BitStringType, EnumeratedType, or IntegerType SHALL NOT be subject to more than one VALUES encoding instruction. Each identifier in a ValueMapping MUST be an identifier appearing in the NamedBitList, Enumerations, or NamedNumberList, as the case may be.
The identifier in a ValueMapping SHALL NOT be the same as the identifier in any other ValueMapping for the same ValueMappingList. Definition (replacement name): Each identifier in a BitStringType, EnumeratedType, or IntegerType subject to a VALUES encoding instruction has a replacement name. If there is a ValueMapping for the identifier, then the replacement name is the character string specified by the NCNameValue in the ValueMapping; else if AllCapitalized is used, then the replacement name is the identifier with the first character uppercased; else if AllUppercased is used, then the replacement name is the identifier with all its characters uppercased; otherwise, the replacement name is the identifier. The replacement names for the identifiers in a BitStringType subject to a VALUES encoding instruction MUST be distinct. The replacement names for the identifiers in an EnumeratedType subject to a VALUES encoding instruction MUST be distinct. The replacement names for the identifiers in an IntegerType subject to a VALUES encoding instruction MUST be distinct. Example Traffic-Light ::= [VALUES ALL CAPITALIZED, red AS "RED"] ENUMERATED { red, -- Replacement name is RED. amber, -- Replacement name is Amber. green -- Replacement name is Green. }23. Insertion Encoding Instructions
Certain of the RXER encoding instructions are categorized as insertion encoding instructions. The insertion encoding instructions are the NO-INSERTIONS, HOLLOW-INSERTIONS, SINGULAR-INSERTIONS, UNIFORM-INSERTIONS, and MULTIFORM-INSERTIONS encoding instructions (whose notations are described respectively by NoInsertionsInstruction, HollowInsertionsInstruction, SingularInsertionsInstruction, UniformInsertionsInstruction, and MultiformInsertionsInstruction). The notation for the insertion encoding instructions is defined as follows:
InsertionsInstruction ::= NoInsertionsInstruction | HollowInsertionsInstruction | SingularInsertionsInstruction | UniformInsertionsInstruction | MultiformInsertionsInstruction NoInsertionsInstruction ::= "NO-INSERTIONS" HollowInsertionsInstruction ::= "HOLLOW-INSERTIONS" SingularInsertionsInstruction ::= "SINGULAR-INSERTIONS" UniformInsertionsInstruction ::= "UNIFORM-INSERTIONS" MultiformInsertionsInstruction ::= "MULTIFORM-INSERTIONS" Using the GROUP encoding instruction on components with extensible types can lead to situations where an unknown extension could be associated with more than one extension insertion point. The insertion encoding instructions remove this ambiguity by limiting the form that extensions can take. That is, the insertion encoding instructions indicate what extensions can be made to an ASN.1 specification without breaking forward compatibility for RXER encodings. Aside: Forward compatibility means the ability for a decoder to successfully decode an encoding containing extensions introduced into a version of the specification that is more recent than the one used by the decoder. In the most general case, an extension to a CHOICE, SET, or SEQUENCE type will generate zero or more attributes and zero or more elements, due to the potential use of the GROUP and ATTRIBUTE encoding instructions by the extension. The MULTIFORM-INSERTIONS encoding instruction indicates that the RXER encodings produced by forward-compatible extensions to a type will always consist of one or more elements and zero or more attributes. No restriction is placed on the names of the elements. Aside: Of necessity, the names of the attributes will all be different in any given encoding. The UNIFORM-INSERTIONS encoding instruction indicates that the RXER encodings produced by forward-compatible extensions to a type will always consist of one or more elements having the same expanded name, and zero or more attributes. The expanded name shared by the
elements in one particular encoding is not required to be the same as the expanded name shared by the elements in any other encoding of the extension. For example, in one encoding of the extension the elements might all be called "foo", while in another encoding of the extension they might all be called "bar". The SINGULAR-INSERTIONS encoding instruction indicates that the RXER encodings produced by forward-compatible extensions to a type will always consist of a single element and zero or more attributes. The name of the single element is not required to be the same in every possible encoding of the extension. The HOLLOW-INSERTIONS encoding instruction indicates that the RXER encodings produced by forward-compatible extensions to a type will always consist of zero elements and zero or more attributes. The NO-INSERTIONS encoding instruction indicates that no forward- compatible extensions can be made to a type. Examples of forward-compatible extensions are provided in Appendix C. The Type in the EncodingPrefixedType for an insertion encoding instruction SHALL be either: (1) a BuiltinType that is a ChoiceType where the ChoiceType is not subject to a UNION encoding instruction, or (2) a BuiltinType that is a SequenceType or SetType, or (3) a ConstrainedType that is not a TypeWithConstraint where the Type in the ConstrainedType is one of (1) to (5), or (4) a BuiltinType that is a PrefixedType that is a TaggedType where the Type in the TaggedType is one of (1) to (5), or (5) a BuiltinType that is a PrefixedType that is an EncodingPrefixedType where the Type in the EncodingPrefixedType is one of (1) to (5). Case (2) is not permitted when the insertion encoding instruction is the SINGULAR-INSERTIONS, UNIFORM-INSERTIONS, or MULTIFORM-INSERTIONS encoding instruction.
Aside: Because extensions to a SET or SEQUENCE type are serial and effectively optional, the SINGULAR-INSERTIONS, UNIFORM-INSERTIONS, and MULTIFORM-INSERTIONS encoding instructions offer no advantage over unrestricted extensions (for a SET or SEQUENCE). For example, an optional series of singular insertions generates zero or more elements and zero or more attributes, just like an unrestricted extension. The Type in case (1) or case (2) is said to be "subject to" the insertion encoding instruction. The Type in case (1) or case (2) MUST be extensible, either explicitly or by default. A Type SHALL NOT be subject to more than one insertion encoding instruction. The insertion encoding instructions indicate what kinds of extensions can be made to a type without breaking forward compatibility, but they do not prohibit extensions that do break forward compatibility. That is, it is not an error for a type's base type to contain extensions that do not satisfy an insertion encoding instruction affecting the type. However, if any such extensions are made, then a new value SHOULD be introduced into the extensible set of permitted values for a version indicator attribute, or attributes (see Section 24), whose scope encompasses the extensions. An example is provided in Appendix C.24. The VERSION-INDICATOR Encoding Instruction
The VERSION-INDICATOR encoding instruction provides a mechanism for RXER decoders to be alerted that an encoding contains extensions that break forward compatibility (see the preceding section). The notation for a VERSION-INDICATOR encoding instruction is defined as follows: VersionIndicatorInstruction ::= "VERSION-INDICATOR" A NamedType that is subject to a VERSION-INDICATOR encoding instruction MUST also be subject to an ATTRIBUTE encoding instruction. The type of the NamedType that is subject to the VERSION-INDICATOR encoding instruction MUST be directly or indirectly a constrained type where the set of permitted values is defined to be extensible. Each value represents a different version of the ASN.1 specification. Ordinarily, an application will set the value of a version indicator
attribute to be the last of these permitted values. An application MAY set the value of the version indicator attribute to the value corresponding to an earlier version of the specification if it has not used any of the extensions added in a subsequent version. If an RXER decoder encounters a value of the type that is not one of the root values or extension additions (but that is still allowed since the set of permitted values is extensible), then this indicates that the decoder is using a version of the ASN.1 specification that is not compatible with the version used to produce the encoding. In such cases, the decoder SHOULD treat the element containing the attribute as having an unknown ASN.1 type. Aside: A version indicator attribute only indicates an incompatibility with respect to RXER encodings. Other encodings are not affected because the GROUP encoding instruction does not apply to them. Examples In this first example, the decoder is using an incompatible older version if the value of the version attribute in a received RXER encoding is not 1, 2, or 3. SEQUENCE { version [ATTRIBUTE] [VERSION-INDICATOR] INTEGER (1, ..., 2..3), message MessageType } In this second example, the decoder is using an incompatible older version if the value of the format attribute in a received RXER encoding is not "1.0", "1.1", or "2.0". SEQUENCE { format [ATTRIBUTE] [VERSION-INDICATOR] UTF8String ("1.0", ..., "1.1" | "2.0"), message MessageType } An extensive example is provided in Appendix C. It is not necessary for every extensible type to have its own version indicator attribute. It would be typical for only the types of top-level element components to include a version indicator attribute, which would serve as the version indicator for all of the nested components.
25. The GROUP Encoding Instruction
The GROUP encoding instruction causes an RXER encoder to encode a value of the component to which it is applied without encapsulation as an element. It allows the construction of non-trivial content models for element content. The notation for a GROUP encoding instruction is defined as follows: GroupInstruction ::= "GROUP" The base type of the type of a NamedType that is subject to a GROUP encoding instruction SHALL be either: (1) a SEQUENCE, SET, or SET OF type, or (2) a CHOICE type where the ChoiceType is not subject to a UNION encoding instruction, or (3) a SEQUENCE OF type where the SequenceOfType is not subject to a LIST encoding instruction. The SEQUENCE type in case (1) SHALL NOT be the associated type for a built-in type, SHALL NOT be a type from the AdditionalBasicDefinitions module [RXER], and SHALL NOT contain a component that is subject to a SIMPLE-CONTENT encoding instruction. Aside: Thus, the CHARACTER STRING, EMBEDDED PDV, EXTERNAL, REAL, and QName types are excluded. The CHOICE type in case (2) SHALL NOT be a type from the AdditionalBasicDefinitions module. Aside: Thus, the Markup type is excluded. Definition (visible component): Ignoring all type constraints, the visible components for a type that is directly or indirectly a combining ASN.1 type (i.e., SEQUENCE, SET, CHOICE, SEQUENCE OF, or SET OF) is the set of components of the combining type definition plus, for each NamedType (of the combining type definition) that is subject to a GROUP encoding instruction, the visible components for the type of the NamedType. The visible components are determined after the COMPONENTS OF transformation specified in X.680, Clause 24.4 [X.680].
Aside: The set of visible attribute and element components for a type is the set of all the components of the type, and any nested types, that describe attributes and child elements appearing in the RXER encodings of values of the outer type. A GROUP encoding instruction MUST NOT be used where it would cause a NamedType to be a visible component of the type of that same NamedType (which is only possible if the type definition is recursive). Aside: Components subject to a GROUP encoding instruction might be translated into a compatible XML Schema [XSD1] as group definitions. A NamedType that is visible to its own type is analogous to a circular group, which XML Schema disallows. Section 25.1 imposes additional conditions on the use of the GROUP encoding instruction. In any use of the GROUP encoding instruction, there is a type, the including type, that contains the component subject to the GROUP encoding instruction, and a type, the included type, that is the base type of that component. Either type can have an extensible content model, either by directly using ASN.1 extensibility or by including through another GROUP encoding instruction some other type that is extensible. The including and included types may be defined in different ASN.1 modules, in which case the owner of the including type, i.e., the person or organization having the authority to add extensions to the including type's definition, may be different from the owner of the included type. If the owner of the including type is not using the most recent version of the included type's definition, then the owner of the including type might add an extension to the including type that is valid with respect to the older version of the included type, but is later found to be invalid when the latest versions of the including and included type definitions are brought together (perhaps by a third party). Although the owner of the including type must necessarily be aware of the existence of the included type, the reverse is not necessarily true. The owner of the included type could add an extension to the included type without realizing that it invalidates someone else's including type.
To avoid these problems, a GROUP encoding instruction MUST NOT be used if: (1) the included type is defined in a different module from the including type, and (2) the included type has an extensible content model, and (3) changes to the included type are not coordinated with the owner of the including type. Changes in the included type are coordinated with the owner of the including type if: (1) the owner of the included type is also the owner of the including type, or (2) the owner of the including type is collaborating with the owner of the included type, or (3) all changes will be vetted by a common third party before being approved and published.25.1. Unambiguous Encodings
Unregulated use of the GROUP encoding instruction can easily lead to specifications in which distinct abstract values have indistinguishable RXER encodings, i.e., ambiguous encodings. This section imposes restrictions on the use of the GROUP encoding instruction to ensure that distinct abstract values have distinct RXER encodings. In addition, these restrictions ensure that an abstract value can be easily decoded in a single pass without back-tracking. An RXER decoder for an ASN.1 type can be abstracted as a recognizer for a notional language, consisting of element and attribute expanded names, where the type definition describes the grammar for that language (in fact it is a context-free grammar). The restrictions on a type definition to ensure easy, unambiguous decoding are more conveniently, completely, and simply expressed as conditions on this associated grammar. Implementations are not expected to verify type definitions exactly in the manner to be described; however, the procedure used MUST produce the same result. Section 25.1.1 describes the procedure for recasting as a grammar a type definition containing components subject to the GROUP encoding instruction. Sections 25.1.2 and 25.1.3 specify conditions that the
grammar must satisfy for the type definition to be valid. Section 25.1.4 describes how unrecognized attributes are accepted by the grammar for an extensible type. Appendices A and B have extensive examples.25.1.1. Grammar Construction
A grammar consists of a collection of productions. A production has a left-hand side and a right-hand side (in this document, separated by the "::=" symbol). The left-hand side (in a context-free grammar) is a single non-terminal symbol. The right-hand side is a sequence of non-terminal and terminal symbols. The terminal symbols are the lexical items of the language that the grammar describes. One of the non-terminals is nominated to be the start symbol. A valid sequence of terminals for the language can be generated from the grammar by beginning with the start symbol and repeatedly replacing any non-terminal with the right-hand side of one of the productions where that non-terminal is on the production's left-hand side. The final sequence of terminals is achieved when there are no remaining non-terminals to replace. Aside: X.680 describes the ASN.1 basic notation using a context-free grammar. Each NamedType has an associated primary and secondary non-terminal. Aside: The secondary non-terminal for a NamedType is used when the base type of the type in the NamedType is a SEQUENCE OF type or SET OF type. Each ExtensionAddition and ExtensionAdditionAlternative has an associated non-terminal. There is a non-terminal associated with the extension insertion point of each extensible type. There is also a primary start non-terminal (this is the start symbol) and a secondary start non-terminal. The exact nature of the non-terminals is not important, however all the non-terminals MUST be mutually distinct. It is adequate for most of the examples in this document (though not in the most general case) for the primary non-terminal for a NamedType to be the identifier of the NamedType, for the primary start non-terminal to be S, for the non-terminals for the instances of ExtensionAddition and ExtensionAdditionAlternative to be E1, E2, E3, and so on, and for the non-terminals for the extension insertion points to be I1, I2, I3, and so on. The secondary non-terminals are labelled by appending a "'" character to the primary non-terminal label, e.g., the primary and secondary start non-terminals are S and S', respectively.
Each NamedType and extension insertion point has an associated terminal. There exists a terminal called the general extension terminal that is not associated with any specific notation. The general extension terminal and the terminals for the extension insertion points are used to represent elements in unknown extensions. The exact nature of the terminals is not important; however, the aforementioned terminals MUST be mutually distinct. The terminals are further categorized as either element terminals or attribute terminals. A terminal for a NamedType is an attribute terminal if its associated NamedType is an attribute component; otherwise, it is an element terminal. The general extension terminal and the terminals for the extension insertion points are categorized as element terminals. Terminals for attributes in unknown extensions are not explicitly provided in the grammar. Certain productions in the grammar are categorized as insertion point productions, and their role in accepting unknown attributes is described in Section 25.1.4. In the examples in this document, the terminal for a component other than an attribute component will be represented as the local name of the expanded name of the component enclosed in double quotes, and the terminal for an attribute component will be represented as the local name of the expanded name of the component prefixed by the '@' character and enclosed in double quotes. The general extension terminal will be represented as "*" and the terminals for the extension insertion points will be represented as "*1", "*2", "*3", and so on. The productions generated from a NamedType depend on the base type of the type of the NamedType. The productions for the start non-terminals depend on the combining type definition being tested. In either case, the procedure for generating productions takes a primary non-terminal, a secondary non-terminal (sometimes), and a type definition. The grammar is constructed beginning with the start non-terminals and the combining type definition being tested. A grammar is constructed after the COMPONENTS OF transformation specified in X.680, Clause 24.4 [X.680]. Given a primary non-terminal, N, and a type where the base type is a SEQUENCE or SET type, a production is added to the grammar with N as the left-hand side. The right-hand side is constructed from an initial empty state according to the following cases considered in order:
(1) If an initial RootComponentTypeList is present in the base type, then the sequence of primary non-terminals for the components nested in that RootComponentTypeList are appended to the right- hand side in the order of their definition. (2) If an ExtensionAdditions instance is present in the base type and not empty, then the non-terminal for the first ExtensionAddition nested in the ExtensionAdditions instance is appended to the right-hand side. (3) If an ExtensionAdditions instance is empty or not present in the base type, and the base type is extensible (explicitly or by default), and the base type is not subject to a NO-INSERTIONS or HOLLOW-INSERTIONS encoding instruction, then the non-terminal for the extension insertion point of the base type is appended to the right-hand side. (4) If a final RootComponentTypeList is present in the base type, then the primary non-terminals for the components nested in that RootComponentTypeList are appended to the right-hand side in the order of their definition. The production is an insertion point production if an ExtensionAdditions instance is empty or not present in the base type, and the base type is extensible (explicitly or by default), and the base type is not subject to a NO-INSERTIONS encoding instruction. If a component in a ComponentTypeList (in either a RootComponentTypeList or an ExtensionAdditionGroup) is marked OPTIONAL or DEFAULT, then a production with the primary non-terminal of the component as the left-hand side and an empty right-hand side is added to the grammar. If a component (regardless of the ASN.1 combining type containing it) is subject to a GROUP encoding instruction, then one or more productions constructed according to the component's type are added to the grammar. Each of these productions has the primary non-terminal of the component as the left-hand side. If a component (regardless of the ASN.1 combining type containing it) is not subject to a GROUP encoding instruction, then a production is added to the grammar with the primary non-terminal of the component as the left-hand side and the terminal of the component as the right-hand side.
Example Consider the following ASN.1 type definition: SEQUENCE { -- Start of initial RootComponentTypeList. one [ATTRIBUTE] UTF8String, two BOOLEAN OPTIONAL, three INTEGER -- End of initial RootComponentTypeList. } Here is the grammar derived from this type: S ::= one two three one ::= "@one" two ::= "two" two ::= three ::= "three" For each ExtensionAddition (of a SEQUENCE or SET base type), a production is added to the grammar where the left-hand side is the non-terminal for the ExtensionAddition and the right-hand side is initially empty. If the ExtensionAddition is a ComponentType, then the primary non-terminal for the NamedType in the ComponentType is appended to the right-hand side; otherwise (an ExtensionAdditionGroup), the sequence of primary non-terminals for the components nested in the ComponentTypeList in the ExtensionAdditionGroup are appended to the right-hand side in the order of their definition. If the ExtensionAddition is followed by another ExtensionAddition, then the non-terminal for the next ExtensionAddition is appended to the right-hand side; otherwise, if the base type is not subject to a NO-INSERTIONS or HOLLOW-INSERTIONS encoding instruction, then the non-terminal for the extension insertion point of the base type is appended to the right-hand side. If the ExtensionAddition is not followed by another ExtensionAddition and the base type is not subject to a NO-INSERTIONS encoding instruction, then the production is an insertion point production. If the empty sequence of terminals cannot be generated from the production (it may be necessary to wait until the grammar is otherwise complete before making this determination), then another production is added to the grammar where the left-hand side is the non-terminal for the ExtensionAddition and the right-hand side is empty. Aside: An extension is always effectively optional since a sender may be using an earlier version of the ASN.1 specification where none, or only some, of the extensions have been defined.
Aside: The grammar generated for ExtensionAdditions is structured to take account of the condition that an extension can only be used if all the earlier extensions are also used [X.680]. If a SEQUENCE or SET base type is extensible (explicitly or by default) and is not subject to a NO-INSERTIONS or HOLLOW-INSERTIONS encoding instruction, then: (1) a production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is the general extension terminal followed by the non-terminal for the extension insertion point, and (2) a production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point and the right-hand side is empty. Example Consider the following ASN.1 type definition: SEQUENCE { -- Start of initial RootComponentTypeList. one BOOLEAN, two INTEGER OPTIONAL, -- End of initial RootComponentTypeList. ..., -- Start of ExtensionAdditions. four INTEGER, -- First ExtensionAddition (E1). five BOOLEAN OPTIONAL, -- Second ExtensionAddition (E2). [[ -- An ExtensionAdditionGroup. six UTF8String, seven INTEGER OPTIONAL ]], -- Third ExtensionAddition (E3). -- End of ExtensionAdditions. -- The extension insertion point is here (I1). ..., -- Start of final RootComponentTypeList. three INTEGER } Here is the grammar derived from this type: S ::= one two E1 three E1 ::= four E2 E1 ::=
E2 ::= five E3 E3 ::= six seven I1 E3 ::= I1 ::= "*" I1 I1 ::= one ::= "one" two ::= "two" two ::= three ::= "three" four ::= "four" five ::= "five" five ::= six ::= "six" seven ::= "seven" seven ::= If the SEQUENCE type were subject to a NO-INSERTIONS or HOLLOW-INSERTIONS encoding instruction, then the productions for I1 would not appear, and the first production for E3 would be: E3 ::= six seven Given a primary non-terminal, N, and a type where the base type is a CHOICE type: (1) A production is added to the grammar for each NamedType nested in the RootAlternativeTypeList of the base type, where the left-hand side is N and the right-hand side is the primary non-terminal for the NamedType. (2) A production is added to the grammar for each ExtensionAdditionAlternative of the base type, where the left- hand side is N and the right-hand side is the non-terminal for the ExtensionAdditionAlternative. (3) If the base type is extensible (explicitly or by default) and the base type is not subject to an insertion encoding instruction, then: (a) A production is added to the grammar where the left-hand side is N and the right-hand side is the non-terminal for the extension insertion point of the base type. This production is an insertion point production.
(b) A production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is the general extension terminal followed by the non-terminal for the extension insertion point. (c) A production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is empty. (4) If the base type is subject to a HOLLOW-INSERTIONS encoding instruction, then a production is added to the grammar where the left-hand side is N and the right-hand side is empty. This production is an insertion point production. (5) If the base type is subject to a SINGULAR-INSERTIONS encoding instruction, then a production is added to the grammar where the left-hand side is N and the right-hand side is the general extension terminal. This production is an insertion point production. (6) If the base type is subject to a UNIFORM-INSERTIONS encoding instruction, then: (a) A production is added to the grammar where the left-hand side is N and the right-hand side is the general extension terminal. Aside: This production is used to verify the correctness of an ASN.1 type definition, but would not be used in the implementation of an RXER decoder. The next production takes precedence over it for accepting an unknown element. (b) A production is added to the grammar where the left-hand side is N and the right-hand side is the terminal for the extension insertion point of the base type followed by the non-terminal for the extension insertion point. This production is an insertion point production. (c) A production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is the terminal for the extension insertion point followed by the non-terminal for the extension insertion point. (d) A production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is empty.
(7) If the base type is subject to a MULTIFORM-INSERTIONS encoding instruction, then: (a) A production is added to the grammar where the left-hand side is N and the right-hand side is the general extension terminal followed by the non-terminal for the extension insertion point of the base type. This production is an insertion point production. (b) A production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is the general extension terminal followed by the non-terminal for the extension insertion point. (c) A production is added to the grammar where the left-hand side is the non-terminal for the extension insertion point of the base type and the right-hand side is empty. If an ExtensionAdditionAlternative is a NamedType, then a production is added to the grammar where the left-hand side is the non-terminal for the ExtensionAdditionAlternative and the right-hand side is the primary non-terminal for the NamedType. If an ExtensionAdditionAlternative is an ExtensionAdditionAlternativesGroup, then a production is added to the grammar for each NamedType nested in the ExtensionAdditionAlternativesGroup, where the left-hand side is the non-terminal for the ExtensionAdditionAlternative and the right-hand side is the primary non-terminal for the NamedType.
Example Consider the following ASN.1 type definition: CHOICE { -- Start of RootAlternativeTypeList. one BOOLEAN, two INTEGER, -- End of RootAlternativeTypeList. ..., -- Start of ExtensionAdditionAlternatives. three INTEGER, -- First ExtensionAdditionAlternative (E1). [[ -- An ExtensionAdditionAlternativesGroup. four UTF8String, five INTEGER ]] -- Second ExtensionAdditionAlternative (E2). -- The extension insertion point is here (I1). } Here is the grammar derived from this type: S ::= one S ::= two S ::= E1 S ::= E2 S ::= I1 I1 ::= "*" I1 I1 ::= E1 ::= three E2 ::= four E2 ::= five one ::= "one" two ::= "two" three ::= "three" four ::= "four" five ::= "five" If the CHOICE type were subject to a NO-INSERTIONS encoding instruction, then the fifth, sixth, and seventh productions would be removed. If the CHOICE type were subject to a HOLLOW-INSERTIONS encoding instruction, then the fifth, sixth, and seventh productions would be replaced by:
S ::= If the CHOICE type were subject to a SINGULAR-INSERTIONS encoding instruction, then the fifth, sixth, and seventh productions would be replaced by: S ::= "*" If the CHOICE type were subject to a UNIFORM-INSERTIONS encoding instruction, then the fifth and sixth productions would be replaced by: S ::= "*" S ::= "*1" I1 I1 ::= "*1" I1 If the CHOICE type were subject to a MULTIFORM-INSERTIONS encoding instruction, then the fifth production would be replaced by: S ::= "*" I1 Constraints on a SEQUENCE, SET, or CHOICE type are ignored. They do not affect the grammar being generated. Aside: This avoids an awkward situation where values of a subtype have to be decoded differently from values of the parent type. It also simplifies the verification procedure. Given a primary non-terminal, N, and a type that has a SEQUENCE OF or SET OF base type and that permits a value of size zero (i.e., an empty sequence or set): (1) a production is added to the grammar where the left-hand side of the production is N and the right-hand side is the primary non-terminal for the NamedType of the component of the SEQUENCE OF or SET OF base type, followed by N, and (2) a production is added to the grammar where the left-hand side of the production is N and the right-hand side is empty. Given a primary non-terminal, N, a secondary non-terminal, N', and a type that has a SEQUENCE OF or SET OF base type and that does not permit a value of size zero:
(1) a production is added to the grammar where the left-hand side of the production is N and the right-hand side is the primary non-terminal for the NamedType of the component of the SEQUENCE OF or SET OF base type, followed by N', and (2) a production is added to the grammar where the left-hand side of the production is N' and the right-hand side is the primary non-terminal for the NamedType of the component of the SEQUENCE OF or SET OF base type, followed by N', and (3) a production is added to the grammar where the left-hand side of the production is N' and the right-hand side is empty. Example Consider the following ASN.1 type definition: SEQUENCE SIZE(1..MAX) OF number INTEGER Here is the grammar derived from this type: S ::= number S' S' ::= number S' S' ::= number ::= "number" All inner subtyping (InnerTypeContraints) is ignored for the purposes of deciding whether a value of size zero is permitted by a SEQUENCE OF or SET OF type. This completes the description of the transformation of ASN.1 combining type definitions into a grammar.25.1.2. Unique Component Attribution
This section describes conditions that the grammar must satisfy so that each element and attribute in a received RXER encoding can be uniquely associated with an ASN.1 component definition. Definition (used by the grammar): A non-terminal, N, is used by the grammar if: (1) N is the start symbol or (2) N appears on the right-hand side of a production where the non-terminal on the left-hand side is used by the grammar.
Definition (multiple derivation paths): A non-terminal, N, has multiple derivation paths if: (1) N appears on the right-hand side of a production where the non-terminal on the left-hand side has multiple derivation paths, or (2) N appears on the right-hand side of more than one production where the non-terminal on the left-hand side is used by the grammar, or (3) N is the start symbol and it appears on the right-hand side of a production where the non-terminal on the left-hand side is used by the grammar. For every ASN.1 type with a base type containing components that are subject to a GROUP encoding instruction, the grammar derived by the method described in this document MUST NOT have: (1) two or more primary non-terminals that are used by the grammar and are associated with element components having the same expanded name, or (2) two or more primary non-terminals that are used by the grammar and are associated with attribute components having the same expanded name, or (3) a primary non-terminal that has multiple derivation paths and is associated with an attribute component. Aside: Case (1) is in response to component referencing notations that are evaluated with respect to the XML encoding of an abstract value. Case (1) guarantees, without having to do extensive testing (which would necessarily have to take account of encoding instructions for all other encoding rules), that all sibling elements with the same expanded name will be associated with equivalent type definitions. Such equivalence allows a component referenced by element name to be re-encoded using a different set of ASN.1 encoding rules without ambiguity as to which type definition and encoding instructions apply. Cases (2) and (3) ensure that an attribute name is always uniquely associated with one component that can occur at most once and is always nested in the same part of an abstract value.
Example The following example types illustrate various uses and misuses of the GROUP encoding instruction with respect to unique component attribution: TA ::= SEQUENCE { a [GROUP] TB, b [GROUP] CHOICE { a [GROUP] TB, b [NAME AS "c"] [ATTRIBUTE] INTEGER, c INTEGER, d TB, e [GROUP] TD, f [ATTRIBUTE] UTF8String }, c [ATTRIBUTE] INTEGER, d [GROUP] SEQUENCE OF a [GROUP] SEQUENCE { a [ATTRIBUTE] OBJECT IDENTIFIER, b INTEGER }, e [NAME AS "c"] INTEGER, COMPONENTS OF TD } TB ::= SEQUENCE { a INTEGER, b [ATTRIBUTE] BOOLEAN, COMPONENTS OF TC } TC ::= SEQUENCE { f OBJECT IDENTIFIER } TD ::= SEQUENCE { g OBJECT IDENTIFIER } The grammar for TA is constructed after performing the COMPONENTS OF transformation. The result of this transformation is shown next. This example will depart from the usual convention of using just the identifier of a NamedType to represent the primary non-terminal for that NamedType. A label relative to the outermost type will be used instead to better illustrate unique component attribution. The labels used for the non-terminals are shown down the right-hand side.
TA ::= SEQUENCE { a [GROUP] TB, -- TA.a b [GROUP] CHOICE { -- TA.b a [GROUP] TB, -- TA.b.a b [NAME AS "c"] [ATTRIBUTE] INTEGER, -- TA.b.b c INTEGER, -- TA.b.c d TB, -- TA.b.d e [GROUP] TD, -- TA.b.e f [ATTRIBUTE] UTF8String -- TA.b.f }, c [ATTRIBUTE] INTEGER, -- TA.c d [GROUP] SEQUENCE OF -- TA.d a [GROUP] SEQUENCE { -- TA.d.a a [ATTRIBUTE] OBJECT IDENTIFIER, -- TA.d.a.a b INTEGER -- TA.d.a.b }, e [NAME AS "c"] INTEGER, -- TA.e g OBJECT IDENTIFIER -- TA.g } TB ::= SEQUENCE { a INTEGER, -- TB.a b [ATTRIBUTE] BOOLEAN, -- TB.b f OBJECT IDENTIFIER -- TB.f } -- Type TC is no longer of interest. -- TD ::= SEQUENCE { g OBJECT IDENTIFIER -- TD.g } The associated grammar is: S ::= TA.a TA.b TA.c TA.d TA.e TA.g TA.a ::= TB.a TB.b TB.f TB.a ::= "a" TB.b ::= "@b" TB.f ::= "f" TA.b ::= TA.b.a TA.b ::= TA.b.b TA.b ::= TA.b.c TA.b ::= TA.b.d TA.b ::= TA.b.e TA.b ::= TA.b.f
TA.b.a ::= TB.a TB.b TB.f TA.b.b ::= "@c" TA.b.c ::= "c" TA.b.d ::= "d" TA.b.e ::= TD.g TA.b.f ::= "@f" TD.g ::= "g" TA.c ::= "@c" TA.d ::= TA.d.a TA.d TA.d ::= TA.d.a ::= TA.d.a.a TA.d.a.b TA.d.a.a := "@a" TA.d.a.b ::= "b" TA.e ::= "c" TA.g ::= "g" All the non-terminals are used by the grammar. The type definition for TA is invalid because there are two instances where two or more primary non-terminals are associated with element components having the same expanded name: (1) TA.b.c and TA.e (both generate the terminal "c"), and (2) TD.g and TA.g (both generate the terminal "g"). In case (2), TD.g and TA.g are derived from the same instance of NamedType notation, but become distinct components following the COMPONENTS OF transformation. AUTOMATIC tagging is applied after the COMPONENTS OF transformation, which means that the types of the components corresponding to TD.g and TA.g will end up with different tags, and therefore the types will not be equivalent. The type definition for TA is also invalid because there is one instance where two or more primary non-terminals are associated with attribute components having the same expanded name: TA.b.b and TA.c (both generate the terminal "@c").
The non-terminals with multiple derivation paths are: TA.d, TA.d.a, TA.d.a.a, TA.d.a.b, TB.a, TB.b, and TB.f. The type definition for TA is also invalid because TA.d.a.a and TB.b are primary non-terminals that are associated with an attribute component.25.1.3. Deterministic Grammars
Let the First Set of a production P, denoted First(P), be the set of all element terminals T where T is the first element terminal in a sequence of terminals that can be generated from the right-hand side of P. There can be any number of leading attribute terminals before T. Let the Follow Set of a non-terminal N, denoted Follow(N), be the set of all element terminals T where T is the first element terminal following N in a sequence of non-terminals and terminals that can be generated from the grammar. There can be any number of attribute terminals between N and T. If a sequence of non-terminals and terminals can be generated from the grammar where N is not followed by any element terminals, then Follow(N) also contains a special end terminal, denoted by "$". Aside: If N does not appear on the right-hand side of any production, then Follow(N) will be empty. For a production P, let the predicate Empty(P) be true if and only if the empty sequence of terminals can be generated from P. Otherwise, Empty(P) is false. Definition (base grammar): The base grammar is a rewriting of the grammar in which the non-terminals for every ExtensionAddition and ExtensionAdditionAlternative are removed from the right-hand side of all productions. For a production P, let the predicate Preselected(P) be true if and only if every sequence of terminals that can be generated from the right-hand side of P using only the base grammar contains at least one attribute terminal. Otherwise, Preselected(P) is false. The Select Set of a production P, denoted Select(P), is empty if Preselected(P) is true; otherwise, it contains First(P). Let N be the non-terminal on the left-hand side of P. If Empty(P) is true, then Select(P) also contains Follow(N).
Aside: It may appear somewhat dubious to include the attribute components in the grammar because, in reality, attributes appear unordered within the start tag of an element, and not interspersed with the child elements as the grammar would suggest. This is why attribute terminals are ignored in composing the First Sets and Follow Sets. However, the attribute terminals are important in composing the Select Sets because they can preselect a production and can prevent a production from being able to generate an empty sequence of terminals. In real terms, this corresponds to an RXER decoder using the attributes to determine the presence or absence of optional components and to select between the alternatives of a CHOICE, even before considering the child elements. An attribute appearing in an extension isn't used to preselect a production since, in general, a decoder using an earlier version of the specification would not be able to associate the attribute with any particular extension insertion point. Let the Reach Set of a non-terminal N, denoted Reach(N), be the set of all element terminals T where T appears in a sequence of terminals that can be generated from N. Aside: It can be readily shown that all the optional attribute components and all but one of the mandatory attribute components of a SEQUENCE or SET type can be ignored in constructing the grammar because their omission does not alter the First, Follow, Select, or Reach Sets, or the evaluation of the Preselected and Empty predicates. A grammar is deterministic (for the purposes of an RXER decoder) if and only if: (1) there do not exist two productions P and Q, with the same non-terminal on the left-hand side, where the intersection of Select(P) and Select(Q) is not empty, and (2) there does not exist a non-terminal E for an ExtensionAddition or ExtensionAdditionAlternative where the intersection of Reach(E) and Follow(E) is not empty. Aside: In case (1), if the intersection is not empty, then a decoder would have two or more possible ways to attempt to decode the input into an abstract value. In case (2), if the intersection is not empty, then a decoder using an earlier version of the ASN.1 specification would confuse an element in an unknown (to that decoder) extension with a known component following the extension.
Aside: In the absence of any attribute components, case (1) is the test for an LL(1) grammar. For every ASN.1 type with a base type containing components that are subject to a GROUP encoding instruction, the grammar derived by the method described in this document MUST be deterministic.25.1.4. Attributes in Unknown Extensions
An insertion point production is able to accept unknown attributes if the non-terminal on the left-hand side of the production does not have multiple derivation paths. Aside: If the non-terminal has multiple derivation paths, then any future extension cannot possibly contain an attribute component because that would violate the requirements of Section 25.1.2. For a deterministic grammar, there is only one possible way to construct a sequence of element terminals matching the element content of an element in a correctly formed RXER encoding. Any unknown attributes of the element are accepted if at least one insertion point production that is able to accept unknown attributes is used in that construction. Example Consider this type definition: CHOICE { one UTF8String, two [GROUP] SEQUENCE { three INTEGER, ... } } The associated grammar is: S ::= one S ::= two two ::= three I1 I1 ::= "*" I1 I1 ::= one ::= "one" three ::= "three"
The third production is an insertion point production, and it is able to accept unknown attributes. When decoding a value of this type, if the element content contains a <one> child element, then any unrecognized attribute would be illegal as the insertion point production would not be used to recognize the input (the "one" alternative does not admit an extension insertion point). If the element content contains a <three> element, then an unrecognized attribute would be accepted because the insertion point production would be used to recognize the input (the "two" alternative that generates the <three> element has an extensible type). If the SEQUENCE type were prefixed by a NO-INSERTIONS encoding instruction, then the third, fourth, and fifth productions would be replaced by: two ::= three With this change, any unrecognized attribute would be illegal for the "two" alternative also, since the replacement production is not an insertion point production. If more than one insertion point production that is able to accept unknown attributes is used in constructing a matching sequence of element terminals, then a decoder is free to associate an unrecognized attribute with any one of the extension insertion points corresponding to those insertion point productions. The justification for doing so comes from the following two observations: (1) If the encoding of an abstract value contains an extension where the type of the extension is unknown to the receiver, then it is generally impossible to re-encode the value using a different set of encoding rules, including the canonical variant of the received encoding. This is true no matter which encoding rules are being used. It is desirable for a decoder to be able to accept and store the raw encoding of an extension without raising an error, and to re-insert the raw encoding of the extension when re-encoding the abstract value using the same non-canonical encoding rules. However, there is little more that an application can do with an unknown extension. An application using RXER can successfully accept, store, and re-encode an unrecognized attribute regardless of which extension insertion point it might be ascribed to.
(2) Even if there is a single extension insertion point, an unknown extension could still be the encoding of a value of any one of an infinite number of valid type definitions. For example, an attribute or element component could be nested to any arbitrary depth within CHOICEs whose components are subject to GROUP encoding instructions. Aside: A similar series of nested CHOICEs could describe an unknown extension in a Basic Encoding Rules (BER) encoding [X.690].