IDL4 to C# Language Mapping
This document describes the OpenDDSharp current implementation of the IDL4 to C# Language Mapping Specification.
Some sections of the specification are not included in this documentation because are not directly related with DDS, therefore won't be implemented.
The following legend is used to define the current version status:
✅ Fully implemented
☑️ Partially implemented
❌ Not implemented
Core Data Types
Modules
✅ IDL modules are mapped to C# namespaces of the same name.
✅ All IDL type declarations within the IDL module shall be mapped to corresponding C# declarations within the generated namespace.
✅ IDL declarations not enclosed in any module shall be mapped into the global scope.
Constants
☑️ IDL constants shall be mapped to public sealed classes of the same name within the equivalent scope and namespace where they are defined.
Note
OpenDDSharp makes the class static instead of sealed. It makes no sense to create instances of the class.
With the current proposal, the following code snippet is possible:
var myUglyCode = new PI();
double myPi = myUglyCode.Value;
☑️ The mapped class shall contain a public const called Value assigned to the value of the IDL constant.
Note
The use of const could be problematic because when using const it does not access to the field but
the value is copied on build-time with the same constant value, therefore you need to recompile all your software
and dependencies to ensure you are using the same value of the constant everywhere.
OpenDDSharp uses a public static readonly field instead, in order to only require compilation of your IDL library and
the value will be changed to all software that reference that library without need to recompile it again.
Data Types
Basic Types
Integer Types
☑️ IDL integer types shall be mapped as shown in the following table:
| IDL Type | C# Type | Status |
|---|---|---|
| int8 | sbyte | ✅ |
| uint8 | byte | ✅ |
| short | short | ✅ |
| int16 | short | ✅ |
| unsigned short | ushort | ✅ |
| uint16 | ushort | ✅ |
| long | int | ✅ |
| int32 | int | ✅ |
| unsigned long | uint | ✅ |
| uint32 | uint | ✅ |
| long long | long | ✅ |
| int64 | long | ✅ |
| unsigned long long | ulong | ✅ |
| uint64 | ulong | ✅ |
Floating-Point Types
☑️ IDL floating-point types shall be mapped as shown in the following table:
| IDL Type | C# Type | Status |
|---|---|---|
| float | float | ✅ |
| double | double | ✅ |
| long double | decimal | ❌ |
Char Types
✅ The IDL char type shall be mapped to the C# type char.
Note
IDL characters are 8-bit quantities representing elements of a character set, while C# characters are 16-bit unsigned quantities representing Unicode characters in UTF-16 encoding.
Wide Char Types
✅ The IDL wchar type shall be mapped to the C# type char.
Boolean
✅ The IDL boolean type shall be mapped to the C# bool, and the IDL constants TRUE and FALSE shall be mapped to
the corresponding C# boolean literals true and false.
Template Types
Sequences
✅ IDL sequences shall be mapped to the C# System.Collections.Generic.IList
✅ In the mapping, everywhere the sequence type is needed, a System.Collections.Generic.IList
✅ Implementations of System.Collections.Generic.IList
❌ Bounds checking on bounded sequences may raise an exception if necessary. ☑️ The following table shows the mapping for sequences of basic types: ✅ IDL ✅ The resulting strings shall be encoded in UTF-16 format. ✅ IDL ✅ The resulting strings shall be encoded in UTF-16 format. ❌ The IDL fixed type shall be mapped to the C# decimal type. ❌ Range checking may raise a System.ArithmeticException exception if necessary. ✅ An IDL struct shall be mapped to a C# ☑️ The ✅ The default constructor shall initialize member fields as follows: ❌ The class shall implement the ❌ An IDL union shall be mapped to a C# ❌ The class shall provide the following: ❌ The normal name conflict resolution rule shall apply (i.e., prepend an "_") to the discriminator property name if
there is a name clash with the mapped union type name or any of the field names. ❌ Property getters shall raise a System.InvalidOperationException if the expected member has not been set. ❌ If there is more than one case label corresponding to a member, the setter of the property representing such member
shall set Discriminator to the first possible case label. If the member corresponds to the default case label, then
❌ The modifier method shall throw a System.ArgumentException exception when a value is passed for the discriminator that is not among the case labels for the member.4 ❌ The class representing the IDL union shall implement the ✅ An IDL ❌ If the IDL enumeration declaration is preceded by a ✅ An IDL array shall be mapped to a C# array of the mapped element type or to a C# ✅ In the mapping, everywhere the array type is needed, an array or an equivalent class of the mapped element type shall be used. ❌ The bounds for the array shall be checked by the setter of the corresponding property and a ✅ C# does not have a ❌ The IDL any type shall be mapped to ✅ An IDL ☑️ The resulting C# ❌ This building block adds the ❌ An IDL ❌ Bounds checking shall raise an exception if necessary. ❌ An IDL ❌ The mapped C# struct shall implement the ❌ The IDL ❌ In the mapping, everywhere the ❌ The C# ❌ The value of each C# ❌ If no position is specified, the C# ❌ The corresponding ❌ The size (number of bits) held in the ❌ User-defined annotations are propagated to the generated code as C# attributes inheriting from the
❌ Each annotation member shall be mapped to a property with public getters and setters. Moreover, the mapped
attribute shall have a public constructor with default values (default constructor) and shall be annotated with the
following attribute: ❌ If the IDL annotation definition provides a default value for a given member, it shall be reflected in the C# definition
accordingly; otherwise, the equivalent C# definition shall have no default value. ❌ IDL elements annotated with user-defined annotations shall map to equivalent C# elements annotated with the
corresponding attribute following the mappings defined in this specification. ❌ Annotations on an IDL OMG-IDL4 defines some annotations and assigns them to logical groups. These annotations may be applied to
various constructs throughout an IDL document, and their impact on the language mapping is dependent on the
context in which they are applied. The following table summarize the annotations that have an impact in the
C# language mapping and the current OpenDDSharp implementation status. This chapter defines specialized annotations that extend the standard set defined in OMG-IDL4 to control the C# code generation. ❌ This annotation provides the means to customize the way a number of IDL constructs are mapped to the C# programming language. The ❌ ❌ ❌
IDL Type
C# Type
Status
sequence<boolean>
System.Collections.Generic.IList<bool>
✅
sequence<char>
System.Collections.Generic.IList<char>
✅
sequence<char>
System.Collections.Generic.IList<char>
✅
sequence<int8>
System.Collections.Generic.IList<sbyte>
❌
sequence<uint8>
System.Collections.Generic.IList<byte>
❌
sequence<octet>
System.Collections.Generic.IList<byte>
✅
sequence<short>
System.Collections.Generic.IList<short>
✅
sequence<int16>
System.Collections.Generic.IList<short>
✅
sequence<unsigned short>
System.Collections.Generic.IList<ushort>
✅
sequence<uint16>
System.Collections.Generic.IList<ushort>
✅
sequence<long>
System.Collections.Generic.IList<int>
✅
sequence<int32>
System.Collections.Generic.IList<int>
✅
sequence<unsigned long>
System.Collections.Generic.IList<uint>
✅
sequence<uint32>
System.Collections.Generic.IList<uint>
✅
sequence<long long>
System.Collections.Generic.IList<long>
✅
sequence<int64>
System.Collections.Generic.IList<long>
✅
sequence<unsigned long long>
System.Collections.Generic.IList<ulong>
✅
sequence<uint64>
System.Collections.Generic.IList<ulong>
✅
sequence<float>
System.Collections.Generic.IList<float>
✅
sequence<double>
System.Collections.Generic.IList<double>
✅
sequence<long double>
System.Collections.Generic.IList<decimal>
❌
Strings
strings, both bounded and unbounded variants, shall be mapped to C# strings.Wstrings
wstrings, both bounded and unbounded variants, shall be mapped to C# strings.Fixed Type
Constructed Types
Structures
public class with the same name.class shall provide the following:
@external
annotation (see the Standardized Annotations building block) shall include both a getter and a setter.
@external
IEquatable<T> interface, where T is the corresponding class name.Unions
public class with the same name.
@externalDiscriminator.
void Set<SequenceMemberName>(System.Collections.IEnumerable<T> elements), where T
is the equivalent type of the IDL sequence elements. The method shall clear the sequence, populate
it with the elements received as an input, and update the discriminator value.void Set<MapMemberName>(). The method shall remove all
the elements in the property representing the map and update the discriminator value. The second
modifier method shall have the following prototype:
void Set<MapMemberName>(System.Collections.IEnumerable<Generic.KeyValuePair<TKey,Tvalue>> elements),
where TKey is the equivalent key type, and TValue is the equivalent value type.
The method shall remove all elements in the equivalent map, populate it with the
elements received as an input, and update the discriminator value.@external
annotation (see the Standardized Annotations building block) shall include both a getter and a setter.Discriminator shall be set to the first available default value starting from the zero-index of the discriminant type.
For all such members, the union shall provide a modifier method void Set<MemberName>(<MemberType> value, <DiscriminatorType> discriminator) to set
the corresponding property value and the discriminator value of choice.IEquatable<T> interface, where T is the corresponding class name.Enumerations
enum shall be mapped to a C# public enum with the same name as the IDL enum type.@bit_bound annotation; the corresponding C# enum type shall
be sbyte for bit bound values between 1 and 8; short, for bit bound values between 9 and 16; int, for bit bound
values between 17 and 32; and long, for bit bound values between 33 and 64.Arrays
class offering an interface
compatible with that of a C# native array of the mapped element type.System.ArgumentOutOfRangeException shall be
raised if a bounds violation occurs.Naming Data Types
typedef construct; therefore, the declaration of types using typedef in IDL shall not result in
the creation of any C# type. Instead, the use of an IDL typedef type shall be replaced with the type referenced by
the typedef statement. For nested typedefs, the typedefed type shall be replaced with the original type in the
sequence of typedef statements.Any
Omg.Types.Any type. The implementation of the Omg.Types.Any is
platform-specific, and should include operations that allow programmers to insert and access the value contained in
an any instance as well as the actual type of that value.Extended Data Types
Structures with Single Inheritance
struct that inherits from a base IDL struct, shall be declared as a
C# public class that extends the class resulting from mapping the base IDL struct.public class shall be mapped according to the general mapping rules for IDL structs with the following additions:
struct.Union Discriminators
int8, uint8, wchar, and octet IDL types to the set of valid types for a discriminator.Additional Template Types
Maps
map shall be mapped to a C# generic System.Collections.Generic.IDictionary<TKey,TValue>
instantiated with the equivalent C# key type and value type. In the mapping, everywhere the map type is needed, a
property of type IDictionary with the equivalent C# key type and value type shall be used.Bitsets
bitset shall map to a C# struct with public properties for each named bitfield in the set. The IDL type
of each bitfield member, if not specified in the IDL, shall take the smallest unsigned integer type able to store the
bit field with no loss; that is, byte if it is between 1 and 8, ushort if it is between 9 and 16, uint if it is between 17
and 32 and ulong if it is between 33 and 64.IEquatable<T> interface, where T is the corresponding bitset name.Bitmask Type
bitmask type shall map to a C# public enum with the same name, followed by the Flags suffix.bitmask type is needed, a System.Collections.BitArray shall be used.enum shall have the System.FlagsAttribute, and shall contain a literal for each named member of the IDL bitmask.enum literal is dictated by the @position annotation of the corresponding IDL bitmask member.enum literals shall be set to the value of the next power of two.enum literals can be used to set, clear, and test individual bits in the corresponding System.Collections.BitArray instance.bitmask determines the corresponding C# enum type. In particular, the enum
type shall be byte, for bit bound values between 1 and 8; ushort, for bit bound values between 9 and 16; uint, for
values between 17 and 32; and ulong for bit bound values between 33 and 64.Annotations
Defining Annotations
System.Attribute class. The name of the corresponding attributes shall be that of the original IDL annotation,
appending the Attribute suffix when applying the .NET Framework Design Guidelines Naming Scheme.[AttributeUsage(AttributeTargets.All, AllowMultiple = true)].Applying Annotations
Applying Annotations in Naming Data Types
typedef shall be applied to uses of the typedef in other type declarations.Standardized Annotations
General Purpose Annotation
Status
@key✅
@topic✅
@optional❌
@position❌
@value❌
@default_literal❌
@default❌
@range❌
@min❌
@max❌
@unit❌
@bit_bound❌
@external❌
@verbatim❌
IDL to C# Language Mapping Annotations
Annotation
@csharp_mapping@csharp_mapping annotation provides three parameters described in the following sections.Parameter
apply_naming_conventionapply_naming_convention specifies whether the IDL to C# language mapping shall apply the IDL Naming
Scheme or the .NET Framework Design Guidelines Naming Scheme when mapping IDL names to C#. In particular:
apply_naming_convention is IDL_NAMING_CONVENTION, the code generator shall generate type
identifiers and names according to the IDL Naming Scheme, leaving the name of the corresponding IDL
construct unchanged.apply_naming_convention is DOTNET_NAMING_CONVENTION, the code generator shall generate type
identifiers and names according to the .NET Framework Design Guidelines Naming Scheme.Parameter
constants_containerconstants_container activates the different options for mapping constants. To enable the
Standalone Constants Mapping, constants_container shall be set to an empty string.
To enable the Constants Container Mapping , constants_container shall bet set to a
valid string. The default name for the containing class is Constants.Parameter
struct_typestruct_type defines the C# type the IDL struct type map to. By default, IDL
structs are mapped to a C# class. This parameter allows changing the default behavior to map an IDL struct
to a C# struct. When mapping an IDL struct to C# struct as a result of this annotation, every setter and constructors shall
perform a deep copy, regardless of annotations modifying the copy behavior, such as @external.