# OMG IDL schema parser

> _OMG IDL parser to flattened message definitions for (de)serialization_

[![npm version](https://img.shields.io/npm/v/@foxglove/omgidl-parser.svg?style=flat)](https://www.npmjs.com/package/@foxglove/omgidl-parser)

This package provides functions to parse raw `.idl` schemas into resolved, flattened message definitions.

Output definitions can be passed to serializers along with a specified root schema name string in `@foxglove/omgidl-serialization` to read and write CDR, XCDR1 and XCDR2 messages.

## Example

```TypeScript

const schemaString = `
// Generated by https://github.com/foxglove/schemas

module foxglove {
// A vector in 3D space that represents a direction only
struct Vector3 {
  double x;
  double y;
  double z;
};
};

module foxglove {
struct Quaternion {
  double x;
  double y;
  double z;
  @default(1.0)
  double w;
};
};

module foxglove {
// A position and orientation for an object or reference frame in 3D space
struct Pose {
  // Point denoting position in 3D space
  Vector3 position;
  // Quaternion denoting orientation in 3D space
  Quaternion orientation;
};
};
`;

const definitions = parseIDL(schemaString);
```

`definitions` results in:

```JavaScript
[
  {
    name: "foxglove::Vector3",
    aggregatedKind: "struct",
    definitions: [
      {
        name: "x",
        isComplex: false,
        type: "float64",
      },
      {
        name: "y",
        isComplex: false,
        type: "float64",
      },
      {
        name: "z",
        isComplex: false,
        type: "float64",
      },
    ],
  },
  {
    name: "foxglove::Quaternion",
    aggregatedKind: "struct",
    definitions: [
      {
        name: "x",
        isComplex: false,
        type: "float64",
      },
      {
        name: "y",
        isComplex: false,
        type: "float64",
      },
      {
        name: "z",
        isComplex: false,
        type: "float64",
      },
      {
        name: "w",
        annotations: {
          default: {
            name: "default",
            type: "const-param",
            value: 1,
          },
        },
        defaultValue: 1,
        isComplex: false,
        type: "float64",
      },
    ],
  },
  {
    name: "foxglove::Pose",
    aggregatedKind: "struct",
    definitions: [
      {
        isComplex: true,
        name: "position",
        type: "foxglove::Vector3",
      },
      {
        isComplex: true,
        name: "orientation",
        type: "foxglove::Quaternion",
      },
    ],
  },
]
```

## API

`parseIDL(schema: string)` - parses raw `.idl` schema string to resolved, flattened definitions.

TypeScript types for the output definitions are also available.

## OMG IDL Subset Support

NOTE: numbers like `7.4.1` refer to sections of the [OMG IDL specification](https://www.omg.org/spec/IDL/4.2/PDF).

- Generally supported features

  - `7.4.1` Building Block Core Data Types (with exceptions below)
  - support for extended numeric types `uint8`, `int8` ... `uint64`, `int64`
    - Note `7.4.13` Building Block Extended Data-Types is not fully supported
  - Literals (with some hexadecimal, character and `wide`-type exceptions)
  - Blanks, horizontal and vertical tabs, newlines, form feeds, and comments (collective, "white space") as described below are ignored except as they serve to separate tokens
  - Parse generic annotations (only defaultValue is read in to AST)
  - unions and cases
  - enumerator overrides with `@value` annotation

- Unsupported features

  - `native` declarations
  - forward declarations
  - Constant expressions
  - unary operators
  - default value annotation type checking
  - identifiers prefixed with `::` scope
  - `7.2.6.1` - Octal integers are not supported (`014`)
  - `7.2.6.2.1` wide character and wide string has limited support
    - can be read in to schema but only considered `uint8`
    - wide character and string literals are not supported (`L'X'`)
  - `7.2.6.3` - wide string literals are not supported
  - `7.2.3.1` - we do not check collision explicitly and we use case-sensitive identifiers whereas IDL requires identifiers to be case insensitive.
  - `7.4.2`-`7.4.16` extended IDL building blocks not supported
  - Composing variable-sized array typedefs with other array typedefs or struct member nodes.
  - `const Color color = RED;` not supported. However `const Color color = Color::RED;` is supported.

- Unsupported reference and type resolution features
  - numeric type checking for constant usage
  - we do not enforce type-based value ranges on constants in schema
