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 c5c0569753d7c30c9abf987bd0edf121be5b9818
Author: chaokunyang <[email protected]>
AuthorDate: Thu May 14 15:48:40 2026 +0000

    🔄 synced local 'docs/guide/' with remote 'docs/guide/'
---
 docs/guide/dart/basic-serialization.md            |   2 +-
 docs/guide/dart/configuration.md                  |   2 +-
 docs/guide/java/static-generated-serializers.md   |  13 +-
 docs/guide/kotlin/android-support.md              | 122 +++++++++
 docs/guide/kotlin/index.md                        |   1 +
 docs/guide/kotlin/static-generated-serializers.md | 288 ++++++++++++++--------
 6 files changed, 326 insertions(+), 102 deletions(-)

diff --git a/docs/guide/dart/basic-serialization.md 
b/docs/guide/dart/basic-serialization.md
index e05761e275..87ea752df2 100644
--- a/docs/guide/dart/basic-serialization.md
+++ b/docs/guide/dart/basic-serialization.md
@@ -1,6 +1,6 @@
 ---
 title: Basic Serialization
-sidebar_position: 1
+sidebar_position: 2
 id: dart_basic_serialization
 license: |
   Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/docs/guide/dart/configuration.md b/docs/guide/dart/configuration.md
index 3798712187..46d87556d3 100644
--- a/docs/guide/dart/configuration.md
+++ b/docs/guide/dart/configuration.md
@@ -1,6 +1,6 @@
 ---
 title: Configuration
-sidebar_position: 2
+sidebar_position: 1
 id: dart_configuration
 license: |
   Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/docs/guide/java/static-generated-serializers.md 
