From 49a6eba5aeecbb377292e74f06134cdbd9ff455e Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Sat, 23 May 2026 16:28:08 +0800 Subject: [PATCH 1/3] docs: refresh language support docs --- README.md | 5 +- docs/README.md | 20 +- docs/compiler/compiler-guide.md | 53 ++- docs/compiler/flatbuffers-idl.md | 6 +- docs/compiler/generated-code.md | 54 +-- docs/compiler/index.md | 21 +- docs/compiler/schema-idl.md | 348 ++++++++++-------- docs/guide/cpp/configuration.md | 4 +- docs/guide/cpp/index.md | 3 +- docs/guide/cpp/native-serialization.md | 5 +- docs/guide/cpp/xlang-serialization.md | 4 +- docs/guide/csharp/index.md | 3 +- docs/guide/dart/index.md | 5 +- docs/guide/go/configuration.md | 3 +- docs/guide/go/index.md | 7 +- docs/guide/go/native-serialization.md | 3 +- docs/guide/go/xlang-serialization.md | 4 +- docs/guide/java/native-serialization.md | 5 +- docs/guide/java/xlang-serialization.md | 2 +- docs/guide/javascript/index.md | 8 +- docs/guide/javascript/xlang-serialization.md | 5 +- docs/guide/python/configuration.md | 18 +- docs/guide/python/native-serialization.md | 3 +- docs/guide/python/xlang-serialization.md | 5 +- docs/guide/rust/index.md | 3 +- docs/guide/rust/native-serialization.md | 3 +- docs/guide/rust/xlang-serialization.md | 3 +- docs/guide/xlang/getting-started.md | 174 ++++++++- docs/guide/xlang/index.md | 18 +- docs/guide/xlang/serialization.md | 4 +- .../specification/xlang_serialization_spec.md | 3 +- docs/specification/xlang_type_mapping.md | 29 +- 32 files changed, 570 insertions(+), 261 deletions(-) diff --git a/README.md b/README.md index bb318b713f..f46fe5008b 100644 --- a/README.md +++ b/README.md @@ -669,8 +669,9 @@ val fory = ForyKotlin.builder() Fory IDL is Fory's schema language for shared data models. It supports references, nullable fields, lists, maps, arrays, enums, messages, and unions, -and generates native data structures for supported languages. Use it when -multiple languages need one shared contract. +and generates native data structures for Java, Python, C++, Go, Rust, +JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. Use it when multiple +languages need one shared contract. ```protobuf package tree; diff --git a/docs/README.md b/docs/README.md index fc36d7c864..678c60ffb7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,14 @@ # User Guide - For xlang serialization, see the [xlang guide](guide/xlang/index.md). -- For Java serialization, see the [Java guide](guide/java/index.md). +- For language-specific serialization, see the [Java](guide/java/index.md), + [Python](guide/python/index.md), [C++](guide/cpp/index.md), + [Go](guide/go/index.md), [Rust](guide/rust/index.md), + [JavaScript/TypeScript](guide/javascript/index.md), + [C#](guide/csharp/index.md), [Swift](guide/swift/index.md), + [Dart](guide/dart/index.md), [Scala](guide/scala/index.md), and + [Kotlin](guide/kotlin/index.md) guides. - For row format, see the [row format spec](specification/row_format_spec.md). -- For Scala serialization, see the [Scala guide](guide/scala/index.md). - For using Apache Fory™ with GraalVM native image, see [graalvm support](guide/java/graalvm-support.md) doc. ## Fory IDL Schema @@ -28,10 +33,19 @@ Define cross-language data structures with Fory IDL and generate native code for - Benchmark source code: - Java: [Java Benchmarks Source](../benchmarks/java) - Python: [Python Benchmarks Source](../benchmarks/python) + - C++: [C++ Benchmarks Source](../benchmarks/cpp) + - Go: [Go Benchmarks Source](../benchmarks/go) - Rust: [Rust Benchmarks Source](../benchmarks/rust/) - Benchmark result: - Java: [Java Benchmarks](benchmarks/java/) - - Rust: [Rust Benchmarks](benchmarks/rust). + - Python: [Python Benchmarks](benchmarks/python/) + - C++: [C++ Benchmarks](benchmarks/cpp/) + - Go: [Go Benchmarks](benchmarks/go/) + - Rust: [Rust Benchmarks](benchmarks/rust/) + - JavaScript/TypeScript: [JavaScript Benchmarks](benchmarks/javascript/) + - C#: [C# Benchmarks](benchmarks/csharp/) + - Swift: [Swift Benchmarks](benchmarks/swift/) + - Dart: [Dart Benchmarks](benchmarks/dart/) ## Development diff --git a/docs/compiler/compiler-guide.md b/docs/compiler/compiler-guide.md index cfa7dd547f..7aeea2fe6d 100644 --- a/docs/compiler/compiler-guide.md +++ b/docs/compiler/compiler-guide.md @@ -63,7 +63,7 @@ Compile options: | `--go_out=DST_DIR` | Generate Go code in DST_DIR | (none) | | `--rust_out=DST_DIR` | Generate Rust code in DST_DIR | (none) | | `--csharp_out=DST_DIR` | Generate C# code in DST_DIR | (none) | -| `--javascript_out=DST_DIR` | Generate JavaScript code in DST_DIR | (none) | +| `--javascript_out=DST_DIR` | Generate JavaScript/TypeScript code in DST_DIR | (none) | | `--swift_out=DST_DIR` | Generate Swift code in DST_DIR | (none) | | `--dart_out=DST_DIR` | Generate Dart code in DST_DIR | (none) | | `--scala_out=DST_DIR` | Generate Scala 3 code in DST_DIR | (none) | @@ -123,7 +123,7 @@ foryc --scan-generated --root ./src --dry-run foryc schema.fdl ``` -**Compile for specific languages:** +**Compile for a selected subset of languages:** ```bash foryc schema.fdl --lang java,python,csharp,javascript,swift,dart,kotlin @@ -185,7 +185,7 @@ foryc src/main.fdl -I libs/common,libs/types --proto_path third_party/ foryc schema.fdl --java_out=./src/main/java # Generate multiple languages to different directories -foryc schema.fdl --java_out=./java/gen --python_out=./python/src --go_out=./go/gen --csharp_out=./csharp/gen --javascript_out=./javascript/src --swift_out=./swift/gen --dart_out=./dart/gen --kotlin_out=./kotlin/gen +foryc schema.fdl --java_out=./java/gen --python_out=./python/src --cpp_out=./cpp/gen --go_out=./go/gen --rust_out=./rust/gen --csharp_out=./csharp/gen --javascript_out=./javascript/src --swift_out=./swift/gen --dart_out=./dart/gen --scala_out=./scala/gen --kotlin_out=./kotlin/gen # Combine with import paths foryc schema.fdl --java_out=./gen/java -I proto/ -I common/ @@ -260,19 +260,19 @@ Compiling src/main.fdl... ## Supported Languages -| Language | Flag | Output Extension | Description | -| ---------- | ------------ | ---------------- | -------------------------------------- | -| Java | `java` | `.java` | POJOs with Fory annotations | -| Python | `python` | `.py` | Dataclasses with type hints | -| Go | `go` | `.go` | Structs with struct tags | -| Rust | `rust` | `.rs` | Structs with derive macros | -| C++ | `cpp` | `.h` | Structs with FORY macros | -| C# | `csharp` | `.cs` | Classes with Fory attributes | -| JavaScript | `javascript` | `.ts` | Interfaces with registration function | -| Swift | `swift` | `.swift` | Fory Swift model macros | -| Dart | `dart` | `.dart` | `@ForyStruct` classes with annotations | -| Scala | `scala` | `.scala` | Scala 3 models with macro derivation | -| Kotlin | `kotlin` | `.kt` | Kotlin models with KSP serializers | +| Language | Flag | Output Extension | Description | +| --------------------- | ------------ | ---------------- | -------------------------------------- | +| Java | `java` | `.java` | POJOs with Fory annotations | +| Python | `python` | `.py` | Dataclasses with type hints | +| Go | `go` | `.go` | Structs with struct tags | +| Rust | `rust` | `.rs` | Structs with derive macros | +| C++ | `cpp` | `.h` | Structs with FORY macros | +| C# | `csharp` | `.cs` | Classes with Fory attributes | +| JavaScript/TypeScript | `javascript` | `.ts` | Interfaces with registration function | +| Swift | `swift` | `.swift` | Fory Swift model macros | +| Dart | `dart` | `.dart` | `@ForyStruct` classes with annotations | +| Scala | `scala` | `.scala` | Scala 3 models with macro derivation | +| Kotlin | `kotlin` | `.kt` | Kotlin models with KSP serializers | ## Output Structure @@ -342,7 +342,7 @@ generated/ - Namespace matches package (dots to `::`) - Header guards and forward declarations -### JavaScript +### JavaScript/TypeScript ``` generated/ @@ -422,6 +422,25 @@ generated/ - Unions use Scala 3 ADT `enum` with `@ForyUnion`, `@ForyCase`, and an `UnknownCase` - Schema module object included +### Kotlin + +``` +generated/ +└── kotlin/ + └── example/ + ├── User.kt + ├── Status.kt + ├── Animal.kt + └── ExampleForyModule.kt +``` + +- One Kotlin source file per generated type +- Package structure uses `kotlin_package` when set, otherwise the Fory IDL package +- Messages use `@ForyStruct` and KSP-generated serializers +- Enums use stable Fory enum IDs +- Unions use sealed classes with `@ForyUnion`, `@ForyCase`, and an unknown-case carrier +- Schema module object included + ### C# IDL Matrix Verification Run the end-to-end C# IDL matrix (FDL/IDL/Proto/FBS generation plus roundtrip tests): diff --git a/docs/compiler/flatbuffers-idl.md b/docs/compiler/flatbuffers-idl.md index e57d1c8a4d..71a249f03e 100644 --- a/docs/compiler/flatbuffers-idl.md +++ b/docs/compiler/flatbuffers-idl.md @@ -187,9 +187,11 @@ table Node { Using `.fbs` as input to Fory still produces normal Fory-generated code, not FlatBuffers `ByteBuffer`-style APIs. -- Java: POJOs/records with Fory metadata +- Java, Scala, and Kotlin: JVM model types with Fory metadata and registration helpers - Python: dataclasses plus registration helpers -- Go/Rust/C++: native structs and Fory metadata +- C++, Go, and Rust: native structs and Fory metadata +- JavaScript/TypeScript: TypeScript interfaces and registration helpers +- C#, Swift, and Dart: annotated or macro-based model types with registration helpers The serialization format is Fory binary protocol, not FlatBuffers wire format. diff --git a/docs/compiler/generated-code.md b/docs/compiler/generated-code.md index beee9cf15d..ed2d02c05e 100644 --- a/docs/compiler/generated-code.md +++ b/docs/compiler/generated-code.md @@ -818,11 +818,11 @@ public static class AddressbookForyRegistration When explicit type IDs are not provided, generated registration uses computed numeric IDs (same behavior as other targets). -## JavaScript +## JavaScript/TypeScript ### Output Layout -JavaScript output is one `.ts` file per schema, for example: +JavaScript/TypeScript output is one `.ts` file per schema, for example: - `/addressbook.ts` @@ -1376,30 +1376,32 @@ object AddressbookForyModule extends org.apache.fory.ForyModule { ### Nested Type Shape -| Language | Nested type form | -| ---------- | ------------------------------ | -| Java | `Person.PhoneNumber` | -| Python | `Person.PhoneNumber` | -| Rust | `person::PhoneNumber` | -| C++ | `Person::PhoneNumber` | -| Go | `Person_PhoneNumber` (default) | -| C# | `Person.PhoneNumber` | -| JavaScript | `Person.PhoneNumber` | -| Swift | `Person.PhoneNumber` | -| Dart | `Person_PhoneNumber` | +| Language | Nested type form | +| --------------------- | ------------------------------ | +| Java | `Person.PhoneNumber` | +| Python | `Person.PhoneNumber` | +| Rust | `person::PhoneNumber` | +| C++ | `Person::PhoneNumber` | +| Go | `Person_PhoneNumber` (default) | +| C# | `Person.PhoneNumber` | +| JavaScript/TypeScript | `Person.PhoneNumber` | +| Swift | `Person.PhoneNumber` | +| Dart | `Person_PhoneNumber` | +| Kotlin | `PersonPhoneNumber` | +| Scala | `Person.PhoneNumber` | ### Byte Helper Naming -| Language | Helpers | -| ---------- | ------------------------- | -| Java | `toBytes` / `fromBytes` | -| Kotlin | `toBytes` / `fromBytes` | -| Scala | `toBytes` / `fromBytes` | -| Python | `to_bytes` / `from_bytes` | -| Rust | `to_bytes` / `from_bytes` | -| C++ | `to_bytes` / `from_bytes` | -| Go | `ToBytes` / `FromBytes` | -| C# | `ToBytes` / `FromBytes` | -| JavaScript | (via `fory.serialize()`) | -| Swift | `toBytes` / `fromBytes` | -| Dart | (via `fory.serialize()`) | +| Language | Helpers | +| --------------------- | ------------------------- | +| Java | `toBytes` / `fromBytes` | +| Kotlin | `toBytes` / `fromBytes` | +| Scala | `toBytes` / `fromBytes` | +| Python | `to_bytes` / `from_bytes` | +| Rust | `to_bytes` / `from_bytes` | +| C++ | `to_bytes` / `from_bytes` | +| Go | `ToBytes` / `FromBytes` | +| C# | `ToBytes` / `FromBytes` | +| JavaScript/TypeScript | (via `fory.serialize()`) | +| Swift | `toBytes` / `fromBytes` | +| Dart | (via `fory.serialize()`) | diff --git a/docs/compiler/index.md b/docs/compiler/index.md index 0b227d7e2a..b61f499171 100644 --- a/docs/compiler/index.md +++ b/docs/compiler/index.md @@ -21,10 +21,11 @@ license: | Fory IDL is a schema definition language for Apache Fory that enables type-safe cross-language serialization. Define your data structures once and generate -native data structure code for Java, Python, Go, Rust, C++, C#, Swift, -JavaScript, Dart, Scala, and Kotlin. Fory IDL can also describe RPC services; -for Java and Python, the compiler can generate gRPC service companions that use -Fory serialization for request and response payloads. +native data structure code for Java, Python, C++, Go, Rust, +JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. Fory IDL can also +describe RPC services; for Java and Python, the compiler can generate gRPC +service companions that use Fory serialization for request and response +payloads. ## Example Schema @@ -128,7 +129,7 @@ Generated code uses native language constructs: - Rust: Structs with `#[derive(ForyObject)]` - C++: Structs with `FORY_STRUCT` macros - C#: Classes with `[ForyObject]` and registration helpers -- JavaScript: Interfaces with registration function +- JavaScript/TypeScript: Interfaces with registration function - Swift: Fory model macros with field/case metadata and registration helpers - Dart: `@ForyStruct` classes with `@ForyField` annotations and registration helpers - Scala: Scala 3 `case class`, normal class, enum, and ADT enum models with macro-derived serializers @@ -227,11 +228,11 @@ message Example { Fory IDL types map to native types in each language: -| Fory IDL Type | Java | Python | Go | Rust | C++ | C# | JavaScript | Swift | Dart | Scala | -| ------------- | --------- | -------------- | -------- | -------- | ------------- | -------- | ---------- | -------- | -------- | --------- | -| `int32` | `int` | `pyfory.Int32` | `int32` | `i32` | `int32_t` | `int` | `number` | `Int32` | `int` | `Int` | -| `string` | `String` | `str` | `string` | `String` | `std::string` | `string` | `string` | `String` | `String` | `String` | -| `bool` | `boolean` | `bool` | `bool` | `bool` | `bool` | `bool` | `boolean` | `Bool` | `bool` | `Boolean` | +| Fory IDL Type | Java | Python | C++ | Go | Rust | JavaScript/TypeScript | C# | Swift | Dart | Scala | Kotlin | +| ------------- | --------- | -------------- | ------------- | -------- | -------- | --------------------- | -------- | -------- | -------- | --------- | --------- | +| `int32` | `int` | `pyfory.Int32` | `int32_t` | `int32` | `i32` | `number` | `int` | `Int32` | `int` | `Int` | `Int` | +| `string` | `String` | `str` | `std::string` | `string` | `String` | `string` | `string` | `String` | `String` | `String` | `String` | +| `bool` | `boolean` | `bool` | `bool` | `bool` | `bool` | `boolean` | `bool` | `Bool` | `bool` | `Boolean` | `Boolean` | See [Type System](schema-idl.md#type-system) for complete mappings. diff --git a/docs/compiler/schema-idl.md b/docs/compiler/schema-idl.md index 8b5835faaf..f5cd9da4c0 100644 --- a/docs/compiler/schema-idl.md +++ b/docs/compiler/schema-idl.md @@ -100,17 +100,19 @@ package com.example.models alias models_v1; **Language Mapping:** -| Language | Package Usage | -| ---------- | --------------------------------- | -| Java | Java package | -| Python | Module name (dots to underscores) | -| Go | Package name (last component) | -| Rust | Module name (dots to underscores) | -| C++ | Namespace (dots to `::`) | -| C# | Namespace | -| JavaScript | Module name (last segment) | -| Dart | Library name (package segments) | -| Kotlin | Kotlin package | +| Language | Package Usage | +| --------------------- | --------------------------------- | +| Java | Java package | +| Python | Module name (dots to underscores) | +| Go | Package name (last component) | +| Rust | Module name (dots to underscores) | +| C++ | Namespace (dots to `::`) | +| C# | Namespace | +| JavaScript/TypeScript | TypeScript module name | +| Swift | Namespace wrapper or prefix | +| Dart | Library name (package segments) | +| Scala | Scala package | +| Kotlin | Kotlin package | ## File-Level Options @@ -596,15 +598,19 @@ FDL does not support `option ...;` statements inside enum bodies. ### Language Mapping -| Language | Implementation | -| ---------- | -------------------------------------- | -| Java | `enum Status { UNKNOWN, ACTIVE, ... }` | -| Python | `class Status(IntEnum): UNKNOWN = 0` | -| Go | `type Status int32` with constants | -| Rust | `#[repr(i32)] enum Status { Unknown }` | -| C++ | `enum class Status : int32_t { ... }` | -| JavaScript | `export enum Status { UNKNOWN, ... }` | -| Dart | `enum Status { unknown, active, ... }` | +| Language | Implementation | +| --------------------- | -------------------------------------- | +| Java | `enum Status { UNKNOWN, ACTIVE, ... }` | +| Python | `class Status(IntEnum): UNKNOWN = 0` | +| Go | `type Status int32` with constants | +| Rust | `#[repr(i32)] enum Status { Unknown }` | +| C++ | `enum class Status : int32_t { ... }` | +| C# | `enum Status { Unknown, Active, ... }` | +| JavaScript/TypeScript | `export enum Status { UNKNOWN, ... }` | +| Swift | `enum Status` with stable IDs | +| Dart | `enum Status { unknown, active, ... }` | +| Scala | Scala 3 `enum Status` | +| Kotlin | `enum class Status` | ### Enum Prefix Stripping @@ -621,15 +627,19 @@ enum DeviceTier { **Generated code:** -| Language | Output | Style | -| ---------- | ----------------------------------------- | -------------- | -| Java | `UNKNOWN, TIER1, TIER2` | Scoped enum | -| Rust | `Unknown, Tier1, Tier2` | Scoped enum | -| C++ | `UNKNOWN, TIER1, TIER2` | Scoped enum | -| Python | `UNKNOWN, TIER1, TIER2` | Scoped IntEnum | -| Go | `DeviceTierUnknown, DeviceTierTier1, ...` | Unscoped const | -| JavaScript | `UNKNOWN, TIER1, TIER2` | Scoped enum | -| Dart | `unknown, tier1, tier2` | Scoped enum | +| Language | Output | Style | +| --------------------- | ----------------------------------------- | -------------- | +| Java | `UNKNOWN, TIER1, TIER2` | Scoped enum | +| Rust | `Unknown, Tier1, Tier2` | Scoped enum | +| C++ | `UNKNOWN, TIER1, TIER2` | Scoped enum | +| Python | `UNKNOWN, TIER1, TIER2` | Scoped IntEnum | +| Go | `DeviceTierUnknown, DeviceTierTier1, ...` | Unscoped const | +| JavaScript/TypeScript | `UNKNOWN, TIER1, TIER2` | Scoped enum | +| C# | `Unknown, Tier1, Tier2` | Scoped enum | +| Swift | `unknown, tier1, tier2` | Scoped enum | +| Dart | `unknown, tier1, tier2` | Scoped enum | +| Scala | `Unknown, Tier1, Tier2` | Scoped enum | +| Kotlin | `UNKNOWN, TIER1, TIER2` | Scoped enum | **Note:** The prefix is only stripped if the remainder is a valid identifier. For example, `DEVICE_TIER_1` is kept unchanged because `1` is not a valid identifier name. @@ -699,15 +709,19 @@ message Person { // Auto-generated when enable_auto_type_id = true ### Language Mapping -| Language | Implementation | -| ---------- | ----------------------------------- | -| Java | POJO class with getters/setters | -| Python | `@dataclass` class | -| Go | Struct with exported fields | -| Rust | Struct with `#[derive(ForyObject)]` | -| C++ | Struct with `FORY_STRUCT` macro | -| JavaScript | `export interface` declaration | -| Dart | `@ForyStruct` `final class` | +| Language | Implementation | +| --------------------- | ----------------------------------- | +| Java | POJO class with getters/setters | +| Python | `@dataclass` class | +| Go | Struct with exported fields | +| Rust | Struct with `#[derive(ForyObject)]` | +| C++ | Struct with `FORY_STRUCT` macro | +| C# | `[ForyObject]` class | +| JavaScript/TypeScript | `export interface` declaration | +| Swift | `@ForyStruct` struct or class | +| Dart | `@ForyStruct` `final class` | +| Scala | Scala 3 `case class` or class | +| Kotlin | `data class` or class | Type IDs control cross-language registration for messages, unions, and enums. See [Type IDs](#type-ids) for auto-generation, aliases, and collision handling. @@ -824,15 +838,19 @@ message OtherMessage { ### Language-Specific Generation -| Language | Nested Type Generation | -| ---------- | --------------------------------------------------------------------------------- | -| Java | Static inner classes (`SearchResponse.Result`) | -| Python | Nested classes within dataclass | -| Go | Flat structs with underscore (`SearchResponse_Result`, configurable to camelcase) | -| Rust | Nested modules (`search_response::Result`) | -| C++ | Nested classes (`SearchResponse::Result`) | -| JavaScript | Flat names (`Result`) | -| Dart | Flat classes with underscore (`SearchResponse_Result`) | +| Language | Nested Type Generation | +| --------------------- | --------------------------------------------------------------------------------- | +| Java | Static inner classes (`SearchResponse.Result`) | +| Python | Nested classes within dataclass | +| Go | Flat structs with underscore (`SearchResponse_Result`, configurable to camelcase) | +| Rust | Nested modules (`search_response::Result`) | +| C++ | Nested classes (`SearchResponse::Result`) | +| C# | Nested classes (`SearchResponse.Result`) | +| JavaScript/TypeScript | Flat names (`Result`) | +| Swift | Nested namespace wrappers or flattened names | +| Dart | Flat classes with underscore (`SearchResponse_Result`) | +| Scala | Nested companion/object scope | +| Kotlin | Flat generated names | **Note:** Go defaults to underscore-separated nested names; set `option go_nested_type_style = "camelcase";` to use concatenated names. Rust emits nested modules for nested types. @@ -986,16 +1004,19 @@ message User { **Generated Code:** -| Language | Non-optional | Optional | -| ---------- | ------------------ | --------------------------------- | -| Java | `String name` | `@Nullable String email` | -| Python | `name: str` | `name: Optional[str]` | -| Go | `Name string` | `Name *string` | -| Rust | `name: String` | `name: Option` | -| C++ | `std::string name` | `std::optional name` | -| JavaScript | `name: string` | `name?: string \| null` | -| Dart | `String name` | `String? email` | -| Scala | `name: String` | `email: Option[String]` | +| Language | Non-optional | Optional | +| --------------------- | ------------------ | --------------------------------- | +| Java | `String name` | `@Nullable String email` | +| Python | `name: str` | `name: Optional[str]` | +| Go | `Name string` | `Name *string` | +| Rust | `name: String` | `name: Option` | +| C++ | `std::string name` | `std::optional name` | +| C# | `string name` | `string? email` | +| JavaScript/TypeScript | `name: string` | `name?: string \| null` | +| Swift | `String name` | `String? email` | +| Dart | `String name` | `String? email` | +| Scala | `name: String` | `email: Option[String]` | +| Kotlin | `name: String` | `email: String?` | **Default Values:** @@ -1024,16 +1045,19 @@ message Node { **Generated Code:** -| Language | Without `ref` | With `ref` | -| ---------- | -------------- | ------------------------------------------ | -| Java | `Node parent` | `Node parent` with `@Ref` | -| Python | `parent: Node` | `parent: Node = pyfory.field(ref=True)` | -| Go | `Parent Node` | `Parent *Node` with `fory:"ref"` | -| Rust | `parent: Node` | `parent: Rc` | -| C++ | `Node parent` | `std::shared_ptr parent` | -| JavaScript | `parent: Node` | `parent: Node` (no ref distinction) | -| Dart | `Node parent` | `Node parent` with `@ForyField(ref: true)` | -| Scala | `parent: Node` | `@Ref parent: Node` | +| Language | Without `ref` | With `ref` | +| --------------------- | -------------- | ------------------------------------------ | +| Java | `Node parent` | `Node parent` with `@Ref` | +| Python | `parent: Node` | `parent: Node = pyfory.field(ref=True)` | +| Go | `Parent Node` | `Parent *Node` with `fory:"ref"` | +| Rust | `parent: Node` | `parent: Rc` | +| C++ | `Node parent` | `std::shared_ptr parent` | +| C# | `Node parent` | `Node? parent` with runtime ref tracking | +| JavaScript/TypeScript | `parent: Node` | `parent: Node` (no ref distinction) | +| Swift | `Node parent` | class reference with runtime ref tracking | +| Dart | `Node parent` | `Node parent` with `@ForyField(ref: true)` | +| Scala | `parent: Node` | `@Ref parent: Node` | +| Kotlin | `parent: Node` | `@Ref parent: Node?` | Rust uses `Rc` and `RcWeak` by default for ref-tracked fields. Use `ref(thread_safe=true)` when the generated Rust type must use `Arc` or @@ -1064,15 +1088,19 @@ message Document { **Generated Code:** -| Language | Type | -| ---------- | -------------------------- | -| Java | `List` | -| Python | `List[str]` | -| Go | `[]string` | -| Rust | `Vec` | -| C++ | `std::vector` | -| JavaScript | `string[]` | -| Dart | `List` | +| Language | Type | +| --------------------- | -------------------------- | +| Java | `List` | +| Python | `List[str]` | +| Go | `[]string` | +| Rust | `Vec` | +| C++ | `std::vector` | +| C# | `List` | +| JavaScript/TypeScript | `string[]` | +| Swift | `[String]` | +| Dart | `List` | +| Scala | `List[String]` | +| Kotlin | `List` | ### Combining Modifiers @@ -1129,6 +1157,10 @@ collections. Field modifiers (`optional`, `ref`) control nullability and reference tracking, while `list` and `array` choose collection schema kind (see [Field Modifiers](#field-modifiers)). +The compact tables in this section show common generated carriers. For the +complete 1.0 runtime surface, including C#, Swift, Dart, Scala, and Kotlin, see +the [xlang type-mapping specification](../specification/xlang_type_mapping.md). + ### Primitive Types | Type | Description | Size | @@ -1156,15 +1188,15 @@ reference tracking, while `list` and `array` choose collection schema kind #### Boolean -| Language | Type | Notes | -| ---------- | --------------------- | ------------------ | -| Java | `boolean` / `Boolean` | Primitive or boxed | -| Python | `bool` | | -| Go | `bool` | | -| Rust | `bool` | | -| C++ | `bool` | | -| JavaScript | `boolean` | | -| Dart | `bool` | | +| Language | Type | Notes | +| --------------------- | --------------------- | ------------------ | +| Java | `boolean` / `Boolean` | Primitive or boxed | +| Python | `bool` | | +| Go | `bool` | | +| Rust | `bool` | | +| C++ | `bool` | | +| JavaScript/TypeScript | `boolean` | | +| Dart | `bool` | | #### Integer Types @@ -1179,12 +1211,12 @@ Fory IDL provides fixed-width signed integers (varint encoding for 32/64-bit by **Language Mapping (Signed):** -| Fory IDL | Java | Python | Go | Rust | C++ | JavaScript | Dart | -| -------- | ------- | -------------- | ------- | ----- | --------- | ------------------ | ------- | -| `int8` | `byte` | `pyfory.Int8` | `int8` | `i8` | `int8_t` | `number` | `int` | -| `int16` | `short` | `pyfory.Int16` | `int16` | `i16` | `int16_t` | `number` | `int` | -| `int32` | `int` | `pyfory.Int32` | `int32` | `i32` | `int32_t` | `number` | `int` | -| `int64` | `long` | `pyfory.Int64` | `int64` | `i64` | `int64_t` | `bigint \| number` | `Int64` | +| Fory IDL | Java | Python | Go | Rust | C++ | JavaScript/TypeScript | Dart | +| -------- | ------- | -------------- | ------- | ----- | --------- | --------------------- | ------- | +| `int8` | `byte` | `pyfory.Int8` | `int8` | `i8` | `int8_t` | `number` | `int` | +| `int16` | `short` | `pyfory.Int16` | `int16` | `i16` | `int16_t` | `number` | `int` | +| `int32` | `int` | `pyfory.Int32` | `int32` | `i32` | `int32_t` | `number` | `int` | +| `int64` | `long` | `pyfory.Int64` | `int64` | `i64` | `int64_t` | `bigint \| number` | `Int64` | Fory IDL provides fixed-width unsigned integers (varint encoding for 32/64-bit by default): @@ -1197,12 +1229,12 @@ Fory IDL provides fixed-width unsigned integers (varint encoding for 32/64-bit b **Language Mapping (Unsigned):** -| Fory IDL | Java | Python | Go | Rust | C++ | JavaScript | Dart | -| -------- | ------- | --------------- | -------- | ----- | ---------- | ------------------ | -------- | -| `uint8` | `short` | `pyfory.UInt8` | `uint8` | `u8` | `uint8_t` | `number` | `int` | -| `uint16` | `int` | `pyfory.UInt16` | `uint16` | `u16` | `uint16_t` | `number` | `int` | -| `uint32` | `long` | `pyfory.UInt32` | `uint32` | `u32` | `uint32_t` | `number` | `int` | -| `uint64` | `long` | `pyfory.UInt64` | `uint64` | `u64` | `uint64_t` | `bigint \| number` | `Uint64` | +| Fory IDL | Java | Python | Go | Rust | C++ | JavaScript/TypeScript | Dart | +| -------- | ------- | --------------- | -------- | ----- | ---------- | --------------------- | -------- | +| `uint8` | `short` | `pyfory.UInt8` | `uint8` | `u8` | `uint8_t` | `number` | `int` | +| `uint16` | `int` | `pyfory.UInt16` | `uint16` | `u16` | `uint16_t` | `number` | `int` | +| `uint32` | `long` | `pyfory.UInt32` | `uint32` | `u32` | `uint32_t` | `number` | `int` | +| `uint64` | `long` | `pyfory.UInt64` | `uint64` | `u64` | `uint64_t` | `bigint \| number` | `Uint64` | #### Integer Encoding Modifiers @@ -1235,62 +1267,62 @@ Underscore spellings for integer encoding are not FDL type names. **Language Mapping:** -| Fory IDL | Java | Python annotation/value | Go | Rust | C++ | JavaScript | Dart | -| ---------- | ---------- | --------------------------- | ------------------- | ---------- | ------------------ | ---------- | --------- | -| `float16` | `Float16` | `pyfory.Float16` / `float` | `float16.Float16` | `Float16` | `fory::float16_t` | `number` | `double` | -| `bfloat16` | `BFloat16` | `pyfory.BFloat16` / `float` | `bfloat16.BFloat16` | `BFloat16` | `fory::bfloat16_t` | `number` | `double` | -| `float32` | `float` | `pyfory.Float32` | `float32` | `f32` | `float` | `number` | `Float32` | -| `float64` | `double` | `pyfory.Float64` | `float64` | `f64` | `double` | `number` | `double` | +| Fory IDL | Java | Python annotation/value | Go | Rust | C++ | JavaScript/TypeScript | Dart | +| ---------- | ---------- | --------------------------- | ------------------- | ---------- | ------------------ | --------------------- | --------- | +| `float16` | `Float16` | `pyfory.Float16` / `float` | `float16.Float16` | `Float16` | `fory::float16_t` | `number` | `double` | +| `bfloat16` | `BFloat16` | `pyfory.BFloat16` / `float` | `bfloat16.BFloat16` | `BFloat16` | `fory::bfloat16_t` | `number` | `double` | +| `float32` | `float` | `pyfory.Float32` | `float32` | `f32` | `float` | `number` | `Float32` | +| `float64` | `double` | `pyfory.Float64` | `float64` | `f64` | `double` | `number` | `double` | #### String Type -| Language | Type | Notes | -| ---------- | ------------- | --------------------- | -| Java | `String` | Immutable | -| Python | `str` | | -| Go | `string` | Immutable | -| Rust | `String` | Owned, heap-allocated | -| C++ | `std::string` | | -| JavaScript | `string` | | -| Dart | `String` | | +| Language | Type | Notes | +| --------------------- | ------------- | --------------------- | +| Java | `String` | Immutable | +| Python | `str` | | +| Go | `string` | Immutable | +| Rust | `String` | Owned, heap-allocated | +| C++ | `std::string` | | +| JavaScript/TypeScript | `string` | | +| Dart | `String` | | #### Bytes Type -| Language | Type | Notes | -| ---------- | ---------------------- | --------- | -| Java | `byte[]` | | -| Python | `bytes` | Immutable | -| Go | `[]byte` | | -| Rust | `Vec` | | -| C++ | `std::vector` | | -| JavaScript | `Uint8Array` | | -| Dart | `Uint8List` | | +| Language | Type | Notes | +| --------------------- | ---------------------- | --------- | +| Java | `byte[]` | | +| Python | `bytes` | Immutable | +| Go | `[]byte` | | +| Rust | `Vec` | | +| C++ | `std::vector` | | +| JavaScript/TypeScript | `Uint8Array` | | +| Dart | `Uint8List` | | #### Temporal Types ##### Date -| Language | Type | Notes | -| ---------- | --------------------------- | --------------------------------------------------------------------------- | -| Java | `java.time.LocalDate` | | -| Python | `datetime.date` | | -| Go | `time.Time` | Time portion ignored | -| Rust | `fory::Date` | Set `rust_use_chrono_temporal_types = true` to generate `chrono::NaiveDate` | -| C++ | `fory::serialization::Date` | | -| JavaScript | `Date` | | -| Dart | `LocalDate` | Fory package type | +| Language | Type | Notes | +| --------------------- | --------------------------- | --------------------------------------------------------------------------- | +| Java | `java.time.LocalDate` | | +| Python | `datetime.date` | | +| Go | `time.Time` | Time portion ignored | +| Rust | `fory::Date` | Set `rust_use_chrono_temporal_types = true` to generate `chrono::NaiveDate` | +| C++ | `fory::serialization::Date` | | +| JavaScript/TypeScript | `Date` | | +| Dart | `LocalDate` | Fory package type | ##### Timestamp -| Language | Type | Notes | -| ---------- | -------------------------------- | ------------------------------------------------------------------------------- | -| Java | `java.time.Instant` | UTC-based | -| Python | `datetime.datetime` | | -| Go | `time.Time` | | -| Rust | `fory::Timestamp` | Set `rust_use_chrono_temporal_types = true` to generate `chrono::NaiveDateTime` | -| C++ | `fory::serialization::Timestamp` | | -| JavaScript | `Date` | | -| Dart | `Timestamp` | Fory package type | +| Language | Type | Notes | +| --------------------- | -------------------------------- | ------------------------------------------------------------------------------- | +| Java | `java.time.Instant` | UTC-based | +| Python | `datetime.datetime` | | +| Go | `time.Time` | | +| Rust | `fory::Timestamp` | Set `rust_use_chrono_temporal_types = true` to generate `chrono::NaiveDateTime` | +| C++ | `fory::serialization::Timestamp` | | +| JavaScript/TypeScript | `Date` | | +| Dart | `Timestamp` | Fory package type | ##### Duration @@ -1305,15 +1337,15 @@ Underscore spellings for integer encoding are not FDL type names. #### Any -| Language | Type | Notes | -| ---------- | -------------- | -------------------- | -| Java | `Object` | Runtime type written | -| Python | `Any` | Runtime type written | -| Go | `any` | Runtime type written | -| Rust | `Box` | Runtime type written | -| C++ | `std::any` | Runtime type written | -| JavaScript | `any` | Runtime type written | -| Dart | `Object?` | Runtime type written | +| Language | Type | Notes | +| --------------------- | -------------- | -------------------- | +| Java | `Object` | Runtime type written | +| Python | `Any` | Runtime type written | +| Go | `any` | Runtime type written | +| Rust | `Box` | Runtime type written | +| C++ | `std::any` | Runtime type written | +| JavaScript/TypeScript | `any` | Runtime type written | +| Dart | `Object?` | Runtime type written | **Example:** @@ -1335,15 +1367,15 @@ message Envelope [id=122] { **Generated Code (`Envelope.payload`):** -| Language | Generated Field Type | -| ---------- | ----------------------- | -| Java | `Object payload` | -| Python | `payload: Any` | -| Go | `Payload any` | -| Rust | `payload: Box` | -| C++ | `std::any payload` | -| JavaScript | `payload: any` | -| Dart | `Object? payload` | +| Language | Generated Field Type | +| --------------------- | ----------------------- | +| Java | `Object payload` | +| Python | `payload: Any` | +| Go | `Payload any` | +| Rust | `payload: Box` | +| C++ | `std::any payload` | +| JavaScript/TypeScript | `payload: any` | +| Dart | `Object? payload` | **Notes:** @@ -1443,7 +1475,7 @@ message Config { **Language Mapping:** -| Fory IDL | Java | Python | Go | Rust | C++ | JavaScript | Dart | +| Fory IDL | Java | Python | Go | Rust | C++ | JavaScript/TypeScript | Dart | | -------------------- | ---------------------- | ----------------- | ------------------ | ----------------------- | -------------------------------- | --------------------- | ------------------- | | `map` | `Map` | `Dict[str, int]` | `map[string]int32` | `HashMap` | `std::map` | `Map` | `Map` | | `map` | `Map` | `Dict[str, User]` | `map[string]User` | `HashMap` | `std::map` | `Map` | `Map` | diff --git a/docs/guide/cpp/configuration.md b/docs/guide/cpp/configuration.md index a693f32091..d829dc8a99 100644 --- a/docs/guide/cpp/configuration.md +++ b/docs/guide/cpp/configuration.md @@ -69,8 +69,8 @@ auto fory = Fory::builder() ``` When `true`, C++ writes the xlang wire format used by Java, Python, Go, Rust, -JavaScript, C#, Swift, and Dart. When `false`, C++ writes native-mode payloads -for C++-only traffic. +JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. When `false`, C++ +writes native-mode payloads for C++-only traffic. **Default:** `true` diff --git a/docs/guide/cpp/index.md b/docs/guide/cpp/index.md index 9e628f89a1..73b91ece50 100644 --- a/docs/guide/cpp/index.md +++ b/docs/guide/cpp/index.md @@ -26,7 +26,8 @@ The C++ implementation provides high-performance serialization with compile-time ## Why Apache Fory™ C++? - **Fast binary encoding**: Fast serialization and optimized binary protocols -- **Xlang**: Seamlessly serialize/deserialize data across Java, Python, C++, Go, JavaScript, and Rust +- **Xlang**: Seamlessly serialize/deserialize data across Java, Python, C++, Go, + Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin - **Type-safe**: Compile-time type checking with macro-based struct registration - **Reference tracking**: Automatic tracking of shared and circular references - **Schema evolution**: Compatible mode for independent schema changes diff --git a/docs/guide/cpp/native-serialization.md b/docs/guide/cpp/native-serialization.md index 0a530278e9..0189d72a78 100644 --- a/docs/guide/cpp/native-serialization.md +++ b/docs/guide/cpp/native-serialization.md @@ -23,8 +23,9 @@ C++ native serialization is the C++-only wire mode selected with `.xlang(false)` writer and reader is C++ and the payload should follow C++ type behavior instead of the portable xlang type system. -Use [Xlang Serialization](xlang-serialization.md), the default C++ mode, when bytes must be read by -Java, Python, Go, Rust, JavaScript, or another non-C++ Fory runtime. +Use [Xlang Serialization](xlang-serialization.md), the default C++ mode, when +bytes must be read by Java, Python, Go, Rust, JavaScript/TypeScript, C#, Swift, +Dart, Scala, Kotlin, or another non-C++ Fory runtime. ## When To Use Native Serialization diff --git a/docs/guide/cpp/xlang-serialization.md b/docs/guide/cpp/xlang-serialization.md index 0570c02176..7d4dbcff36 100644 --- a/docs/guide/cpp/xlang-serialization.md +++ b/docs/guide/cpp/xlang-serialization.md @@ -23,7 +23,9 @@ This page explains how to use Fory xlang serialization between C++ and other lan ## Overview -Apache Fory™ enables seamless data exchange between C++, Java, Python, Go, Rust, and JavaScript. Xlang mode ensures binary compatibility across all supported languages. +Apache Fory™ enables seamless data exchange between C++, Java, Python, Go, Rust, +JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. Xlang mode ensures +binary compatibility across all supported languages. ## Create an Xlang Runtime diff --git a/docs/guide/csharp/index.md b/docs/guide/csharp/index.md index 531b8958a2..9fbb06b018 100644 --- a/docs/guide/csharp/index.md +++ b/docs/guide/csharp/index.md @@ -24,7 +24,8 @@ Apache Fory™ C# is a high-performance, cross-language serialization runtime fo ## Why Fory C#? - High performance binary serialization for .NET 8+ -- Xlang compatibility with Fory implementations in Java, Python, C++, Go, Rust, and JavaScript +- Xlang compatibility with Fory implementations in Java, Python, C++, Go, Rust, + JavaScript/TypeScript, Swift, Dart, Scala, and Kotlin - Source-generator-based serializers for `[ForyObject]` types - Optional reference tracking for shared and circular object graphs - Compatible mode for schema evolution diff --git a/docs/guide/dart/index.md b/docs/guide/dart/index.md index c60016edbb..74bb39b883 100644 --- a/docs/guide/dart/index.md +++ b/docs/guide/dart/index.md @@ -19,7 +19,10 @@ license: | limitations under the License. --- -Apache Fory™ Dart lets you serialize Dart objects to bytes and deserialize them back — including across services written in Java, Go, C#, Python, and other Fory-supported languages. +Apache Fory™ Dart lets you serialize Dart objects to bytes and deserialize them +back, including across services written in Java, Python, C++, Go, Rust, +JavaScript/TypeScript, C#, Swift, Scala, Kotlin, and other Fory-supported +languages. ## Why Fory Dart? diff --git a/docs/guide/go/configuration.md b/docs/guide/go/configuration.md index 4ca85273dd..d2c73e7f65 100644 --- a/docs/guide/go/configuration.md +++ b/docs/guide/go/configuration.md @@ -131,7 +131,8 @@ xlang := fory.New(fory.WithXlang(true)) **When enabled:** - Uses cross-language type system -- Compatible with Java, Python, C++, Rust, JavaScript +- Compatible with Java, Python, C++, Rust, JavaScript/TypeScript, C#, Swift, + Dart, Scala, and Kotlin - Type IDs follow xlang specification **When disabled:** diff --git a/docs/guide/go/index.md b/docs/guide/go/index.md index fb74931d62..84ebb77a11 100644 --- a/docs/guide/go/index.md +++ b/docs/guide/go/index.md @@ -24,7 +24,8 @@ Apache Fory Go is a high-performance serialization library for Go. It supports x ## Why Fory Go? - **High Performance**: Fast serialization and optimized binary protocols -- **Xlang**: Seamless data exchange with Java, Python, C++, Rust, and JavaScript +- **Xlang**: Seamless data exchange with Java, Python, C++, Rust, + JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin - **Automatic Serialization**: No IDL definitions or schema compilation required - **Reference Tracking**: Built-in support for circular references and shared objects - **Type Safety**: Strong typing with schema-aware serializers @@ -120,7 +121,9 @@ See [Supported Types](supported-types.md) for the complete type mapping. ## Xlang Serialization -Fory Go is fully compatible with other Fory implementations. Data serialized in Go can be deserialized in Java, Python, C++, Rust, or JavaScript: +Fory Go is fully compatible with other Fory implementations. Data serialized in +Go can be deserialized in Java, Python, C++, Rust, JavaScript/TypeScript, C#, +Swift, Dart, Scala, or Kotlin: ```go // Go serialization diff --git a/docs/guide/go/native-serialization.md b/docs/guide/go/native-serialization.md index 00dde847dc..0dc6bc0ce4 100644 --- a/docs/guide/go/native-serialization.md +++ b/docs/guide/go/native-serialization.md @@ -24,7 +24,8 @@ when every writer and reader is a Go service and the payload should follow Go's of the portable xlang type system. Use [Xlang Serialization](xlang-serialization.md), the default Go mode, when bytes must be read by -Java, Python, C++, Rust, JavaScript, or another non-Go Fory runtime. +Java, Python, C++, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, Kotlin, +or another non-Go Fory runtime. ## When To Use Native Serialization diff --git a/docs/guide/go/xlang-serialization.md b/docs/guide/go/xlang-serialization.md index e7df613b75..6ef2d8e589 100644 --- a/docs/guide/go/xlang-serialization.md +++ b/docs/guide/go/xlang-serialization.md @@ -19,7 +19,9 @@ license: | limitations under the License. --- -Fory Go enables seamless data exchange with Java, Python, C++, Rust, and JavaScript. This guide covers xlang compatibility and type mapping. +Fory Go enables seamless data exchange with Java, Python, C++, Rust, +JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. This guide covers +xlang compatibility and type mapping. ## Create an Xlang Runtime diff --git a/docs/guide/java/native-serialization.md b/docs/guide/java/native-serialization.md index 133c0d4ad5..7dd6fe58dc 100644 --- a/docs/guide/java/native-serialization.md +++ b/docs/guide/java/native-serialization.md @@ -44,8 +44,9 @@ Use native serialization when: - Large primitive arrays or binary payloads should use native-mode out-of-band buffers. - You are replacing Java-only serialization frameworks and want the broadest Java object surface. -Use xlang serialization instead when the payload must be read by Python, C++, Go, Rust, -JavaScript/TypeScript, C#, Swift, Dart, or another non-Java runtime. +Use xlang serialization instead when the payload must be read by Python, C++, Go, +Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, Kotlin, or another +non-Java runtime. ## Create a Native Runtime diff --git a/docs/guide/java/xlang-serialization.md b/docs/guide/java/xlang-serialization.md index 425d5b41b3..8d6ea9d521 100644 --- a/docs/guide/java/xlang-serialization.md +++ b/docs/guide/java/xlang-serialization.md @@ -20,7 +20,7 @@ license: | --- Apache Fory™ xlang serialization is the Java wire mode for payloads that must be read by Python, -Rust, Go, JavaScript, C++, C#, Swift, Dart, or another non-Java Fory runtime. Java defaults to +Rust, Go, JavaScript/TypeScript, C++, C#, Swift, Dart, Scala, Kotlin, or another non-Java Fory runtime. Java defaults to xlang mode with compatible schema evolution, but examples set the mode explicitly so the payload contract is visible in code. diff --git a/docs/guide/javascript/index.md b/docs/guide/javascript/index.md index 49d4de7290..86280097c2 100644 --- a/docs/guide/javascript/index.md +++ b/docs/guide/javascript/index.md @@ -19,11 +19,15 @@ license: | limitations under the License. --- -Apache Fory JavaScript lets you serialize JavaScript and TypeScript objects to bytes and deserialize them back — including across services written in Java, Python, Go, Rust, Swift, and other Fory-supported languages. +Apache Fory JavaScript lets you serialize JavaScript and TypeScript objects to +bytes and deserialize them back, including across services written in Java, +Python, C++, Go, Rust, C#, Swift, Dart, Scala, Kotlin, and other +Fory-supported languages. ## Why Fory JavaScript? -- **Xlang**: serialize in JavaScript, deserialize in Java, Python, Go, and more without writing glue code +- **Xlang**: serialize in JavaScript/TypeScript, deserialize in any supported + Fory runtime without writing glue code - **Fast**: serializer code is generated and cached the first time you register a schema, not on every call - **Reference-aware**: shared references and circular object graphs are supported when enabled - **Explicit schemas**: field types, nullability, and polymorphism are declared once with `Type.*` builders or TypeScript decorators diff --git a/docs/guide/javascript/xlang-serialization.md b/docs/guide/javascript/xlang-serialization.md index 13ed956747..17f1413b02 100644 --- a/docs/guide/javascript/xlang-serialization.md +++ b/docs/guide/javascript/xlang-serialization.md @@ -19,7 +19,10 @@ license: | limitations under the License. --- -Fory JavaScript serializes to the same binary format as the Java, Python, Go, Rust, Swift, and C++ Fory runtimes. You can write a message in JavaScript and read it in Java — or any other direction — without any conversion layer. +Fory JavaScript serializes to the same binary format as the Java, Python, C++, +Go, Rust, C#, Swift, Dart, Scala, and Kotlin Fory runtimes. You can write a +message in JavaScript and read it in Java, or any other direction, without a +conversion layer. Things to keep in mind: diff --git a/docs/guide/python/configuration.md b/docs/guide/python/configuration.md index fc6433debb..a902192382 100644 --- a/docs/guide/python/configuration.md +++ b/docs/guide/python/configuration.md @@ -89,15 +89,15 @@ fory.register(MyClass, typename="my.package.MyClass", serializer=custom_serializ ## Xlang And Native Mode Comparison -| Feature | Native mode (`xlang=False`) | Xlang mode (default) | -| ------------------- | ---------------------------------------------- | ------------------------------------- | -| Use case | Python-only applications | Multi-language systems | -| Compatibility | Python only | Java, Go, Rust, C++, JavaScript, etc. | -| Supported types | Python object surface | Cross-language compatible types | -| Functions/lambdas | Supported with trusted dynamic deserialization | Not allowed | -| Local classes | Supported with trusted dynamic deserialization | Not allowed | -| Dynamic classes | Supported with trusted dynamic deserialization | Not allowed | -| Schema mode default | Schema-consistent | Compatible | +| Feature | Native mode (`xlang=False`) | Xlang mode (default) | +| ------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------- | +| Use case | Python-only applications | Multi-language systems | +| Compatibility | Python only | Java, C++, Go, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, Kotlin, etc. | +| Supported types | Python object surface | Cross-language compatible types | +| Functions/lambdas | Supported with trusted dynamic deserialization | Not allowed | +| Local classes | Supported with trusted dynamic deserialization | Not allowed | +| Dynamic classes | Supported with trusted dynamic deserialization | Not allowed | +| Schema mode default | Schema-consistent | Compatible | ## Xlang Mode diff --git a/docs/guide/python/native-serialization.md b/docs/guide/python/native-serialization.md index b67bc2f662..ec0f5c4a60 100644 --- a/docs/guide/python/native-serialization.md +++ b/docs/guide/python/native-serialization.md @@ -24,7 +24,8 @@ every writer and reader is Python and the payload should follow Python's object the portable xlang type system. Use [Xlang Serialization](xlang-serialization.md), the default Python mode, when bytes must be read -by Java, Go, Rust, C++, JavaScript, or another non-Python Fory runtime. +by Java, C++, Go, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, Kotlin, +or another non-Python Fory runtime. ## When To Use Native Serialization diff --git a/docs/guide/python/xlang-serialization.md b/docs/guide/python/xlang-serialization.md index 6bf564951e..cf1bd19b56 100644 --- a/docs/guide/python/xlang-serialization.md +++ b/docs/guide/python/xlang-serialization.md @@ -19,7 +19,10 @@ license: | limitations under the License. --- -`pyfory` supports xlang object graph serialization, allowing you to serialize data in Python and deserialize it in Java, Go, Rust, or other supported languages. +`pyfory` supports xlang object graph serialization, allowing you to serialize +data in Python and deserialize it in Java, C++, Go, Rust, +JavaScript/TypeScript, C#, Swift, Dart, Scala, Kotlin, or another supported +language. ## Create an Xlang Runtime diff --git a/docs/guide/rust/index.md b/docs/guide/rust/index.md index e90aebce7e..b7b878db99 100644 --- a/docs/guide/rust/index.md +++ b/docs/guide/rust/index.md @@ -26,7 +26,8 @@ The Rust implementation provides versatile and high-performance serialization wi ## Why Apache Fory™ Rust? - **Fast binary encoding**: Zero-copy deserialization and optimized binary protocols -- **Xlang**: Seamlessly serialize/deserialize data across Java, Python, C++, Go, JavaScript, and Rust +- **Xlang**: Seamlessly serialize/deserialize data across Java, Python, C++, + Go, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin - **Type-safe**: Compile-time type checking with derive macros - **Circular references**: Automatic tracking of shared and circular references with `Rc`/`Arc` and weak pointers - **Polymorphic**: Serialize trait objects with `Box`, `Rc`, and `Arc` diff --git a/docs/guide/rust/native-serialization.md b/docs/guide/rust/native-serialization.md index 387e8deae7..cba76f7010 100644 --- a/docs/guide/rust/native-serialization.md +++ b/docs/guide/rust/native-serialization.md @@ -24,7 +24,8 @@ every writer and reader is Rust and the payload should preserve Rust object-grap of the portable xlang type system. Use [Xlang Serialization](xlang-serialization.md), the default Rust mode, when bytes must be read -by Java, Python, C++, Go, JavaScript, or another non-Rust Fory runtime. +by Java, Python, C++, Go, JavaScript/TypeScript, C#, Swift, Dart, Scala, +Kotlin, or another non-Rust Fory runtime. ## When To Use Native Serialization diff --git a/docs/guide/rust/xlang-serialization.md b/docs/guide/rust/xlang-serialization.md index 299e158834..a823a7218a 100644 --- a/docs/guide/rust/xlang-serialization.md +++ b/docs/guide/rust/xlang-serialization.md @@ -19,7 +19,8 @@ license: | limitations under the License. --- -Apache Fory™ supports seamless data exchange across multiple languages including Java, Python, C++, Go, and JavaScript. +Apache Fory™ supports seamless data exchange across Java, Python, C++, Go, +Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. ## Create an Xlang Runtime diff --git a/docs/guide/xlang/getting-started.md b/docs/guide/xlang/getting-started.md index 6fa858e747..03232e9698 100644 --- a/docs/guide/xlang/getting-started.md +++ b/docs/guide/xlang/getting-started.md @@ -60,12 +60,53 @@ go get github.com/apache/fory/go/fory fory = "1.0.0" ``` -### JavaScript +### JavaScript/TypeScript ```bash npm install @apache-fory/core ``` +For the optional Node.js string fast path: + +```bash +npm install @apache-fory/core @apache-fory/hps +``` + +### C# + +```bash +dotnet add package Apache.Fory --version 1.0.0 +``` + +### Dart + +```bash +dart pub add fory:^1.0.0 +dart pub add dev:build_runner +``` + +### Swift + +Add Fory to `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/apache/fory.git", exact: "1.0.0") +] +``` + +### Scala + +```scala +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.0.0" +``` + +### Kotlin + +```kotlin +implementation("org.apache.fory:fory-kotlin:1.0.0") +``` + ### C++ Use Bazel or CMake to build from source. See [C++ Guide](../cpp/index.md) for details. @@ -117,7 +158,7 @@ use fory::Fory; let fory = Fory::builder().xlang(true).build(); ``` -### JavaScript +### JavaScript/TypeScript ```javascript import Fory, { Type } from "@apache-fory/core"; @@ -125,6 +166,50 @@ import Fory, { Type } from "@apache-fory/core"; const fory = new Fory(); ``` +### C# + +```csharp +using Apache.Fory; + +Fory fory = Fory.Builder().Build(); +``` + +### Dart + +```dart +import 'package:fory/fory.dart'; + +final fory = Fory(); +``` + +### Swift + +```swift +import Fory + +let fory = Fory() +``` + +### Scala + +```scala +import org.apache.fory.scala.ForyScala + +val fory = ForyScala.builder() + .withXlang(true) + .build() +``` + +### Kotlin + +```kotlin +import org.apache.fory.kotlin.ForyKotlin + +val fory = ForyKotlin.builder() + .withXlang(true) + .build() +``` + ### C++ ```cpp @@ -178,7 +263,7 @@ fory .expect("register Person"); ``` -**JavaScript:** +**JavaScript/TypeScript:** ```javascript const personType = Type.struct( @@ -199,6 +284,41 @@ fory.register_struct("example", "Person"); // fory.register_enum("example", "Color"); ``` +**C#:** + +```csharp +fory.Register("example", "Person"); +``` + +**Dart:** + +```dart +PersonFory.register( + fory, + Person, + namespace: 'example', + typeName: 'Person', +); +``` + +**Swift:** + +```swift +try fory.register(Person.self, namespace: "example", name: "Person") +``` + +**Scala:** + +```scala +fory.register(classOf[Person], "example.Person") +``` + +**Kotlin:** + +```kotlin +fory.register(Person::class.java, "example.Person") +``` + ### Register by ID Using numeric IDs is faster and produces smaller binary output: @@ -221,6 +341,24 @@ fory.register_type(Person, type_id=100) fory.RegisterStruct(Person{}, 100) ``` +**Rust:** + +```rust +fory.register::(100)?; +``` + +**JavaScript/TypeScript:** + +```javascript +const personType = Type.struct( + { typeId: 100 }, + { + name: Type.string(), + age: Type.int32(), + }, +); +``` + **C++:** ```cpp @@ -229,6 +367,36 @@ fory.register_struct(100); // fory.register_enum(101); ``` +**C#:** + +```csharp +fory.Register(100); +``` + +**Dart:** + +```dart +PersonFory.register(fory, Person, id: 100); +``` + +**Swift:** + +```swift +fory.register(Person.self, id: 100) +``` + +**Scala:** + +```scala +fory.register(classOf[Person], 100) +``` + +**Kotlin:** + +```kotlin +fory.register(Person::class.java, 100) +``` + ## Hello World Example A complete example showing serialization in Java and deserialization in Python: diff --git a/docs/guide/xlang/index.md b/docs/guide/xlang/index.md index af7f22b181..dd1f9393d0 100644 --- a/docs/guide/xlang/index.md +++ b/docs/guide/xlang/index.md @@ -27,7 +27,9 @@ workflow is a better fit. ## Features - **No IDL required**: Serialize objects directly with language model types. -- **Multi-language support**: Java, Python, C++, Go, Rust, JavaScript/TypeScript, C#, Swift, and Dart interoperate through the same xlang format. +- **Multi-language support**: Java, Python, C++, Go, Rust, + JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin interoperate through + the same xlang format. - **Reference support**: Shared and circular references work across language boundaries when reference tracking is enabled in each runtime. - **Schema evolution**: Compatible mode is the xlang default so readers can tolerate added, removed, or reordered fields. - **Out-of-band buffers**: Language runtimes can expose zero-copy buffer paths for large binary data. @@ -46,6 +48,8 @@ workflow is a better fit. | C# | Supported | `Apache.Fory` | | Swift | Supported | Swift Package Manager target | | Dart | Supported | `fory` package | +| Scala | Supported | `org.apache.fory:fory-scala` | +| Kotlin | Supported | `org.apache.fory:fory-kotlin` | ## When to Use Xlang Mode @@ -53,7 +57,8 @@ Use xlang mode when: - Building multi-language microservices - Creating polyglot data pipelines -- Sharing data between frontend (JavaScript) and backend (Java/Python/Go) +- Sharing data between frontend JavaScript/TypeScript and backend runtimes such + as Java, Python, Go, C#, Scala, or Kotlin Use native mode for same-language traffic in Java, Scala, Kotlin, Python, C++, Go, or Rust: @@ -128,7 +133,7 @@ message Person { Generate code: ```bash -foryc person.fdl --lang java,python,go,rust,cpp --output ./generated +foryc person.fdl --lang java,python,cpp,go,rust,javascript,csharp,swift,dart,scala,kotlin --output ./generated ``` This generates native language types with consistent field/type mappings across all targets. @@ -159,7 +164,14 @@ For language-specific details and API reference: - [Java Xlang Serialization Guide](../java/xlang-serialization.md) - [Python Xlang Serialization Guide](../python/xlang-serialization.md) - [C++ Xlang Serialization Guide](../cpp/xlang-serialization.md) +- [Go Xlang Serialization Guide](../go/xlang-serialization.md) - [Rust Xlang Serialization Guide](../rust/xlang-serialization.md) +- [JavaScript/TypeScript Xlang Serialization Guide](../javascript/xlang-serialization.md) +- [C# Xlang Serialization Guide](../csharp/xlang-serialization.md) +- [Swift Xlang Serialization Guide](../swift/xlang-serialization.md) +- [Dart Xlang Serialization Guide](../dart/xlang-serialization.md) +- [Scala Schema IDL And Xlang Guide](../scala/schema-idl.md) +- [Kotlin Static Generated Serializers Guide](../kotlin/static-generated-serializers.md) ## Specifications diff --git a/docs/guide/xlang/serialization.md b/docs/guide/xlang/serialization.md index cd4e94bf54..fd20751f82 100644 --- a/docs/guide/xlang/serialization.md +++ b/docs/guide/xlang/serialization.md @@ -19,7 +19,9 @@ license: | limitations under the License. --- -This page demonstrates cross-language serialization patterns with examples in all supported languages. Data serialized in one language can be deserialized in any other supported language. +This page demonstrates common cross-language serialization patterns. Data serialized in one +supported language can be deserialized in any other supported language when peers use matching type +identity, field schema, and compatibility settings. ## Serialize Built-in Types diff --git a/docs/specification/xlang_serialization_spec.md b/docs/specification/xlang_serialization_spec.md index 6e1784b402..2c7e16cd0d 100644 --- a/docs/specification/xlang_serialization_spec.md +++ b/docs/specification/xlang_serialization_spec.md @@ -26,7 +26,8 @@ Apache Fory™ xlang serialization enables automatic cross-language object seria Key characteristics: - **Automatic**: No IDL definition, no schema compilation, no manual object-to-protocol conversion -- **Cross-language**: Same binary format works seamlessly across Java, Python, C++, Rust, Go, JavaScript, and more +- **Cross-language**: Same binary format works across Java, Python, C++, Go, + Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin - **Reference-aware**: Handles shared references and circular references without duplication or infinite recursion - **Polymorphic**: Supports object polymorphism with runtime type resolution diff --git a/docs/specification/xlang_type_mapping.md b/docs/specification/xlang_type_mapping.md index 8dd242c202..edfd27622a 100644 --- a/docs/specification/xlang_type_mapping.md +++ b/docs/specification/xlang_type_mapping.md @@ -23,7 +23,9 @@ Note: - For type definition, see [Type Systems in Spec](xlang_serialization_spec.md#type-systems) - `int16_t[n]/vector` indicates `int16_t[n]/vector` -- The cross-language serialization is not stable, do not use it in your production environment. +- Xlang serialization is the portable wire format shared by Java, Python, C++, + Go, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. Keep type + IDs, names, schemas, and compatibility settings aligned across every peer. ## User Type IDs @@ -52,7 +54,7 @@ The first column names the Fory schema expression or canonical wire tag. Scalar encoding rows such as `fixed int32` and `tagged int64` are not FDL type names; FDL spells them as an encoding modifier plus a semantic integer type. -| Fory schema / wire tag | Fory Type ID | Java | Python | Javascript | C++ | Golang | Rust | +| Fory schema / wire tag | Fory Type ID | Java | Python | JavaScript/TypeScript | C++ | Go | Rust | | ---------------------------------- | ------------ | ----------------------------------------- | ----------------------------------------- | ------------------------------------- | --------------------------------------------------- | ---------------------------------------------- | --------------------------------- | | bool | 1 | bool/Boolean | bool | Boolean | bool | bool | bool | | int8 | 2 | byte/Byte | int/pyfory.Int8 | Type.int8() | int8_t | int8 | i8 | @@ -143,6 +145,29 @@ Notes: payload that declares nullable or ref-tracked elements must raise a compatible-read error when the local matched field is `array`. +### Additional Supported Language Mapping + +The main table above lists per-wire-tag mappings for Java, Python, +JavaScript/TypeScript, C++, Go, and Rust. Fory 1.0 also supports C#, Swift, +Dart, Scala, and Kotlin. Their generated carriers follow the same schema kinds: + +| Fory schema kind | C# | Swift | Dart | Scala | Kotlin | +| ------------------------------------- | ------------------------------------------ | ------------------------------------- | ------------------------------------------ | -------------------------------------------- | --------------------------------------- | +| `bool` | `bool` | `Bool` | `bool` | `Boolean` | `Boolean` | +| `int8`, `int16`, `int32`, `int64` | `sbyte`, `short`, `int`, `long` | `Int8`, `Int16`, `Int32`, `Int64` | `int` with field metadata | `Byte`, `Short`, `Int`, `Long` | `Byte`, `Short`, `Int`, `Long` | +| `uint8`, `uint16`, `uint32`, `uint64` | `byte`, `ushort`, `uint`, `ulong` | `UInt8`, `UInt16`, `UInt32`, `UInt64` | `int`/`Uint64` with field metadata | `Int`, `Int`, `Long`, `Long` plus metadata | `UByte`, `UShort`, `UInt`, `ULong` | +| `float16`, `bfloat16` | `Half`, `BFloat16` | `Float16`, `BFloat16` | `double` with `Float16Type`/`Bfloat16Type` | JVM `Float16`, `BFloat16` | JVM `Float16`, `BFloat16` | +| `float32`, `float64` | `float`, `double` | `Float`, `Double` | `Float32`, `double` | `Float`, `Double` | `Float`, `Double` | +| `string`, `binary` | `string`, `byte[]` | `String`, `Data` | `String`, `Uint8List` | `String`, `Array[Byte]` | `String`, `ByteArray` | +| `list`, `set`, `map` | `List`, `HashSet`, `Dictionary` | `[T]`, `Set`, `[K: V]` | `List`, `Set`, `Map` | `List[T]`, `Set[T]`, `Map[K, V]` | `List`, `Set`, `Map` | +| `array` | primitive arrays or schema descriptors | arrays with `@ArrayField` metadata | typed-data lists or Fory dense-array lists | primitive arrays with descriptor metadata | primitive/unsigned arrays with metadata | +| `date`, `timestamp`, `duration` | `DateOnly`, `DateTime`, `TimeSpan` | `LocalDate`, `Date`, `Duration` | `LocalDate`, `Timestamp`, `Duration` | `java.time.LocalDate`, `Instant`, `Duration` | Java time / Kotlin duration carriers | +| `decimal` | `decimal` | `Decimal` | `Decimal` | `java.math.BigDecimal` | `java.math.BigDecimal` | +| `message` | `[ForyObject]` class or struct | `@ForyStruct` struct or class | `@ForyStruct` class | Scala 3 `case class` or class | `data class` or class | +| `enum` | C# enum | Swift enum | Dart enum | Scala 3 enum | Kotlin enum class | +| `union` | `Union` subclass | tagged associated-value enum | `@ForyUnion` class | Scala 3 ADT enum | sealed class | +| `any` | `object?` | `Any` | `Object?` | `AnyRef` | `Any?` | + ### Scala IDL Mapping The Scala schema IDL target emits Scala 3 source only. The `fory-scala` runtime From ad6504d051e1a219fef6125a7fb57d88700a1e66 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Sat, 23 May 2026 16:38:19 +0800 Subject: [PATCH 2/3] docs: merge xlang language mapping table --- docs/specification/xlang_type_mapping.md | 133 ++++++++++------------- 1 file changed, 55 insertions(+), 78 deletions(-) diff --git a/docs/specification/xlang_type_mapping.md b/docs/specification/xlang_type_mapping.md index edfd27622a..a50c64261c 100644 --- a/docs/specification/xlang_type_mapping.md +++ b/docs/specification/xlang_type_mapping.md @@ -54,61 +54,61 @@ The first column names the Fory schema expression or canonical wire tag. Scalar encoding rows such as `fixed int32` and `tagged int64` are not FDL type names; FDL spells them as an encoding modifier plus a semantic integer type. -| Fory schema / wire tag | Fory Type ID | Java | Python | JavaScript/TypeScript | C++ | Go | Rust | -| ---------------------------------- | ------------ | ----------------------------------------- | ----------------------------------------- | ------------------------------------- | --------------------------------------------------- | ---------------------------------------------- | --------------------------------- | -| bool | 1 | bool/Boolean | bool | Boolean | bool | bool | bool | -| int8 | 2 | byte/Byte | int/pyfory.Int8 | Type.int8() | int8_t | int8 | i8 | -| int16 | 3 | short/Short | int/pyfory.Int16 | Type.int16() | int16_t | int16 | i16 | -| fixed int32 | 4 | int/Integer | int/pyfory.FixedInt32 | `Type.int32({ encoding: "fixed" })` | int32_t | int32 | i32 | -| int32 | 5 | int/Integer | int/pyfory.Int32 | Type.int32() | int32_t | int32 | i32 | -| fixed int64 | 6 | long/Long | int/pyfory.FixedInt64 | `Type.int64({ encoding: "fixed" })` | int64_t | int64 | i64 | -| int64 | 7 | long/Long | int/pyfory.Int64 | Type.int64() | int64_t | int64 | i64 | -| tagged int64 | 8 | long/Long | int/pyfory.TaggedInt64 | `Type.int64({ encoding: "tagged" })` | int64_t | int64 | i64 | -| uint8 | 9 | short/Short | int/pyfory.UInt8 | Type.uint8() | uint8_t | uint8 | u8 | -| uint16 | 10 | int/Integer | int/pyfory.UInt16 | Type.uint16() | uint16_t | uint16 | u16 | -| fixed uint32 | 11 | long/Long | int/pyfory.FixedUInt32 | `Type.uint32({ encoding: "fixed" })` | uint32_t | uint32 | u32 | -| uint32 | 12 | long/Long | int/pyfory.UInt32 | Type.uint32() | uint32_t | uint32 | u32 | -| fixed uint64 | 13 | long/Long | int/pyfory.FixedUInt64 | `Type.uint64({ encoding: "fixed" })` | uint64_t | uint64 | u64 | -| uint64 | 14 | long/Long | int/pyfory.UInt64 | Type.uint64() | uint64_t | uint64 | u64 | -| tagged uint64 | 15 | long/Long | int/pyfory.TaggedUInt64 | `Type.uint64({ encoding: "tagged" })` | uint64_t | uint64 | u64 | -| float8 | 16 | / | / | / | / | / | / | -| float16 | 17 | Float16 | native float / pyfory.Float16 annotation | `number` | `fory::float16_t` | `float16.Float16` | `Float16` | -| bfloat16 | 18 | BFloat16 | native float / pyfory.BFloat16 annotation | `number` | `fory::bfloat16_t` | `bfloat16.BFloat16` | `BFloat16` | -| float32 | 19 | float/Float | float/pyfory.Float32 | Type.float32() | float | float32 | f32 | -| float64 | 20 | double/Double | float/pyfory.Float64 | Type.float64() | double | float64 | f64 | -| string | 21 | String | str | String | string | string | String/str | -| list | 22 | List/Collection | list/tuple | array | vector | slice | Vec | -| set | 23 | Set | set | / | set | fory.Set | Set | -| map | 24 | Map | dict | Map | unordered_map | map | HashMap | -| enum | 25 | Enum subclasses | enum subclasses | / | enum | / | enum | -| named_enum | 26 | Enum subclasses | enum subclasses | / | enum | / | enum | -| struct | 27 | pojo/record | data class | object | struct/class | struct | struct | -| compatible_struct | 28 | pojo/record | data class | object | struct/class | struct | struct | -| named_struct | 29 | pojo/record | data class | object | struct/class | struct | struct | -| named_compatible_struct | 30 | pojo/record | data class | object | struct/class | struct | struct | -| ext | 31 | pojo/record | data class | object | struct/class | struct | struct | -| named_ext | 32 | pojo/record | data class | object | struct/class | struct | struct | -| union | 33 | Union | typing.Union | / | `std::variant` | / | tagged union enum | -| none | 36 | null | None | null | `std::monostate` | nil | `()` | -| duration | 37 | Duration | timedelta | Number | duration | Duration | Duration | -| timestamp | 38 | Instant | datetime | Number | std::chrono::nanoseconds | Time | Timestamp | -| date | 39 | LocalDate | datetime.date | Date | fory::serialization::Date | fory.Date | Date | -| decimal | 40 | BigDecimal | Decimal | Decimal | / | fory.Decimal | fory::Decimal | -| binary | 41 | byte[] | bytes | / | `uint8_t[n]/vector` | `[n]uint8/[]T` | `Vec` | -| `array` (bool_array) | 43 | bool[] | BoolArray / ndarray(np.bool\_) | BoolArray / Type.boolArray() | `bool[n]` | `[n]bool/[]T` | `Vec` | -| `array` (int8_array) | 44 | `@Int8Type byte[]` | Int8Array / ndarray(int8) | Type.int8Array() | `int8_t[n]/vector` | `[n]int8/[]T` | `Vec` | -| `array` (int16_array) | 45 | short[] | Int16Array / ndarray(int16) | Type.int16Array() | `int16_t[n]/vector` | `[n]int16/[]T` | `Vec` | -| `array` (int32_array) | 46 | int[] | Int32Array / ndarray(int32) | Type.int32Array() | `int32_t[n]/vector` | `[n]int32/[]T` | `Vec` | -| `array` (int64_array) | 47 | long[] | Int64Array / ndarray(int64) | Type.int64Array() | `int64_t[n]/vector` | `[n]int64/[]T` | `Vec` | -| `array` (uint8_array) | 48 | `@UInt8Type byte[]` | UInt8Array / ndarray(uint8) | Type.uint8Array() | `uint8_t[n]/vector` | `[n]uint8/[]T` | `Vec` | -| `array` (uint16_array) | 49 | `@UInt16Type short[]` | UInt16Array / ndarray(uint16) | Type.uint16Array() | `uint16_t[n]/vector` | `[n]uint16/[]T` | `Vec` | -| `array` (uint32_array) | 50 | `@UInt32Type int[]` | UInt32Array / ndarray(uint32) | Type.uint32Array() | `uint32_t[n]/vector` | `[n]uint32/[]T` | `Vec` | -| `array` (uint64_array) | 51 | `@UInt64Type long[]` | UInt64Array / ndarray(uint64) | Type.uint64Array() | `uint64_t[n]/vector` | `[n]uint64/[]T` | `Vec` | -| `array` (float8_array) | 52 | / | / | / | / | / | / | -| `array` (float16_array) | 53 | `Float16Array` / `@Float16Type short[]` | Float16Array / ndarray(float16) | Float16Array / Type.float16Array() | `fory::float16_t[n]/std::vector` | `[N]float16.Float16` / `[]float16.Float16` | `Vec` / `[Float16; N]` | -| `array` (bfloat16_array) | 54 | `BFloat16Array` / `@BFloat16Type short[]` | BFloat16Array / ndarray(bfloat16) | BFloat16Array / Type.bfloat16Array() | `fory::bfloat16_t[n]/std::vector` | `[N]bfloat16.BFloat16` / `[]bfloat16.BFloat16` | `Vec` / `[BFloat16; N]` | -| `array` (float32_array) | 55 | float[] | Float32Array / ndarray(float32) | Type.float32Array() | `float[n]/vector` | `[n]float32/[]T` | `Vec` | -| `array` (float64_array) | 56 | double[] | Float64Array / ndarray(float64) | Type.float64Array() | `double[n]/vector` | `[n]float64/[]T` | `Vec` | +| Fory schema / wire tag | Fory Type ID | Java | Python | JavaScript/TypeScript | C++ | Go | Rust | C# | Swift | Dart | Scala | Kotlin | +| ---------------------------------- | ------------ | ----------------------------------------- | ----------------------------------------- | ------------------------------------- | --------------------------------------------------- | ---------------------------------------------- | --------------------------------- | -------------------------------- | ------------------------ | --------------------------- | ------------------------------- | ---------------------- | +| bool | 1 | bool/Boolean | bool | Boolean | bool | bool | bool | bool | Bool | bool | Boolean | Boolean | +| int8 | 2 | byte/Byte | int/pyfory.Int8 | Type.int8() | int8_t | int8 | i8 | sbyte | Int8 | int + `Int8Type` | Byte | Byte | +| int16 | 3 | short/Short | int/pyfory.Int16 | Type.int16() | int16_t | int16 | i16 | short | Int16 | int + `Int16Type` | Short | Short | +| fixed int32 | 4 | int/Integer | int/pyfory.FixedInt32 | `Type.int32({ encoding: "fixed" })` | int32_t | int32 | i32 | int + `S.Fixed` | Int32 + `.fixed` | int + fixed metadata | Int + fixed metadata | `@Fixed Int` | +| int32 | 5 | int/Integer | int/pyfory.Int32 | Type.int32() | int32_t | int32 | i32 | int | Int32 | int + `Int32Type` | Int | Int | +| fixed int64 | 6 | long/Long | int/pyfory.FixedInt64 | `Type.int64({ encoding: "fixed" })` | int64_t | int64 | i64 | long + `S.Fixed` | Int64 + `.fixed` | Int64 + fixed metadata | Long + fixed metadata | `@Fixed Long` | +| int64 | 7 | long/Long | int/pyfory.Int64 | Type.int64() | int64_t | int64 | i64 | long | Int64 | int / Int64 | Long | Long | +| tagged int64 | 8 | long/Long | int/pyfory.TaggedInt64 | `Type.int64({ encoding: "tagged" })` | int64_t | int64 | i64 | long + `S.Tagged` | Int64 + `.tagged` | Int64 + tagged metadata | Long + tagged metadata | `@Tagged Long` | +| uint8 | 9 | short/Short | int/pyfory.UInt8 | Type.uint8() | uint8_t | uint8 | u8 | byte | UInt8 | int + `Uint8Type` | Int + unsigned metadata | UByte | +| uint16 | 10 | int/Integer | int/pyfory.UInt16 | Type.uint16() | uint16_t | uint16 | u16 | ushort | UInt16 | int + `Uint16Type` | Int + unsigned metadata | UShort | +| fixed uint32 | 11 | long/Long | int/pyfory.FixedUInt32 | `Type.uint32({ encoding: "fixed" })` | uint32_t | uint32 | u32 | uint + `S.Fixed` | UInt32 + `.fixed` | int + fixed uint32 metadata | Long + fixed unsigned metadata | `@Fixed UInt` | +| uint32 | 12 | long/Long | int/pyfory.UInt32 | Type.uint32() | uint32_t | uint32 | u32 | uint | UInt32 | int + `Uint32Type` | Long + unsigned metadata | UInt | +| fixed uint64 | 13 | long/Long | int/pyfory.FixedUInt64 | `Type.uint64({ encoding: "fixed" })` | uint64_t | uint64 | u64 | ulong + `S.Fixed` | UInt64 + `.fixed` | Uint64 + fixed metadata | Long + fixed unsigned metadata | `@Fixed ULong` | +| uint64 | 14 | long/Long | int/pyfory.UInt64 | Type.uint64() | uint64_t | uint64 | u64 | ulong | UInt64 | Uint64 | Long + unsigned metadata | ULong | +| tagged uint64 | 15 | long/Long | int/pyfory.TaggedUInt64 | `Type.uint64({ encoding: "tagged" })` | uint64_t | uint64 | u64 | ulong + `S.Tagged` | UInt64 + `.tagged` | Uint64 + tagged metadata | Long + tagged unsigned metadata | `@Tagged ULong` | +| float8 | 16 | / | / | / | / | / | / | / | / | / | / | / | +| float16 | 17 | Float16 | native float / pyfory.Float16 annotation | `number` | `fory::float16_t` | `float16.Float16` | `Float16` | Half | Float16 | double + `Float16Type` | Float16 | Float16 | +| bfloat16 | 18 | BFloat16 | native float / pyfory.BFloat16 annotation | `number` | `fory::bfloat16_t` | `bfloat16.BFloat16` | `BFloat16` | BFloat16 | BFloat16 | double + `Bfloat16Type` | BFloat16 | BFloat16 | +| float32 | 19 | float/Float | float/pyfory.Float32 | Type.float32() | float | float32 | f32 | float | Float | Float32 | Float | Float | +| float64 | 20 | double/Double | float/pyfory.Float64 | Type.float64() | double | float64 | f64 | double | Double | double | Double | Double | +| string | 21 | String | str | String | string | string | String/str | string | String | String | String | String | +| list | 22 | List/Collection | list/tuple | array | vector | slice | Vec | List | [T] | List | List[T] | List | +| set | 23 | Set | set | / | set | fory.Set | Set | HashSet | Set | Set | Set[T] | Set | +| map | 24 | Map | dict | Map | unordered_map | map | HashMap | Dictionary | [K: V] | Map | Map[K, V] | Map | +| enum | 25 | Enum subclasses | enum subclasses | / | enum | / | enum | enum | enum | enum | Scala 3 enum | enum class | +| named_enum | 26 | Enum subclasses | enum subclasses | / | enum | / | enum | enum | enum | enum | Scala 3 enum | enum class | +| struct | 27 | pojo/record | data class | object | struct/class | struct | struct | [ForyObject] class/struct | @ForyStruct struct/class | @ForyStruct class | case class/class | data class/class | +| compatible_struct | 28 | pojo/record | data class | object | struct/class | struct | struct | [ForyObject] class/struct | @ForyStruct struct/class | @ForyStruct class | case class/class | data class/class | +| named_struct | 29 | pojo/record | data class | object | struct/class | struct | struct | [ForyObject] class/struct | @ForyStruct struct/class | @ForyStruct class | case class/class | data class/class | +| named_compatible_struct | 30 | pojo/record | data class | object | struct/class | struct | struct | [ForyObject] class/struct | @ForyStruct struct/class | @ForyStruct class | case class/class | data class/class | +| ext | 31 | pojo/record | data class | object | struct/class | struct | struct | [ForyObject] class/struct | @ForyStruct struct/class | @ForyStruct class | case class/class | data class/class | +| named_ext | 32 | pojo/record | data class | object | struct/class | struct | struct | [ForyObject] class/struct | @ForyStruct struct/class | @ForyStruct class | case class/class | data class/class | +| union | 33 | Union | typing.Union | / | `std::variant` | / | tagged union enum | Union subclass | tagged enum | @ForyUnion class | ADT enum | sealed class | +| none | 36 | null | None | null | `std::monostate` | nil | `()` | null | nil | null | null | null | +| duration | 37 | Duration | timedelta | Number | duration | Duration | Duration | TimeSpan | Duration | Duration | java.time.Duration | kotlin.time.Duration | +| timestamp | 38 | Instant | datetime | Number | std::chrono::nanoseconds | Time | Timestamp | DateTime/DateTimeOffset | Date | Timestamp | java.time.Instant | java.time.Instant | +| date | 39 | LocalDate | datetime.date | Date | fory::serialization::Date | fory.Date | Date | DateOnly | LocalDate | LocalDate | java.time.LocalDate | java.time.LocalDate | +| decimal | 40 | BigDecimal | Decimal | Decimal | / | fory.Decimal | fory::Decimal | decimal | Decimal | Decimal | java.math.BigDecimal | java.math.BigDecimal | +| binary | 41 | byte[] | bytes | / | `uint8_t[n]/vector` | `[n]uint8/[]T` | `Vec` | byte[] | Data | Uint8List | Array[Byte] | ByteArray | +| `array` (bool_array) | 43 | bool[] | BoolArray / ndarray(np.bool\_) | BoolArray / Type.boolArray() | `bool[n]` | `[n]bool/[]T` | `Vec` | bool[] | [Bool] + @ArrayField | BoolList | Array[Boolean] | BooleanArray | +| `array` (int8_array) | 44 | `@Int8Type byte[]` | Int8Array / ndarray(int8) | Type.int8Array() | `int8_t[n]/vector` | `[n]int8/[]T` | `Vec` | sbyte[] | [Int8] + @ArrayField | Int8List | Array[Byte] + metadata | ByteArray + @ArrayType | +| `array` (int16_array) | 45 | short[] | Int16Array / ndarray(int16) | Type.int16Array() | `int16_t[n]/vector` | `[n]int16/[]T` | `Vec` | short[] | [Int16] + @ArrayField | Int16List | Array[Short] | ShortArray | +| `array` (int32_array) | 46 | int[] | Int32Array / ndarray(int32) | Type.int32Array() | `int32_t[n]/vector` | `[n]int32/[]T` | `Vec` | int[] | [Int32] + @ArrayField | Int32List | Array[Int] | IntArray | +| `array` (int64_array) | 47 | long[] | Int64Array / ndarray(int64) | Type.int64Array() | `int64_t[n]/vector` | `[n]int64/[]T` | `Vec` | long[] | [Int64] + @ArrayField | Int64List | Array[Long] | LongArray | +| `array` (uint8_array) | 48 | `@UInt8Type byte[]` | UInt8Array / ndarray(uint8) | Type.uint8Array() | `uint8_t[n]/vector` | `[n]uint8/[]T` | `Vec` | byte[] | [UInt8] + @ArrayField | Uint8List | Array[Byte] + metadata | UByteArray | +| `array` (uint16_array) | 49 | `@UInt16Type short[]` | UInt16Array / ndarray(uint16) | Type.uint16Array() | `uint16_t[n]/vector` | `[n]uint16/[]T` | `Vec` | ushort[] | [UInt16] + @ArrayField | Uint16List | Array[Short] + metadata | UShortArray | +| `array` (uint32_array) | 50 | `@UInt32Type int[]` | UInt32Array / ndarray(uint32) | Type.uint32Array() | `uint32_t[n]/vector` | `[n]uint32/[]T` | `Vec` | uint[] | [UInt32] + @ArrayField | Uint32List | Array[Int] + metadata | UIntArray | +| `array` (uint64_array) | 51 | `@UInt64Type long[]` | UInt64Array / ndarray(uint64) | Type.uint64Array() | `uint64_t[n]/vector` | `[n]uint64/[]T` | `Vec` | ulong[] | [UInt64] + @ArrayField | Uint64List | Array[Long] + metadata | ULongArray | +| `array` (float8_array) | 52 | / | / | / | / | / | / | / | / | / | / | / | +| `array` (float16_array) | 53 | `Float16Array` / `@Float16Type short[]` | Float16Array / ndarray(float16) | Float16Array / Type.float16Array() | `fory::float16_t[n]/std::vector` | `[N]float16.Float16` / `[]float16.Float16` | `Vec` / `[Float16; N]` | Half[] / S.Array | [Float16] + @ArrayField | Float16List | Array[Short] + metadata | Float16Array | +| `array` (bfloat16_array) | 54 | `BFloat16Array` / `@BFloat16Type short[]` | BFloat16Array / ndarray(bfloat16) | BFloat16Array / Type.bfloat16Array() | `fory::bfloat16_t[n]/std::vector` | `[N]bfloat16.BFloat16` / `[]bfloat16.BFloat16` | `Vec` / `[BFloat16; N]` | BFloat16[] / S.Array | [BFloat16] + @ArrayField | Bfloat16List | Array[Short] + metadata | BFloat16Array | +| `array` (float32_array) | 55 | float[] | Float32Array / ndarray(float32) | Type.float32Array() | `float[n]/vector` | `[n]float32/[]T` | `Vec` | float[] | [Float] + @ArrayField | Float32List | Array[Float] | FloatArray | +| `array` (float64_array) | 56 | double[] | Float64Array / ndarray(float64) | Type.float64Array() | `double[n]/vector` | `[n]float64/[]T` | `Vec` | double[] | [Double] + @ArrayField | Float64List | Array[Double] | DoubleArray | Notes: @@ -145,29 +145,6 @@ Notes: payload that declares nullable or ref-tracked elements must raise a compatible-read error when the local matched field is `array`. -### Additional Supported Language Mapping - -The main table above lists per-wire-tag mappings for Java, Python, -JavaScript/TypeScript, C++, Go, and Rust. Fory 1.0 also supports C#, Swift, -Dart, Scala, and Kotlin. Their generated carriers follow the same schema kinds: - -| Fory schema kind | C# | Swift | Dart | Scala | Kotlin | -| ------------------------------------- | ------------------------------------------ | ------------------------------------- | ------------------------------------------ | -------------------------------------------- | --------------------------------------- | -| `bool` | `bool` | `Bool` | `bool` | `Boolean` | `Boolean` | -| `int8`, `int16`, `int32`, `int64` | `sbyte`, `short`, `int`, `long` | `Int8`, `Int16`, `Int32`, `Int64` | `int` with field metadata | `Byte`, `Short`, `Int`, `Long` | `Byte`, `Short`, `Int`, `Long` | -| `uint8`, `uint16`, `uint32`, `uint64` | `byte`, `ushort`, `uint`, `ulong` | `UInt8`, `UInt16`, `UInt32`, `UInt64` | `int`/`Uint64` with field metadata | `Int`, `Int`, `Long`, `Long` plus metadata | `UByte`, `UShort`, `UInt`, `ULong` | -| `float16`, `bfloat16` | `Half`, `BFloat16` | `Float16`, `BFloat16` | `double` with `Float16Type`/`Bfloat16Type` | JVM `Float16`, `BFloat16` | JVM `Float16`, `BFloat16` | -| `float32`, `float64` | `float`, `double` | `Float`, `Double` | `Float32`, `double` | `Float`, `Double` | `Float`, `Double` | -| `string`, `binary` | `string`, `byte[]` | `String`, `Data` | `String`, `Uint8List` | `String`, `Array[Byte]` | `String`, `ByteArray` | -| `list`, `set`, `map` | `List`, `HashSet`, `Dictionary` | `[T]`, `Set`, `[K: V]` | `List`, `Set`, `Map` | `List[T]`, `Set[T]`, `Map[K, V]` | `List`, `Set`, `Map` | -| `array` | primitive arrays or schema descriptors | arrays with `@ArrayField` metadata | typed-data lists or Fory dense-array lists | primitive arrays with descriptor metadata | primitive/unsigned arrays with metadata | -| `date`, `timestamp`, `duration` | `DateOnly`, `DateTime`, `TimeSpan` | `LocalDate`, `Date`, `Duration` | `LocalDate`, `Timestamp`, `Duration` | `java.time.LocalDate`, `Instant`, `Duration` | Java time / Kotlin duration carriers | -| `decimal` | `decimal` | `Decimal` | `Decimal` | `java.math.BigDecimal` | `java.math.BigDecimal` | -| `message` | `[ForyObject]` class or struct | `@ForyStruct` struct or class | `@ForyStruct` class | Scala 3 `case class` or class | `data class` or class | -| `enum` | C# enum | Swift enum | Dart enum | Scala 3 enum | Kotlin enum class | -| `union` | `Union` subclass | tagged associated-value enum | `@ForyUnion` class | Scala 3 ADT enum | sealed class | -| `any` | `object?` | `Any` | `Object?` | `AnyRef` | `Any?` | - ### Scala IDL Mapping The Scala schema IDL target emits Scala 3 source only. The `fory-scala` runtime From 4dc48bfce639d2dcb3c2703d93afb0cf7dca9ed3 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Sat, 23 May 2026 16:54:21 +0800 Subject: [PATCH 3/3] docs: escape C sharp markdown headings --- docs/guide/xlang/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/xlang/getting-started.md b/docs/guide/xlang/getting-started.md index 03232e9698..c5a7a30b1b 100644 --- a/docs/guide/xlang/getting-started.md +++ b/docs/guide/xlang/getting-started.md @@ -72,7 +72,7 @@ For the optional Node.js string fast path: npm install @apache-fory/core @apache-fory/hps ``` -### C# +### C\# ```bash dotnet add package Apache.Fory --version 1.0.0 @@ -166,7 +166,7 @@ import Fory, { Type } from "@apache-fory/core"; const fory = new Fory(); ``` -### C# +### C\# ```csharp using Apache.Fory;