diff --git a/blog/2026-09-04-fory_1_7_1_released.md b/blog/2026-09-04-fory_1_7_1_released.md new file mode 100644 index 00000000000..14cb6bcfae8 --- /dev/null +++ b/blog/2026-09-04-fory_1_7_1_released.md @@ -0,0 +1,136 @@ +--- +slug: fory_1_7_1_release +title: Fory v1.7.1 Released +description: "Fory 1.7.1 adds string output for 64-bit integers and makes Base64 the default JSON representation for byte arrays." +authors: [chaokunyang] +tags: [fory, java, json, javascript, xlang] +--- + +The Apache Fory team is pleased to announce the 1.7.1 release. This patch release improves Java +JSON interoperability, expands cross-language field tag IDs, and delivers correctness and +compatibility fixes across multiple runtimes. See the +[Getting Started](https://fory.apache.org/docs/start/) page to get the libraries for your platform. + +## Highlights + +- Java JSON can write 64-bit integer values as strings, helping applications preserve exact values + when JSON passes through JavaScript. +- Java JSON now writes byte arrays as Base64 strings by default, providing a more compact and + conventional representation for binary data. + +## JSON-Safe 64-Bit Integers + +JavaScript numbers cannot exactly represent every 64-bit integer. Fory JSON 1.7.1 adds the +`writeLongAsString` builder option so applications can emit Java `long` and `Long` values as quoted +decimal strings when data will pass through JavaScript or another number-limited consumer: + +```java +import org.apache.fory.json.ForyJson; + +ForyJson json = ForyJson.builder().writeLongAsString(true).build(); +String encoded = json.toJson(9_007_199_254_740_993L); + +assert encoded.equals("\"9007199254740993\""); +``` + +The option is disabled by default. It also applies to the supported Long-like wrappers and to +declared Long values inside arrays, collections, maps, and equivalent Scala and Kotlin containers. +Readers accept both quoted and unquoted integer tokens regardless of the writer setting. See the +[Java JSON object mapping guide](/docs/json/object-mapping) for the complete behavior. + +## Base64 Byte Arrays by Default + +Unannotated Java `byte[]` values now use quoted standard Base64 strings instead of JSON arrays of +decimal byte values. For example, the bytes `{1, -2, 3}` are written as `"Af4D"`. This matches the +usual JSON representation for binary data and reduces encoding and parsing overhead for +binary-heavy payloads. + +This is a default representation change from Fory 1.7.0. The Base64 reader does not accept the old +numeric-array representation. Applications that need to retain that representation can select it +for an exact field or getter: + +```java +import org.apache.fory.json.annotation.JsonByteArray; + +public final class Attachment { + @JsonByteArray(JsonByteArray.Format.ARRAY) + public byte[] content; +} +``` + +See the [JSON annotations guide](/docs/json/annotations) for `JsonByteArray` Base64 and +numeric-array mapping details. + +## Features + +- feat(xlang): expand field tag IDs to signed int32 by + [@chaokunyang](https://github.com/chaokunyang) in + [#3982](https://github.com/apache/fory/pull/3982) +- feat(json): support writing long values as strings by + [@chaokunyang](https://github.com/chaokunyang) in + [#4008](https://github.com/apache/fory/pull/4008) +- feat(json): encode byte arrays as Base64 JSON strings by default by + [@ingokegel](https://github.com/ingokegel) in + [#4012](https://github.com/apache/fory/pull/4012) + +## Bug Fixes + +- fix(ci): increase Android Gradle memory by [@chaokunyang](https://github.com/chaokunyang) in + [#3980](https://github.com/apache/fory/pull/3980) +- fix(xlang): close field tag validation gaps by + [@chaokunyang](https://github.com/chaokunyang) in + [#3984](https://github.com/apache/fory/pull/3984) +- test(java): shorten inherited tag test name by + [@chaokunyang](https://github.com/chaokunyang) in + [#3985](https://github.com/apache/fory/pull/3985) +- fix: harden low-level codec boundaries by [@chaokunyang](https://github.com/chaokunyang) in + [#3987](https://github.com/apache/fory/pull/3987) +- fix(go): preserve primitive map iteration across chunks by + [@chaokunyang](https://github.com/chaokunyang) in + [#3990](https://github.com/apache/fory/pull/3990) +- fix(js): avoid precision loss in negative varint64 fast path by + [@ayush00git](https://github.com/ayush00git) in + [#3992](https://github.com/apache/fory/pull/3992) +- fix(java): reuse local compatible type info by + [@chaokunyang](https://github.com/chaokunyang) in + [#4000](https://github.com/apache/fory/pull/4000) +- fix(kotlin): accept supported metadata versions by + [@chaokunyang](https://github.com/chaokunyang) in + [#4001](https://github.com/apache/fory/pull/4001) +- fix(javascript): use correct typemeta special chars by + [@ayush00git](https://github.com/ayush00git) in + [#3995](https://github.com/apache/fory/pull/3995) +- ci(kotlin): test Kotlin 2.4.10 on JDK 26 by + [@chaokunyang](https://github.com/chaokunyang) in + [#4002](https://github.com/apache/fory/pull/4002) +- fix(javascript): reserve writer capacity for write paths by + [@ayush00git](https://github.com/ayush00git) in + [#3994](https://github.com/apache/fory/pull/3994) +- fix(rust): correct send sync ownership by [@chaokunyang](https://github.com/chaokunyang) in + [#4003](https://github.com/apache/fory/pull/4003) +- fix(scala): support nested case classes in fory-json-scala by + [@pjfanning](https://github.com/pjfanning) in + [#4006](https://github.com/apache/fory/pull/4006) +- fix(javascript): underflow tiny float16 magnitudes to signed zero by + [@ayush00git](https://github.com/ayush00git) in + [#4004](https://github.com/apache/fory/pull/4004) +- fix(javascript): keep float64 precision for dynamic non-integer numbers by + [@ayush00git](https://github.com/ayush00git) in + [#4005](https://github.com/apache/fory/pull/4005) +- fix(javascript): round float16 values to nearest even by + [@chaokunyang](https://github.com/chaokunyang) in + [#4007](https://github.com/apache/fory/pull/4007) + +## Other Improvements + +- chore: improve Fory release skill by [@chaokunyang](https://github.com/chaokunyang) in + [#3979](https://github.com/apache/fory/pull/3979) +- chore: clean unnecessary buffer checks by [@chaokunyang](https://github.com/chaokunyang) in + [#3988](https://github.com/apache/fory/pull/3988) + +## New Contributors + +- [@ingokegel](https://github.com/ingokegel) made their first contribution in + [#4012](https://github.com/apache/fory/pull/4012) + +**Full Changelog**: [v1.7.0...v1.7.1](https://github.com/apache/fory/compare/v1.7.0...v1.7.1) diff --git a/i18n/zh-CN/docusaurus-plugin-content-blog/2026-09-04-fory_1_7_1_released.md b/i18n/zh-CN/docusaurus-plugin-content-blog/2026-09-04-fory_1_7_1_released.md new file mode 100644 index 00000000000..109ab781773 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-blog/2026-09-04-fory_1_7_1_released.md @@ -0,0 +1,126 @@ +--- +slug: fory_1_7_1_release +title: Apache Fory 1.7.1 正式发布 +description: "Fory 1.7.1 支持将 64 位整数写为字符串,并默认使用 Base64 表示 JSON 字节数组。" +authors: [chaokunyang] +tags: [fory, java, json, javascript, xlang] +--- + +Apache Fory 团队很高兴地宣布 1.7.1 版本正式发布。这个补丁版本提升了 Java JSON 的互操作性, +扩展了跨语言字段 tag ID,并为多个运行时带来了正确性与兼容性修复。请访问 +[快速开始](https://fory.apache.org/zh-CN/docs/start/)页面,获取适用于您所用平台的库。 + +## 亮点 + +- Java JSON 支持将 64 位整数值写为字符串,帮助应用在 JSON 经过 JavaScript 时保持精确值。 +- Java JSON 现在默认将字节数组写为 Base64 字符串,为二进制数据提供更紧凑、更通用的表示形式。 + +## 避免 JSON 中的 64 位整数精度损失 + +JavaScript 数字无法精确表示所有 64 位整数。Fory JSON 1.7.1 新增 `writeLongAsString` builder 选项, +当数据会经过 JavaScript 或其他数值范围受限的使用方时,应用可以将 Java `long` 和 `Long` 值输出为 +带引号的十进制字符串: + +```java +import org.apache.fory.json.ForyJson; + +ForyJson json = ForyJson.builder().writeLongAsString(true).build(); +String encoded = json.toJson(9_007_199_254_740_993L); + +assert encoded.equals("\"9007199254740993\""); +``` + +该选项默认关闭。它也适用于受支持的 Long 类包装器,以及数组、collection、Map 和等效 Scala、Kotlin +容器中声明的 Long 值。无论写入端是否启用该选项,Reader 都同时接受带引号和不带引号的整数 token。 +完整行为请参阅 [Java JSON 对象映射指南](/zh-CN/docs/json/object-mapping)。 + +## 默认使用 Base64 表示字节数组 + +未标注的 Java `byte[]` 值现在使用带引号的标准 Base64 字符串,不再使用十进制字节值组成的 JSON +数组。例如,字节 `{1, -2, 3}` 会写为 `"Af4D"`。这符合 JSON 生态中常见的二进制数据表示方式, +并能减少二进制密集型载荷的编码和解析开销。 + +这是相对于 Fory 1.7.0 的默认表示变化。Base64 Reader 不接受旧的数字数组表示。需要保留该表示的 +应用可以为精确字段或 getter 显式选择数字数组格式: + +```java +import org.apache.fory.json.annotation.JsonByteArray; + +public final class Attachment { + @JsonByteArray(JsonByteArray.Format.ARRAY) + public byte[] content; +} +``` + +Base64 与数字数组的映射详情请参阅 [JSON 注解指南](/zh-CN/docs/json/annotations)中的 +`JsonByteArray` 说明。 + +## 功能改进 + +- feat(xlang): 将字段 tag ID 扩展为 signed int32,由 + [@chaokunyang](https://github.com/chaokunyang) 在 + [#3982](https://github.com/apache/fory/pull/3982) 中贡献 +- feat(json): 支持将 long 值写为字符串,由 + [@chaokunyang](https://github.com/chaokunyang) 在 + [#4008](https://github.com/apache/fory/pull/4008) 中贡献 +- feat(json): 默认将字节数组编码为 Base64 JSON 字符串,由 + [@ingokegel](https://github.com/ingokegel) 在 + [#4012](https://github.com/apache/fory/pull/4012) 中贡献 + +## 问题修复 + +- fix(ci): 增加 Android Gradle 内存,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#3980](https://github.com/apache/fory/pull/3980) 中贡献 +- fix(xlang): 补全字段 tag 校验,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#3984](https://github.com/apache/fory/pull/3984) 中贡献 +- test(java): 缩短继承 tag 测试名称,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#3985](https://github.com/apache/fory/pull/3985) 中贡献 +- fix: 加固底层编解码器边界,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#3987](https://github.com/apache/fory/pull/3987) 中贡献 +- fix(go): 在分块处理期间保留基本类型 Map 的迭代状态,由 + [@chaokunyang](https://github.com/chaokunyang) 在 + [#3990](https://github.com/apache/fory/pull/3990) 中贡献 +- fix(js): 避免负数 varint64 快速路径中的精度损失,由 + [@ayush00git](https://github.com/ayush00git) 在 + [#3992](https://github.com/apache/fory/pull/3992) 中贡献 +- fix(java): 复用本地兼容类型信息,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#4000](https://github.com/apache/fory/pull/4000) 中贡献 +- fix(kotlin): 接受受支持的元数据版本,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#4001](https://github.com/apache/fory/pull/4001) 中贡献 +- fix(javascript): 为类型元信息使用正确的特殊字符,由 + [@ayush00git](https://github.com/ayush00git) 在 + [#3995](https://github.com/apache/fory/pull/3995) 中贡献 +- ci(kotlin): 在 JDK 26 上测试 Kotlin 2.4.10,由 + [@chaokunyang](https://github.com/chaokunyang) 在 + [#4002](https://github.com/apache/fory/pull/4002) 中贡献 +- fix(javascript): 为写入路径预留 writer 容量,由 + [@ayush00git](https://github.com/ayush00git) 在 + [#3994](https://github.com/apache/fory/pull/3994) 中贡献 +- fix(rust): 修正 `Send`/`Sync` 所有权,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#4003](https://github.com/apache/fory/pull/4003) 中贡献 +- fix(scala): 支持 fory-json-scala 中的嵌套 case class,由 + [@pjfanning](https://github.com/pjfanning) 在 + [#4006](https://github.com/apache/fory/pull/4006) 中贡献 +- fix(javascript): 将过小的 float16 值下溢为带符号零,由 + [@ayush00git](https://github.com/ayush00git) 在 + [#4004](https://github.com/apache/fory/pull/4004) 中贡献 +- fix(javascript): 为动态非整数保留 float64 精度,由 + [@ayush00git](https://github.com/ayush00git) 在 + [#4005](https://github.com/apache/fory/pull/4005) 中贡献 +- fix(javascript): 按最近偶数规则舍入 float16 值,由 + [@chaokunyang](https://github.com/chaokunyang) 在 + [#4007](https://github.com/apache/fory/pull/4007) 中贡献 + +## 其他改进 + +- chore: 改进 Fory 发布 skill,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#3979](https://github.com/apache/fory/pull/3979) 中贡献 +- chore: 清理不必要的缓冲区检查,由 [@chaokunyang](https://github.com/chaokunyang) 在 + [#3988](https://github.com/apache/fory/pull/3988) 中贡献 + +## 新贡献者 + +- [@ingokegel](https://github.com/ingokegel) 在 + [#4012](https://github.com/apache/fory/pull/4012) 中完成首次贡献 + +**完整变更日志**:[v1.7.0...v1.7.1](https://github.com/apache/fory/compare/v1.7.0...v1.7.1) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/build-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/build-integration.md index e9af0bf8e06..4ec2647c0cf 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/build-integration.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/build-integration.md @@ -211,7 +211,7 @@ cc_library( ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/cli.md index 19f04b0624a..7b63012b769 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/cli.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/cli.md @@ -659,5 +659,5 @@ fory = "x.y.z" ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/csharp.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/csharp.md index 90e47065b1f..286e3707c62 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/csharp.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/csharp.md @@ -36,7 +36,7 @@ gRPC 客户端、服务基类、方法描述符、元数据、截止时间、取 ```xml - + ``` @@ -45,7 +45,7 @@ gRPC 客户端、服务基类、方法描述符、元数据、截止时间、取 ```xml - + diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/dart.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/dart.md index 6990adafcb0..4f647c9f265 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/dart.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/dart.md @@ -29,7 +29,7 @@ license: | ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 grpc: ^4.0.0 dev_dependencies: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/rust.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/rust.md index b52738581d1..92db84efcd3 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/rust.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/grpc/rust.md @@ -29,7 +29,7 @@ license: | ```toml [dependencies] -fory = "1.7.0" +fory = "1.7.1" bytes = "1" tonic = { version = "0.14", features = ["transport"] } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/android.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/android.md index ca12aafd46f..abdab317b24 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/android.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/android.md @@ -115,12 +115,12 @@ public final class Invoice { ```java import org.apache.fory.json.ForyJson; -import org.apache.fory.json.annotation.JsonBase64; +import org.apache.fory.json.annotation.JsonByteArray; import org.apache.fory.json.annotation.JsonMixin; @JsonMixin(target = ThirdPartyInvoice.class) public abstract class ThirdPartyInvoiceMixin { - @JsonBase64 byte[] signature; + @JsonByteArray(JsonByteArray.Format.BASE64) byte[] signature; } ForyJson json = @@ -158,7 +158,7 @@ Mixin 可在与目标公共方法精确匹配的公共抽象无参 `void` 方法 本节的反射规则适用于 Java 模型。Kotlin 模型使用 Kotlin JSON 模块;启用代码压缩的 Android 构建应使用 KSP,而不是编写宽泛的包级 keep 规则。 -Java `@JsonType` 模型支持有效的 `JsonValidator`、`JsonValue`、`JsonRawValue`、`JsonBase64` 和 `JsonFormat` 注解。未标注 `@JsonType` 时,这些注解仍可通过反射工作,但经过发布压缩的应用必须自行保留精确的注解成员、注解属性和编解码器构造函数。`JsonValue` 方法可以使用不符合 JavaBean 约定的名称,因此手写规则必须明确指定该方法。 +Java `@JsonType` 模型支持有效的 `JsonValidator`、`JsonValue`、`JsonRawValue`、`JsonByteArray` 和 `JsonFormat` 注解。未标注 `@JsonType` 时,这些注解仍可通过反射工作,但经过发布压缩的应用必须自行保留精确的注解成员、注解属性和编解码器构造函数。`JsonValue` 方法可以使用不符合 JavaBean 约定的名称,因此手写规则必须明确指定该方法。 Kotlin 模型使用相同的有效注解。启用代码压缩时,请使用 KSP。`JsonFormat` 与 JVM 上一样支持直接字段和一层包装,包括为 `Instant`、`ZonedDateTime` 和 `OffsetDateTime` 指定 `timezone`。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/annotations.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/annotations.md index 13671782f4e..a51f79afde0 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/annotations.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/annotations.md @@ -19,7 +19,7 @@ license: | limitations under the License. --- -Fory JSON 在 `org.apache.fory.json.annotation` 中提供以下映射和验证注解:`JsonAnyGetter`、`JsonAnyProperty`、`JsonAnySetter`、`JsonBase64`、`JsonCodec`、`JsonCreator`、`JsonFormat`、`JsonIgnore`、`JsonProperty`、`JsonPropertyOrder`、`JsonRawValue`、`JsonSubTypes`、`JsonUnwrapped`、`JsonValidator` 和 `JsonValue`。`JsonType` 是独立的构建期模型标记。这些属于 Fory JSON API,不是 Jackson、Gson 或 Fory 二进制协议兼容注解。 +Fory JSON 在 `org.apache.fory.json.annotation` 中提供以下映射和验证注解:`JsonAnyGetter`、`JsonAnyProperty`、`JsonAnySetter`、`JsonByteArray`、`JsonCodec`、`JsonCreator`、`JsonFormat`、`JsonIgnore`、`JsonProperty`、`JsonPropertyOrder`、`JsonRawValue`、`JsonSubTypes`、`JsonUnwrapped`、`JsonValidator` 和 `JsonValue`。`JsonType` 是独立的构建期模型标记。这些属于 Fory JSON API,不是 Jackson、Gson 或 Fory 二进制协议兼容注解。 `JsonType` 不会被继承,因此每个需要参与平台构建流程且符合要求的具体模型都必须单独标注。Java 源码需要使用 `fory-annotation-processor`。未标注的普通 Java 类仍可使用反射;在 Android 上,它们需要由应用编写精确 R8 规则。经过 Android 脱糖处理的 Record 必须直接声明 `JsonType`,或使用已编译的精确 `JsonMixin` 配对。在 Native Image 之外,直接标注的 Java 模型如果使用默认对象编解码器却未运行注解处理器,会在创建编解码器时失败。 @@ -304,26 +304,34 @@ Map 值。它不能放在 setter、创建器参数或 Any 声明上,也不能 `JsonValue` 和 `JsonRawValue` 可以组合在同一个 String 成员上,将所属对象写为可信的原始根值。 这种组合仅支持序列化:普通的单 String 参数 `JsonCreator` 无法将输入对象或数组转换为 String。 -## `JsonBase64` +## `JsonByteArray` -`JsonBase64` 为一个精确的 `byte[]` 字段或 getter 选择带引号的标准 Base64 JSON 字符串表示: +未标注的 `byte[]` 值使用带引号的标准 Base64 JSON 字符串。`JsonByteArray` 为一个精确的 `byte[]` +字段或 getter 选择 `BASE64` 或 `ARRAY` 表示,并同时作用于读写: ```java -import org.apache.fory.json.annotation.JsonBase64; +import org.apache.fory.json.annotation.JsonByteArray; public final class Attachment { - @JsonBase64 + @JsonByteArray(JsonByteArray.Format.ARRAY) + public byte[] numbers; + + @JsonByteArray(JsonByteArray.Format.BASE64) public byte[] content; } ``` -字节 `{1, 2, 3}` 会写为 `{"content":"AQID"}`,并可解码回原始数组。Fory 会将 Base64 字符直接写入 -JSON 输出,也会直接从 JSON 输入解码,不创建中间 String。标准 Base64 填充会被保留。Java null 遵循 -属性的常规包含规则,从 JSON null 读取时也得到 null。 +对于字节 `{1, -2, 3}`,`numbers` 写为 `[1,-2,3]`,`content` 写为 `"Af4D"`。`ARRAY` 按有符号 +字节范围 `[-128, 127]` 读取 JSON 数组;`BASE64` 读取标准 Base64 字符串,并在写入时保留填充符。 +两种表示都接受 JSON null,null 输出遵循属性的常规包含规则。默认 Base64 编解码器不接受数字数组 +输入;使用该格式的属性应选择 `ARRAY`。 + +使用该注解时必须指定格式。它只作用于被标注的字节数组属性,不作用于容器元素或 Map 值。Mixin +声明可以选择或移除该注解。它不能与 `JsonRawValue`、声明位置上的 `JsonCodec`、`JsonFormat` 或 Any +声明共用于同一逻辑属性。同一属性的字段和 getter 选择冲突格式时会被拒绝。 -该注解不是类型使用注解,不会改变普通的未标注 `byte[]` 属性、容器元素或 Map 值。它不能与 -`JsonRawValue`、声明位置上的 `JsonCodec`、`JsonFormat` 或 Any 声明共用于同一逻辑属性。等效的显式 -编解码器为 `@JsonCodec(Base64ByteArrayCodec.class)`。 +Base64 值是二进制叶值,不计入对象图内存配额;数字数组则会将其数组存储计入该配额。详见 +[安全](security.md#depth-and-graph-memory-limits)。 ## `JsonFormat` @@ -377,7 +385,7 @@ public final class Schedule { 原始类型或通配符直接子元素、JSON Any 值以及展开值会被有意拒绝。不支持格式化语义模糊的类型,包括 旧版和 SQL 日期类型、`Duration`、`Period`、`TimeZone`、`ZoneId` 和 `ZoneOffset`。具有完整注册表示、 注解选择表示、多态表示或 `JsonValue` 表示的包装类型也会被拒绝,因为这些表示方式拥有整个包装对象。 -`JsonFormat` 不能与 `JsonCodec`、`JsonBase64`、`JsonRawValue`、`JsonAnyProperty`、`JsonUnwrapped` 或 +`JsonFormat` 不能与 `JsonCodec`、`JsonByteArray`、`JsonRawValue`、`JsonAnyProperty`、`JsonUnwrapped` 或 `JsonValue` 共用于同一字段。 ## `JsonUnwrapped` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/getting-started.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/getting-started.md index 96363f75e03..90b5c840463 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/getting-started.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/getting-started.md @@ -41,7 +41,7 @@ Maven: org.apache.fory fory-json - 1.7.0 + 1.7.1 ``` @@ -55,7 +55,7 @@ repositories { mavenCentral() } -implementation("org.apache.fory:fory-json:1.7.0") +implementation("org.apache.fory:fory-json:1.7.1") ``` ### Kotlin @@ -64,7 +64,7 @@ Kotlin/JVM 应用添加可选的 Kotlin JSON 运行时,并使用其统一 buil ```kotlin title="build.gradle.kts" dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/graalvm.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/graalvm.md index e430f668d6e..e76f9b7ff3c 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/graalvm.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/graalvm.md @@ -150,7 +150,7 @@ public class JsonExample { 支持在类型、字段、有效的普通 getter、setter 值参数和 `JsonCreator` 参数上使用 `@JsonCodec` 注解。Feature 会保留每个选定的完整值、元素、内容、Map 键和 Map 值 Codec 的构造函数。这与 JVM 和 Android 使用的注解模型相同。 -支持 `JsonValue` 字段和有效的 public 无参数方法,包括匹配的单 String `JsonCreator` 构造函数和 public static factory。固定的 `JsonRawValue` 字段和 getter 支持可信的原始 String 值;固定的 `JsonBase64` 字段和 getter 与 JVM 上一样支持 Base64 `byte[]` 值。`JsonFormat` 日期/时间字段使用与 JVM 相同的直接字段、单层包装和 `timezone` 行为。对于直接放在目标类上的注解,请使用 `JsonType` 标注每个可达的所属模型,以便 Native Image 保留这些成员和 Base64 Codec 构造函数。 +支持 `JsonValue` 字段和有效的 public 无参数方法,包括匹配的单 String `JsonCreator` 构造函数和 public static factory。固定的 `JsonRawValue` 字段和 getter 支持可信的原始 String 值;`JsonByteArray` 字段和 getter 与 JVM 上一样选择 Base64 字符串或数字字节数组。`JsonFormat` 日期/时间字段使用与 JVM 相同的直接字段、单层包装和 `timezone` 行为。对于直接放在目标类上的注解,请使用 `JsonType` 标注每个可达的所属模型,以便 Native Image 保留这些成员和所选字节数组编解码器的构造函数。 直接标注的 `JsonValue` Record 会使用生成的 component accessor 和 canonical constructor 操作。由 Mixin 提供的有效声明则使用上述 Mixin 工作流。 `JsonAnyProperty` 和 `JsonAnyGetter` 会将其 Map 展平到外层对象中。可以在该字段或 getter 上使用 `@JsonCodec(valueCodec = ...)` 来定制每个动态值。`JsonAnySetter` 的第二个参数可以对自身的值结构使用常规配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/kotlin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/kotlin.md index 4d96c8407d5..50fcc4c06f4 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/kotlin.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/kotlin.md @@ -38,7 +38,7 @@ repositories { } dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` @@ -50,7 +50,7 @@ plugins { } dependencies { - ksp("org.apache.fory:fory-json-kotlin-ksp:1.7.0") + ksp("org.apache.fory:fory-json-kotlin-ksp:1.7.1") } ``` @@ -77,6 +77,11 @@ val text = json.toJson(Account(7u, "Alice"), accountType) val decoded = json.fromJson(text, accountType) ``` +当有符号 `Long` 和无符号 `ULong` 值需要以带引号的十进制字符串输出时,请使用 +`ForyJsonKotlin.builder().writeLongAsString(true)`。该设置还适用于声明的 collection 和 Map 值、 +可空值、以这些类型为底层值的 Kotlin 值类、`ULongArray`,以及核心 JSON 运行时支持的 Java Long +类包装器。Reader 同时接受带引号和不带引号的整数 token。 + `jsonTypeRef()` 是类型令牌,不是编解码器查找操作。应创建一次并复用。Java `Class` 或普通 Java `TypeRef` 无法表达 `List`、`UInt` 或降低为基本类型载体的逻辑值类等区别。 也可以通过 builder 显式安装模块: @@ -212,7 +217,7 @@ Fory 执行经过验证的编译器构造操作,因此值类初始化检查仍 | 文本 | `String`、精确 `CharSequence`、`StringBuilder` 和 `StringBuffer` 使用字符串表示 | | 任意精度/低精度数值 | `BigInteger`、`BigDecimal`、Fory `Float16` 和 `BFloat16` 使用核心数值表示与限制 | | 枚举 | 带引号的枚举常量名 | -| Java/Kotlin 数组 | 常规 JSON 数组;`ByteArray` 默认表示数字,除非 `JsonBase64` 选择二进制表示;无符号语义数组见下文 | +| Java/Kotlin 数组 | 除 `ByteArray` 默认使用 Base64 字符串外,均为普通 JSON 数组;`@field:JsonByteArray(JsonByteArray.Format.ARRAY)` 可选择数字数组;无符号语义数组见下文 | | Optional 与原子类 | `Optional`、基本类型 Optional、原子标量/引用和原子数组保持核心透明表示,并受上述可空性规则约束 | | 带引号的 JDK 值 | `Currency`、`File`、`URI`、`Path`、`Pattern`、`UUID`、`Locale`、`Charset` 和 `TimeZone` 保持核心字符串表示 | | 旧版日期/时间 | `Date`、`Calendar` 及可用的 `java.sql.Date`、`Time` 和 `Timestamp` 保持自 Unix 纪元起的毫秒数表示 | diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/object-mapping.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/object-mapping.md index caef3326915..5da73b14b25 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/object-mapping.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/object-mapping.md @@ -187,6 +187,7 @@ JSON 对象成员名都是字符串。声明的 Map 键支持 `String`、`byte` | Builder 方法 | 默认值 | 用户可见的效果 | | -------------------------------------- | ----------------------------------------- | ---------------------------------------------- | | `writeNullFields(boolean)` | `false` | 是否默认包含值为 null 的对象属性 | +| `writeLongAsString(boolean)` | `false` | 将内置 64 位整数值写为十进制字符串 | | `withCodegen(boolean)` | `true` | 启用生成的对象编解码器 | | `withAsyncCompilation(boolean)` | `true` | 异步编译生成的编解码器 | | `withFieldMode(boolean)` | `false` | 为 true 时,仅发现字段而不使用 getter/setter | @@ -197,6 +198,12 @@ JSON 对象成员名都是字符串。声明的 Map 键支持 `String`、`byte` | `registerCodec(type, codec)` | None | 替换允许注册的精确类的完整 JSON 编解码器 | | `registerMixin(mixinType)` | None | 将一个注解 Mixin 应用于其精确声明的目标 | +当 64 位整数必须经过 JavaScript 且不能损失 `Number` 精度时,请启用 `writeLongAsString(true)`。 +该设置会将内置 `long`/`Long`、`AtomicLong`、`AtomicLongArray` 和 `OptionalLong` 值写为带引号的 +十进制字符串,也会沿着数组、collection、Map 值、`Optional`、`AtomicReference` 和 +等效语言模块容器中的声明 Long 子项生效。无论是否启用该设置,Reader 都同时接受数字和带引号的 +整数 token。自定义编解码器以及声明位置上的编解码器或格式注解仍保持自己的输出形式。 + 并发级别和缓冲区保留限制必须为正数。字段名缓存上限分别应用于每个 reader;零会禁用该缓存。该上限 只限制缓存的字段名数量,不限制输入中可接受的名称。缓冲区保留设置不会限制 JSON 输入或输出大小, 只限制一次操作结束后保留以供复用的 writer 存储空间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/scala.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/scala.md index 4c90d58a602..5990297ee9a 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/scala.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/scala.md @@ -24,7 +24,7 @@ Fory JSON 通过可选的 `fory-json-scala` 制品支持 Scala 2.13 和 Scala 3 ## 设置 {#setup} ```sbt -libraryDependencies += "org.apache.fory" %% "fory-json-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-json-scala" % "1.7.1" ``` `ForyJsonScala.builder()` 安装 Scala 模块并返回标准 Fory JSON builder: @@ -40,6 +40,10 @@ val person = json.fromJson(text, classOf[Person]) ``` 请复用得到的 `ForyJson` 实例。它在构建后不可变且线程安全。 +使用 `ForyJsonScala.builder().writeLongAsString(true)` 可将 Scala `Long` 值以带引号的十进制字符串 +输出,包括声明的 collection 和 Map 值、`Option[Long]`、以 `Long` 为底层值的值类以及 Java Long +类包装器。Reader 同时接受带引号和不带引号的整数 token。参数化声明包含 `Long` 时应使用 +`ScalaTypeRef`,因为普通 JVM 签名可能会将 Scala 值类型参数擦除为 `Object`。 ## Case class 与注解 {#case-classes-and-annotations} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/security.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/security.md index 5486bb23300..da20ee49564 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/security.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/json/security.md @@ -53,7 +53,7 @@ ClassLoader。此后更改线程上下文 ClassLoader 不会影响该 `ForyJson` 和 `InetSocketAddress`。应用可以通过自己拥有的精确自定义 codec 支持 `URL`。任意 `Number` 和 `CharSequence` 子类同样需要精确的内置或自定义 codec。 -## 深度与对象图内存限制 +## 深度与对象图内存限制 {#depth-and-graph-memory-limits} `maxDepth` 限制数组和对象的嵌套深度,默认值为 `20`,配置值必须为正数。它并不是输入字节数或 内存配额。`ForyJsonBuilder.withMaxGraphMemoryBytes` 独立限制每次根读取所创建并保留的对象图 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/cpp/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/cpp/index.md index 966c5e58570..e83b4266d91 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/cpp/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/cpp/index.md @@ -60,7 +60,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) @@ -90,11 +90,11 @@ module( bazel_dep(name = "rules_cc", version = "0.1.1") -bazel_dep(name = "fory", version = "1.7.0") +bazel_dep(name = "fory", version = "1.7.1") git_override( module_name = "fory", remote = "https://github.com/apache/fory.git", - commit = "v1.7.0", # Or use a specific commit hash for reproducibility + commit = "v1.7.1", # Or use a specific commit hash for reproducibility ) ``` @@ -125,7 +125,7 @@ bazel run //:my_app 本地开发时,可以改用 `local_path_override`: ```bazel -bazel_dep(name = "fory", version = "1.7.0") +bazel_dep(name = "fory", version = "1.7.1") local_path_override( module_name = "fory", path = "/path/to/fory", diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/csharp/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/csharp/index.md index 33de125c89f..5a3a9322420 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/csharp/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/csharp/index.md @@ -44,7 +44,7 @@ Apache Fory™ C# 是面向 .NET 的高性能跨语言序列化库。它支持 ```xml - + ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/dart/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/dart/index.md index 881f6a216ac..11d3e50a1c1 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/dart/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/dart/index.md @@ -44,7 +44,7 @@ Apache Fory™ Dart 可以将 Dart 对象序列化为字节并反序列化,也 ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/java/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/java/index.md index d49d5ec4e7f..97fa151b4b8 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/java/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/java/index.md @@ -51,7 +51,7 @@ Fory core 支持 Java 8 及更高版本。Java Record 序列化需要 Java 17 org.apache.fory fory-core - 1.7.0 + 1.7.1 ``` @@ -59,7 +59,7 @@ Fory core 支持 Java 8 及更高版本。Java Record 序列化需要 Java 17 ```kotlin // Binary object serialization -implementation("org.apache.fory:fory-core:1.7.0") +implementation("org.apache.fory:fory-core:1.7.1") ``` #### JDK 25 及更高版本 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/javascript/supported-types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/javascript/supported-types.md index 7c2ca911aa7..7f33527cf99 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/javascript/supported-types.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/javascript/supported-types.md @@ -70,6 +70,8 @@ Type.bfloat16(); 与使用低精度数值格式的语言或载荷互操作时,`float16` 和 `bfloat16` 很有用。 +`Type.float16()` 会将数值舍入为最接近的半精度值;输入恰好位于两个值的中点时,选择最低有效位为偶数的值。Float16 数组转换使用相同的舍入规则。带符号零、无穷大和 NaN 会被保留;数值可能下溢为带符号零,也可能上溢为带符号无穷大。 + ## Array 和 Typed Array ### 列表 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/kotlin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/kotlin/index.md index e38e00b4caa..d050e80c2ab 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/kotlin/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/kotlin/index.md @@ -53,14 +53,14 @@ Fory Kotlin 继承了 Fory Java 的全部功能,并增加了 Kotlin 特有优 org.apache.fory fory-kotlin - 1.7.0 + 1.7.1 ``` ### Gradle ```kotlin -implementation("org.apache.fory:fory-kotlin:1.7.0") +implementation("org.apache.fory:fory-kotlin:1.7.1") ``` ### JDK25+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/basic-serialization.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/basic-serialization.md index b403d479ecb..5052e5f8e83 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/basic-serialization.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/basic-serialization.md @@ -145,7 +145,7 @@ Rust 启用 `chrono::NaiveDate`、`chrono::NaiveDateTime` 和 `chrono::Duration` ```toml [dependencies] -fory = { version = "1.7.0", features = ["chrono"] } +fory = { version = "1.7.1", features = ["chrono"] } ``` ### 自定义类型 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/index.md index db34d4e8bd2..eae7b0d44f7 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/rust/index.md @@ -36,9 +36,9 @@ Rust 实现通过自动内存管理和编译期类型安全提供灵活的高性 | Crate | 说明 | 版本 | | --------------------------------------------------------------------------- | ---------------------------------- | --------------------------------------------- | -| [`fory`](https://github.com/apache/fory/blob/main/rust/fory) | 面向用户的 API、运行时类型和派生宏 | [1.7.0](https://crates.io/crates/fory) | -| [`fory-core`](https://github.com/apache/fory/blob/main/rust/fory-core/) | 用于高级集成的底层运行时 crate | [1.7.0](https://crates.io/crates/fory-core) | -| [`fory-derive`](https://github.com/apache/fory/blob/main/rust/fory-derive/) | 供直接使用运行时的底层过程宏 crate | [1.7.0](https://crates.io/crates/fory-derive) | +| [`fory`](https://github.com/apache/fory/blob/main/rust/fory) | 面向用户的 API、运行时类型和派生宏 | [1.7.1](https://crates.io/crates/fory) | +| [`fory-core`](https://github.com/apache/fory/blob/main/rust/fory-core/) | 用于高级集成的底层运行时 crate | [1.7.1](https://crates.io/crates/fory-core) | +| [`fory-derive`](https://github.com/apache/fory/blob/main/rust/fory-derive/) | 供直接使用运行时的底层过程宏 crate | [1.7.1](https://crates.io/crates/fory-derive) | 大多数应用程序只需依赖 `fory`。它重新导出生成代码所需的派生宏和公共运行时类型。只有明确要基于底层运行时 crate 构建时,才直接使用 `fory-core` 或 `fory-derive`。 @@ -48,7 +48,7 @@ Rust 实现通过自动内存管理和编译期类型安全提供灵活的高性 ```toml [dependencies] -fory = "1.7.0" +fory = "1.7.1" ``` ### 基本示例 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/scala/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/scala/index.md index 9814e6aa0a8..b2b37cf2894 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/scala/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/object-serialization/scala/index.md @@ -49,7 +49,7 @@ Fory Scala 继承了 Fory Java 的全部功能,并增加了 Scala 特有优化 使用 sbt 添加依赖: ```sbt -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1" ``` ### JDK25+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/row-format/java.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/row-format/java.md index 558d8119e6a..698f8d1e62f 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/row-format/java.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/row-format/java.md @@ -41,14 +41,14 @@ Maven: org.apache.fory fory-format - 1.7.0 + 1.7.1 ``` Gradle: ```kotlin -implementation("org.apache.fory:fory-format:1.7.0") +implementation("org.apache.fory:fory-format:1.7.1") ``` ## 基本用法 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/cpp.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/cpp.md index 4c175ac8d65..4cd7b0e1fd1 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/cpp.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/cpp.md @@ -42,7 +42,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/csharp.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/csharp.md index d8425763f7f..733e59d574e 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/csharp.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/csharp.md @@ -34,7 +34,7 @@ dotnet --version ```bash dotnet new console -n ForyExample cd ForyExample -dotnet add package Apache.Fory --version 1.7.0 +dotnet add package Apache.Fory --version 1.7.1 ``` 将 `Program.cs` 替换为: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/dart.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/dart.md index cfdd2ba67ef..bd688453ac2 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/dart.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/dart.md @@ -34,7 +34,7 @@ dart pub --help ```yaml dependencies: - fory: 1.7.0 + fory: 1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/go.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/go.md index 6b65be740da..0311f1a0326 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/go.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/go.md @@ -36,7 +36,7 @@ go env GOPROXY mkdir fory-example cd fory-example go mod init example.com/fory-example -go get github.com/apache/fory/go/fory@v1.7.0 +go get github.com/apache/fory/go/fory@v1.7.1 ``` 如果 Go proxy 尚未收录新的 submodule tag,请稍后重试,或者暂时使用 `GOPROXY=direct`。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/java.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/java.md index e9f3da03f65..a77f2810c29 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/java.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/java.md @@ -39,14 +39,14 @@ Maven: org.apache.fory fory-core - 1.7.0 + 1.7.1 ``` Gradle: ```kotlin -implementation("org.apache.fory:fory-core:1.7.0") +implementation("org.apache.fory:fory-core:1.7.1") ``` 运行下面完整的 xlang 往返示例: @@ -85,7 +85,7 @@ public final class ForyExample { Fory JSON 将 Java 对象映射为标准 JSON 文本和 UTF-8 字节。如果应用只需要 JSON,请添加 `fory-json`,无需添加 `fory-core`: ```kotlin -implementation("org.apache.fory:fory-json:1.7.0") +implementation("org.apache.fory:fory-json:1.7.1") ``` 在 `ForyExample.java` 中添加 import: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/javascript.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/javascript.md index 893e217461f..a05e5b7c0a9 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/javascript.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/javascript.md @@ -33,7 +33,7 @@ npm --version 安装 core 软件包: ```bash -npm install @apache-fory/core@1.7.0 +npm install @apache-fory/core@1.7.1 ``` 定义 Schema 并运行 xlang 往返示例: @@ -65,7 +65,7 @@ JavaScript 使用 xlang 模式。接下来可阅读 [JavaScript/TypeScript 对 若要使用可选的 Node.js 字符串快速路径,请安装版本匹配的软件包: ```bash -npm install @apache-fory/core@1.7.0 @apache-fory/hps@1.7.0 +npm install @apache-fory/core@1.7.1 @apache-fory/hps@1.7.1 ``` ## 其他能力 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/kotlin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/kotlin.md index 47d928e78eb..2a9ab996084 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/kotlin.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/kotlin.md @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation("org.apache.fory:fory-kotlin:1.7.0") + implementation("org.apache.fory:fory-kotlin:1.7.1") } ``` @@ -81,7 +81,7 @@ Fory JSON 是独立于二进制对象序列化的文本格式。与普通 JSON A ```kotlin title="build.gradle.kts" dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/python.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/python.md index b29379879f5..0b310b60b49 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/python.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/python.md @@ -33,7 +33,7 @@ python -m pip --version 安装已发布的软件包: ```bash -python -m pip install pyfory==1.7.0 +python -m pip install pyfory==1.7.1 ``` 运行 xlang 往返示例: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/rust.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/rust.md index 8ee9df68594..298d47cde63 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/rust.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/rust.md @@ -34,7 +34,7 @@ cargo --version ```toml title="Cargo.toml" [dependencies] -fory = "1.7.0" +fory = "1.7.1" ``` ```rust diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/scala.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/scala.md index 0fdced2ccaa..c2e9471adf6 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/scala.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/scala.md @@ -35,7 +35,7 @@ sbt --version ```sbt ThisBuild / scalaVersion := "3.3.1" -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1" ``` 创建 `src/main/scala/ScalaExample.scala`: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/swift.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/swift.md index 364617276be..b70c97fd675 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/swift.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/swift.md @@ -39,7 +39,7 @@ swift package init --type executable --name ForyExample ```swift title="Package.swift" dependencies: [ - .package(url: "https://github.com/apache/fory.git", exact: "1.7.0") + .package(url: "https://github.com/apache/fory.git", exact: "1.7.1") ], targets: [ .executableTarget( diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/build-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/build-integration.md index e9af0bf8e06..4ec2647c0cf 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/build-integration.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/build-integration.md @@ -211,7 +211,7 @@ cc_library( ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/cli.md index 19f04b0624a..7b63012b769 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/cli.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/cli.md @@ -659,5 +659,5 @@ fory = "x.y.z" ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/schema-idl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/schema-idl.md index d77254570a8..675d4dc3b4b 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/schema-idl.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/compiler/schema-idl.md @@ -961,6 +961,8 @@ rpc_method := 'rpc' IDENTIFIER '(' ['stream'] named_type ')' field_type field_name = field_number; ``` +`field_number` 是字段 tag ID,必须在消息内唯一,并满足 `0 <= field_number < 2^29`(`0` 至 `536870911`)。已分配的编号应保持稳定;删除字段后应保留其编号,不要分配给其他字段。 + ### 带修饰符 ```protobuf @@ -1130,22 +1132,22 @@ Rust 中的 `Arc`。 ## 字段编号 -每个字段必须有一个唯一的正整数标识符: +每个字段都必须使用协议范围内唯一的 tag ID: ```protobuf message Example { - string first = 1; - string second = 2; - string third = 3; + string first = 0; + string second = 1; + string third = 2; } ``` **规则和最佳实践:** - 消息中的数字必须是唯一的。 -- 数字必须是正整数。 +- 编号必须满足 `0 <= field_number < 2^29`(`0` 至 `536870911`)。 - 允许有间隙,并且在删除字段时很有用。 -- 优先选择从 `1` 开始的顺序编号。 +- 建议连续编号。 - 切勿将已删除的字段编号重复用于其他字段。 ## 类型系统 {#type-system} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/csharp.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/csharp.md index 90e47065b1f..286e3707c62 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/csharp.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/csharp.md @@ -36,7 +36,7 @@ gRPC 客户端、服务基类、方法描述符、元数据、截止时间、取 ```xml - + ``` @@ -45,7 +45,7 @@ gRPC 客户端、服务基类、方法描述符、元数据、截止时间、取 ```xml - + diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/dart.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/dart.md index 6990adafcb0..4f647c9f265 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/dart.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/dart.md @@ -29,7 +29,7 @@ license: | ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 grpc: ^4.0.0 dev_dependencies: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/rust.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/rust.md index b52738581d1..92db84efcd3 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/rust.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/grpc/rust.md @@ -29,7 +29,7 @@ license: | ```toml [dependencies] -fory = "1.7.0" +fory = "1.7.1" bytes = "1" tonic = { version = "0.14", features = ["transport"] } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/android.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/android.md index ca12aafd46f..abdab317b24 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/android.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/android.md @@ -115,12 +115,12 @@ public final class Invoice { ```java import org.apache.fory.json.ForyJson; -import org.apache.fory.json.annotation.JsonBase64; +import org.apache.fory.json.annotation.JsonByteArray; import org.apache.fory.json.annotation.JsonMixin; @JsonMixin(target = ThirdPartyInvoice.class) public abstract class ThirdPartyInvoiceMixin { - @JsonBase64 byte[] signature; + @JsonByteArray(JsonByteArray.Format.BASE64) byte[] signature; } ForyJson json = @@ -158,7 +158,7 @@ Mixin 可在与目标公共方法精确匹配的公共抽象无参 `void` 方法 本节的反射规则适用于 Java 模型。Kotlin 模型使用 Kotlin JSON 模块;启用代码压缩的 Android 构建应使用 KSP,而不是编写宽泛的包级 keep 规则。 -Java `@JsonType` 模型支持有效的 `JsonValidator`、`JsonValue`、`JsonRawValue`、`JsonBase64` 和 `JsonFormat` 注解。未标注 `@JsonType` 时,这些注解仍可通过反射工作,但经过发布压缩的应用必须自行保留精确的注解成员、注解属性和编解码器构造函数。`JsonValue` 方法可以使用不符合 JavaBean 约定的名称,因此手写规则必须明确指定该方法。 +Java `@JsonType` 模型支持有效的 `JsonValidator`、`JsonValue`、`JsonRawValue`、`JsonByteArray` 和 `JsonFormat` 注解。未标注 `@JsonType` 时,这些注解仍可通过反射工作,但经过发布压缩的应用必须自行保留精确的注解成员、注解属性和编解码器构造函数。`JsonValue` 方法可以使用不符合 JavaBean 约定的名称,因此手写规则必须明确指定该方法。 Kotlin 模型使用相同的有效注解。启用代码压缩时,请使用 KSP。`JsonFormat` 与 JVM 上一样支持直接字段和一层包装,包括为 `Instant`、`ZonedDateTime` 和 `OffsetDateTime` 指定 `timezone`。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/annotations.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/annotations.md index 13671782f4e..a51f79afde0 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/annotations.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/annotations.md @@ -19,7 +19,7 @@ license: | limitations under the License. --- -Fory JSON 在 `org.apache.fory.json.annotation` 中提供以下映射和验证注解:`JsonAnyGetter`、`JsonAnyProperty`、`JsonAnySetter`、`JsonBase64`、`JsonCodec`、`JsonCreator`、`JsonFormat`、`JsonIgnore`、`JsonProperty`、`JsonPropertyOrder`、`JsonRawValue`、`JsonSubTypes`、`JsonUnwrapped`、`JsonValidator` 和 `JsonValue`。`JsonType` 是独立的构建期模型标记。这些属于 Fory JSON API,不是 Jackson、Gson 或 Fory 二进制协议兼容注解。 +Fory JSON 在 `org.apache.fory.json.annotation` 中提供以下映射和验证注解:`JsonAnyGetter`、`JsonAnyProperty`、`JsonAnySetter`、`JsonByteArray`、`JsonCodec`、`JsonCreator`、`JsonFormat`、`JsonIgnore`、`JsonProperty`、`JsonPropertyOrder`、`JsonRawValue`、`JsonSubTypes`、`JsonUnwrapped`、`JsonValidator` 和 `JsonValue`。`JsonType` 是独立的构建期模型标记。这些属于 Fory JSON API,不是 Jackson、Gson 或 Fory 二进制协议兼容注解。 `JsonType` 不会被继承,因此每个需要参与平台构建流程且符合要求的具体模型都必须单独标注。Java 源码需要使用 `fory-annotation-processor`。未标注的普通 Java 类仍可使用反射;在 Android 上,它们需要由应用编写精确 R8 规则。经过 Android 脱糖处理的 Record 必须直接声明 `JsonType`,或使用已编译的精确 `JsonMixin` 配对。在 Native Image 之外,直接标注的 Java 模型如果使用默认对象编解码器却未运行注解处理器,会在创建编解码器时失败。 @@ -304,26 +304,34 @@ Map 值。它不能放在 setter、创建器参数或 Any 声明上,也不能 `JsonValue` 和 `JsonRawValue` 可以组合在同一个 String 成员上,将所属对象写为可信的原始根值。 这种组合仅支持序列化:普通的单 String 参数 `JsonCreator` 无法将输入对象或数组转换为 String。 -## `JsonBase64` +## `JsonByteArray` -`JsonBase64` 为一个精确的 `byte[]` 字段或 getter 选择带引号的标准 Base64 JSON 字符串表示: +未标注的 `byte[]` 值使用带引号的标准 Base64 JSON 字符串。`JsonByteArray` 为一个精确的 `byte[]` +字段或 getter 选择 `BASE64` 或 `ARRAY` 表示,并同时作用于读写: ```java -import org.apache.fory.json.annotation.JsonBase64; +import org.apache.fory.json.annotation.JsonByteArray; public final class Attachment { - @JsonBase64 + @JsonByteArray(JsonByteArray.Format.ARRAY) + public byte[] numbers; + + @JsonByteArray(JsonByteArray.Format.BASE64) public byte[] content; } ``` -字节 `{1, 2, 3}` 会写为 `{"content":"AQID"}`,并可解码回原始数组。Fory 会将 Base64 字符直接写入 -JSON 输出,也会直接从 JSON 输入解码,不创建中间 String。标准 Base64 填充会被保留。Java null 遵循 -属性的常规包含规则,从 JSON null 读取时也得到 null。 +对于字节 `{1, -2, 3}`,`numbers` 写为 `[1,-2,3]`,`content` 写为 `"Af4D"`。`ARRAY` 按有符号 +字节范围 `[-128, 127]` 读取 JSON 数组;`BASE64` 读取标准 Base64 字符串,并在写入时保留填充符。 +两种表示都接受 JSON null,null 输出遵循属性的常规包含规则。默认 Base64 编解码器不接受数字数组 +输入;使用该格式的属性应选择 `ARRAY`。 + +使用该注解时必须指定格式。它只作用于被标注的字节数组属性,不作用于容器元素或 Map 值。Mixin +声明可以选择或移除该注解。它不能与 `JsonRawValue`、声明位置上的 `JsonCodec`、`JsonFormat` 或 Any +声明共用于同一逻辑属性。同一属性的字段和 getter 选择冲突格式时会被拒绝。 -该注解不是类型使用注解,不会改变普通的未标注 `byte[]` 属性、容器元素或 Map 值。它不能与 -`JsonRawValue`、声明位置上的 `JsonCodec`、`JsonFormat` 或 Any 声明共用于同一逻辑属性。等效的显式 -编解码器为 `@JsonCodec(Base64ByteArrayCodec.class)`。 +Base64 值是二进制叶值,不计入对象图内存配额;数字数组则会将其数组存储计入该配额。详见 +[安全](security.md#depth-and-graph-memory-limits)。 ## `JsonFormat` @@ -377,7 +385,7 @@ public final class Schedule { 原始类型或通配符直接子元素、JSON Any 值以及展开值会被有意拒绝。不支持格式化语义模糊的类型,包括 旧版和 SQL 日期类型、`Duration`、`Period`、`TimeZone`、`ZoneId` 和 `ZoneOffset`。具有完整注册表示、 注解选择表示、多态表示或 `JsonValue` 表示的包装类型也会被拒绝,因为这些表示方式拥有整个包装对象。 -`JsonFormat` 不能与 `JsonCodec`、`JsonBase64`、`JsonRawValue`、`JsonAnyProperty`、`JsonUnwrapped` 或 +`JsonFormat` 不能与 `JsonCodec`、`JsonByteArray`、`JsonRawValue`、`JsonAnyProperty`、`JsonUnwrapped` 或 `JsonValue` 共用于同一字段。 ## `JsonUnwrapped` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/getting-started.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/getting-started.md index 96363f75e03..90b5c840463 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/getting-started.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/getting-started.md @@ -41,7 +41,7 @@ Maven: org.apache.fory fory-json - 1.7.0 + 1.7.1 ``` @@ -55,7 +55,7 @@ repositories { mavenCentral() } -implementation("org.apache.fory:fory-json:1.7.0") +implementation("org.apache.fory:fory-json:1.7.1") ``` ### Kotlin @@ -64,7 +64,7 @@ Kotlin/JVM 应用添加可选的 Kotlin JSON 运行时,并使用其统一 buil ```kotlin title="build.gradle.kts" dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/graalvm.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/graalvm.md index e430f668d6e..e76f9b7ff3c 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/graalvm.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/graalvm.md @@ -150,7 +150,7 @@ public class JsonExample { 支持在类型、字段、有效的普通 getter、setter 值参数和 `JsonCreator` 参数上使用 `@JsonCodec` 注解。Feature 会保留每个选定的完整值、元素、内容、Map 键和 Map 值 Codec 的构造函数。这与 JVM 和 Android 使用的注解模型相同。 -支持 `JsonValue` 字段和有效的 public 无参数方法,包括匹配的单 String `JsonCreator` 构造函数和 public static factory。固定的 `JsonRawValue` 字段和 getter 支持可信的原始 String 值;固定的 `JsonBase64` 字段和 getter 与 JVM 上一样支持 Base64 `byte[]` 值。`JsonFormat` 日期/时间字段使用与 JVM 相同的直接字段、单层包装和 `timezone` 行为。对于直接放在目标类上的注解,请使用 `JsonType` 标注每个可达的所属模型,以便 Native Image 保留这些成员和 Base64 Codec 构造函数。 +支持 `JsonValue` 字段和有效的 public 无参数方法,包括匹配的单 String `JsonCreator` 构造函数和 public static factory。固定的 `JsonRawValue` 字段和 getter 支持可信的原始 String 值;`JsonByteArray` 字段和 getter 与 JVM 上一样选择 Base64 字符串或数字字节数组。`JsonFormat` 日期/时间字段使用与 JVM 相同的直接字段、单层包装和 `timezone` 行为。对于直接放在目标类上的注解,请使用 `JsonType` 标注每个可达的所属模型,以便 Native Image 保留这些成员和所选字节数组编解码器的构造函数。 直接标注的 `JsonValue` Record 会使用生成的 component accessor 和 canonical constructor 操作。由 Mixin 提供的有效声明则使用上述 Mixin 工作流。 `JsonAnyProperty` 和 `JsonAnyGetter` 会将其 Map 展平到外层对象中。可以在该字段或 getter 上使用 `@JsonCodec(valueCodec = ...)` 来定制每个动态值。`JsonAnySetter` 的第二个参数可以对自身的值结构使用常规配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/kotlin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/kotlin.md index fef3e2c98eb..50fcc4c06f4 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/kotlin.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/kotlin.md @@ -23,7 +23,7 @@ Fory JSON Kotlin 将 Kotlin/JVM 类型映射为普通 JSON,同时保留 Kotlin ## 安装 {#installation} -运行时支持 Kotlin/JVM 元数据 ABI 2.3,并使用 Kotlin 2.3.20 构建。所有模块应使用相同的 Fory 版本: +运行时接受 Kotlin 严格元数据读取器所支持的模型元数据,并使用 Kotlin 2.3.20 构建。所有模块应使用相同的 Fory 版本: ```kotlin title="build.gradle.kts" plugins { @@ -38,7 +38,7 @@ repositories { } dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` @@ -50,7 +50,7 @@ plugins { } dependencies { - ksp("org.apache.fory:fory-json-kotlin-ksp:1.7.0") + ksp("org.apache.fory:fory-json-kotlin-ksp:1.7.1") } ``` @@ -77,6 +77,11 @@ val text = json.toJson(Account(7u, "Alice"), accountType) val decoded = json.fromJson(text, accountType) ``` +当有符号 `Long` 和无符号 `ULong` 值需要以带引号的十进制字符串输出时,请使用 +`ForyJsonKotlin.builder().writeLongAsString(true)`。该设置还适用于声明的 collection 和 Map 值、 +可空值、以这些类型为底层值的 Kotlin 值类、`ULongArray`,以及核心 JSON 运行时支持的 Java Long +类包装器。Reader 同时接受带引号和不带引号的整数 token。 + `jsonTypeRef()` 是类型令牌,不是编解码器查找操作。应创建一次并复用。Java `Class` 或普通 Java `TypeRef` 无法表达 `List`、`UInt` 或降低为基本类型载体的逻辑值类等区别。 也可以通过 builder 显式安装模块: @@ -212,7 +217,7 @@ Fory 执行经过验证的编译器构造操作,因此值类初始化检查仍 | 文本 | `String`、精确 `CharSequence`、`StringBuilder` 和 `StringBuffer` 使用字符串表示 | | 任意精度/低精度数值 | `BigInteger`、`BigDecimal`、Fory `Float16` 和 `BFloat16` 使用核心数值表示与限制 | | 枚举 | 带引号的枚举常量名 | -| Java/Kotlin 数组 | 常规 JSON 数组;`ByteArray` 默认表示数字,除非 `JsonBase64` 选择二进制表示;无符号语义数组见下文 | +| Java/Kotlin 数组 | 除 `ByteArray` 默认使用 Base64 字符串外,均为普通 JSON 数组;`@field:JsonByteArray(JsonByteArray.Format.ARRAY)` 可选择数字数组;无符号语义数组见下文 | | Optional 与原子类 | `Optional`、基本类型 Optional、原子标量/引用和原子数组保持核心透明表示,并受上述可空性规则约束 | | 带引号的 JDK 值 | `Currency`、`File`、`URI`、`Path`、`Pattern`、`UUID`、`Locale`、`Charset` 和 `TimeZone` 保持核心字符串表示 | | 旧版日期/时间 | `Date`、`Calendar` 及可用的 `java.sql.Date`、`Time` 和 `Timestamp` 保持自 Unix 纪元起的毫秒数表示 | diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/object-mapping.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/object-mapping.md index caef3326915..5da73b14b25 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/object-mapping.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/object-mapping.md @@ -187,6 +187,7 @@ JSON 对象成员名都是字符串。声明的 Map 键支持 `String`、`byte` | Builder 方法 | 默认值 | 用户可见的效果 | | -------------------------------------- | ----------------------------------------- | ---------------------------------------------- | | `writeNullFields(boolean)` | `false` | 是否默认包含值为 null 的对象属性 | +| `writeLongAsString(boolean)` | `false` | 将内置 64 位整数值写为十进制字符串 | | `withCodegen(boolean)` | `true` | 启用生成的对象编解码器 | | `withAsyncCompilation(boolean)` | `true` | 异步编译生成的编解码器 | | `withFieldMode(boolean)` | `false` | 为 true 时,仅发现字段而不使用 getter/setter | @@ -197,6 +198,12 @@ JSON 对象成员名都是字符串。声明的 Map 键支持 `String`、`byte` | `registerCodec(type, codec)` | None | 替换允许注册的精确类的完整 JSON 编解码器 | | `registerMixin(mixinType)` | None | 将一个注解 Mixin 应用于其精确声明的目标 | +当 64 位整数必须经过 JavaScript 且不能损失 `Number` 精度时,请启用 `writeLongAsString(true)`。 +该设置会将内置 `long`/`Long`、`AtomicLong`、`AtomicLongArray` 和 `OptionalLong` 值写为带引号的 +十进制字符串,也会沿着数组、collection、Map 值、`Optional`、`AtomicReference` 和 +等效语言模块容器中的声明 Long 子项生效。无论是否启用该设置,Reader 都同时接受数字和带引号的 +整数 token。自定义编解码器以及声明位置上的编解码器或格式注解仍保持自己的输出形式。 + 并发级别和缓冲区保留限制必须为正数。字段名缓存上限分别应用于每个 reader;零会禁用该缓存。该上限 只限制缓存的字段名数量,不限制输入中可接受的名称。缓冲区保留设置不会限制 JSON 输入或输出大小, 只限制一次操作结束后保留以供复用的 writer 存储空间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/scala.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/scala.md index 964d8b6e64e..5990297ee9a 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/scala.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/scala.md @@ -24,7 +24,7 @@ Fory JSON 通过可选的 `fory-json-scala` 制品支持 Scala 2.13 和 Scala 3 ## 设置 {#setup} ```sbt -libraryDependencies += "org.apache.fory" %% "fory-json-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-json-scala" % "1.7.1" ``` `ForyJsonScala.builder()` 安装 Scala 模块并返回标准 Fory JSON builder: @@ -40,11 +40,17 @@ val person = json.fromJson(text, classOf[Person]) ``` 请复用得到的 `ForyJson` 实例。它在构建后不可变且线程安全。 +使用 `ForyJsonScala.builder().writeLongAsString(true)` 可将 Scala `Long` 值以带引号的十进制字符串 +输出,包括声明的 collection 和 Map 值、`Option[Long]`、以 `Long` 为底层值的值类以及 Java Long +类包装器。Reader 同时接受带引号和不带引号的整数 token。参数化声明包含 `Long` 时应使用 +`ScalaTypeRef`,因为普通 JVM 签名可能会将 Scala 值类型参数擦除为 `Object`。 ## Case class 与注解 {#case-classes-and-annotations} case class 通过调用完整主构造函数解码。对于缺失且有默认值的参数,Fory 调用 Scala 生成的构造函数默认值方法,不解析默认值表达式,也不修改构造函数 `val` 字段。后续参数列表中的默认值会按 Scala 语义接收前面已确定的构造函数参数。缺少无默认值的参数会报错。类体中的可变属性在构造后赋值。 +case class 可以声明在顶层,也可以嵌套在任意层数的 `object` 内,但每一层外部作用域都必须是 `object`。如果外层是 `class`、trait 或方法,读写都会被拒绝,因为 Fory 无法访问重建值所需的外部实例或伴生对象。 + Fory JSON 注解可以直接放在 Scala 构造函数属性上: ```scala diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/security.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/security.md index 5486bb23300..da20ee49564 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/security.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/security.md @@ -53,7 +53,7 @@ ClassLoader。此后更改线程上下文 ClassLoader 不会影响该 `ForyJson` 和 `InetSocketAddress`。应用可以通过自己拥有的精确自定义 codec 支持 `URL`。任意 `Number` 和 `CharSequence` 子类同样需要精确的内置或自定义 codec。 -## 深度与对象图内存限制 +## 深度与对象图内存限制 {#depth-and-graph-memory-limits} `maxDepth` 限制数组和对象的嵌套深度,默认值为 `20`,配置值必须为正数。它并不是输入字节数或 内存配额。`ForyJsonBuilder.withMaxGraphMemoryBytes` 独立限制每次根读取所创建并保留的对象图 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/troubleshooting.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/troubleshooting.md index 6be15b8cff7..6965756676c 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/troubleshooting.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/json/troubleshooting.md @@ -37,7 +37,7 @@ license: | | OutputStream 写入失败 | 底层 `IOException` 被包装为 `ForyJsonException` 的 cause | | Kotlin null 或成员缺失导致失败 | 检查精确的 `jsonTypeRef`、构造函数默认值和可空使用位置;null 不会请求编译器默认值 | | Kotlin 原始泛型、星投影或类型投影失败 | 提供完整的 `jsonTypeRef()`;`in` 和星投影无法重建一个精确 Schema | -| 不支持的 Kotlin 元数据 | 使用受支持的 Kotlin 2.3 编译器编译模型,并确保经过验证的 JVM 成员与元数据匹配 | +| 不支持的 Kotlin 元数据 | 确保解析到的 `kotlin-metadata-jvm` 支持模型编译器的元数据,并且经过验证的 JVM 成员与元数据匹配 | | Kotlin 模型在 Android 代码压缩后失败 | 启用 KSP;精确 Mixin 的来源或目标任一为 Kotlin 时均需使用,并验证生成的规则已打包 | | Native Image 中缺少 Kotlin 模型 | 从可达的 `ForyJsonProvider` 安装 `ForyJsonKotlin`,启用代码生成,并使精确绑定从该配置可达 | diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/index.md index 966c5e58570..e83b4266d91 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/index.md @@ -60,7 +60,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) @@ -90,11 +90,11 @@ module( bazel_dep(name = "rules_cc", version = "0.1.1") -bazel_dep(name = "fory", version = "1.7.0") +bazel_dep(name = "fory", version = "1.7.1") git_override( module_name = "fory", remote = "https://github.com/apache/fory.git", - commit = "v1.7.0", # Or use a specific commit hash for reproducibility + commit = "v1.7.1", # Or use a specific commit hash for reproducibility ) ``` @@ -125,7 +125,7 @@ bazel run //:my_app 本地开发时,可以改用 `local_path_override`: ```bazel -bazel_dep(name = "fory", version = "1.7.0") +bazel_dep(name = "fory", version = "1.7.1") local_path_override( module_name = "fory", path = "/path/to/fory", diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/schema-metadata.md index 2058fc3390b..62124a97fee 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/cpp/schema-metadata.md @@ -56,7 +56,7 @@ FORY_STRUCT(DataV2, id, (timestamp, fory::F().tagged()), version); FORY_STRUCT(Counter, FORY_PROPERTY(value, fory::F().varint())); ``` -`fory::F(id)` 使用显式的 ID 字段标识。ID 必须为非负数: +`fory::F(id)` 使用显式基于 ID 的字段身份。配置的 ID 必须在完整结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`): ```cpp FORY_STRUCT(DataV2, (id, fory::F(0)), (timestamp, fory::F(1).tagged()), diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/index.md index 33de125c89f..5a3a9322420 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/index.md @@ -44,7 +44,7 @@ Apache Fory™ C# 是面向 .NET 的高性能跨语言序列化库。它支持 ```xml - + ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/schema-metadata.md index 7c625d85c59..366019499be 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/csharp/schema-metadata.md @@ -23,7 +23,7 @@ license: | ## `[ForyStruct]` 和 `[ForyField]` -使用 `[ForyStruct]` 启用源码生成序列化器。使用 `[ForyField]` 分配可选、稳定的非负字段 ID,或覆盖字段所用的 Fory Schema 类型。 +使用 `[ForyStruct]` 启用源码生成的序列化器。使用 `[ForyField]` 可分配可选的稳定字段 ID,或覆盖字段使用的 Fory Schema 类型。配置的 ID 必须在完整结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`)。 外部类型序列化在本地抽象序列化器声明上设置 `Target`。该声明的属性定义字段名称、ID、Schema 描述符和可空性。独立声明还定义其 `Evolving` 设置。外部 `BaseOnly` 声明不能设置 `Evolving`;该设置由每个具体派生类型负责。目标提供目标类型的值和直接访问的成员。 @@ -64,7 +64,7 @@ public sealed class Metrics } ``` -`Id` 是可选的。省略时,兼容模式仍按名称匹配字段。 +`Id` 是可选的。省略时,兼容模式仍按字段名匹配。分配 ID 后应保持稳定,不要将其复用于其他字段。 ```csharp using Apache.Fory; diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/index.md index 881f6a216ac..11d3e50a1c1 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/index.md @@ -44,7 +44,7 @@ Apache Fory™ Dart 可以将 Dart 对象序列化为字节并反序列化,也 ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/schema-metadata.md index 020b6509baa..41278894bcb 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/dart/schema-metadata.md @@ -57,7 +57,7 @@ String cachedDisplayName = ''; String name = ''; ``` -载荷开始跨服务共享后,绝不要为其他字段复用 `id`。 +载荷一旦在服务之间共享,就不要将某个 `id` 复用于其他字段。配置的 ID 必须满足 `0 <= id < 2^29`(`0` 至 `536870911`)。 普通子类只有一个扁平字段命名空间。因此,在子类、父类和所应用 mixin 声明中纳入的所有字段之间,ID 必须唯一。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/schema-metadata.md index a4d54eb3c64..28a22ba2617 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/schema-metadata.md @@ -47,6 +47,8 @@ type User struct { } ``` +配置的 ID 必须在结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`)。已分配的 ID 应保持稳定,不要复用于其他字段。 + **优势**: - 序列化体积更小(数字 ID 相比字段名称) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/troubleshooting.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/troubleshooting.md index 16c0dfe6d05..68984fc5652 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/troubleshooting.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/go/troubleshooting.md @@ -206,7 +206,7 @@ f2 := fory.New(fory.WithTrackRef(true)) // Must match! **常见原因**: -1. **标签 ID 无效**:ID 必须为非负数 +1. **无效 tag ID**:ID 必须满足 `0 <= id < 2^29`(`0` 至 `536870911`) ```go // Wrong: negative ID @@ -218,6 +218,11 @@ type Bad struct { type Good struct { Field int `fory:"id=0"` } + +// Wrong: ID reaches the exclusive upper bound +type TooLarge struct { + Field int `fory:"id=536870912"` +} ``` 2. **标签 ID 重复**:结构体中的每个字段必须具有唯一 ID @@ -256,7 +261,7 @@ type User struct { } ``` -2. **使用字段 ID 保持顺序一致**:字段 ID(非负整数)作为字段名称的别名,同时用于排序和反序列化期间的字段匹配: +2. **使用字段 ID 保持一致顺序**:协议范围内的字段 ID 充当字段名的别名,在反序列化时同时用于排序和字段匹配: ```go type User struct { diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/index.md index d49d5ec4e7f..97fa151b4b8 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/index.md @@ -51,7 +51,7 @@ Fory core 支持 Java 8 及更高版本。Java Record 序列化需要 Java 17 org.apache.fory fory-core - 1.7.0 + 1.7.1 ``` @@ -59,7 +59,7 @@ Fory core 支持 Java 8 及更高版本。Java Record 序列化需要 Java 17 ```kotlin // Binary object serialization -implementation("org.apache.fory:fory-core:1.7.0") +implementation("org.apache.fory:fory-core:1.7.1") ``` #### JDK 25 及更高版本 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/schema-metadata.md index 837461a6e35..6d39d129319 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/java/schema-metadata.md @@ -87,10 +87,10 @@ public class User { ### 参数 -| 参数 | 类型 | 默认值 | 说明 | -| --------- | --------- | ------ | ---------------------------- | -| `id` | `int` | `-1` | 非负字段 tag ID,或不设置 ID | -| `dynamic` | `Dynamic` | `AUTO` | 控制结构体字段的多态行为 | +| 参数 | 类型 | 默认值 | 说明 | +| --------- | --------- | ------- | -------------------------------- | +| `id` | `int` | `-1` | 字段 tag ID,或内部无 ID 哨兵值 | +| `dynamic` | `Dynamic` | `AUTO` | 控制结构体字段的多态行为 | 在字段类型或嵌套类型位置使用 `@Nullable` 表示可空 Schema 元数据,使用 `@Ref` 表示引用跟踪。`@ForyField` 本身不包含这两项设置。 @@ -121,9 +121,10 @@ public class User { **注意事项**: -- ID 在类中必须唯一 -- 配置的 ID 必须 >= 0 -- 如果未指定,注解默认值 `-1` 会被忽略,元数据改用字段名(开销更大) +- 配置的 ID 必须满足 `0 <= id < 2^29`(`0` 至 `536870911`) +- ID 必须在完整结构体 Schema 内唯一,包括继承字段 +- 未指定时,注解默认值 `-1` 是内部无 ID 哨兵值,元数据中使用字段名(开销更大) +- 分配 ID 后应保持稳定,不要复用于其他字段 **不使用字段 ID**(元数据使用字段名): diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/schema-metadata.md index c30a00baef5..b01f795062c 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/schema-metadata.md @@ -47,6 +47,22 @@ const byName = Type.struct( 使用 `.` 在 `typeName` 中添加命名空间前缀。 +## 字段 ID {#field-ids} + +在字段类型上调用 `setId(id)`,即可分配稳定的数字字段身份: + +```ts +const userType = Type.struct( + { typeId: 1001 }, + { + id: Type.int64().setId(0), + name: Type.string().setId(1), + }, +); +``` + +配置的 ID 必须在结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`)。已分配的 ID 应保持稳定,不要复用于其他字段。未设置 ID 的字段使用字段名。 + ## 装饰器元数据 装饰器可以让 Schema 与 TypeScript 类声明放在一起: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/supported-types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/supported-types.md index 7c2ca911aa7..7f33527cf99 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/supported-types.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/javascript/supported-types.md @@ -70,6 +70,8 @@ Type.bfloat16(); 与使用低精度数值格式的语言或载荷互操作时,`float16` 和 `bfloat16` 很有用。 +`Type.float16()` 会将数值舍入为最接近的半精度值;输入恰好位于两个值的中点时,选择最低有效位为偶数的值。Float16 数组转换使用相同的舍入规则。带符号零、无穷大和 NaN 会被保留;数值可能下溢为带符号零,也可能上溢为带符号无穷大。 + ## Array 和 Typed Array ### 列表 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/index.md index e38e00b4caa..d050e80c2ab 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/index.md @@ -53,14 +53,14 @@ Fory Kotlin 继承了 Fory Java 的全部功能,并增加了 Kotlin 特有优 org.apache.fory fory-kotlin - 1.7.0 + 1.7.1 ``` ### Gradle ```kotlin -implementation("org.apache.fory:fory-kotlin:1.7.0") +implementation("org.apache.fory:fory-kotlin:1.7.1") ``` ### JDK25+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md index 05cfa8fba6a..f1996a03022 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md @@ -49,6 +49,8 @@ data class User( `@field:ForyField(id = 1)`。不要使用 `@get:ForyField` 或 `@set:ForyField`;访问器不是 Schema 字段,处理器会拒绝它们。 +配置的字段 ID 必须在结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`)。已分配的 ID 应保持稳定,不要复用于其他字段。省略 `id` 时使用字段名。 + ## 可空性 使用 Kotlin `?` 描述可空的 Schema 位置。集合和 map 内部会保留可空性: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/python/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/python/schema-metadata.md index dfda648e725..14fff5d3ccd 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/python/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/python/schema-metadata.md @@ -70,15 +70,15 @@ class User: ### 参数 -| 参数 | 类型 | 默认值 | 说明 | -| ----------------- | -------- | --------- | -------------------- | -| `id` | `int` | 省略 | 非负字段 tag ID | -| `nullable` | `bool` | `False` | 字段是否可以为 null | -| `ref` | `bool` | `False` | 启用引用跟踪 | -| `ignore` | `bool` | `False` | 从序列化中排除字段 | -| `dynamic` | `bool` | `None` | 控制是否写入类型信息 | -| `default` | Any | `MISSING` | 字段默认值 | -| `default_factory` | Callable | `MISSING` | 默认值工厂函数 | +| 参数 | 类型 | 默认值 | 说明 | +| ----------------- | ------ | --------- | ------------------------------- | +| `id` | `int` | 省略 | `0 <= id < 2^29` 范围内的字段 tag ID | +| `nullable` | `bool` | `False` | 字段是否可以为 null | +| `ref` | `bool` | `False` | 启用引用跟踪 | +| `ignore` | `bool` | `False` | 从序列化中排除字段 | +| `dynamic` | `bool` | `None` | 控制是否写入类型信息 | +| `default` | Any | `MISSING` | 字段默认值 | +| `default_factory` | Callable | `MISSING` | 默认值工厂函数 | ## 字段 ID(`id`) @@ -102,9 +102,10 @@ class User: **注意事项**: -- ID 在类中必须唯一 -- ID 必须 >= 0 +- ID 必须在结构体 Schema 内唯一 +- ID 必须满足 `0 <= id < 2^29`(`0` 至 `536870911`) - 如果未指定,元数据使用字段名(开销更大) +- 分配 ID 后应保持稳定,不要复用于其他字段 **不使用字段 ID**(元数据使用字段名): diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/basic-serialization.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/basic-serialization.md index b403d479ecb..5052e5f8e83 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/basic-serialization.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/basic-serialization.md @@ -145,7 +145,7 @@ Rust 启用 `chrono::NaiveDate`、`chrono::NaiveDateTime` 和 `chrono::Duration` ```toml [dependencies] -fory = { version = "1.7.0", features = ["chrono"] } +fory = { version = "1.7.1", features = ["chrono"] } ``` ### 自定义类型 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/index.md index db34d4e8bd2..eae7b0d44f7 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/index.md @@ -36,9 +36,9 @@ Rust 实现通过自动内存管理和编译期类型安全提供灵活的高性 | Crate | 说明 | 版本 | | --------------------------------------------------------------------------- | ---------------------------------- | --------------------------------------------- | -| [`fory`](https://github.com/apache/fory/blob/main/rust/fory) | 面向用户的 API、运行时类型和派生宏 | [1.7.0](https://crates.io/crates/fory) | -| [`fory-core`](https://github.com/apache/fory/blob/main/rust/fory-core/) | 用于高级集成的底层运行时 crate | [1.7.0](https://crates.io/crates/fory-core) | -| [`fory-derive`](https://github.com/apache/fory/blob/main/rust/fory-derive/) | 供直接使用运行时的底层过程宏 crate | [1.7.0](https://crates.io/crates/fory-derive) | +| [`fory`](https://github.com/apache/fory/blob/main/rust/fory) | 面向用户的 API、运行时类型和派生宏 | [1.7.1](https://crates.io/crates/fory) | +| [`fory-core`](https://github.com/apache/fory/blob/main/rust/fory-core/) | 用于高级集成的底层运行时 crate | [1.7.1](https://crates.io/crates/fory-core) | +| [`fory-derive`](https://github.com/apache/fory/blob/main/rust/fory-derive/) | 供直接使用运行时的底层过程宏 crate | [1.7.1](https://crates.io/crates/fory-derive) | 大多数应用程序只需依赖 `fory`。它重新导出生成代码所需的派生宏和公共运行时类型。只有明确要基于底层运行时 crate 构建时,才直接使用 `fory-core` 或 `fory-derive`。 @@ -48,7 +48,7 @@ Rust 实现通过自动内存管理和编译期类型安全提供灵活的高性 ```toml [dependencies] -fory = "1.7.0" +fory = "1.7.1" ``` ### 基本示例 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/schema-metadata.md index 8f227905107..0088b45efab 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/rust/schema-metadata.md @@ -83,8 +83,9 @@ struct User { **注意事项**: - ID 在结构体中必须唯一 -- ID 必须为非负数 +- ID 必须满足 `0 <= id < 2^29`(`0` 至 `536870911`) - 未指定时在元数据中使用字段名称(开销更大) +- 分配 ID 后应保持稳定,不要复用于其他字段 ### 跳过字段(`skip`) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/index.md index 9814e6aa0a8..b2b37cf2894 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/index.md @@ -49,7 +49,7 @@ Fory Scala 继承了 Fory Java 的全部功能,并增加了 Scala 特有优化 使用 sbt 添加依赖: ```sbt -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1" ``` ### JDK25+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/schema-metadata.md index 1d85ea555d7..b804c1f009f 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/scala/schema-metadata.md @@ -37,6 +37,8 @@ final case class Person( ) derives ForySerializer ``` +配置的字段 ID 必须在结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`)。已分配的 ID 应保持稳定,不要复用于其他字段。省略 `id` 时使用字段名。 + Schema `optional T` 字段表示为 `Option[T]`。 ## 引用跟踪 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/swift/schema-metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/swift/schema-metadata.md index 3457c581002..eb4cbd4fef9 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/swift/schema-metadata.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/object-serialization/swift/schema-metadata.md @@ -26,6 +26,7 @@ license: | - `@ForyStruct`:用于 struct/class 模型和外部结构化序列化器 - `@ForyEnum`:用于 C 风格 enum 模型和外部 enum 序列化器 - `@ForyUnion` 和 `@ForyCase`:用于关联值 enum 模型和外部 union 序列化器 +- `@ForyField(id: ...)` 用于稳定的数字字段身份 - `@ForyField(encoding: ...)`:用于数值字段 - `@ForyField(with: ...)`:用于精确选择序列化器 - `@ListField`、`@ArrayField`、`@SetField` 和 `@MapField`:用于集合字段元数据 @@ -45,6 +46,20 @@ struct UserSerializer { `@ForyEnum` 和 `@ForyUnion` 也提供等价的目标参数。目标访问和构造要求请参阅 [外部类型序列化](external-types.md)。 +## `@ForyField(id:)` + +需要在重命名或 Schema 演进中保持字段身份稳定时,请分配 ID: + +```swift +@ForyStruct +struct User { + @ForyField(id: 1) + var name: String +} +``` + +配置的 ID 必须在结构体 Schema 内唯一,并满足 `0 <= id < 2^29`(`0` 至 `536870911`)。已分配的 ID 应保持稳定,不要复用于其他字段。未设置 ID 的字段使用字段名。 + ## `@ForyField(with:)` 如果未添加注解的字段,其声明类型实现了 `Serializer` 且 `Target == Self`,该字段会隐式 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/row-format/java.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/row-format/java.md index 558d8119e6a..698f8d1e62f 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/row-format/java.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/row-format/java.md @@ -41,14 +41,14 @@ Maven: org.apache.fory fory-format - 1.7.0 + 1.7.1 ``` Gradle: ```kotlin -implementation("org.apache.fory:fory-format:1.7.0") +implementation("org.apache.fory:fory-format:1.7.1") ``` ## 基本用法 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/java_serialization_spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/java_serialization_spec.md index 8d84a4c4eab..710dc3f690c 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/java_serialization_spec.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/java_serialization_spec.md @@ -270,9 +270,9 @@ Java 原生对象序列化器使用与当前 xlang 协议相同的确定性字 字段标识符按以下规则选择: -- 如果字段具有显式非负 `@ForyField(id = ...)`,该数值 ID 即为字段标识符。 -- 否则,将转换为 snake_case 的 Java 字段名用作字段标识符。 -- 负数注解值不是有效字段 ID。注解默认值 `-1` 表示没有显式 ID,选择标识符时会忽略它。 +- 如果字段显式设置了 `@ForyField(id = ...)`,且满足 `0 <= id < 2^29`,该数字 ID 就是字段标识符。 +- 注解默认值 `id = -1`,以及未显式指定 `@ForyField` ID 的字段,使用转换为 snake_case 的 Java 字段名。 +- 其他注解 ID 均无效;小于 `-1` 或大于等于 `2^29` 的值不会选择基于名称的身份。 标识符比较规则如下: @@ -380,9 +380,7 @@ class_layer: 对于名称编码,位 `4..6` 存储 `encoded_length - 1`,前提是该值小于 `7`。 如果值为 `7`,则再读取一个 `varuint32` 并加到 `7` 上。 -对于 tag ID 编码,位 `4..6` 存储数值字段 ID,前提是该 ID 小于 `7`。 -如果值为 `7`,则再读取一个 `varuint32` 并加到 `7` 上。字段 ID 必须为非负数。 -同一个 TypeDef 中不能出现重复字段 ID。 +在 tag ID 编码中,小于 `7` 的数字字段 ID 存放在位 `4..6`。若该值为 `7`,则读取额外的 `varuint32` 并加上 `7`。字段 ID 必须满足 `0 <= tag_id < 2^29`,最大合法值为 `536870911`。一个 TypeDef 中不允许重复字段 ID。 ### 字段类型 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/xlang_serialization_spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/xlang_serialization_spec.md index 85048249bc3..ca12d0ed9c4 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/xlang_serialization_spec.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/specification/xlang_serialization_spec.md @@ -619,18 +619,20 @@ struct TypeDef 的元信息 header 字节: 每个字段的编码如下: ``` -| field header (1 byte) | field type info | [field name bytes] | +| field header (1 byte) | [extended name or tag value] | field type info | [field name bytes] | ``` +可选扩展值为 `varuint32`。当较长的编码名称或扩展 tag ID 使四位大小字段饱和时出现,具体规则如下。 + 字段 header 布局: -- Bits 6-7:字段名称编码(`UTF8`、`ALL_TO_LOWER_SPECIAL`、`LOWER_UPPER_DIGIT_SPECIAL` 或 `TAG_ID`) -- Bits 2-5:大小 - - 对于名称编码:`size = (name_bytes_length - 1)` - - 对于 tag ID:`size = tag_id` - - 如果 `size == 0b1111`,读取 `varuint32(size - 15)` 并加到该值上 -- Bit 1:nullable flag -- Bit 0:引用跟踪 flag +- 位 6-7:字段名编码(`UTF8`、`ALL_TO_LOWER_SPECIAL`、`LOWER_UPPER_DIGIT_SPECIAL` 或 `TAG_ID`) +- 位 2-5:大小 + - 名称编码中,令 `logical_size = name_bytes_length - 1`,存储 `size = min(logical_size, 15)`。若 `logical_size >= 15`,在头部后写入 `varuint32(logical_size - 15)`;解码时将扩展值加上 `15`,再加 `1` 得到 `name_bytes_length`。 + - tag ID:`size = min(tag_id, 15)` + - tag ID 的 `size == 0b1111` 时,在头部后写入 `varuint32(tag_id - 15)`;解码时将扩展值加上 `15` +- 位 1:可空标志 +- 位 0:引用跟踪标志 字段类型信息: @@ -641,9 +643,10 @@ struct TypeDef 的元信息 header 字节: 字段名称: -- 如果使用 `TAG_ID` 编码,则不写入名称字节。 -- 否则,将编码后的字段名称字节作为元字符串写入。 -- 对于 xlang,字段名称在编码前转换为 `snake_case`,以实现跨语言兼容。 +- 使用 `TAG_ID` 编码时,不写入名称字节。 +- tag ID 是范围为 `0 <= tag_id < 2^29`(`0` 至 `536870911`)的有符号 32 位协议值。该上限确保完整协议域可由每种实现的有符号 32 位字段 ID 类型表示;扩展形式仍使用现有 `varuint32` 编码写入 `tag_id - 15`。 +- 否则,将编码后的字段名字节作为元字符串写入。 +- 在 xlang 中,字段名转换为 `snake_case`,以支持跨语言兼容。 字段顺序: @@ -1449,7 +1452,7 @@ Struct 指 `class/pojo/struct/bean/record` 类型的对象。Struct 值按 Fory - 如果配置了非负 tag ID(例如 `@ForyField(id=...)`),则使用该 tag ID。 - 否则,使用转换为 `snake_case` 的字段名称。 -配置的 tag ID 必须为非负值。配置负 tag ID 无效;语言只能将负值用作表示“未配置 tag ID”的默认值或内部 sentinel,此时回退到 `snake_case` 字段名称,该负值不是 tag ID。tag ID 在一个类型内必须唯一;重复的 tag ID 无效。 +配置的 tag ID 必须满足 `0 <= tag_id < 2^29`。负的配置 tag ID 无效;语言实现仅可用负值作为“未配置 tag ID”的默认值或内部哨兵值,此时回退到 `snake_case` 字段名,该值本身不是 tag ID。大于等于 `2^29` 的值无效。tag ID 必须在类型内唯一,不允许重复。 字段标识符按以下规则比较: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/cpp.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/cpp.md index 4c175ac8d65..4cd7b0e1fd1 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/cpp.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/cpp.md @@ -42,7 +42,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/csharp.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/csharp.md index d8425763f7f..733e59d574e 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/csharp.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/csharp.md @@ -34,7 +34,7 @@ dotnet --version ```bash dotnet new console -n ForyExample cd ForyExample -dotnet add package Apache.Fory --version 1.7.0 +dotnet add package Apache.Fory --version 1.7.1 ``` 将 `Program.cs` 替换为: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/dart.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/dart.md index cfdd2ba67ef..bd688453ac2 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/dart.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/dart.md @@ -34,7 +34,7 @@ dart pub --help ```yaml dependencies: - fory: 1.7.0 + fory: 1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/go.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/go.md index 6b65be740da..0311f1a0326 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/go.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/go.md @@ -36,7 +36,7 @@ go env GOPROXY mkdir fory-example cd fory-example go mod init example.com/fory-example -go get github.com/apache/fory/go/fory@v1.7.0 +go get github.com/apache/fory/go/fory@v1.7.1 ``` 如果 Go proxy 尚未收录新的 submodule tag,请稍后重试,或者暂时使用 `GOPROXY=direct`。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/java.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/java.md index e9f3da03f65..a77f2810c29 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/java.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/java.md @@ -39,14 +39,14 @@ Maven: org.apache.fory fory-core - 1.7.0 + 1.7.1 ``` Gradle: ```kotlin -implementation("org.apache.fory:fory-core:1.7.0") +implementation("org.apache.fory:fory-core:1.7.1") ``` 运行下面完整的 xlang 往返示例: @@ -85,7 +85,7 @@ public final class ForyExample { Fory JSON 将 Java 对象映射为标准 JSON 文本和 UTF-8 字节。如果应用只需要 JSON,请添加 `fory-json`,无需添加 `fory-core`: ```kotlin -implementation("org.apache.fory:fory-json:1.7.0") +implementation("org.apache.fory:fory-json:1.7.1") ``` 在 `ForyExample.java` 中添加 import: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/javascript.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/javascript.md index 893e217461f..a05e5b7c0a9 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/javascript.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/javascript.md @@ -33,7 +33,7 @@ npm --version 安装 core 软件包: ```bash -npm install @apache-fory/core@1.7.0 +npm install @apache-fory/core@1.7.1 ``` 定义 Schema 并运行 xlang 往返示例: @@ -65,7 +65,7 @@ JavaScript 使用 xlang 模式。接下来可阅读 [JavaScript/TypeScript 对 若要使用可选的 Node.js 字符串快速路径,请安装版本匹配的软件包: ```bash -npm install @apache-fory/core@1.7.0 @apache-fory/hps@1.7.0 +npm install @apache-fory/core@1.7.1 @apache-fory/hps@1.7.1 ``` ## 其他能力 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/kotlin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/kotlin.md index 47d928e78eb..2a9ab996084 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/kotlin.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/kotlin.md @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation("org.apache.fory:fory-kotlin:1.7.0") + implementation("org.apache.fory:fory-kotlin:1.7.1") } ``` @@ -81,7 +81,7 @@ Fory JSON 是独立于二进制对象序列化的文本格式。与普通 JSON A ```kotlin title="build.gradle.kts" dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/python.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/python.md index b29379879f5..0b310b60b49 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/python.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/python.md @@ -33,7 +33,7 @@ python -m pip --version 安装已发布的软件包: ```bash -python -m pip install pyfory==1.7.0 +python -m pip install pyfory==1.7.1 ``` 运行 xlang 往返示例: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/rust.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/rust.md index 8ee9df68594..298d47cde63 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/rust.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/rust.md @@ -34,7 +34,7 @@ cargo --version ```toml title="Cargo.toml" [dependencies] -fory = "1.7.0" +fory = "1.7.1" ``` ```rust diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/scala.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/scala.md index 0fdced2ccaa..c2e9471adf6 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/scala.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/scala.md @@ -35,7 +35,7 @@ sbt --version ```sbt ThisBuild / scalaVersion := "3.3.1" -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1" ``` 创建 `src/main/scala/ScalaExample.scala`: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/swift.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/swift.md index 364617276be..b70c97fd675 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/swift.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.7.0/start/swift.md @@ -39,7 +39,7 @@ swift package init --type executable --name ForyExample ```swift title="Package.swift" dependencies: [ - .package(url: "https://github.com/apache/fory.git", exact: "1.7.0") + .package(url: "https://github.com/apache/fory.git", exact: "1.7.1") ], targets: [ .executableTarget( diff --git a/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md b/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md index 9b13b71f480..71cef6be2d5 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md @@ -9,11 +9,11 @@ Apache Fory™ 的官方发布以源码制品形式提供。 ## 最新版本 -当前最新源码版本为 1.7.0: +当前最新源码版本为 1.7.1: -| 版本 | 日期 | 源码 | 发布说明 | -| ----- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| 1.7.0 | 2026-08-28 | [source](https://www.apache.org/dyn/closer.lua/fory/1.7.0/apache-fory-1.7.0-src.tar.gz?action=download) [asc](https://downloads.apache.org/fory/1.7.0/apache-fory-1.7.0-src.tar.gz.asc) [sha512](https://downloads.apache.org/fory/1.7.0/apache-fory-1.7.0-src.tar.gz.sha512) | [release notes](https://github.com/apache/fory/releases/tag/v1.7.0) | +| 版本 | 日期 | 源码 | 发布说明 | +| ----- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| 1.7.1 | 2026-09-04 | [source](https://www.apache.org/dyn/closer.lua/fory/1.7.1/apache-fory-1.7.1-src.tar.gz?action=download) [asc](https://downloads.apache.org/fory/1.7.1/apache-fory-1.7.1-src.tar.gz.asc) [sha512](https://downloads.apache.org/fory/1.7.1/apache-fory-1.7.1-src.tar.gz.sha512) | [release notes](https://github.com/apache/fory/releases/tag/v1.7.1) | ## 所有归档版本 @@ -31,13 +31,13 @@ Fory 为下载站点上的所有文件提供 SHA 摘要和 PGP 签名文件。 要验证 SHA 摘要,你需要 `.tar.gz` 文件及其对应的 `.tar.gz.sha512` 文件。示例命令如下: ```bash -sha512sum --check apache-fory-1.7.0-src.tar.gz.sha512 +sha512sum --check apache-fory-1.7.1-src.tar.gz.sha512 ``` 输出类似下面这样即表示校验通过: ```bash -apache-fory-1.7.0-src.tar.gz: OK +apache-fory-1.7.1-src.tar.gz: OK ``` ### 校验签名 @@ -53,13 +53,13 @@ gpg --import KEYS 之后可以校验签名: ```bash -gpg --verify apache-fory-1.7.0-src.tar.gz.asc apache-fory-1.7.0-src.tar.gz +gpg --verify apache-fory-1.7.1-src.tar.gz.asc apache-fory-1.7.1-src.tar.gz ``` 如果出现如下输出,即表示签名正确: ```bash -gpg: Signature made Tue Aug 25 18:38:25 2026 CST +gpg: Signature made Tue Sep 01 11:19:44 2026 CST gpg: using RSA key 1E2CDAE4C08AD7D694D1CB139D7BE8E45E580BA4 gpg: Good signature from "chaokunyang (CODE SIGNING KEY) " [unknown] ``` diff --git a/src/components/home/HomepageLanding.tsx b/src/components/home/HomepageLanding.tsx index 5bc29a614de..f00acde6be9 100644 --- a/src/components/home/HomepageLanding.tsx +++ b/src/components/home/HomepageLanding.tsx @@ -138,7 +138,7 @@ const runtimeExamples: RuntimeExample[] = [ install: ` org.apache.fory fory-core - 1.7.0 + 1.7.1 `, codeLanguage: "java", guide: "/docs/object-serialization/java/", @@ -159,7 +159,7 @@ Person out = (Person) fory.deserialize(bytes);`, id: "python", label: "Python", installLanguage: "bash", - install: `pip install pyfory==1.7.0`, + install: `pip install pyfory==1.7.1`, codeLanguage: "python", guide: "/docs/object-serialization/python/", summary: "pyfory supports xlang, Python native mode, dataclasses, row format, and out-of-band buffers.", @@ -181,7 +181,7 @@ out = fory.deserialize(data)`, id: "rust", label: "Rust", installLanguage: "bash", - install: `cargo add fory@1.7.0`, + install: `cargo add fory@1.7.1`, codeLanguage: "rust", guide: "/docs/object-serialization/rust/", summary: "Rust uses derive macros for type-safe structs and supports both xlang and native payloads.", @@ -206,7 +206,7 @@ fn main() -> Result<(), Error> { id: "go", label: "Go", installLanguage: "bash", - install: `go get github.com/apache/fory/go/fory@v1.7.0`, + install: `go get github.com/apache/fory/go/fory@v1.7.1`, codeLanguage: "go", guide: "/docs/object-serialization/go/", summary: "Go supports xlang and native modes with exported structs, circular references, and schema-aware serializers.", @@ -230,7 +230,7 @@ _ = f.Deserialize(payload, &out)`, FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory)`, @@ -257,7 +257,7 @@ auto out = fory.deserialize(bytes).value();`, id: "javascript", label: "JavaScript", installLanguage: "bash", - install: `npm install @apache-fory/core@1.7.0 @apache-fory/hps@1.7.0`, + install: `npm install @apache-fory/core@1.7.1 @apache-fory/hps@1.7.1`, codeLanguage: "typescript", guide: "/docs/object-serialization/javascript/", summary: "JavaScript/TypeScript is xlang-only, schema-driven, and runs in Node.js or browsers.", @@ -278,7 +278,7 @@ const out = deserialize(payload);`, id: "csharp", label: "C#", installLanguage: "bash", - install: `dotnet add package Apache.Fory --version 1.7.0`, + install: `dotnet add package Apache.Fory --version 1.7.1`, codeLanguage: "csharp", guide: "/docs/object-serialization/csharp/", summary: ".NET support uses source-generated serializers for Fory structs, enums, and unions.", @@ -301,7 +301,7 @@ Person out = fory.Deserialize(payload);`, id: "swift", label: "Swift", installLanguage: "swift", - install: `.package(url: "https://github.com/apache/fory.git", exact: "1.7.0")`, + install: `.package(url: "https://github.com/apache/fory.git", exact: "1.7.1")`, codeLanguage: "swift", guide: "/docs/object-serialization/swift/", summary: "Swift uses @ForyStruct, @ForyEnum, and @ForyUnion macros for xlang-compatible models.", @@ -324,7 +324,7 @@ let out: Person = try fory.deserialize(payload)`, label: "Dart", installLanguage: "yaml", install: `dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.13`, @@ -359,7 +359,7 @@ final out = fory.deserialize(payload);`, id: "scala", label: "Scala", installLanguage: "sbt", - install: `libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0"`, + install: `libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1"`, codeLanguage: "scala", guide: "/docs/object-serialization/scala/", summary: "Scala builds on Fory Java with optimized serializers for case classes, collections, tuples, and Option.", @@ -379,8 +379,8 @@ val out = fory.deserialize(payload).asInstanceOf[Person]`, id: "kotlin", label: "Kotlin", installLanguage: "kotlin", - install: `implementation("org.apache.fory:fory-kotlin:1.7.0") -ksp("org.apache.fory:fory-kotlin-ksp:1.7.0")`, + install: `implementation("org.apache.fory:fory-kotlin:1.7.1") +ksp("org.apache.fory:fory-kotlin-ksp:1.7.1")`, codeLanguage: "kotlin", guide: "/docs/object-serialization/kotlin/", summary: "Kotlin adds data-class support, Android guidance, and KSP static serializers for xlang/schema mode.", diff --git a/src/pages/download/index.md b/src/pages/download/index.md index d5e6ada6fa2..e3a1a2f7691 100644 --- a/src/pages/download/index.md +++ b/src/pages/download/index.md @@ -9,11 +9,11 @@ For binary install, please see the Apache Fory™ [getting started](/docs/start/ ## The latest release -The latest source release is 1.7.0: +The latest source release is 1.7.1: -| Version | Date | Source | Release Notes | -| ------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| 1.7.0 | 2026-08-28 | [source](https://www.apache.org/dyn/closer.lua/fory/1.7.0/apache-fory-1.7.0-src.tar.gz?action=download) [asc](https://downloads.apache.org/fory/1.7.0/apache-fory-1.7.0-src.tar.gz.asc) [sha512](https://downloads.apache.org/fory/1.7.0/apache-fory-1.7.0-src.tar.gz.sha512) | [release notes](https://github.com/apache/fory/releases/tag/v1.7.0) | +| Version | Date | Source | Release Notes | +| ------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| 1.7.1 | 2026-09-04 | [source](https://www.apache.org/dyn/closer.lua/fory/1.7.1/apache-fory-1.7.1-src.tar.gz?action=download) [asc](https://downloads.apache.org/fory/1.7.1/apache-fory-1.7.1-src.tar.gz.asc) [sha512](https://downloads.apache.org/fory/1.7.1/apache-fory-1.7.1-src.tar.gz.sha512) | [release notes](https://github.com/apache/fory/releases/tag/v1.7.1) | ## All archived releases @@ -31,13 +31,13 @@ These files are named after the files they relate to but have `.sha512/.asc` ext To verify the SHA digests, you need the `.tar.gz` file and its associated `.tar.gz.sha512` file. An example command: ```bash -sha512sum --check apache-fory-1.7.0-src.tar.gz.sha512 +sha512sum --check apache-fory-1.7.1-src.tar.gz.sha512 ``` It should output something like: ```bash -apache-fory-1.7.0-src.tar.gz: OK +apache-fory-1.7.1-src.tar.gz: OK ``` ### Verifying Signatures @@ -54,13 +54,13 @@ gpg --import KEYS Then you can verify signature: ```bash -gpg --verify apache-fory-1.7.0-src.tar.gz.asc apache-fory-1.7.0-src.tar.gz +gpg --verify apache-fory-1.7.1-src.tar.gz.asc apache-fory-1.7.1-src.tar.gz ``` If something like the following appears, it means the signature is correct: ```bash -gpg: Signature made Tue Aug 25 18:38:25 2026 CST +gpg: Signature made Tue Sep 01 11:19:44 2026 CST gpg: using RSA key 1E2CDAE4C08AD7D694D1CB139D7BE8E45E580BA4 gpg: Good signature from "chaokunyang (CODE SIGNING KEY) " [unknown] ``` diff --git a/versioned_docs/version-1.7.0/compiler/build-integration.md b/versioned_docs/version-1.7.0/compiler/build-integration.md index e251f09beb6..a902240449f 100644 --- a/versioned_docs/version-1.7.0/compiler/build-integration.md +++ b/versioned_docs/version-1.7.0/compiler/build-integration.md @@ -211,7 +211,7 @@ Add the Fory dependency to `pubspec.yaml`: ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/versioned_docs/version-1.7.0/compiler/cli.md b/versioned_docs/version-1.7.0/compiler/cli.md index f5188aa3882..55ea8b0a919 100644 --- a/versioned_docs/version-1.7.0/compiler/cli.md +++ b/versioned_docs/version-1.7.0/compiler/cli.md @@ -689,5 +689,5 @@ fory = "x.y.z" ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 ``` diff --git a/versioned_docs/version-1.7.0/compiler/schema-idl.md b/versioned_docs/version-1.7.0/compiler/schema-idl.md index 4291e9b649e..9c1244fdd90 100644 --- a/versioned_docs/version-1.7.0/compiler/schema-idl.md +++ b/versioned_docs/version-1.7.0/compiler/schema-idl.md @@ -976,6 +976,11 @@ Fields define the properties of a message. field_type field_name = field_number; ``` +`field_number` is the field tag ID. It must be unique within the message and +satisfy `0 <= field_number < 2^29` (`0` through `536870911`). Keep +assigned field numbers stable and reserve removed numbers instead of reusing +them for different fields. + ### With Modifiers ```protobuf @@ -1149,22 +1154,22 @@ Use `ref(thread_safe=false)` in Fory IDL (or ## Field Numbers -Each field must have a unique positive integer identifier: +Each field must have a unique tag ID in the protocol range: ```protobuf message Example { - string first = 1; - string second = 2; - string third = 3; + string first = 0; + string second = 1; + string third = 2; } ``` **Rules and best practices:** - Numbers must be unique within a message. -- Numbers must be positive integers. +- Numbers must satisfy `0 <= field_number < 2^29` (`0` through `536870911`). - Gaps are allowed and are useful when fields are removed. -- Prefer sequential numbering from `1`. +- Prefer sequential numbering. - Never reuse a removed field number for a different field. ## Type System diff --git a/versioned_docs/version-1.7.0/grpc/csharp.md b/versioned_docs/version-1.7.0/grpc/csharp.md index e96c3d9dd59..dc2048b01ce 100644 --- a/versioned_docs/version-1.7.0/grpc/csharp.md +++ b/versioned_docs/version-1.7.0/grpc/csharp.md @@ -39,7 +39,7 @@ Server project: ```xml - + ``` @@ -48,7 +48,7 @@ Client project: ```xml - + diff --git a/versioned_docs/version-1.7.0/grpc/dart.md b/versioned_docs/version-1.7.0/grpc/dart.md index 8c2f14db9ad..22e54183331 100644 --- a/versioned_docs/version-1.7.0/grpc/dart.md +++ b/versioned_docs/version-1.7.0/grpc/dart.md @@ -38,7 +38,7 @@ application that compiles or runs generated service companions: ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 grpc: ^4.0.0 dev_dependencies: diff --git a/versioned_docs/version-1.7.0/grpc/rust.md b/versioned_docs/version-1.7.0/grpc/rust.md index bf96d36b559..b30d7ddf443 100644 --- a/versioned_docs/version-1.7.0/grpc/rust.md +++ b/versioned_docs/version-1.7.0/grpc/rust.md @@ -37,7 +37,7 @@ to build streaming responses or request streams. ```toml [dependencies] -fory = "1.7.0" +fory = "1.7.1" bytes = "1" tonic = { version = "0.14", features = ["transport"] } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/versioned_docs/version-1.7.0/json/android.md b/versioned_docs/version-1.7.0/json/android.md index 96db8a1c52c..c9b706dfa4c 100644 --- a/versioned_docs/version-1.7.0/json/android.md +++ b/versioned_docs/version-1.7.0/json/android.md @@ -130,12 +130,12 @@ on the `ForyJson` builder that should use it: ```java import org.apache.fory.json.ForyJson; -import org.apache.fory.json.annotation.JsonBase64; +import org.apache.fory.json.annotation.JsonByteArray; import org.apache.fory.json.annotation.JsonMixin; @JsonMixin(target = ThirdPartyInvoice.class) public abstract class ThirdPartyInvoiceMixin { - @JsonBase64 byte[] signature; + @JsonByteArray(JsonByteArray.Format.BASE64) byte[] signature; } ForyJson json = @@ -191,7 +191,7 @@ This reflection-based section applies to Java models. Kotlin models use the Kotl a minified Android build, apply KSP instead of writing broad package keep rules. Java `@JsonType` models support effective `JsonValidator`, `JsonValue`, `JsonRawValue`, -`JsonBase64`, and `JsonFormat` annotations. Without `@JsonType`, those annotations still work +`JsonByteArray`, and `JsonFormat` annotations. Without `@JsonType`, those annotations still work through reflection, but a release-minified application must keep the exact annotated members, annotation attributes, and codec constructor itself. A `JsonValue` method may use a non-JavaBean name, so its manual rule must name that method explicitly. diff --git a/versioned_docs/version-1.7.0/json/annotations.md b/versioned_docs/version-1.7.0/json/annotations.md index 46353322b06..d06a0c72b35 100644 --- a/versioned_docs/version-1.7.0/json/annotations.md +++ b/versioned_docs/version-1.7.0/json/annotations.md @@ -21,7 +21,7 @@ license: | Fory JSON provides these mapping and validation annotations in `org.apache.fory.json.annotation`: -`JsonAnyGetter`, `JsonAnyProperty`, `JsonAnySetter`, `JsonBase64`, `JsonCodec`, `JsonCreator`, `JsonFormat`, +`JsonAnyGetter`, `JsonAnyProperty`, `JsonAnySetter`, `JsonByteArray`, `JsonCodec`, `JsonCreator`, `JsonFormat`, `JsonIgnore`, `JsonProperty`, `JsonPropertyOrder`, `JsonRawValue`, `JsonSubTypes`, `JsonUnwrapped`, `JsonValidator`, and `JsonValue`. `JsonType` is a separate build-time model marker. They are Fory JSON APIs, not Jackson, Gson, or Fory binary-protocol compatibility annotations. @@ -356,28 +356,36 @@ Any-property features are independent. as a trusted raw root value. That combination is serialization-only: the ordinary one-String `JsonCreator` cannot turn an input object or array into a String. -## `JsonBase64` +## `JsonByteArray` -`JsonBase64` selects a quoted standard Base64 JSON string for one exact `byte[]` field or getter: +Unannotated `byte[]` values use quoted standard Base64 JSON strings. `JsonByteArray` selects +`BASE64` or `ARRAY` for one exact `byte[]` field or getter, in both reading and writing: ```java -import org.apache.fory.json.annotation.JsonBase64; +import org.apache.fory.json.annotation.JsonByteArray; public final class Attachment { - @JsonBase64 + @JsonByteArray(JsonByteArray.Format.ARRAY) + public byte[] numbers; + + @JsonByteArray(JsonByteArray.Format.BASE64) public byte[] content; } ``` -Bytes `{1, 2, 3}` are written as `{"content":"AQID"}` and decoded back to the original array. -Fory writes the Base64 characters directly to the JSON output and decodes directly from the JSON -input without creating an intermediate String. Standard Base64 padding is preserved. Java null -follows the property's normal inclusion rule and reads from JSON null as null. +For bytes `{1, -2, 3}`, `numbers` is written as `[1,-2,3]` and `content` as `"Af4D"`. +`ARRAY` reads JSON arrays using the signed byte range `[-128, 127]`; `BASE64` reads standard +Base64 strings and preserves padding when writing. Each representation also accepts JSON null, +and null output follows the property's normal inclusion rule. The default Base64 codec does not +accept numeric-array input; select `ARRAY` for a property that uses that format. + +The format is required when the annotation is present. It applies only to the annotated byte-array +property, not to container elements or map values. Mixin declarations can select or remove it. +It cannot share a logical property with `JsonRawValue`, an occurrence `JsonCodec`, `JsonFormat`, +or an Any declaration. Conflicting formats on the field and getter of one property are rejected. -The annotation is not a type-use annotation and does not change ordinary unannotated `byte[]` -properties, container elements, or Map values. It cannot share a logical property with -`JsonRawValue`, an occurrence `JsonCodec`, `JsonFormat`, or an Any declaration. The equivalent explicit codec is -`@JsonCodec(Base64ByteArrayCodec.class)`. +Base64 values are binary leaves excluded from the graph-memory budget. Numeric arrays count their +array storage against that budget; see [Security](security.md#depth-and-graph-memory-limits). ## `JsonFormat` @@ -439,7 +447,7 @@ unwrapped values are intentionally rejected. Types with ambiguous formatting sem legacy and SQL date types, `Duration`, `Period`, `TimeZone`, `ZoneId`, and `ZoneOffset`, are not supported. A wrapper with a complete registered, annotation-selected, polymorphic, or `JsonValue` representation is also rejected because that representation owns the whole wrapper. -`JsonFormat` cannot share a field with `JsonCodec`, `JsonBase64`, `JsonRawValue`, `JsonAnyProperty`, +`JsonFormat` cannot share a field with `JsonCodec`, `JsonByteArray`, `JsonRawValue`, `JsonAnyProperty`, `JsonUnwrapped`, or `JsonValue`. ## `JsonUnwrapped` diff --git a/versioned_docs/version-1.7.0/json/getting-started.md b/versioned_docs/version-1.7.0/json/getting-started.md index 93ee0a8f2ba..051fe067cd1 100644 --- a/versioned_docs/version-1.7.0/json/getting-started.md +++ b/versioned_docs/version-1.7.0/json/getting-started.md @@ -43,7 +43,7 @@ Maven: org.apache.fory fory-json - 1.7.0 + 1.7.1 ``` @@ -57,7 +57,7 @@ repositories { mavenCentral() } -implementation("org.apache.fory:fory-json:1.7.0") +implementation("org.apache.fory:fory-json:1.7.1") ``` ### Kotlin @@ -66,7 +66,7 @@ Kotlin/JVM applications add the optional Kotlin JSON runtime and use its single ```kotlin title="build.gradle.kts" dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` diff --git a/versioned_docs/version-1.7.0/json/graalvm.md b/versioned_docs/version-1.7.0/json/graalvm.md index 08295063c49..22d48b3f974 100644 --- a/versioned_docs/version-1.7.0/json/graalvm.md +++ b/versioned_docs/version-1.7.0/json/graalvm.md @@ -209,10 +209,10 @@ JVM and Android. `JsonValue` fields and effective public zero-argument methods are supported, including matching one-String `JsonCreator` constructors and public static factories. Fixed `JsonRawValue` fields and -getters support trusted raw String values, and fixed `JsonBase64` fields and getters support Base64 -`byte[]` values as on the JVM. `JsonFormat` date/time fields use the same direct-field, +getters support trusted raw String values, and `JsonByteArray` fields and getters select Base64 strings or numeric +byte arrays as on the JVM. `JsonFormat` date/time fields use the same direct-field, one-wrapper-level, and `timezone` behavior as on the JVM. For direct target annotations, annotate -each reachable owning model with `JsonType` so Native Image retains these members and the Base64 +each reachable owning model with `JsonType` so Native Image retains these members and the selected byte-array codec constructor. A directly annotated `JsonValue` Record uses its generated component accessor and canonical constructor operations. An effective declaration supplied by a Mixin uses the Mixin workflow above diff --git a/versioned_docs/version-1.7.0/json/kotlin.md b/versioned_docs/version-1.7.0/json/kotlin.md index 8599c06a64f..3d9cddedb78 100644 --- a/versioned_docs/version-1.7.0/json/kotlin.md +++ b/versioned_docs/version-1.7.0/json/kotlin.md @@ -25,8 +25,8 @@ Fory JSON; it does not change Fory's binary protocols. ## Installation -The runtime supports Kotlin/JVM metadata ABI 2.3 and is built with Kotlin 2.3.20. Use the same Fory -version for every module: +The runtime accepts model metadata supported by Kotlin's strict metadata reader and is built with +Kotlin 2.3.20. Use the same Fory version for every module: ```kotlin title="build.gradle.kts" plugins { @@ -41,7 +41,7 @@ repositories { } dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` @@ -54,7 +54,7 @@ plugins { } dependencies { - ksp("org.apache.fory:fory-json-kotlin-ksp:1.7.0") + ksp("org.apache.fory:fory-json-kotlin-ksp:1.7.1") } ``` @@ -87,6 +87,12 @@ val text = json.toJson(Account(7u, "Alice"), accountType) val decoded = json.fromJson(text, accountType) ``` +Use `ForyJsonKotlin.builder().writeLongAsString(true)` when signed `Long` and unsigned `ULong` +values must be emitted as quoted decimal strings. The setting also applies to their declared +collection and map values, nullable values, Kotlin value classes backed by them, `ULongArray`, and +the Java Long-like wrappers supported by the core JSON runtime. Readers accept both quoted and +unquoted integer tokens. + `jsonTypeRef()` is a type token, not a codec lookup. Construct it once and reuse it. A Java `Class` or ordinary Java `TypeRef` cannot express distinctions such as `List`, `UInt`, or a logical value class lowered to a primitive carrier. @@ -274,7 +280,7 @@ their normal Fory JSON representation when used from Kotlin: | text | `String`, exact `CharSequence`, `StringBuilder`, and `StringBuffer` use String shapes | | arbitrary/reduced-precision number | `BigInteger`, `BigDecimal`, Fory `Float16`, and `BFloat16` use their core numeric shapes and limits | | enum | quoted enum constant name | -| Java/Kotlin arrays | normal JSON arrays; `ByteArray` is numeric unless `JsonBase64` selects binary; unsigned semantic arrays are listed below | +| Java/Kotlin arrays | normal JSON arrays except `ByteArray`, which uses Base64 strings by default; `@field:JsonByteArray(JsonByteArray.Format.ARRAY)` selects numeric arrays; unsigned semantic arrays are listed below | | Optional and atomic | `Optional`, primitive Optionals, atomic scalars/references, and atomic arrays keep their transparent core shapes subject to the nullability rules above | | quoted JDK values | `Currency`, `File`, `URI`, `Path`, `Pattern`, `UUID`, `Locale`, `Charset`, and `TimeZone` keep their core String shapes | | legacy date/time | `Date`, `Calendar`, and available `java.sql.Date`, `Time`, and `Timestamp` keep their epoch-millisecond shapes | @@ -363,5 +369,6 @@ See [Troubleshooting](troubleshooting.md) for Kotlin metadata, nullability, gene Android shrinking, Native Image, syntax, limits, custom codecs, subtypes, and root-operation failures. -See [Kotlin JSON benchmarks](../benchmarks/json/kotlin/README.md) for the workloads and setup -used to compare Fory JSON Kotlin, kotlinx.serialization, Moshi, and Jackson Kotlin. +The source-aligned four-library benchmark methodology and publication status are in the +[Kotlin JSON benchmark report](../benchmarks/json/kotlin/README.md). No Kotlin result is inferred +from the Java or Scala benchmark. diff --git a/versioned_docs/version-1.7.0/json/object-mapping.md b/versioned_docs/version-1.7.0/json/object-mapping.md index e64b7116b1a..537c8486086 100644 --- a/versioned_docs/version-1.7.0/json/object-mapping.md +++ b/versioned_docs/version-1.7.0/json/object-mapping.md @@ -215,6 +215,7 @@ original key type. Null map keys are rejected. | Builder method | Default | User-visible effect | | -------------------------------------- | ----------------------------------------- | ---------------------------------------------------------- | | `writeNullFields(boolean)` | `false` | Default inclusion of null object properties | +| `writeLongAsString(boolean)` | `false` | Write built-in 64-bit integer values as decimal strings | | `withCodegen(boolean)` | `true` | Enable generated object codecs | | `withAsyncCompilation(boolean)` | `true` | Compile generated codecs asynchronously | | `withFieldMode(boolean)` | `false` | When true, discover fields without getters/setters | @@ -225,6 +226,14 @@ original key type. Null map keys are rejected. | `registerCodec(type, codec)` | None | Replace an eligible exact class's complete JSON codec | | `registerMixin(mixinType)` | None | Apply one annotation Mixin to its exact declared target | +Enable `writeLongAsString(true)` when 64-bit integer values must pass through JavaScript without +`Number` precision loss. The setting writes built-in `long`/`Long`, `AtomicLong`, +`AtomicLongArray`, and `OptionalLong` values as quoted decimal strings. It also follows declared +Long children through arrays, collections, map values, `Optional`, `AtomicReference`, +and equivalent language-module containers. Readers accept both numeric and quoted integer tokens +regardless of this setting. Custom codecs and occurrence-level codec or format annotations retain +their own output shape. + Concurrency-level and buffer-retention limits must be positive. The cached-field-name limit applies independently to each reader; zero disables this cache. It bounds only cached field names, not names accepted from the input. The buffer-retention setting does not limit JSON input or output diff --git a/versioned_docs/version-1.7.0/json/scala.md b/versioned_docs/version-1.7.0/json/scala.md index a988157bffd..dba2334a6bc 100644 --- a/versioned_docs/version-1.7.0/json/scala.md +++ b/versioned_docs/version-1.7.0/json/scala.md @@ -25,7 +25,7 @@ module works on the ordinary JVM and GraalVM Native Image. Android is not suppor ## Setup ```sbt -libraryDependencies += "org.apache.fory" %% "fory-json-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-json-scala" % "1.7.1" ``` `ForyJsonScala.builder()` installs the Scala module and returns the standard Fory JSON builder: @@ -41,6 +41,11 @@ val person = json.fromJson(text, classOf[Person]) ``` Reuse the resulting `ForyJson` instance. It is immutable and thread-safe after construction. +Use `ForyJsonScala.builder().writeLongAsString(true)` to emit Scala `Long` values, including +declared collection and map values, `Option[Long]`, `Long`-backed value classes, and Java Long-like +wrappers as quoted decimal strings. Readers accept both quoted and unquoted integer tokens. +Use `ScalaTypeRef` when a parameterized declaration contains `Long` because normal JVM signatures +can erase Scala value-type arguments to `Object`. ## Case classes and annotations @@ -50,6 +55,11 @@ or mutate constructor `val` fields. Defaults in later parameter lists receive th constructor arguments exactly as Scala defines them. A missing parameter without a default is an error. Mutable body properties are applied after construction. +A case class may be declared at the top level, or inside an `object` at any nesting depth, as long +as every enclosing scope is itself an `object`. A case class enclosed by a `class`, a trait, or a +method is rejected for both reading and writing, because Fory cannot reach the enclosing instance +or the companion it needs to rebuild the value. + Fory JSON annotations can be placed directly on Scala constructor properties: ```scala diff --git a/versioned_docs/version-1.7.0/json/troubleshooting.md b/versioned_docs/version-1.7.0/json/troubleshooting.md index 94839267c15..5d301fddf51 100644 --- a/versioned_docs/version-1.7.0/json/troubleshooting.md +++ b/versioned_docs/version-1.7.0/json/troubleshooting.md @@ -37,7 +37,7 @@ license: | | OutputStream write fails | The underlying `IOException` is wrapped as the cause of `ForyJsonException` | | Kotlin null or missing member fails | Check the exact `jsonTypeRef`, constructor default, and nullable occurrence; null does not request a compiler default | | Raw/star/projected Kotlin generic fails | Supply a complete `jsonTypeRef()`; `in` and star projections cannot reconstruct one exact schema | -| Unsupported Kotlin metadata | Compile the model with a supported Kotlin 2.3 compiler and ensure its validated JVM members match the metadata | +| Unsupported Kotlin metadata | Ensure the resolved `kotlin-metadata-jvm` supports the model compiler's metadata and that validated JVM members match it | | Kotlin model fails after Android shrinking | Apply KSP; for an exact Mixin, use it when either its source or target is Kotlin, and verify that the generated rules are packaged | | Kotlin model is absent in Native Image | Install `ForyJsonKotlin` from a reachable `ForyJsonProvider`, enable code generation, and make the exact binding reachable from that configuration | diff --git a/versioned_docs/version-1.7.0/object-serialization/cpp/index.md b/versioned_docs/version-1.7.0/object-serialization/cpp/index.md index df2ad692e60..4e2632510f3 100644 --- a/versioned_docs/version-1.7.0/object-serialization/cpp/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/cpp/index.md @@ -62,7 +62,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) @@ -92,11 +92,11 @@ module( bazel_dep(name = "rules_cc", version = "0.1.1") -bazel_dep(name = "fory", version = "1.7.0") +bazel_dep(name = "fory", version = "1.7.1") git_override( module_name = "fory", remote = "https://github.com/apache/fory.git", - commit = "v1.7.0", # Or use a specific commit hash for reproducibility + commit = "v1.7.1", # Or use a specific commit hash for reproducibility ) ``` @@ -128,7 +128,7 @@ bazel run //:my_app For local development, you can use `local_path_override` instead: ```bazel -bazel_dep(name = "fory", version = "1.7.0") +bazel_dep(name = "fory", version = "1.7.1") local_path_override( module_name = "fory", path = "/path/to/fory", diff --git a/versioned_docs/version-1.7.0/object-serialization/cpp/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/cpp/schema-metadata.md index c60f3866e50..5c05de1c0e9 100644 --- a/versioned_docs/version-1.7.0/object-serialization/cpp/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/cpp/schema-metadata.md @@ -59,8 +59,9 @@ FORY_STRUCT(DataV2, id, (timestamp, fory::F().tagged()), version); FORY_STRUCT(Counter, FORY_PROPERTY(value, fory::F().varint())); ``` -`fory::F(id)` uses explicit id-based field identity. IDs must be -non-negative: +`fory::F(id)` uses explicit id-based field identity. Configured IDs must be +unique within the complete struct schema and satisfy `0 <= id < 2^29` (`0` +through `536870911`): ```cpp FORY_STRUCT(DataV2, (id, fory::F(0)), (timestamp, fory::F(1).tagged()), diff --git a/versioned_docs/version-1.7.0/object-serialization/csharp/index.md b/versioned_docs/version-1.7.0/object-serialization/csharp/index.md index 30933c6ff15..291ae18baa3 100644 --- a/versioned_docs/version-1.7.0/object-serialization/csharp/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/csharp/index.md @@ -46,7 +46,7 @@ Reference the single `Apache.Fory` package. It includes the Fory library and the ```xml - + ``` diff --git a/versioned_docs/version-1.7.0/object-serialization/csharp/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/csharp/schema-metadata.md index d9858982e5c..c555671441b 100644 --- a/versioned_docs/version-1.7.0/object-serialization/csharp/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/csharp/schema-metadata.md @@ -23,7 +23,7 @@ This page covers schema metadata for C# generated serializers. ## `[ForyStruct]` and `[ForyField]` -Use `[ForyStruct]` to enable source-generated serializers. Use `[ForyField]` to assign an optional stable non-negative field id or to override the Fory schema type used for a field. +Use `[ForyStruct]` to enable source-generated serializers. Use `[ForyField]` to assign an optional stable field ID or to override the Fory schema type used for a field. Configured IDs must be unique within the complete struct schema and satisfy `0 <= id < 2^29` (`0` through `536870911`). External-type serialization puts `Target` on a local abstract serializer declaration. Its properties own the field names, IDs, schema descriptors, @@ -77,6 +77,7 @@ public sealed class Metrics ``` `Id` is optional. When it is omitted, compatible mode still matches the field by name. +Once assigned, keep an ID stable and do not reuse it for a different field. ```csharp using Apache.Fory; diff --git a/versioned_docs/version-1.7.0/object-serialization/dart/index.md b/versioned_docs/version-1.7.0/object-serialization/dart/index.md index 9d6c20497e5..2f48d6f9531 100644 --- a/versioned_docs/version-1.7.0/object-serialization/dart/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/dart/index.md @@ -47,7 +47,7 @@ Add the dependency to your `pubspec.yaml`: ```yaml dependencies: - fory: ^1.7.0 + fory: ^1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/versioned_docs/version-1.7.0/object-serialization/dart/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/dart/schema-metadata.md index 3073cf6bb83..ed4a957cc59 100644 --- a/versioned_docs/version-1.7.0/object-serialization/dart/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/dart/schema-metadata.md @@ -69,6 +69,7 @@ String name = ''; ``` Once a payload is shared across services, never reuse an `id` for a different field. +Configured IDs must satisfy `0 <= id < 2^29` (`0` through `536870911`). An ordinary child has one flattened field namespace. IDs must therefore be unique across all fields included from its child, superclass, and diff --git a/versioned_docs/version-1.7.0/object-serialization/go/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/go/schema-metadata.md index 878661dabbf..7073e1e2439 100644 --- a/versioned_docs/version-1.7.0/object-serialization/go/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/go/schema-metadata.md @@ -47,6 +47,10 @@ type User struct { } ``` +Configured IDs must be unique within the struct schema and satisfy +`0 <= id < 2^29` (`0` through `536870911`). Keep assigned IDs stable and do +not reuse them for different fields. + **Benefits**: - Smaller serialized size (numeric IDs vs field names) diff --git a/versioned_docs/version-1.7.0/object-serialization/go/troubleshooting.md b/versioned_docs/version-1.7.0/object-serialization/go/troubleshooting.md index 9c51ba6be01..be7fa1e9bb8 100644 --- a/versioned_docs/version-1.7.0/object-serialization/go/troubleshooting.md +++ b/versioned_docs/version-1.7.0/object-serialization/go/troubleshooting.md @@ -206,7 +206,8 @@ f2 := fory.New(fory.WithTrackRef(true)) // Must match! **Common causes**: -1. **Invalid tag ID**: ID must be non-negative +1. **Invalid tag ID**: ID must satisfy `0 <= id < 2^29` (`0` through + `536870911`) ```go // Wrong: negative ID @@ -218,6 +219,11 @@ type Bad struct { type Good struct { Field int `fory:"id=0"` } + +// Wrong: ID reaches the exclusive upper bound +type TooLarge struct { + Field int `fory:"id=536870912"` +} ``` 2. **Duplicate tag IDs**: Each field must have a unique ID within the struct @@ -256,7 +262,7 @@ type User struct { } ``` -2. **Use field IDs for consistent ordering**: Field IDs (non-negative integers) act as aliases for field names, used for both sorting and field matching during deserialization: +2. **Use field IDs for consistent ordering**: Field IDs in the protocol range act as aliases for field names, used for both sorting and field matching during deserialization: ```go type User struct { diff --git a/versioned_docs/version-1.7.0/object-serialization/java/index.md b/versioned_docs/version-1.7.0/object-serialization/java/index.md index a984be804f9..13ee77a3f5c 100644 --- a/versioned_docs/version-1.7.0/object-serialization/java/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/java/index.md @@ -63,7 +63,7 @@ or later. org.apache.fory fory-core - 1.7.0 + 1.7.1 ``` @@ -71,7 +71,7 @@ or later. ```kotlin // Binary object serialization -implementation("org.apache.fory:fory-core:1.7.0") +implementation("org.apache.fory:fory-core:1.7.1") ``` #### JDK 25 and Later diff --git a/versioned_docs/version-1.7.0/object-serialization/java/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/java/schema-metadata.md index 981e47184a2..8a1265d84b2 100644 --- a/versioned_docs/version-1.7.0/object-serialization/java/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/java/schema-metadata.md @@ -87,10 +87,10 @@ public class User { ### Parameters -| Parameter | Type | Default | Description | -| --------- | --------- | ------- | -------------------------------------- | -| `id` | `int` | `-1` | Non-negative field tag ID, or no ID | -| `dynamic` | `Dynamic` | `AUTO` | Control polymorphism for struct fields | +| Parameter | Type | Default | Description | +| --------- | --------- | ------- | -------------------------------------------- | +| `id` | `int` | `-1` | Field tag ID, or the internal no-ID sentinel | +| `dynamic` | `Dynamic` | `AUTO` | Control polymorphism for struct fields | Use `@Nullable` on the field type or nested type position for nullable schema metadata and `@Ref` for reference tracking. `@ForyField` does not carry either @@ -123,10 +123,11 @@ public class User { **Notes**: -- IDs must be unique within a class -- IDs must be >= 0 when configured -- If not specified, the annotation default `-1` is ignored and field name is used in metadata +- Configured IDs must satisfy `0 <= id < 2^29` (`0` through `536870911`) +- IDs must be unique within the complete struct schema, including inherited fields +- If not specified, the annotation default `-1` is the internal no-ID sentinel and the field name is used in metadata (larger overhead) +- Once assigned, keep an ID stable and do not reuse it for a different field **Without field IDs** (field names used in metadata): diff --git a/versioned_docs/version-1.7.0/object-serialization/javascript/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/javascript/schema-metadata.md index c891701b614..6884795978e 100644 --- a/versioned_docs/version-1.7.0/object-serialization/javascript/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/javascript/schema-metadata.md @@ -50,6 +50,24 @@ const byName = Type.struct( Use `.` inside `typeName` to add a namespace prefix. +## Field IDs + +Call `setId(id)` on a field type to assign a stable numeric field identity: + +```ts +const userType = Type.struct( + { typeId: 1001 }, + { + id: Type.int64().setId(0), + name: Type.string().setId(1), + }, +); +``` + +Configured IDs must be unique within the struct schema and satisfy +`0 <= id < 2^29` (`0` through `536870911`). Keep assigned IDs stable and do +not reuse them for different fields. Fields without an ID use their names. + ## Decorator Metadata Decorators keep the schema next to a TypeScript class declaration: diff --git a/versioned_docs/version-1.7.0/object-serialization/javascript/supported-types.md b/versioned_docs/version-1.7.0/object-serialization/javascript/supported-types.md index 57ca8eb011d..7949aeb1abe 100644 --- a/versioned_docs/version-1.7.0/object-serialization/javascript/supported-types.md +++ b/versioned_docs/version-1.7.0/object-serialization/javascript/supported-types.md @@ -70,6 +70,8 @@ Type.bfloat16(); `float16` and `bfloat16` are useful when interoperating with languages or payloads that use reduced-precision numeric formats. +`Type.float16()` rounds numbers to the nearest half-precision value, choosing the value with an even least-significant bit when the input is exactly halfway between two values. Float16 array conversion uses the same rounding rule. Signed zero, infinities, and NaN are preserved; values can underflow to signed zero or overflow to signed infinity. + ## Arrays and Typed Arrays ### Lists diff --git a/versioned_docs/version-1.7.0/object-serialization/kotlin/index.md b/versioned_docs/version-1.7.0/object-serialization/kotlin/index.md index 57d00d20e8c..62cb4cc6a3b 100644 --- a/versioned_docs/version-1.7.0/object-serialization/kotlin/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/kotlin/index.md @@ -53,14 +53,14 @@ See [Java Features](../java/index.md#features) for complete feature list. org.apache.fory fory-kotlin - 1.7.0 + 1.7.1 ``` ### Gradle ```kotlin -implementation("org.apache.fory:fory-kotlin:1.7.0") +implementation("org.apache.fory:fory-kotlin:1.7.1") ``` ### JDK25+ diff --git a/versioned_docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md index b46bd14f9f8..a7fb57abd96 100644 --- a/versioned_docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/kotlin/schema-metadata.md @@ -51,6 +51,10 @@ Use `@ForyField(id = 1)` on constructor properties. `@field:ForyField(id = 1)` i for field-backed properties. Do not use `@get:ForyField` or `@set:ForyField`; accessors are not schema fields and the processor rejects them. +Configured field IDs must be unique within the struct schema and satisfy +`0 <= id < 2^29` (`0` through `536870911`). Keep assigned IDs stable and do +not reuse them for different fields. If `id` is omitted, the field name is used. + ## Nullability Use Kotlin `?` to describe nullable schema positions. Nullability is preserved inside collections diff --git a/versioned_docs/version-1.7.0/object-serialization/python/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/python/schema-metadata.md index e7359c96a92..cd8517dba59 100644 --- a/versioned_docs/version-1.7.0/object-serialization/python/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/python/schema-metadata.md @@ -72,7 +72,7 @@ class User: | Parameter | Type | Default | Description | | ----------------- | -------- | --------- | ------------------------------------ | -| `id` | `int` | omitted | Non-negative field tag ID | +| `id` | `int` | omitted | Field tag ID in `0 <= id < 2^29` | | `nullable` | `bool` | `False` | Whether the field can be null | | `ref` | `bool` | `False` | Enable reference tracking | | `ignore` | `bool` | `False` | Exclude field from serialization | @@ -102,9 +102,10 @@ class User: **Notes**: -- IDs must be unique within a class -- IDs must be >= 0 +- IDs must be unique within the struct schema +- IDs must satisfy `0 <= id < 2^29` (`0` through `536870911`) - If not specified, field name is used in metadata (larger overhead) +- Once assigned, keep an ID stable and do not reuse it for a different field **Without field IDs** (field names used in metadata): diff --git a/versioned_docs/version-1.7.0/object-serialization/rust/basic-serialization.md b/versioned_docs/version-1.7.0/object-serialization/rust/basic-serialization.md index 6945bfc5d28..73b01a5877e 100644 --- a/versioned_docs/version-1.7.0/object-serialization/rust/basic-serialization.md +++ b/versioned_docs/version-1.7.0/object-serialization/rust/basic-serialization.md @@ -147,7 +147,7 @@ let later = timestamp.checked_add_duration(duration)?; ```toml [dependencies] -fory = { version = "1.7.0", features = ["chrono"] } +fory = { version = "1.7.1", features = ["chrono"] } ``` ### Custom Types diff --git a/versioned_docs/version-1.7.0/object-serialization/rust/index.md b/versioned_docs/version-1.7.0/object-serialization/rust/index.md index cc0da34599f..d60c058aeaf 100644 --- a/versioned_docs/version-1.7.0/object-serialization/rust/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/rust/index.md @@ -37,9 +37,9 @@ The Rust implementation provides versatile and high-performance serialization wi | Crate | Description | Version | | --------------------------------------------------------------------------- | ----------------------------------------------------- | --------------------------------------------- | -| [`fory`](https://github.com/apache/fory/blob/main/rust/fory) | User-facing API, public Fory types, and derive macros | [1.7.0](https://crates.io/crates/fory) | -| [`fory-core`](https://github.com/apache/fory/blob/main/rust/fory-core/) | Lower-level core crate for advanced integrations | [1.7.0](https://crates.io/crates/fory-core) | -| [`fory-derive`](https://github.com/apache/fory/blob/main/rust/fory-derive/) | Procedural macro crate for direct derive-macro use | [1.7.0](https://crates.io/crates/fory-derive) | +| [`fory`](https://github.com/apache/fory/blob/main/rust/fory) | User-facing API, public Fory types, and derive macros | [1.7.1](https://crates.io/crates/fory) | +| [`fory-core`](https://github.com/apache/fory/blob/main/rust/fory-core/) | Lower-level core crate for advanced integrations | [1.7.1](https://crates.io/crates/fory-core) | +| [`fory-derive`](https://github.com/apache/fory/blob/main/rust/fory-derive/) | Procedural macro crate for direct derive-macro use | [1.7.1](https://crates.io/crates/fory-derive) | Most applications should depend on `fory` only. It re-exports the derive macros and the public Fory types needed by generated code. Use `fory-core` @@ -52,7 +52,7 @@ Add Apache Fory™ to your `Cargo.toml`: ```toml [dependencies] -fory = "1.7.0" +fory = "1.7.1" ``` ### Basic Example diff --git a/versioned_docs/version-1.7.0/object-serialization/rust/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/rust/schema-metadata.md index 249f9a906a9..4b18c04d7a6 100644 --- a/versioned_docs/version-1.7.0/object-serialization/rust/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/rust/schema-metadata.md @@ -83,8 +83,9 @@ struct User { **Notes**: - IDs must be unique within a struct -- IDs must be non-negative +- IDs must satisfy `0 <= id < 2^29` (`0` through `536870911`) - If not specified, field name is used in metadata (larger overhead) +- Once assigned, keep an ID stable and do not reuse it for a different field ### Skipping Fields (`skip`) diff --git a/versioned_docs/version-1.7.0/object-serialization/scala/index.md b/versioned_docs/version-1.7.0/object-serialization/scala/index.md index 7288a51f388..5785ad8059f 100644 --- a/versioned_docs/version-1.7.0/object-serialization/scala/index.md +++ b/versioned_docs/version-1.7.0/object-serialization/scala/index.md @@ -49,7 +49,7 @@ See [Java Features](../java/index.md#features) for complete feature list. Add the dependency with sbt: ```sbt -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1" ``` ### JDK25+ diff --git a/versioned_docs/version-1.7.0/object-serialization/scala/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/scala/schema-metadata.md index d630690824c..151c8cdb616 100644 --- a/versioned_docs/version-1.7.0/object-serialization/scala/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/scala/schema-metadata.md @@ -38,6 +38,10 @@ final case class Person( ) derives ForySerializer ``` +Configured field IDs must be unique within the struct schema and satisfy +`0 <= id < 2^29` (`0` through `536870911`). Keep assigned IDs stable and do +not reuse them for different fields. If `id` is omitted, the field name is used. + Schema `optional T` fields are represented as `Option[T]`. ## Reference Tracking diff --git a/versioned_docs/version-1.7.0/object-serialization/swift/schema-metadata.md b/versioned_docs/version-1.7.0/object-serialization/swift/schema-metadata.md index e805210003c..2a216e4f7b6 100644 --- a/versioned_docs/version-1.7.0/object-serialization/swift/schema-metadata.md +++ b/versioned_docs/version-1.7.0/object-serialization/swift/schema-metadata.md @@ -26,6 +26,7 @@ This page covers macro-level schema metadata in Swift. - `@ForyStruct` on struct/class models and external structural serializers - `@ForyEnum` on C-style enum models and external enum serializers - `@ForyUnion` and `@ForyCase` on associated-value enum models and external union serializers +- `@ForyField(id: ...)` for stable numeric field identity - `@ForyField(encoding: ...)` on numeric fields - `@ForyField(with: ...)` for exact serializer selection - `@ListField`, `@ArrayField`, `@SetField`, and `@MapField` for collection field metadata @@ -47,6 +48,23 @@ Equivalent target arguments are available on `@ForyEnum` and `@ForyUnion`. See [External-Type Serialization](external-types.md) for target access and construction requirements. +## `@ForyField(id:)` + +Assign an ID when field identity must remain stable across renames or schema +evolution: + +```swift +@ForyStruct +struct User { + @ForyField(id: 1) + var name: String +} +``` + +Configured IDs must be unique within the struct schema and satisfy +`0 <= id < 2^29` (`0` through `536870911`). Keep assigned IDs stable and do +not reuse them for different fields. Fields without an ID use their names. + ## `@ForyField(with:)` An unannotated field implicitly selects its declared type when that type diff --git a/versioned_docs/version-1.7.0/row-format/java.md b/versioned_docs/version-1.7.0/row-format/java.md index c21bfaf9ba0..66a3a5b2a2c 100644 --- a/versioned_docs/version-1.7.0/row-format/java.md +++ b/versioned_docs/version-1.7.0/row-format/java.md @@ -43,14 +43,14 @@ For Maven: org.apache.fory fory-format - 1.7.0 + 1.7.1 ``` For Gradle: ```kotlin -implementation("org.apache.fory:fory-format:1.7.0") +implementation("org.apache.fory:fory-format:1.7.1") ``` ## Basic Usage diff --git a/versioned_docs/version-1.7.0/specification/java_serialization_spec.md b/versioned_docs/version-1.7.0/specification/java_serialization_spec.md index 732cbfd351e..012d27f06f7 100644 --- a/versioned_docs/version-1.7.0/specification/java_serialization_spec.md +++ b/versioned_docs/version-1.7.0/specification/java_serialization_spec.md @@ -317,12 +317,12 @@ participate in field order. Field identifiers are selected as follows: -- If a field has an explicit non-negative `@ForyField(id = ...)`, that numeric - ID is the field identifier. -- Otherwise, the Java field name converted to snake_case is the field - identifier. -- Negative annotation values are not valid field IDs. The annotation default - value `-1` means no explicit ID and is ignored for identifier selection. +- If a field has an explicit `@ForyField(id = ...)` in the range + `0 <= id < 2^29`, that numeric ID is the field identifier. +- The annotation default `id = -1`, including a field without an explicit + `@ForyField` ID, uses the Java field name converted to snake_case. +- Every other annotation ID is invalid; values below `-1` and values greater + than or equal to `2^29` do not select name-based identity. Identifier comparison is: @@ -448,7 +448,8 @@ For name encodings, bits `4..6` store `encoded_length - 1` when it is less than For tag ID encoding, bits `4..6` store the numeric field ID when it is less than `7`. If the value is `7`, read an extra `varuint32` and add it to `7`. Field IDs -must be non-negative. Duplicate field IDs in one TypeDef are invalid. +must satisfy `0 <= tag_id < 2^29`; the largest legal value is `536870911`. +Duplicate field IDs in one TypeDef are invalid. ### Field Type diff --git a/versioned_docs/version-1.7.0/specification/xlang_serialization_spec.md b/versioned_docs/version-1.7.0/specification/xlang_serialization_spec.md index 7706cc9eafc..83f579a6532 100644 --- a/versioned_docs/version-1.7.0/specification/xlang_serialization_spec.md +++ b/versioned_docs/version-1.7.0/specification/xlang_serialization_spec.md @@ -840,17 +840,25 @@ Field info list: Each field is encoded as: ``` -| field header (1 byte) | field type info | [field name bytes] | +| field header (1 byte) | [extended name or tag value] | field type info | [field name bytes] | ``` +The optional extended value is a `varuint32`. It is present when the four-bit +size field is saturated for a long encoded name or an extended tag ID, as +defined below. + Field header layout: - Bits 6-7: field name encoding (`UTF8`, `ALL_TO_LOWER_SPECIAL`, `LOWER_UPPER_DIGIT_SPECIAL`, or `TAG_ID`) - Bits 2-5: size - - For name encoding: `size = (name_bytes_length - 1)` - - For tag ID: `size = tag_id` - - If `size == 0b1111`, read `varuint32(size - 15)` and add it + - For name encoding, let `logical_size = name_bytes_length - 1` and store + `size = min(logical_size, 15)`. If `logical_size >= 15`, write + `varuint32(logical_size - 15)` after the header; decoding adds that + extension to `15`, then adds `1` to obtain `name_bytes_length`. + - For tag ID: `size = min(tag_id, 15)` + - If a tag ID has `size == 0b1111`, write `varuint32(tag_id - 15)` after the + header; decoding adds that extension to `15` - Bit 1: nullable flag - Bit 0: reference tracking flag @@ -865,6 +873,11 @@ Field type info: Field names: - If `TAG_ID` encoding is used, no name bytes are written. +- Tag IDs are signed-32-bit protocol values in the range + `0 <= tag_id < 2^29` (`0` through `536870911`). The upper bound leaves the + complete protocol domain representable by every implementation's signed + 32-bit field-ID type; the extended form still writes `tag_id - 15` with the + existing `varuint32` encoding. - Otherwise, write the encoded field name bytes as a meta string. - For xlang, field names are converted to `snake_case` before encoding for cross-language compatibility. @@ -1718,10 +1731,11 @@ For every field, compute a stable identifier used for ordering: - If a non-negative tag ID is configured (e.g., `@ForyField(id=...)`), use the tag ID. - Otherwise, use the field name converted to `snake_case`. -Configured tag IDs must be non-negative. A negative configured tag ID is invalid; languages may -use a negative value only as a default or internal sentinel for "no tag ID configured", which falls -back to the `snake_case` field name and is not a tag ID. Tag IDs must be unique within a type; -duplicate tag IDs are invalid. +Configured tag IDs must satisfy `0 <= tag_id < 2^29`. A negative configured tag ID is invalid; +languages may use a negative value only as a default or internal sentinel for "no tag ID +configured", which falls back to the `snake_case` field name and is not a tag ID. Values greater +than or equal to `2^29` are invalid. Tag IDs must be unique within a type; duplicate tag IDs are +invalid. Field identifiers compare as follows: diff --git a/versioned_docs/version-1.7.0/start/cpp.md b/versioned_docs/version-1.7.0/start/cpp.md index 4b8931b1144..70b56620961 100644 --- a/versioned_docs/version-1.7.0/start/cpp.md +++ b/versioned_docs/version-1.7.0/start/cpp.md @@ -45,7 +45,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.7.0 + GIT_TAG v1.7.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) diff --git a/versioned_docs/version-1.7.0/start/csharp.md b/versioned_docs/version-1.7.0/start/csharp.md index fca5acc643f..9affebdec6c 100644 --- a/versioned_docs/version-1.7.0/start/csharp.md +++ b/versioned_docs/version-1.7.0/start/csharp.md @@ -36,7 +36,7 @@ Create a console project and add the released package: ```bash dotnet new console -n ForyExample cd ForyExample -dotnet add package Apache.Fory --version 1.7.0 +dotnet add package Apache.Fory --version 1.7.1 ``` Replace `Program.cs` with: diff --git a/versioned_docs/version-1.7.0/start/dart.md b/versioned_docs/version-1.7.0/start/dart.md index 1977c2077a4..6993ada37cb 100644 --- a/versioned_docs/version-1.7.0/start/dart.md +++ b/versioned_docs/version-1.7.0/start/dart.md @@ -36,7 +36,7 @@ Add Fory and the generator to `pubspec.yaml`: ```yaml dependencies: - fory: 1.7.0 + fory: 1.7.1 dev_dependencies: build_runner: ^2.4.0 diff --git a/versioned_docs/version-1.7.0/start/go.md b/versioned_docs/version-1.7.0/start/go.md index d2c6db2d564..3f202862af4 100644 --- a/versioned_docs/version-1.7.0/start/go.md +++ b/versioned_docs/version-1.7.0/start/go.md @@ -38,7 +38,7 @@ Create a module and install the released Fory module: mkdir fory-example cd fory-example go mod init example.com/fory-example -go get github.com/apache/fory/go/fory@v1.7.0 +go get github.com/apache/fory/go/fory@v1.7.1 ``` If a Go proxy has not picked up a new submodule tag yet, retry later or use diff --git a/versioned_docs/version-1.7.0/start/java.md b/versioned_docs/version-1.7.0/start/java.md index a6093037de2..0e910fb28df 100644 --- a/versioned_docs/version-1.7.0/start/java.md +++ b/versioned_docs/version-1.7.0/start/java.md @@ -44,14 +44,14 @@ Maven: org.apache.fory fory-core - 1.7.0 + 1.7.1 ``` Gradle: ```kotlin -implementation("org.apache.fory:fory-core:1.7.0") +implementation("org.apache.fory:fory-core:1.7.1") ``` Run this complete xlang round trip: @@ -97,7 +97,7 @@ Fory JSON maps Java objects to standard JSON text and UTF-8 bytes. Add `fory-json` instead of `fory-core` when the application only needs JSON: ```kotlin -implementation("org.apache.fory:fory-json:1.7.0") +implementation("org.apache.fory:fory-json:1.7.1") ``` Add the import to `ForyExample.java`: diff --git a/versioned_docs/version-1.7.0/start/javascript.md b/versioned_docs/version-1.7.0/start/javascript.md index 76828774085..04e06128fe0 100644 --- a/versioned_docs/version-1.7.0/start/javascript.md +++ b/versioned_docs/version-1.7.0/start/javascript.md @@ -36,7 +36,7 @@ npm --version Install the core package: ```bash -npm install @apache-fory/core@1.7.0 +npm install @apache-fory/core@1.7.1 ``` Define a schema and run an xlang round trip: @@ -72,7 +72,7 @@ JavaScript uses xlang mode. Continue with For the optional Node.js string fast path, install the matching package version: ```bash -npm install @apache-fory/core@1.7.0 @apache-fory/hps@1.7.0 +npm install @apache-fory/core@1.7.1 @apache-fory/hps@1.7.1 ``` ## Other Capabilities diff --git a/versioned_docs/version-1.7.0/start/kotlin.md b/versioned_docs/version-1.7.0/start/kotlin.md index edbcbd6ce4d..1244374f2ba 100644 --- a/versioned_docs/version-1.7.0/start/kotlin.md +++ b/versioned_docs/version-1.7.0/start/kotlin.md @@ -44,7 +44,7 @@ repositories { } dependencies { - implementation("org.apache.fory:fory-kotlin:1.7.0") + implementation("org.apache.fory:fory-kotlin:1.7.1") } ``` @@ -88,7 +88,7 @@ module when interoperating with ordinary JSON APIs, browsers, logs, or other JSO ```kotlin title="build.gradle.kts" dependencies { - implementation("org.apache.fory:fory-json-kotlin:1.7.0") + implementation("org.apache.fory:fory-json-kotlin:1.7.1") } ``` diff --git a/versioned_docs/version-1.7.0/start/python.md b/versioned_docs/version-1.7.0/start/python.md index c71f72c5aa1..d7a419ad5b1 100644 --- a/versioned_docs/version-1.7.0/start/python.md +++ b/versioned_docs/version-1.7.0/start/python.md @@ -35,7 +35,7 @@ python -m pip --version Install the released package: ```bash -python -m pip install pyfory==1.7.0 +python -m pip install pyfory==1.7.1 ``` Run an xlang round trip: diff --git a/versioned_docs/version-1.7.0/start/rust.md b/versioned_docs/version-1.7.0/start/rust.md index f65ef728743..8acffa0f856 100644 --- a/versioned_docs/version-1.7.0/start/rust.md +++ b/versioned_docs/version-1.7.0/start/rust.md @@ -36,7 +36,7 @@ Add the public crate: ```toml title="Cargo.toml" [dependencies] -fory = "1.7.0" +fory = "1.7.1" ``` ```rust diff --git a/versioned_docs/version-1.7.0/start/scala.md b/versioned_docs/version-1.7.0/start/scala.md index d0be44646e4..c3c9913bfc1 100644 --- a/versioned_docs/version-1.7.0/start/scala.md +++ b/versioned_docs/version-1.7.0/start/scala.md @@ -37,7 +37,7 @@ Add the Fory Scala library to `build.sbt`: ```sbt ThisBuild / scalaVersion := "3.3.1" -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.7.1" ``` Create `src/main/scala/ScalaExample.scala`: diff --git a/versioned_docs/version-1.7.0/start/swift.md b/versioned_docs/version-1.7.0/start/swift.md index efd8c8c4dd3..67a499668ac 100644 --- a/versioned_docs/version-1.7.0/start/swift.md +++ b/versioned_docs/version-1.7.0/start/swift.md @@ -42,7 +42,7 @@ Add the released package and depend on its `Fory` library in the generated `Pack ```swift title="Package.swift" dependencies: [ - .package(url: "https://github.com/apache/fory.git", exact: "1.7.0") + .package(url: "https://github.com/apache/fory.git", exact: "1.7.1") ], targets: [ .executableTarget(