Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Nullability

Schema nullability is expressed with optional<T>. Code generators map that schema type to the strongest nullability representation available in each target language.

Runtime bundles encode optional values with explicit presence. Generated code should preserve that distinction in its public API instead of relying on undocumented null conventions.

Built-In Representations

Targetoptional<T> representation
RustOption<T>
C#T? with nullable reference types enabled
KotlinT?
DartT?
ScalaOption[T]
TypeScript`T
JavaScript d.ts`T
Python`T
C++std::optional<T> for C++17 and newer; SoraOptional<T> for older standards
Cgenerated optional wrapper type with presence state
Go*T
Erlang`T
LuaT? EmmyLua annotation
GodotVariant with null
Javanullable value type plus annotation

Dynamic targets such as JavaScript, Lua, and Godot can only document nullability for tooling. Statically typed targets expose it in the generated type whenever the language supports that.

Java Annotations

Java has no standard nullable type syntax. Sora emits nullable Java fields, constructor parameters, and nullable lookup results with an annotation.

By default, Java generation uses a self-contained package-local SoraNullable annotation:

@SoraNullable
public final String nickname;

Projects that use a specific annotation package can configure it:

[codegen.java]
nullable_annotation = "org.jetbrains.annotations.Nullable"

Set nullable_annotation = "" to emit nullable Java values without annotations.

Custom Type Mappings

Type mapping scripts can provide nullable_type_name when the target language needs a different type expression for optional<YourType>:

{
  target = "java",
  schema_type = "UserId",
  type_name = "int",
  nullable_type_name = "Integer",
}

This only changes the generated type expression. The backend still controls how optional presence is decoded.