<!--
  Copyright (c) 2009-2026 ASN Lab
  All rights reserved.
-->

# ASN.1 C# Compiler Guide

The ASN.1 C# Compiler (`asncsc`) generates C# source code from ASN.1
modules. Generated types are C# classes/structs and work with the C# runtime
library for encoding and decoding.

## Compiler Options

| Field                       | Type    | Default      | Description |
|-----------------------------|---------|--------------|-------------|
| `output-folder`             | string  | `"c#"`       | Output directory for generated C# sources. |
| `mapping.integer`           | ENUM    | `automatic`  | See [Integer Mapping](#integer-mapping). |
| `mapping.real`              | ENUM    | `double`     | `automatic`, `float`, `double`. |
| `lower-case-namespace`      | BOOLEAN | TRUE         | Convert module names to lower case for C# namespace names. |
| `namespace-prefix`          | string  | `""`         | Prefix prepended to every generated namespace. |
| `generate.properties`       | BOOLEAN | FALSE        | Generate C# properties instead of public fields. |
| `generate.clones`           | BOOLEAN | FALSE        | Generate `Clone()` methods. |
| `generate.equals`           | BOOLEAN | TRUE         | Generate `Equals()` and `GetHashCode()` overrides. |
| `generate.prints`           | BOOLEAN | FALSE        | Generate `ToString()` overrides. |
| `generate.hash-code`        | BOOLEAN | TRUE         | Generate `GetHashCode()` overrides. |

## Integer Mapping

Controls how ASN.1 INTEGER is mapped to C# types:

| Option        | C# type |
|---------------|---------|
| `automatic`   | `BigInteger` when unconstrained; smallest `long`/`int` that fits otherwise. |
| `int32`       | `int`. |
| `int64`       | `long`. |
| `big-integer` | `BigInteger`. |

## Real Mapping

| Option      | C# type |
|-------------|---------|
| `automatic` | `double`. |
| `float`     | `float`. |
| `double`    | `double`. |

## Project Configuration Example

```asn1
compilers {
    {
        id "asncsc",
        language "c#",
        options {
            output-folder "c#",
            mapping {
                integer automatic,
                real double
            },
            lower-case-namespace TRUE,
            namespace-prefix "MyCompany.Protocols",
            generate {
                properties FALSE,
                clones FALSE,
                equals TRUE,
                prints FALSE,
                hash-code TRUE
            }
        }
    }
}
```

## Runtime Library Usage

After the compiler generates C# source files for your ASN.1 modules, add a
reference to the C# runtime library. The generated code depends on the
`org.asnlab.asndt.asnrt` namespace.

### Encoding

Populate your generated PDU object, create a buffer, and call `Encode`:

```csharp
using org.asnlab.asndt.asnrt.type;
using org.asnlab.asndt.asnrt.conv;

var pdu = new MyPdu();
pdu.field1 = 42;
// ... populate other fields ...

var buffer = AsnBuffer.Allocate(1024, EncodingRules.ALIGNED_PACKED_ENCODING_RULES);
MyPdu.TYPE.Encode(pdu, buffer, MyPdu.CONVERTER);
byte[] encoded = buffer.Array();
```

### Decoding

Wrap received bytes in a buffer and call `Decode`:

```csharp
var buffer = AsnBuffer.Wrap(receivedBytes, EncodingRules.ALIGNED_PACKED_ENCODING_RULES);
var pdu = (MyPdu) MyPdu.TYPE.Decode(buffer, MyPdu.CONVERTER);
// use pdu.field1, etc.
```

Each generated type exposes static `TYPE` (an `AsnType`) and `CONVERTER` (an
`AsnConverter`) fields. Pass these to every encode/decode call.

### Encoding Rules

Constants in `EncodingRules`:

| Constant | Encoding |
|---|---|
| `BASIC_ENCODING_RULES` | BER |
| `CANONICAL_ENCODING_RULES` | CER |
| `DISTINGUISHED_ENCODING_RULES` | DER |
| `UNALIGNED_PACKED_ENCODING_RULES` | UPER |
| `ALIGNED_PACKED_ENCODING_RULES` | APER |
| `OCTET_ENCODING_RULES` | OER |
| `XML_ENCODING_RULES` | XER |
| `JSON_ENCODING_RULES` | JER |
| `ASN_VALUE_NOTATION` | AVN |

### Error Handling

All runtime errors extend `AsnRuntimeException`:

```csharp
try {
    var pdu = (MyPdu) MyPdu.TYPE.Decode(buffer, MyPdu.CONVERTER);
} catch (AsnRuntimeException e) {
    // handle InvalidTagException, BufferUnderflowException,
    // MissingComponentException, InvalidValueException, etc.
}
```

### Utility Methods

```csharp
var copy = (MyPdu) MyPdu.TYPE.Clone(original, MyPdu.CONVERTER);
bool same = MyPdu.TYPE.Equals(a, b, MyPdu.CONVERTER);
MyPdu.TYPE.Print(pdu, MyPdu.CONVERTER, Console.Out);   // AVN format
string json = MyPdu.TYPE.Json(pdu, MyPdu.CONVERTER);   // JSON string
```

## Generated Output

With `output "build"` and `csharp.output-folder "c#"`, output is written under
`build/c#/`. Each ASN.1 module produces C# source files inside a namespace
derived from the module name.
