Skip to content

Commit 92e7a5c

Browse files
authored
feat(xlang): refine register by name api (#3739)
## Why? ## What does this PR do? ## Related issues ## AI Contribution Checklist - [ ] Substantial AI assistance was used in this PR: `yes` / `no` - [ ] If `yes`, I included a completed [AI Contribution Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs) in this PR description and the required `AI Usage Disclosure`. - [ ] If `yes`, my PR description includes the required `ai_review` summary and screenshot evidence of the final clean AI review results from both fresh reviewers on the current PR diff or current HEAD after the latest code changes. ## Does this PR introduce any user-facing change? - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark
1 parent 7752c01 commit 92e7a5c

151 files changed

Lines changed: 1759 additions & 1156 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ class Person:
370370
age: pyfory.Int32
371371

372372
fory = pyfory.Fory(xlang=True)
373-
fory.register_type(Person, typename="example.Person")
373+
fory.register_type(Person, name="example.Person")
374374

375375
data = fory.serialize(Person("Alice", 30))
376376
person = fory.deserialize(data)
@@ -421,7 +421,7 @@ struct Person {
421421

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

426426
let bytes = fory.serialize(&Person {
427427
name: "Alice".to_string(),
@@ -451,7 +451,7 @@ FORY_STRUCT(Person, name, age);
451451

452452
int main() {
453453
auto fory = Fory::builder().xlang(true).build();
454-
fory.register_struct<Person>("example", "Person");
454+
fory.register_struct<Person>("example.Person");
455455

456456
auto bytes = fory.serialize(Person{"Alice", 30}).value();
457457
Person person = fory.deserialize<Person>(bytes).value();
@@ -525,8 +525,7 @@ void main() {
525525
PersonFory.register(
526526
fory,
527527
Person,
528-
namespace: 'example',
529-
typeName: 'Person',
528+
name: 'example.Person',
530529
);
531530
532531
final bytes = fory.serialize(Person()
@@ -556,7 +555,7 @@ struct Person {
556555
}
557556

558557
let fory = Fory()
559-
try fory.register(Person.self, namespace: "example", name: "Person")
558+
try fory.register(Person.self, name: "example.Person")
560559

561560
let bytes = try fory.serialize(Person(name: "Alice", age: 30))
562561
let person: Person = try fory.deserialize(bytes)

compiler/fory_compiler/generators/dart.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -436,13 +436,15 @@ def _dart_string_literal(self, value: str) -> str:
436436
escaped = value.replace("\\", "\\\\").replace("'", "\\'")
437437
return f"'{escaped}'"
438438

439-
def _registration_defaults(self, type_def: object) -> Tuple[str, str, str]:
439+
def _registration_defaults(self, type_def: object) -> Tuple[str, str]:
440440
if self.should_register_by_id(type_def):
441-
return str(type_def.type_id), "null", "null"
441+
return str(type_def.type_id), "null"
442+
name = self.registration_type_name(type_def)
443+
if self.package:
444+
name = f"{self.package}.{name}"
442445
return (
443446
"null",
444-
self._dart_string_literal(self.package or ""),
445-
self._dart_string_literal(self.registration_type_name(type_def)),
447+
self._dart_string_literal(name),
446448
)
447449

448450
def _supports_direct_container_cast(
@@ -1300,12 +1302,10 @@ def generate_module_type(self, indent: int) -> List[str]:
13001302

13011303
def registration_lines(type_def: object, call_line: str) -> List[str]:
13021304
n = self.local_name(type_def)
1303-
default_id, default_namespace, default_type_name = (
1304-
self._registration_defaults(type_def)
1305-
)
1305+
default_id, default_name = self._registration_defaults(type_def)
13061306
return [
13071307
f"{self.indent_str * (indent + 2)}if (type == {n}) {{",
1308-
f"{self.indent_str * (indent + 3)}{call_line.format(id=default_id, namespace=default_namespace, type_name=default_type_name)}",
1308+
f"{self.indent_str * (indent + 3)}{call_line.format(id=default_id, name=default_name)}",
13091309
f"{self.indent_str * (indent + 3)}return;",
13101310
f"{self.indent_str * (indent + 2)}}}",
13111311
]
@@ -1318,7 +1318,7 @@ def registration_lines(type_def: object, call_line: str) -> List[str]:
13181318
lines.extend(
13191319
registration_lines(
13201320
enum,
1321-
f"registerGeneratedEnum(fory, {schema_name}, id: {{id}}, namespace: {{namespace}}, typeName: {{type_name}});",
1321+
f"registerGeneratedEnum(fory, {schema_name}, id: {{id}}, name: {{name}});",
13221322
)
13231323
)
13241324
for union in self.schema.unions:
@@ -1328,7 +1328,7 @@ def registration_lines(type_def: object, call_line: str) -> List[str]:
13281328
lines.extend(
13291329
registration_lines(
13301330
union,
1331-
f"fory.registerSerializer({n}, const _{n}ForySerializer(), id: {{id}}, namespace: {{namespace}}, typeName: {{type_name}});",
1331+
f"fory.registerSerializer({n}, const _{n}ForySerializer(), id: {{id}}, name: {{name}});",
13321332
)
13331333
)
13341334

@@ -1340,7 +1340,7 @@ def visit_message(message: Message):
13401340
lines.extend(
13411341
registration_lines(
13421342
message,
1343-
f"registerGeneratedStruct(fory, {schema_name}, id: {{id}}, namespace: {{namespace}}, typeName: {{type_name}});",
1343+
f"registerGeneratedStruct(fory, {schema_name}, id: {{id}}, name: {{name}});",
13441344
)
13451345
)
13461346
for enum in message.nested_enums:
@@ -1349,15 +1349,15 @@ def visit_message(message: Message):
13491349
lines.extend(
13501350
registration_lines(
13511351
enum,
1352-
f"registerGeneratedEnum(fory, {schema_name}, id: {{id}}, namespace: {{namespace}}, typeName: {{type_name}});",
1352+
f"registerGeneratedEnum(fory, {schema_name}, id: {{id}}, name: {{name}});",
13531353
)
13541354
)
13551355
for union in message.nested_unions:
13561356
un = self.local_name(union)
13571357
lines.extend(
13581358
registration_lines(
13591359
union,
1360-
f"fory.registerSerializer({un}, const _{un}ForySerializer(), id: {{id}}, namespace: {{namespace}}, typeName: {{type_name}});",
1360+
f"fory.registerSerializer({un}, const _{un}ForySerializer(), id: {{id}}, name: {{name}});",
13611361
)
13621362
)
13631363
for nested in message.nested_messages:

compiler/fory_compiler/generators/python.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ def generate_enum_registration(
10311031
else:
10321032
ns = self.package or "default"
10331033
lines.append(
1034-
f' fory.register_type({class_ref}, namespace="{ns}", typename="{type_name}")'
1034+
f' fory.register_type({class_ref}, name="{ns}.{type_name}")'
10351035
)
10361036

10371037
def generate_message_registration(
@@ -1048,7 +1048,7 @@ def generate_message_registration(
10481048
else:
10491049
ns = self.package or "default"
10501050
lines.append(
1051-
f' fory.register_type({class_ref}, namespace="{ns}", typename="{type_name}")'
1051+
f' fory.register_type({class_ref}, name="{ns}.{type_name}")'
10521052
)
10531053

10541054
# Register nested enums
@@ -1081,5 +1081,5 @@ def generate_union_registration(
10811081
else:
10821082
ns = self.package or "default"
10831083
lines.append(
1084-
f' fory.register_union({class_ref}, namespace="{ns}", typename="{type_name}", serializer={serializer_ref}(fory.type_resolver))'
1084+
f' fory.register_union({class_ref}, name="{ns}.{type_name}", serializer={serializer_ref}(fory.type_resolver))'
10851085
)

compiler/fory_compiler/generators/swift.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,16 +1262,12 @@ def generate_module_type(self, indent: int = 0) -> List[str]:
12621262
continue
12631263

12641264
schema_type_name = self.schema_type_name(type_def)
1265-
escaped_name = schema_type_name.replace('"', '\\"')
12661265
if namespace:
1267-
escaped_ns = namespace.replace('"', '\\"')
1268-
lines.append(
1269-
f'{ind}{self.indent_str * 2}try fory.register({type_name}.self, namespace: "{escaped_ns}", name: "{escaped_name}")'
1270-
)
1271-
else:
1272-
lines.append(
1273-
f'{ind}{self.indent_str * 2}try fory.register({type_name}.self, name: "{escaped_name}")'
1274-
)
1266+
schema_type_name = f"{namespace}.{schema_type_name}"
1267+
escaped_name = schema_type_name.replace('"', '\\"')
1268+
lines.append(
1269+
f'{ind}{self.indent_str * 2}try fory.register({type_name}.self, name: "{escaped_name}")'
1270+
)
12751271
lines.append(f"{ind}{self.indent_str}" + "}")
12761272

12771273
lines.append(f"{ind}" + "}")

compiler/fory_compiler/tests/test_dart_generator.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_dart_generator_emits_annotated_structs_and_generated_part_registration(
6868
assert "int fixedValue = 0;" in file.content
6969
assert "Uint64 taggedValue = Uint64(0);" in file.content
7070
assert (
71-
"registerGeneratedStruct(fory, _scalarForySchema, id: 100, namespace: null, typeName: null);"
71+
"registerGeneratedStruct(fory, _scalarForySchema, id: 100, name: null);"
7272
in file.content
7373
)
7474
assert "abstract final class DemoForyModule" in file.content
@@ -98,7 +98,7 @@ def test_dart_generator_keeps_enum_helpers_in_source_and_uses_generated_enum_reg
9898
assert "static Status fromRawValue(int value) => switch (value) {" in file.content
9999
assert "_StatusForySerializer" not in file.content
100100
assert (
101-
"registerGeneratedEnum(fory, _statusForySchema, id: 101, namespace: null, typeName: null);"
101+
"registerGeneratedEnum(fory, _statusForySchema, id: 101, name: null);"
102102
in file.content
103103
)
104104

@@ -140,7 +140,7 @@ def test_dart_generator_keeps_union_serializers_direct_and_marks_union_types():
140140
assert "void write(" not in file.content
141141
assert "Animal read(" not in file.content
142142
assert (
143-
"fory.registerSerializer(Animal, const _AnimalForySerializer(), id: 101, namespace: null, typeName: null);"
143+
"fory.registerSerializer(Animal, const _AnimalForySerializer(), id: 101, name: null);"
144144
in file.content
145145
)
146146

@@ -330,11 +330,11 @@ def test_dart_generator_uses_name_registration_when_auto_id_disabled():
330330
)
331331

332332
assert (
333-
"registerGeneratedStruct(fory, _envelopeForySchema, id: null, namespace: 'demo', typeName: 'Envelope');"
333+
"registerGeneratedStruct(fory, _envelopeForySchema, id: null, name: 'demo.Envelope');"
334334
in file.content
335335
)
336336
assert (
337-
"registerGeneratedStruct(fory, _envelopePayloadForySchema, id: null, namespace: 'demo', typeName: 'Envelope.Payload');"
337+
"registerGeneratedStruct(fory, _envelopePayloadForySchema, id: null, name: 'demo.Envelope.Payload');"
338338
in file.content
339339
)
340340

compiler/fory_compiler/tests/test_generated_code.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,77 @@ def test_java_nested_name_registration_uses_owner_namespace():
613613
)
614614

615615

616+
def test_generated_registration_uses_single_name_for_dart_python_swift():
617+
schema = parse_fdl(
618+
"""
619+
option enable_auto_type_id = false;
620+
package demo;
621+
622+
message Envelope {
623+
message Payload {
624+
int32 value = 1;
625+
}
626+
627+
enum Kind {
628+
UNKNOWN = 0;
629+
ACTIVE = 1;
630+
}
631+
632+
union Choice {
633+
Payload payload = 1;
634+
string note = 2;
635+
}
636+
637+
Payload payload = 1;
638+
Kind kind = 2;
639+
Choice choice = 3;
640+
}
641+
"""
642+
)
643+
644+
dart_output = render_files(generate_files(schema, DartGenerator))
645+
assert (
646+
"registerGeneratedStruct(fory, _envelopeForySchema, id: null, name: 'demo.Envelope');"
647+
in dart_output
648+
)
649+
assert (
650+
"registerGeneratedEnum(fory, _envelopeKindForySchema, id: null, name: 'demo.Envelope.Kind');"
651+
in dart_output
652+
)
653+
assert (
654+
"fory.registerSerializer(Envelope_Choice, const _Envelope_ChoiceForySerializer(), id: null, name: 'demo.Envelope.Choice');"
655+
in dart_output
656+
)
657+
assert "namespace:" not in dart_output
658+
assert "typeName:" not in dart_output
659+
660+
python_output = render_files(generate_files(schema, PythonGenerator))
661+
assert 'fory.register_type(Envelope, name="demo.Envelope")' in python_output
662+
assert (
663+
'fory.register_type(Envelope.Kind, name="demo.Envelope.Kind")' in python_output
664+
)
665+
assert (
666+
'fory.register_union(Envelope.Choice, name="demo.Envelope.Choice", serializer=Envelope.ChoiceSerializer(fory.type_resolver))'
667+
in python_output
668+
)
669+
assert "namespace=" not in python_output
670+
assert "typename=" not in python_output
671+
672+
swift_output = render_files(generate_files(schema, SwiftGenerator))
673+
assert (
674+
'try fory.register(Demo.Envelope.self, name: "demo.Envelope")' in swift_output
675+
)
676+
assert (
677+
'try fory.register(Demo.Envelope.Kind.self, name: "demo.Envelope.Kind")'
678+
in swift_output
679+
)
680+
assert (
681+
'try fory.register(Demo.Envelope.Choice.self, name: "demo.Envelope.Choice")'
682+
in swift_output
683+
)
684+
assert "namespace:" not in swift_output
685+
686+
616687
def test_java_default_package_import_registers_dependency(tmp_path):
617688
common = tmp_path / "common.fdl"
618689
common.write_text(

0 commit comments

Comments
 (0)