b/docs/guide/java/static-generated-serializers.md
index 428b3eff35..0d84a635e0 100644
--- a/docs/guide/java/static-generated-serializers.md
+++ b/docs/guide/java/static-generated-serializers.md
@@ -78,11 +78,11 @@ public class Order {
 The processor generates serializer classes in the same Java package as the 
annotated class. For
 `Order`, the generated classes are:
 
-- `Order__ForySerializer__` for cross-language mode.
-- `Order__ForyNativeSerializer__` for Java native mode.
+- `Order_ForySerializer` for cross-language mode.
+- `Order_ForyNativeSerializer` for Java native mode.
 
 For a static nested type such as `Outer.Inner`, the generated top-level 
classes are
-`Outer$Inner__ForySerializer__` and `Outer$Inner__ForyNativeSerializer__`.
+`Outer_Inner_ForySerializer` and `Outer_Inner_ForyNativeSerializer`.
 
 ## Field Debug Tracing
 
@@ -114,6 +114,9 @@ Fory uses static generated serializers when they are 
available on:
 
 On an ordinary JVM with `codegen=true`, Fory continues to prefer 
runtime-generated serializers.
 
+The runtime resolves generated serializers from the registered target class 
name. Application code
+should not reference generated serializer classes directly.
+
 ## Field Access Rules
 
 Generated serializers must be able to access serialized fields or their 
accessors at compile time.
@@ -151,6 +154,10 @@ Without the generated serializer metadata, Android may not 
expose enough nested
 Fory to preserve annotations such as `@Ref`, `@Int8Type`, `@UInt8Type`, 
`@Float16Type`, or
 `@BFloat16Type`.
 
+The annotation processor emits generated consumer R8/ProGuard rules under 
`META-INF/proguard/` for
+the exact serializer constructors used by Fory. Android applications should 
not add broad generated
+serializer keep rules by hand.
+
 ## Compatible Reads
 
 Static generated serializers support both normal serialization and 
compatible-mode reads. Compatible
diff --git a/docs/guide/kotlin/android-support.md 
b/docs/guide/kotlin/android-support.md
new file mode 100644
index 0000000000..78db86bf6c
--- /dev/null
+++ b/docs/guide/kotlin/android-support.md
@@ -0,0 +1,122 @@
+---
+title: Android Support
+sidebar_position: 5
+id: android_support
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Apache Fory Kotlin supports Kotlin/JVM and Android. Android support is built on
+the existing Fory Java runtime plus Kotlin runtime serializers from
+`fory-kotlin`. Kotlin schema serializers are generated by `fory-kotlin-ksp` at
+build time.
+
+Use this page for Android setup and release-build constraints. Use
+[Static Generated Serializers](static-generated-serializers.md) for the Kotlin
+KSP serializer model itself. If your Android project also contains Java
+`@ForyStruct` classes, use the Java annotation processor documented in
+[Java Static Generated Serializers](../java/static-generated-serializers.md).
+
+## Dependencies
+
+Add `fory-kotlin` to the Android module that uses Fory. Add
+`fory-kotlin-ksp` to the module that compiles Kotlin `@ForyStruct` model
+classes.
+
+```kotlin
+plugins {
+  id("com.android.application")
+  id("org.jetbrains.kotlin.android")
+  id("com.google.devtools.ksp")
+}
+
+dependencies {
+  implementation("org.apache.fory:fory-kotlin:<fory-version>")
+  ksp("org.apache.fory:fory-kotlin-ksp:<fory-version>")
+}
+```
+
+For Android library modules, apply KSP in the library module that owns the
+annotated Kotlin classes. The generated serializers and generated consumer R8
+rules must be packaged with that library artifact.
+
+## Runtime Setup
+
+Register the Kotlin runtime serializers once for each Fory instance, then
+register application classes through the normal Fory Java registration APIs.
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+val fory = Fory.builder()
+  .withXlang(true)
+  .requireClassRegistration(true)
+  .build()
+
+KotlinSerializers.registerSerializers(fory)
+fory.register(User::class.java, "example", "User")
+```
+
+Do not reference generated serializer classes from application code. The 
runtime
+resolves generated serializers from the registered target class.
+
+## Xlang Schema Mode
+
+Android Kotlin structs that participate in Fory cross-language schema
+serialization should use KSP generated serializers. Generated serializers avoid
+using runtime reflection as the source of Kotlin schema metadata and call the
+same Fory Java runtime infrastructure used by other generated serializers.
+
+Kotlin KSP generated serializers are xlang/schema serializers only. They do not
+replace Java native object serializers and do not preserve concrete JVM
+collection implementation identity. For example, a Kotlin `List<String>` field
+is schema `list<string>`; deserialization only guarantees a value assignable to
+the declared field type.
+
+## Minified Release Builds
+
+Validate Fory Android behavior with a minified release build. Debug builds do
+not prove that generated serializers, generated constructor entry points, or
+Kotlin metadata survive R8.
+
+KSP emits generated consumer R8/ProGuard rules under `META-INF/proguard/` for
+the generated serializer constructors and Kotlin metadata required by Fory.
+Android apps should not need broad user-written keep rules for generated Kotlin
+serializers. If a custom packaging setup drops generated `META-INF/proguard/`
+resources, fix that packaging path instead of adding broad keep rules for every
+generated serializer.
+
+The Apache Fory repository validates this path with
+`integration_tests/android_tests`, including release-minified instrumented
+tests.
+
+## Java Models In Android Apps
+
+Kotlin KSP only processes Kotlin source. If your Android app contains Java
+classes annotated with `@ForyStruct`, configure the Java
+`fory-annotation-processor` for those Java sources.
+
+Static generated Java serializers are also important on Android when Java model
+classes use Fory type-use annotations on nested types, such as
+`List<@UInt8Type Integer>`. See
+[Java Static Generated Serializers](../java/static-generated-serializers.md)
+for that path.
+
+## Unsupported Targets
+
+`fory-kotlin` and `fory-kotlin-ksp` target Kotlin/JVM and Android only.
+Kotlin/Native and Kotlin/JS are not supported.
diff --git a/docs/guide/kotlin/index.md b/docs/guide/kotlin/index.md
index af8f6bf106..0b65c2a5d1 100644
--- a/docs/guide/kotlin/index.md
+++ b/docs/guide/kotlin/index.md
@@ -108,3 +108,4 @@ Fory Kotlin is built on top of Fory Java. Most 
configuration options, features,
 - [Type Serialization](type-serialization.md) - Serializing Kotlin types
 - [Default Values](default-values.md) - Kotlin data class default values 
support
 - [Static Generated Serializers](static-generated-serializers.md) - KSP 
xlang/schema serializer generation
+- [Android Support](android-support.md) - Android setup, R8 behavior, and 
release-build validation
diff --git a/docs/guide/kotlin/static-generated-serializers.md 
b/docs/guide/kotlin/static-generated-serializers.md
index f2a2e48b1b..8836ac44e1 100644
--- a/docs/guide/kotlin/static-generated-serializers.md
+++ b/docs/guide/kotlin/static-generated-serializers.md
@@ -19,48 +19,39 @@ license: |
   limitations under the License.
 ---
 
-`fory-kotlin-ksp` generates Kotlin source serializers for Fory xlang/schema
-mode. The generated serializers use the existing Java runtime
-`WriteContext`, `ReadContext`, and `MemoryBuffer`; they do not define a
-Kotlin-only protocol or buffer abstraction.
-
-## Scope
-
-KSP generation is only for xlang/schema mode. It does not generate Fory Java
-native object serializers and does not preserve concrete JVM runtime identity
-for object graphs. Collection declarations are schema carriers: `List<T>` is
-encoded as `list<T>`, `Map<K, V>` as `map<K, V>`, and deserialization only
-guarantees a value assignable to the declared Kotlin field type.
-
-Mutable collection interface fields are supported by reconstructing a mutable
-implementation assignable to the declared type. Sorted collection declarations
-without an explicit comparator, such as `TreeSet` and `ConcurrentSkipListSet`,
-are accepted only for non-null scalar or string elements. Concurrent map
-declarations are accepted only with non-null values because the JVM concurrent
-map implementations reject null entries.
-
-Kotlin/JVM and Android are supported. Kotlin/Native and Kotlin/JS are not
-supported by this module.
-
-Phase 1 KSP generation emits serializers for public concrete, non-generic
-`@ForyStruct` classes with primary-constructor fields and a public or internal
-primary constructor. Kotlin `private` and `internal` struct classes are 
rejected
-because generated serializers and SPI providers are public runtime entry
-points. Kotlin `object` declarations, annotated interfaces, abstract classes,
-sealed declarations, and generic struct targets are rejected during KSP
-processing because they are not single constructor-field serializer targets for
-the phase 1 generator. Dense primitive and unsigned array types, such as
-`IntArray` and `UIntArray`, are supported as top-level fields. Nested dense
-arrays, such as `List<UIntArray>` or `Map<String, IntArray>`, are rejected in
-phase 1. Fory Java `@ArrayType` is also supported on top-level `List<T>` fields
-when `T` is a non-null bool or numeric dense-array element domain. The 
generated
-serializer writes the field as dense `array<T>` schema and converts decoded JVM
-list elements back to the declared Kotlin carrier, such as `Int`, `UInt`, or
-`Double`.
-
-## Annotations
-
-Reuse Java annotations for Fory concepts:
+Use `fory-kotlin-ksp` when Kotlin classes must participate in Fory
+cross-language schema serialization. The processor generates Kotlin source
+serializers at build time. Those serializers call the existing Fory Java
+runtime, including `WriteContext`, `ReadContext`, and `MemoryBuffer`; there is
+no Kotlin-only protocol.
+
+Static generated Kotlin serializers are for Kotlin/JVM and Android xlang/schema
+mode. They are not Java native object serializers and do not preserve JVM 
object
+graph implementation details such as the exact concrete collection class.
+
+## Add KSP
+
+Add `fory-kotlin` at runtime and run `fory-kotlin-ksp` as a KSP processor in
+the module that compiles your `@ForyStruct` Kotlin classes.
+
+```kotlin
+plugins {
+  id("com.google.devtools.ksp") version "<ksp-version>"
+}
+
+dependencies {
+  implementation("org.apache.fory:fory-kotlin:<fory-version>")
+  ksp("org.apache.fory:fory-kotlin-ksp:<fory-version>")
+}
+```
+
+For Android, configure KSP in the Android module or library module that owns
+the Kotlin model classes.
+
+## Define A Struct
+
+Reuse the Java Fory annotations for schema concepts. Use Kotlin type-use
+annotations only when you need to override integer encoding.
 
 ```kotlin
 import org.apache.fory.annotation.ForyField
@@ -75,27 +66,126 @@ data class User(
 
   @ForyField(id = 2)
   val score: @VarInt Long,
+
+  @ForyField(id = 3)
+  val tags: List<String>,
+)
+```
+
+Use `@ForyField(id = 1)` on constructor properties. `@field:ForyField(id = 1)`
+is also accepted for field-backed properties. Do not use `@get:ForyField` or
+`@set:ForyField`; accessors are not schema fields and the processor rejects
+them.
+
+## Supported Structs
+
+The processor generates serializers for public or internal, concrete,
+non-generic classes in named packages. A supported class must have a primary
+constructor whose serialized parameters are `val` or `var` properties. `data
+class` is the common case, but it is not required.
+
+Internal Kotlin struct classes are supported when KSP runs in the same Kotlin
+module that owns the struct. The generated Kotlin serializer is also internal,
+so it can call the internal constructor and expose the internal type in
+overrides while still producing a JVM class that the Fory Java runtime can 
load.
+Application code outside that Kotlin module still cannot refer to the internal
+struct directly, so registration must happen from code that can see the class.
+
+The processor rejects these declarations:
+
+- `private` struct classes.
+- local, anonymous, or nested `@ForyStruct` classes.
+- Kotlin `object` declarations.
+- interfaces, abstract classes, and sealed classes as serializer targets.
+- generic `@ForyStruct` classes.
+- private constructor properties.
+- private or protected primary constructors.
+
+Kotlin default constructor arguments are supported for compatible reads. A
+struct can have up to 12 defaulted constructor fields.
+
+## Nullability
+
+Use Kotlin `?` to describe nullable schema positions. Nullability is preserved
+inside collections and maps.
+
+```kotlin
+@ForyStruct
+data class NullabilityExample(
+  @ForyField(id = 1)
+  val a: List<String>,
+
+  @ForyField(id = 2)
+  val b: List<String?>,
+
+  @ForyField(id = 3)
+  val c: List<String>?,
+
+  @ForyField(id = 4)
+  val d: List<String?>?,
 )
 ```
 
-Use `@ForyField(id = 1)`. `@field:ForyField(id = 1)` is also accepted for
-field-backed properties. `@get:ForyField` and `@set:ForyField` are rejected
-because accessors are not schema fields.
+Do not use Fory `@Nullable` in Kotlin source. The KSP processor rejects it so
+the schema is always read from Kotlin source nullability.
+
+## References
+
+`@ForyField(ref = true)` is not supported by Kotlin xlang generated
+serializers. Generated reads construct Kotlin values through primary
+constructors, so they cannot publish partially constructed objects for cyclic
+back-references. Use non-cyclic schemas for Kotlin xlang structs.
+
+## Collections
+
+Collection declarations carry schema shape, not JVM implementation identity.
+For example, `List<String>` is encoded as `list<string>` and
+`Map<String, Int>` is encoded as `map<string, int32>`.
+
+Deserialization only guarantees that the result is assignable to the declared
+field type. Fory does not preserve whether the original runtime value was an
+`ArrayList`, `LinkedList`, `Collections.unmodifiableList`, synchronized
+collection wrapper, or another JVM-specific collection implementation.
+
+Supported collection declarations include Kotlin and Java list, set, and map
+types. Mutable collection interface fields are deserialized to mutable
+implementations assignable to the declared type. Sorted collections without an
+explicit comparator, such as `TreeSet` and `ConcurrentSkipListSet`, are 
accepted
+only for non-null scalar or string elements. Concurrent map declarations are
+accepted only with non-null values because JVM concurrent map implementations
+reject null entries.
+
+`Set<*>`, `Map<*, T>`, `Map<*, *>`, and raw Java collections are rejected.
+`List<*>` and `Map<K, *>` are accepted and use dynamic nullable values.
+
+## Dense Arrays
+
+Kotlin dense primitive and unsigned array fields are supported:
 
-Kotlin nullability is expressed with `?`, including nested positions such as
-`List<String?>?`. Do not use Fory `@Nullable` in Kotlin source.
+- `BooleanArray`
+- `ByteArray`
+- `ShortArray`
+- `IntArray`
+- `LongArray`
+- `FloatArray`
+- `DoubleArray`
+- `UByteArray`
+- `UShortArray`
+- `UIntArray`
+- `ULongArray`
 
-`@ForyField(ref = true)` is rejected by the KSP xlang processor. Phase 1
-generated serializers construct Kotlin values through primary constructors and
-therefore cannot publish partially constructed objects for cyclic
-back-references. Use non-cyclic xlang schemas for Kotlin KSP serializers.
+Dense arrays are supported as top-level fields. Nested dense arrays, such as
+`List<UIntArray>` or `Map<String, IntArray>`, are rejected.
 
-Kotlin default constructor arguments are supported for compatible reads by
-generating constructor calls that omit missing defaulted arguments. Because
-Kotlin source generation must emit these calls statically, the first KSP
-implementation supports at most 12 defaulted constructor fields per struct.
+`ByteArray` is encoded as Fory `binary` unless you explicitly annotate the
+field with Java `@ArrayType`.
 
-## Encoding
+`@ArrayType` is also supported on top-level `List<T>` fields when `T` is a
+non-null boolean or numeric dense-array element type. In that case the field is
+encoded as dense `array<T>` schema, and generated reads convert decoded JVM 
list
+elements back to the declared Kotlin element carrier.
+
+## Integer Encoding
 
 Kotlin type-use encoding annotations map to Fory xlang integer encodings:
 
@@ -109,10 +199,11 @@ Without an annotation, xlang `Int`, `Long`, `UInt`, and 
`ULong` use varint
 encoding. This is required by xlang mode and is not controlled by Java native
 mode numeric compression options.
 
-## Registration
+## Register Classes
 
-Users register Kotlin struct classes with the normal Fory Java registration
-APIs. Do not reference generated serializer class names.
+Register Kotlin struct classes with the normal Fory Java registration APIs. You
+choose the xlang namespace and type name; generated serializers do not choose
+IDs or names for you.
 
 ```kotlin
 val fory = Fory.builder()
@@ -124,42 +215,45 @@ KotlinSerializers.registerSerializers(fory)
 fory.register(User::class.java, "example", "User")
 ```
 
-The KSP processor emits a service provider that maps target classes to their
-generated serializers. On Android and for Kotlin classes, the Java runtime
-requires this provider mapping for xlang structs. Missing KSP/SPI metadata is a
-configuration error, not a reflective fallback path. This avoids generated-name
-`Class.forName` lookups and works as an R8-compatible discovery path when the
-generated service resource and serializer classes are kept by the application
-build.
-
-Android builds that run R8 must preserve the generated SPI resource and the
-generated provider/serializer classes. Application shrinker rules should keep:
-
-```text
--keep class * implements 
org.apache.fory.resolver.StaticGeneratedSerializerProvider { *; }
--keep class * implements 
org.apache.fory.resolver.StaticGeneratedSerializerProvider$KotlinSymbolProcessor
 { *; }
--keep class * implements 
org.apache.fory.resolver.StaticGeneratedSerializerProvider$JavaAnnotationProcessor
 { *; }
--keep class **.*__ForySerializer__ { *; }
--keep class org.apache.fory.resolver.StaticGeneratedSerializerProvider { *; }
--keep class org.apache.fory.resolver.StaticGeneratedSerializerProvider$* { *; }
-```
+`KotlinSerializers.registerSerializers(fory)` installs the Kotlin runtime
+serializers used by Kotlin-specific carriers such as unsigned types. The
+`fory.register(...)` call registers your xlang schema type name.
+
+Do not register or reference generated serializer classes in application code.
+The runtime resolves them from the registered target class.
+
+## Generated Names
+
+The generated serializer is emitted in the same package as the target class.
+Its name is `<target>_ForySerializer`. For nested binary names, `$` is encoded
+as `_`; source underscores are encoded as `_u_`.
+
+These names are an implementation detail. They matter for diagnostics and
+Android shrinking, but user code should only register target classes.
+
+If a Kotlin xlang struct is registered but its KSP generated serializer is
+missing, Fory fails with a configuration error. It does not fall back to
+runtime reflection for Kotlin schema metadata.
+
+## Android And R8
+
+Android apps should not need user-written keep rules for generated Kotlin
+serializers. KSP emits generated consumer R8/ProGuard rules under
+`META-INF/proguard/` for the generated serializer constructors used by Fory and
+the Kotlin metadata needed to detect required Kotlin generated serializers.
+
+For library modules, package the generated `META-INF/proguard/` resources into
+the produced artifact. For Android application modules, make sure your KSP
+setup includes generated resources in the minified variant.
+
+See [Android Support](android-support.md) for Android Gradle setup and
+release-minified validation guidance.
+
+## Native Object Mode
+
+Kotlin KSP generated serializers are only for xlang/schema mode. They do not
+replace Fory Java native object serializers and do not preserve JVM object 
graph
+identity. If you use Fory with `withXlang(false)`, Fory uses the normal Java 
and
+Kotlin runtime serializers instead.
 
-The Kotlin KSP generated service resource
-`META-INF/services/org.apache.fory.resolver.StaticGeneratedSerializerProvider$KotlinSymbolProcessor`
-must also be packaged. Java annotation-processor generated serializers use the
-separate
-`META-INF/services/org.apache.fory.resolver.StaticGeneratedSerializerProvider$JavaAnnotationProcessor`
-resource so mixed Java/Kotlin artifacts do not overwrite one another's provider
-lists. If a build plugin strips service resources, configure the application
-packaging step to retain these files.
-
-The KSP processor emits one aggregate provider for the compilation module in
-`org.apache.fory.kotlin.generated`. The provider class name includes a stable
-hash of the generated target mappings, so multiple Kotlin artifacts can publish
-providers on the same classpath without binary-name collisions. That provider
-contains mappings for all annotated Kotlin structs in the module, across source
-packages.
-
-Applications must package the generated service resource. There is no manual
-provider registration API; users still register only target classes and their
-IDs or xlang names through the normal Fory Java registration APIs.
+Kotlin/Native and Kotlin/JS are not supported by this module.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to