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

# ASN.1 Java Compiler Guide

The ASN.1 Java Compiler (`asnjc`) generates Java source code from ASN.1
modules. Generated types are placed in packages derived from module names
and work with the `asnrt` Java runtime library for encoding and decoding.

## Compiler Options

| Field                        | Type    | Default      | Description |
|------------------------------|---------|--------------|-------------|
| `output-folder`              | string  | `"java"`     | Output directory for generated Java sources. |
| `mapping.integer`            | ENUM    | `automatic`  | See [Integer Mapping](#integer-mapping). |
| `mapping.enumerated`         | ENUM    | `enum-type`  | See [Enumerated Mapping](#enumerated-mapping). |
| `mapping.real`               | ENUM    | `double`     | `automatic`, `float`, `double`. |
| `mapping.list`               | ENUM    | `automatic`  | See [List Mapping](#list-mapping). |
| `lower-case-package`         | BOOLEAN | TRUE         | Convert module names to lower case for Java package names. |
| `package-prefix`             | string  | `""`         | Prefix prepended to every generated package name. |
| `generate.setters-getters`   | BOOLEAN | FALSE        | Generate JavaBean-style setters and getters. |
| `generate.clones`            | BOOLEAN | FALSE        | Generate `clone()` methods. |
| `generate.equals`            | BOOLEAN | FALSE        | Generate `equals()` and `hashCode()` methods. |
| `generate.prints`            | BOOLEAN | FALSE        | Generate `toString()` methods. |

## Integer Mapping

Controls how ASN.1 INTEGER is mapped to Java types:

| Option         | Java type |
|----------------|-----------|
| `automatic`    | `BigInteger` when unconstrained; smallest `long`/`int`/`short` that fits otherwise. |
| `integer`      | `long` (legacy alias for `long`). |
| `long`         | `long`. |
| `xlong`        | `long`. |
| `big-integer`  | `BigInteger`. |

## Real Mapping

| Option      | Java type |
|-------------|-----------|
| `automatic` | `double`. |
| `float`     | `float`. |
| `double`    | `double`. |

## Enumerated Mapping

Controls how ASN.1 ENUMERATED is represented:

| Option       | Description |
|--------------|-------------|
| `automatic`  | `enum-type` for extensible ENUMERATED, `enums` for non-extensible. |
| `enum-type`  | A Java class with `public static final` named constants. Supports extensibility through the runtime type system. |
| `enums`      | A Java `enum`. Simpler but does not support extension additions. |
| `singleton`  | A singleton class with named constants. |

## List Mapping

Controls how ASN.1 SEQUENCE OF / SET OF is represented:

| Option        | Java type |
|---------------|-----------|
| `automatic`   | `Vector` for CHOICE/SET lists, `ArrayList` otherwise. |
| `array`       | Java array (`T[]`). |
| `array-list`  | `ArrayList<T>`. |
| `linked-list` | `LinkedList<T>`. |
| `vector`      | `Vector<T>`. |

## Project Configuration Example

```asn1
compilers {
    {
        id "asnjc",
        language "java",
        options {
            output-folder "java",
            mapping {
                integer automatic,
                enumerated automatic,
                real double,
                list automatic
            },
            lower-case-package TRUE,
            package-prefix "com.example",
            generate {
                setters-getters FALSE,
                clones FALSE,
                equals FALSE,
                prints FALSE
            }
        }
    }
}
```

## Runtime Library Usage

After the compiler generates Java source files for your ASN.1 modules, add
the `asnrt` JAR to your classpath. The generated code depends on
`org.asnlab.asndt.runtime` types.

### Encoding

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

```java
import org.asnlab.asndt.runtime.type.*;
import org.asnlab.asndt.runtime.conv.*;

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

Buffer buffer = Buffer.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`:

```java
Buffer buffer = Buffer.wrap(receivedBytes, EncodingRules.ALIGNED_PACKED_ENCODING_RULES);
MyPdu 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 `org.asnlab.asndt.runtime.conv.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`:

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

### Utility Methods

```java
MyPdu copy = (MyPdu) MyPdu.TYPE.clone(original, MyPdu.CONVERTER);
boolean same = MyPdu.TYPE.equals(a, b, MyPdu.CONVERTER);
MyPdu.TYPE.print(pdu, MyPdu.CONVERTER, System.out);   // AVN format
MyPdu.TYPE.json(pdu, MyPdu.CONVERTER, System.out);    // JSON format
```

## Generated Output

With `output "build"` and `java.output-folder "java"`, output is written
under `build/java/` with a package structure derived from each ASN.1 module
name. For example, module `MyModule` with `package-prefix "com.example"`
produces classes under `com/example/mymodule/`.
