Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .agents/docs-and-formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Load this file when changing documentation, public APIs, protocol specs, benchma
- Update the relevant docs under `docs/` when important public APIs change.
- Update `docs/specification/**` when protocol behavior changes.
- Keep examples working and aligned with the current API and protocol behavior.
- Do not use emoji in documentation, including headings, feature lists, status
tables, callouts, or READMEs. Use plain words such as "Supported" or
"Unsupported" instead.
- Provide or update working examples when adding new features or materially changing workflows.
- Add migration guidance when a change is breaking or materially changes workflow.
- `docs/DEVELOPMENT.md` plus updates under `docs/guide/` and `docs/benchmarks/` are synced to `apache/fory-site`; other website content should be changed there instead of this repo.
Expand Down
2 changes: 1 addition & 1 deletion .agents/languages/csharp.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# C#
# C\#

Load this file when changing `csharp/` or C# xlang behavior.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Canonical runtime-specific rules now live under `../../../languages/*.md` and `.
- `mvn -T16 test`
- targeted: `mvn -T16 test -Dtest=<Class>#<method>`

## C#
## C\#

- Build/test from `csharp/`
- Typical checks:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Canonical runtime-specific rules now live under `../../../languages/*.md` and `.
- Format: `go fmt ./...`
- Profile: `pprof` (`go test -bench` + cpu/mem profiles)

## C#
## C\#

- Build: `dotnet build Fory.sln -c Release --no-restore`
- Tests: `dotnet test Fory.sln -c Release`
Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ This is the entry point for AI guidance in Apache Fory. Read this file first, th
- Do not replace existing C, C++, Cython, unsafe, or other low-level optimized paths with simpler high-level implementations just to make a refactor easier.
- If a refactor accidentally changes logic or implementation strategy, revert that part and re-implement the refactor around the existing logic.
- Use English only in code, comments, and documentation.
- Do not use emoji in documentation, including headings, feature lists, status
tables, callouts, or READMEs. Use plain words such as "Supported" or
"Unsupported" instead.
- After editing Markdown files outside `tasks/`, run `prettier --write <file>` on each changed Markdown file before finishing. Do not format Markdown under `tasks/`.
- User guide docs must explain user-visible behavior, commands, and examples.
Do not add implementation details, internal ownership rationale, build flags,
Expand Down
89 changes: 44 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ idiomatic domain objects, schema IDL, and cross-language data exchange.

<https://fory.apache.org>

> [!IMPORTANT]
> Apache Fory™ was previously named Apache Fury. For versions before 0.11, use
> `fury` instead of `fory` in package names, imports, and dependencies. See the
> [Fury docs](https://fory.apache.org/docs/0.10/docs/introduction/) for older
> releases.

## Why Fory

Fory is built for fast, compact serialization across languages and runtimes. It
Expand Down Expand Up @@ -285,16 +279,23 @@ Snapshots for Java, Scala, and Kotlin are available from

## Choose Serialization Mode

| Mode | Use it when | Start here |
| -------------------- | ------------------------------------------------------------- | -------------------------------------------------------- |
| Xlang serialization | Data crosses language boundaries | [Cross-language guide](docs/guide/xlang) |
| Native serialization | Producer and consumer are in the same language | Language guide for your runtime |
| Row format | You need random field access or analytics-style partial reads | [Row format spec](docs/specification/row_format_spec.md) |
| Mode | Use it when | Start here |
| ----------- | ------------------------------------------------------------- | -------------------------------------------------------- |
| Xlang mode | Data crosses language boundaries | [Cross-language guide](docs/guide/xlang) |
| Native mode | Producer and consumer are in the same language | Language guide for your runtime |
| Row format | You need random field access or analytics-style partial reads | [Row format spec](docs/specification/row_format_spec.md) |

For Java, Scala, Kotlin, Python, C++, Go, and Rust, use native mode for
same-language traffic. It avoids xlang's cross-language type mapping and
metadata constraints, stays closer to each runtime's native type system, and
supports broader language-specific object graphs. Use it when both producer and
consumer are in the same runtime family and you want the native object model
rather than a portable cross-language schema.

Use native mode for same-language traffic. It avoids xlang's cross-language
type mapping and metadata constraints, so it can serialize broader
language-specific object graphs and is the fastest path for same-language
payloads.
For Java/JVM-only systems, native mode is the replacement path for JDK
serialization, Kryo, FST, Hessian, and Java-only Protocol Buffers payloads. For
Python-only systems, native mode is the replacement path for pickle and
cloudpickle.

Compatible mode is Fory's schema-evolution mode. It writes the metadata readers
and writers need to tolerate schema differences. Xlang mode enables compatible
Expand Down Expand Up @@ -327,7 +328,7 @@ public class Example {
}

public static void main(String[] args) {
Fory fory = Fory.builder().withXlang(true).withCompatible(true).build();
Fory fory = Fory.builder().withXlang(true).build();
fory.register(Person.class, "example.Person");

Person person = new Person();
Expand All @@ -353,7 +354,7 @@ class Person:
name: str
age: pyfory.Int32

fory = pyfory.Fory(xlang=True, compatible=True)
fory = pyfory.Fory(xlang=True)
fory.register_type(Person, typename="example.Person")

data = fory.serialize(Person("Alice", 30))
Expand All @@ -378,7 +379,7 @@ type Person struct {
}

func main() {
f := fory.New(fory.WithXlang(true), fory.WithCompatible(true))
f := fory.New(fory.WithXlang(true))
if err := f.RegisterStructByName(Person{}, "example.Person"); err != nil {
panic(err)
}
Expand All @@ -404,7 +405,7 @@ struct Person {
}

fn main() -> Result<(), Error> {
let mut fory = Fory::builder().xlang(true).compatible(true).build();
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Person>("example", "Person")?;

let bytes = fory.serialize(&Person {
Expand Down Expand Up @@ -434,8 +435,8 @@ struct Person {
FORY_STRUCT(Person, name, age);

int main() {
auto fory = Fory::builder().xlang(true).compatible(true).build();
fory.register_struct<Person>("example.Person");
auto fory = Fory::builder().xlang(true).build();
fory.register_struct<Person>("example", "Person");

auto bytes = fory.serialize(Person{"Alice", 30}).value();
Person person = fory.deserialize<Person>(bytes).value();
Expand All @@ -456,7 +457,7 @@ const personType = Type.struct(
},
);

const fory = new Fory({ compatible: true });
const fory = new Fory();
const { serialize, deserialize } = fory.register(personType);

const bytes = serialize({ name: "Alice", age: 30 });
Expand All @@ -476,9 +477,7 @@ public sealed class Person
public int Age { get; set; }
}

Fory fory = Fory.Builder()
.Compatible(true)
.Build();
Fory fory = Fory.Builder().Build();
fory.Register<Person>("example", "Person");

byte[] bytes = fory.Serialize(new Person { Name = "Alice", Age = 30 });
Expand Down Expand Up @@ -507,7 +506,7 @@ class Person {
}

void main() {
final fory = Fory(compatible: true);
final fory = Fory();
PersonFory.register(
fory,
Person,
Expand Down Expand Up @@ -541,7 +540,7 @@ struct Person {
var age: Int32 = 0
}

let fory = Fory(xlang: true, compatible: true)
let fory = Fory()
try fory.register(Person.self, namespace: "example", name: "Person")

let bytes = try fory.serialize(Person(name: "Alice", age: 30))
Expand All @@ -556,10 +555,7 @@ import org.apache.fory.scala.ForyScala

case class Person(name: String, age: Int)

val fory = ForyScala.builder()
.withXlang(true)
.withCompatible(true)
.build()
val fory = ForyScala.builder().withXlang(true).build()
fory.register(classOf[Person], "example.Person")

val bytes = fory.serialize(Person("Alice", 30))
Expand All @@ -575,10 +571,7 @@ import org.apache.fory.kotlin.ForyKotlin
data class Person(val name: String, val age: Int)

fun main() {
val fory = ForyKotlin.builder()
.withXlang(true)
.withCompatible(true)
.build()
val fory = ForyKotlin.builder().withXlang(true).build()
fory.register(Person::class.java, "example.Person")

val bytes = fory.serialize(Person("Alice", 30))
Expand All @@ -593,10 +586,16 @@ type-mapping rules, see the [cross-language guide](docs/guide/xlang) and

## Native Serialization

Use native mode when the writer and reader are in the same language. Java and
Python can serialize broader language-specific object graphs this way. The
languages below expose an explicit `xlang=false` or native-mode setting; runtimes
without that switch stay on their documented default path.
Use native mode when the writer and reader are in the same language. It is
optimized for each runtime's native type system and can cover language-specific
types, object graphs, and framework-replacement cases that xlang mode keeps out
of the portable wire format. The languages below expose an explicit
`xlang=false` or native-mode setting; runtimes without that switch stay on their
documented default path.

Choose Java native mode for Java/JVM-only replacements of JDK serialization,
Kryo, FST, Hessian, or Java-only Protocol Buffers payloads. Choose Python native
mode when replacing pickle or cloudpickle for Python-only payloads.

Keep class/type registration enabled for untrusted input. See the language guides
for runtime-specific security and compatibility settings.
Expand Down Expand Up @@ -769,12 +768,12 @@ deserialization, see the

**Specifications**

| Specification | Source | Website |
| ---------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Xlang serialization | [xlang_serialization_spec.md](docs/specification/xlang_serialization_spec.md) | [View](https://fory.apache.org/docs/specification/fory_xlang_serialization_spec) |
| Java serialization | [java_serialization_spec.md](docs/specification/java_serialization_spec.md) | [View](https://fory.apache.org/docs/specification/fory_java_serialization_spec) |
| Row format | [row_format_spec.md](docs/specification/row_format_spec.md) | [View](https://fory.apache.org/docs/specification/fory_row_format_spec) |
| Cross-language mapping | [xlang_type_mapping.md](docs/specification/xlang_type_mapping.md) | [View](https://fory.apache.org/docs/specification/fory_xlang_serialization_spec) |
| Specification | Source | Website |
| ---------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Xlang serialization | [xlang_serialization_spec.md](docs/specification/xlang_serialization_spec.md) | [View](https://fory.apache.org/docs/specification/xlang_serialization_spec) |
| Java serialization | [java_serialization_spec.md](docs/specification/java_serialization_spec.md) | [View](https://fory.apache.org/docs/specification/java_serialization_spec) |
| Row format | [row_format_spec.md](docs/specification/row_format_spec.md) | [View](https://fory.apache.org/docs/specification/row_format_spec) |
| Cross-language mapping | [xlang_type_mapping.md](docs/specification/xlang_type_mapping.md) | [View](https://fory.apache.org/docs/specification/xlang_type_mapping) |

## Community

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class ProtobufSerializerTest {
public void testSample() {
Sample object = new Sample().populate(false);
ProtoMessage.Sample samplePb = ProtoBuffersState.buildSample(object);
Fory fory = Fory.builder().requireClassRegistration(false).build();
Fory fory = Fory.builder().withXlang(false).requireClassRegistration(false).build();
fory.register(ProtoMessage.Sample.class);
byte[] bytes = fory.serialize(samplePb);
Object newObj = fory.deserialize(bytes);
Expand All @@ -40,7 +40,7 @@ public void testSample() {

@Test
public void testByteString() {
Fory fory = Fory.builder().requireClassRegistration(false).build();
Fory fory = Fory.builder().withXlang(false).requireClassRegistration(false).build();
Assert.assertEquals(fory.deserialize(fory.serialize(ByteString.empty())), ByteString.empty());
ByteString bytes = ByteString.copyFrom(new byte[] {1, 2, 3});
Assert.assertEquals(fory.deserialize(fory.serialize(bytes)), bytes);
Expand Down
7 changes: 3 additions & 4 deletions compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ The FDL compiler generates cross-language serialization code from schema definit
For comprehensive documentation, see the [FDL Schema Guide](../docs/compiler/index.md):

- [FDL Syntax Reference](../docs/compiler/schema-idl.md) - Complete language syntax and grammar
- [Type System](../docs/compiler/type-system.md) - Primitive types, collections, and language mappings
- [Type System](../docs/compiler/schema-idl.md#type-system) - Primitive types, collections, and language mappings
- [Compiler Guide](../docs/compiler/compiler-guide.md) - CLI options and build integration
- [Generated Code](../docs/compiler/generated-code.md) - Output format for each target language
- [Protocol Buffers vs FDL](../docs/compiler/protobuf-idl.md) - Feature comparison and migration guide
- [Protocol Buffers vs FDL](../docs/compiler/protobuf-idl.md) - Feature comparison and porting guide

## Installation

Expand Down Expand Up @@ -83,7 +83,6 @@ import org.apache.fory.Fory;

Fory fory = Fory.builder()
.withXlang(true)
.withCompatible(true)
.withRefTracking(true)
.withModule(DemoForyModule.INSTANCE)
.build();
Expand All @@ -100,7 +99,7 @@ byte[] bytes = fory.serialize(cat);
import pyfory
from demo import Cat, register_demo_types

fory = pyfory.Fory()
fory = pyfory.Fory(xlang=True)
register_demo_types(fory)

cat = Cat(name="Whiskers", lives=9)
Expand Down
2 changes: 1 addition & 1 deletion compiler/fory_compiler/generators/swift.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ def generate_registration_type(self, indent: int = 0) -> List[str]:
f"{ind}{self.indent_str * 2}nonisolated(unsafe) static let fory: Fory = {{"
)
lines.append(
f"{ind}{self.indent_str * 3}let fory = Fory(config: .init(xlang: true, trackRef: true, compatible: true))"
f"{ind}{self.indent_str * 3}let fory = Fory(config: .init(trackRef: true, compatible: true))"
)
lines.append(f"{ind}{self.indent_str * 3}do {{")
lines.append(f"{ind}{self.indent_str * 4}try register(fory)")
Expand Down
Loading
Loading