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 class
es 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
string
s, both bounded and unbounded variants, shall be mapped to C# string
s.Wstrings
wstring
s, both bounded and unbounded variants, shall be mapped to C# string
s.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.
@external
Discriminator
.
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 typedef
s, the typedef
ed 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 struct
s 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_convention
apply_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_container
constants_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_type
struct_type
defines the C# type the IDL struct
type map to. By default, IDL
struct
s 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
.