This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/fory-site.git
commit cd0c1ec3cc50443270367bc87afc2fa29e3e6c4d Author: chaokunyang <[email protected]> AuthorDate: Fri May 15 11:18:15 2026 +0000 🔄 synced local 'docs/specification/' with remote 'docs/specification/' --- docs/specification/xlang_serialization_spec.md | 17 +++++++++--- docs/specification/xlang_type_mapping.md | 37 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/docs/specification/xlang_serialization_spec.md b/docs/specification/xlang_serialization_spec.md index 6343392c7e..477fcef506 100644 --- a/docs/specification/xlang_serialization_spec.md +++ b/docs/specification/xlang_serialization_spec.md @@ -444,10 +444,10 @@ In xlang mode, for cross-language compatibility: **Annotation examples:** ```java -// Java: use @ForyField annotation +// Java: use @Ref for reference tracking public class MyClass { @Nullable - @ForyField(ref = true) + @Ref private Object refField; private String requiredField; @@ -456,10 +456,10 @@ public class MyClass { ```python # Python: use typing with fory field descriptors -from pyfory import Fory, ForyField +from pyfory import ForyField, Ref class MyClass: - ref_field: ForyField(SomeType, nullable=True, ref=True) + ref_field: ForyField(Ref[SomeType], nullable=True) required_field: ForyField(str, nullable=False) ``` @@ -1578,6 +1578,8 @@ Rules: - Each union alternative MUST have a stable tag number (`= 1`, `= 2`, ...). - Tag numbers MUST be unique within the union and MUST NOT be reused. +- Tag number `0` is reserved for language bindings that expose an unknown-case + carrier. Schema-defined alternatives MUST NOT use tag `0`. #### Type IDs and type meta @@ -1611,6 +1613,13 @@ A union payload is: This is required even for primitives so unknown alternatives can be skipped safely. +If a reader sees a positive `case_id` that is not present in its local union +schema, it SHOULD preserve the unknown case when the target language has a +language-neutral carrier for it. Such a carrier MUST store the original positive +case ID and the deserialized `case_value`. Writers MUST NOT serialize `0` as a +schema-defined case ID; `0` is only the local unknown-case slot used by bindings +that need one. + #### Wire layouts **UNION (schema known from context)** diff --git a/docs/specification/xlang_type_mapping.md b/docs/specification/xlang_type_mapping.md index 654fa14cfc..a2a49ebfb8 100644 --- a/docs/specification/xlang_type_mapping.md +++ b/docs/specification/xlang_type_mapping.md @@ -158,6 +158,43 @@ Notes: payload that declares nullable or ref-tracked elements must raise a compatible-read error when the local matched field is `array<T>`. +### Scala IDL Mapping + +The Scala schema IDL target emits Scala 3 source only. The `fory-scala` runtime +artifact remains cross-built for Scala 2.13 and Scala 3. + +| Fory schema kind | Scala generated carrier | +| ------------------------------------- | ---------------------------------------------------------------------------------------- | +| `optional T` | `Option[T]` | +| `bool` | `Boolean` | +| `int8`, `int16`, `int32`, `int64` | `Byte`, `Short`, `Int`, `Long` | +| `uint8`, `uint16`, `uint32`, `uint64` | `Int`, `Int`, `Long`, `Long` plus unsigned Fory type metadata | +| `float16`, `bfloat16` | JVM half-float and bfloat16 carriers | +| `float32`, `float64` | `Float`, `Double` | +| `string` | `String` | +| `binary` | `Array[Byte]` | +| `list<T>`, `set<T>`, `map<K, V>` | `List[T]`, `Set[T]`, `Map[K, V]` | +| `array<bool>` | `Array[Boolean]` | +| `array<int8>`, `array<uint8>` | `Array[Byte]` with signed/unsigned descriptor metadata | +| `array<int16>`, `array<uint16>` | `Array[Short]` with signed/unsigned descriptor metadata | +| `array<int32>`, `array<uint32>` | `Array[Int]` with signed/unsigned descriptor metadata | +| `array<int64>`, `array<uint64>` | `Array[Long]` with signed/unsigned descriptor metadata | +| `array<float16>`, `array<bfloat16>` | `Array[Short]` with reduced-precision descriptor metadata | +| `array<float32>`, `array<float64>` | `Array[Float]`, `Array[Double]` | +| `date`, `timestamp`, `duration` | `java.time.LocalDate`, `java.time.Instant`, `java.time.Duration` | +| `decimal` | `java.math.BigDecimal` | +| `message` | Scala 3 `case class` by default; normal class only for message/union construction cycles | +| `enum` | Scala 3 `enum` with stable Fory enum IDs on case-level `@ForyEnumId` annotations | +| `union` | Scala 3 ADT `enum derives ForySerializer` | +| `any` | `AnyRef` | + +Generated Scala descriptor metadata is produced by Scala 3 macro derivation +from Scala compile-time types, including nested generics, `Option`, arrays, +scalar encoding annotations, nullability, and `@Ref`. Java reflection is not the +source of truth for generated Scala TypeDef metadata. Scala `@Ref` metadata is +represented by the shared `org.apache.fory.annotation.Ref` annotation; `@Ref` +is the JVM owner for reference tracking metadata. + ## Type info Due to differences between type systems of languages, those types can't be mapped one-to-one between languages. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
