This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 3cd75123c refactor(dart): register xlang types by Type (#3332)
3cd75123c is described below

commit 3cd75123cf73ddc1d229425debf1ab0c8c831e43
Author: Shawn Yang <[email protected]>
AuthorDate: Tue Feb 17 21:41:51 2026 +0800

    refactor(dart): register xlang types by Type (#3332)
    
    ## Why?
    
    - Dart registration currently requires generated `$TypeName` schema
    symbols, which exposes codegen internals and makes usage less ergonomic.
    - Cross-language Dart tests relied on a large hand-maintained schema
    definition file, which is hard to maintain and easy to drift.
    - Some declared-type serializer and type-fingerprint paths need stronger
    handling to keep schema behavior consistent.
    
    
    ## What does this PR do?
    
    - Refactors Dart registration APIs to register by `Type` (`register`,
    `registerType`, `registerStruct`, `registerEnum`, `registerUnion`)
    instead of passing `CustomTypeSpec` directly.
    - Adds `SpecLookup` with manual registration plus mirrors/stub lookup so
    generated specs can be resolved from `Type` at runtime.
    - Adds `ref` support to `@ForyKey` and propagates it through codegen to
    field `trackingRef` metadata.
    - Updates class/list/map deserialization paths to resolve registered
    serializers for declared element/key/value/field types and throw clearer
    state errors when declared type metadata is missing.
    - Aligns field sorting and struct hash fingerprinting for
    `INT32`/`INT64` by mapping them to `VAR_INT32`/`VAR_INT64` IDs.
    - Replaces the large manual xlang test schema file with
    annotation-driven models and migrates Dart examples/tests/perf usage
    from `$TypeName` registration to `Type` registration.
    
    
    ## Related issues
    
    
    
    ## Does this PR introduce any user-facing change?
    
    - Dart registration usage changes from generated spec symbols (for
    example, `$Person`) to Dart types (for example, `Person`).
    
    - [x] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
    
    N/A
---
 .github/workflows/ci.yml                           |    4 +
 dart/example/example.dart                          |    4 +-
 dart/example/example.g.dart                        |    5 -
 dart/example/nested_collection_example.dart        |    2 +-
 dart/example/nested_collection_example.g.dart      |    5 -
 dart/example/typed_data_array_example.dart         |    2 +-
 dart/example/typed_data_array_example.g.dart       |    5 -
 .../fory-test/lib/entity/complex_obj_1.dart        |    2 +-
 .../fory-test/lib/entity/complex_obj_2.dart        |    2 +-
 .../fory-test/lib/entity/complex_obj_3.dart        |    2 +-
 .../fory-test/lib/entity/complex_obj_4.dart        |    2 +-
 .../fory-test/lib/entity/simple_struct1.dart       |    2 +-
 dart/packages/fory-test/lib/entity/some_class.dart |    2 +-
 dart/packages/fory-test/lib/entity/time_obj.dart   |    2 +-
 .../lib/entity/uint_annotated_struct.dart          |    2 +-
 .../packages/fory-test/lib/entity/uint_struct.dart |    2 +-
 .../fory-test/lib/entity/xlang_test_models.dart    |  293 ++++
 .../codegen_test/simple_struct_codegen_test.dart   |    6 +-
 .../cross_lang_struct_serialization_test.dart      |   10 +-
 .../cross_lang_test/cross_language_type_test.dart  |    8 +-
 .../register_serialization_test.dart               |    2 +-
 .../test/cross_lang_test/units/algorithm_test.dart |    2 +-
 .../cross_lang_test/units/preserve_type_test.dart  |    2 +-
 .../test/cross_lang_test/xlang_test_defs.dart      | 1723 --------------------
 .../test/cross_lang_test/xlang_test_main.dart      |   80 +-
 .../fory-test/test/perf_test/serial_perf_test.dart |   20 +-
 .../struct_test/uint_annotated_struct_test.dart    |   12 +-
 .../test/struct_test/uint_struct_test.dart         |    6 +-
 dart/packages/fory/README.md                       |    8 +-
 dart/packages/fory/example/example.dart            |    4 +-
 dart/packages/fory/example/example.g.dart          |    5 -
 .../packages/fory/lib/src/annotation/fory_key.dart |    4 +
 .../impl/annotation/key_annotation_analyzer.dart   |    3 +
 .../analyze/impl/field/field_analyzer_impl.dart    |    1 +
 .../codegen/meta/impl/class_spec_generator.dart    |   17 -
 .../codegen/meta/impl/field_spec_immutable.dart    |    9 +-
 dart/packages/fory/lib/src/fory_impl.dart          |   40 +-
 .../fory/lib/src/meta/specs/field_sorter.dart      |    4 +-
 .../lib/src/resolver/impl/type_resolver_impl.dart  |  107 ++
 .../fory/lib/src/resolver/spec_lookup.dart         |   52 +
 .../fory/lib/src/resolver/spec_lookup_mirrors.dart |   89 +
 .../fory/lib/src/resolver/spec_lookup_stub.dart}   |   11 +-
 .../lib/src/resolver/struct_hash_resolver.dart     |    6 +
 .../fory/lib/src/resolver/type_resolver.dart       |   26 +-
 .../fory/lib/src/serializer/class_serializer.dart  |   18 +
 .../collection/list/list_serializer.dart           |    7 +-
 .../serializer/collection/map/map_serializer.dart  |   39 +-
 .../java/org/apache/fory/xlang/DartXlangTest.java  |   31 +-
 48 files changed, 785 insertions(+), 1905 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8071b79da..e289bbe06 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -708,6 +708,10 @@ jobs:
         run: |
           cd dart
           dart pub get
+      - name: Generate Dart code
+        run: |
+          cd dart/packages/fory-test
+          dart run build_runner build --delete-conflicting-outputs
       - name: Run Dart Xlang Test
         env:
           FORY_DART_JAVA_CI: "1"
diff --git a/dart/example/example.dart b/dart/example/example.dart
index 12b965991..44b88a6e5 100644
--- a/dart/example/example.dart
+++ b/dart/example/example.dart
@@ -24,7 +24,7 @@ import 'package:fory/fory.dart';
 part 'example.g.dart';
 
 @foryClass
-class Person with _$PersonFory {
+class Person {
   final String firstName, lastName;
   final int age;
   final LocalDate dateOfBirth;
@@ -34,7 +34,7 @@ class Person with _$PersonFory {
 
 void main() {
   Fory fory = Fory(ref: true);
-  fory.register($Person, typename: "example.Person");
+  fory.register(Person, typename: "example.Person");
   Person obj = Person('Leo', 'Leo', 21, LocalDate(2004, 1, 1));
 
   // Serialize
diff --git a/dart/example/example.g.dart b/dart/example/example.g.dart
index 31635b0ab..016177afb 100644
--- a/dart/example/example.g.dart
+++ b/dart/example/example.g.dart
@@ -99,8 +99,3 @@ final $Person = TypeSpec(
   ),
   null,
 );
-
-mixin _$PersonFory implements ForyTypeProvider {
-  @override
-  Type get foryType => Person;
-}
diff --git a/dart/example/nested_collection_example.dart 
b/dart/example/nested_collection_example.dart
index 805932705..0754ca6a5 100644
--- a/dart/example/nested_collection_example.dart
+++ b/dart/example/nested_collection_example.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
 part 'nested_collection_example.g.dart';
 
 @foryClass
-class NestedObject with _$NestedObjectFory {
+class NestedObject {
   late final String name;
   late final List<String> names;
   late final Map<double, Map<String, int>> map;
diff --git a/dart/example/nested_collection_example.g.dart 
b/dart/example/nested_collection_example.g.dart
index 919e914fa..4f9ff7110 100644
--- a/dart/example/nested_collection_example.g.dart
+++ b/dart/example/nested_collection_example.g.dart
@@ -127,8 +127,3 @@ final $NestedObject = TypeSpec(
   null,
   () => NestedObject(),
 );
-
-mixin _$NestedObjectFory implements ForyTypeProvider {
-  @override
-  Type get foryType => NestedObject;
-}
diff --git a/dart/example/typed_data_array_example.dart 
b/dart/example/typed_data_array_example.dart
index a314d810e..ef630c7f5 100644
--- a/dart/example/typed_data_array_example.dart
+++ b/dart/example/typed_data_array_example.dart
@@ -24,7 +24,7 @@ import 'package:fory/fory.dart';
 part 'typed_data_array_example.g.dart';
 
 @foryClass
-class TypedDataArrayExample with _$TypedDataArrayExampleFory {
+class TypedDataArrayExample {
   late final Uint8List bytes;
   late final Int32List nums;
   late final BoolList bools;
diff --git a/dart/example/typed_data_array_example.g.dart 
b/dart/example/typed_data_array_example.g.dart
index 4526efbe8..50d5fd60d 100644
--- a/dart/example/typed_data_array_example.g.dart
+++ b/dart/example/typed_data_array_example.g.dart
@@ -82,8 +82,3 @@ final $TypedDataArrayExample = TypeSpec(
   null,
   () => TypedDataArrayExample(),
 );
-
-mixin _$TypedDataArrayExampleFory implements ForyTypeProvider {
-  @override
-  Type get foryType => TypedDataArrayExample;
-}
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_1.dart 
b/dart/packages/fory-test/lib/entity/complex_obj_1.dart
index b580cfc39..37be47dc2 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_1.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_1.dart
@@ -24,7 +24,7 @@ import 'package:fory_test/extensions/map_ext.dart';
 part '../generated/complex_obj_1.g.dart';
 
 @foryClass
-class ComplexObject1 with _$ComplexObject1Fory {
+class ComplexObject1 {
   late Object f1;
   late String f2;
   late List<Object> f3;
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_2.dart 
b/dart/packages/fory-test/lib/entity/complex_obj_2.dart
index 1cf17f58e..8b96ea764 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_2.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_2.dart
@@ -23,7 +23,7 @@ import 'package:fory_test/extensions/map_ext.dart';
 part '../generated/complex_obj_2.g.dart';
 
 @ForyClass(promiseAcyclic: true)
-class ComplexObject2 with _$ComplexObject2Fory {
+class ComplexObject2 {
   final Object f1;
   final Map<Int8, Int32> f2;
 
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_3.dart 
b/dart/packages/fory-test/lib/entity/complex_obj_3.dart
index 4a6abbfa4..7949ff23b 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_3.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_3.dart
@@ -24,7 +24,7 @@ import 'package:fory_test/extensions/map_ext.dart';
 part '../generated/complex_obj_3.g.dart';
 
 @foryClass
-class ComplexObject3 with _$ComplexObject3Fory {
+class ComplexObject3 {
   late final List<Map<int, Float32>> f1;
   late final HashMap<String, List<SplayTreeMap<int, Float32>>> f2;
   late final LinkedHashMap<String, HashSet<Int8>> f3;
diff --git a/dart/packages/fory-test/lib/entity/complex_obj_4.dart 
b/dart/packages/fory-test/lib/entity/complex_obj_4.dart
index 02e2c37c0..b76c9ec65 100644
--- a/dart/packages/fory-test/lib/entity/complex_obj_4.dart
+++ b/dart/packages/fory-test/lib/entity/complex_obj_4.dart
@@ -23,7 +23,7 @@ import 'package:fory_test/extensions/map_ext.dart';
 part '../generated/complex_obj_4.g.dart';
 
 @foryClass
-class ComplexObject4 with _$ComplexObject4Fory {
+class ComplexObject4 {
   late String f1;
   late String f2;
   late List<String> f3;
diff --git a/dart/packages/fory-test/lib/entity/simple_struct1.dart 
b/dart/packages/fory-test/lib/entity/simple_struct1.dart
index dc1794b67..bcaf3e719 100644
--- a/dart/packages/fory-test/lib/entity/simple_struct1.dart
+++ b/dart/packages/fory-test/lib/entity/simple_struct1.dart
@@ -21,7 +21,7 @@ import 'package:fory/fory.dart';
 part '../generated/simple_struct1.g.dart';
 
 @foryClass
-class SimpleStruct1 with _$SimpleStruct1Fory {
+class SimpleStruct1 {
   late Int32 a;
 
   @override
diff --git a/dart/packages/fory-test/lib/entity/some_class.dart 
b/dart/packages/fory-test/lib/entity/some_class.dart
index 78eb65fdb..2ea6eab7b 100644
--- a/dart/packages/fory-test/lib/entity/some_class.dart
+++ b/dart/packages/fory-test/lib/entity/some_class.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
 part '../generated/some_class.g.dart';
 
 @foryClass
-class SomeClass with _$SomeClassFory {
+class SomeClass {
   late int id;
   late String name;
   late Map<String, double> map;
diff --git a/dart/packages/fory-test/lib/entity/time_obj.dart 
b/dart/packages/fory-test/lib/entity/time_obj.dart
index 55f0f1837..302c6f48c 100644
--- a/dart/packages/fory-test/lib/entity/time_obj.dart
+++ b/dart/packages/fory-test/lib/entity/time_obj.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
 part '../generated/time_obj.g.dart';
 
 @ForyClass(promiseAcyclic: true)
-class TimeObj with _$TimeObjFory {
+class TimeObj {
   final LocalDate date1;
   final LocalDate date2;
   final LocalDate date3;
diff --git a/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart 
b/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
index dcc8b0595..bea56b34f 100644
--- a/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
+++ b/dart/packages/fory-test/lib/entity/uint_annotated_struct.dart
@@ -24,7 +24,7 @@ part '../generated/uint_annotated_struct.g.dart';
 /// Test struct for uint type annotations.
 /// Uses native int types with annotations to specify serialization format.
 @ForyClass(promiseAcyclic: true)
-class UIntAnnotatedStruct with _$UIntAnnotatedStructFory {
+class UIntAnnotatedStruct {
   @Uint8Type()
   final int age;
 
diff --git a/dart/packages/fory-test/lib/entity/uint_struct.dart 
b/dart/packages/fory-test/lib/entity/uint_struct.dart
index 70563e12b..ba7fa3515 100644
--- a/dart/packages/fory-test/lib/entity/uint_struct.dart
+++ b/dart/packages/fory-test/lib/entity/uint_struct.dart
@@ -22,7 +22,7 @@ import 'package:fory/fory.dart';
 part '../generated/uint_struct.g.dart';
 
 @ForyClass(promiseAcyclic: true)
-class UIntStruct with _$UIntStructFory {
+class UIntStruct {
   final UInt8 age;
   final UInt16 port;
   final UInt32 count;
diff --git a/dart/packages/fory-test/lib/entity/xlang_test_models.dart 
b/dart/packages/fory-test/lib/entity/xlang_test_models.dart
new file mode 100644
index 000000000..6f9aef9b9
--- /dev/null
+++ b/dart/packages/fory-test/lib/entity/xlang_test_models.dart
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import 'package:fory/fory.dart';
+import 'package:fory/src/resolver/spec_lookup.dart';
+
+part '../generated/xlang_test_models.g.dart';
+
+bool _xlangSpecLookupReady = false;
+
+void _ensureXlangSpecLookupReady() {
+  if (_xlangSpecLookupReady) {
+    return;
+  }
+  SpecLookup.register($TestEnum);
+  SpecLookup.register($TwoEnumFieldStructEvolution);
+  SpecLookup.register($RefOverrideElement);
+  SpecLookup.register($RefOverrideContainer);
+  SpecLookup.register($NullableComprehensiveCompatible);
+  SpecLookup.register($Color);
+  SpecLookup.register($Item);
+  SpecLookup.register($SimpleStruct);
+  SpecLookup.register($Item1);
+  SpecLookup.register($StructWithList);
+  SpecLookup.register($StructWithMap);
+  SpecLookup.register($VersionCheckStruct);
+  SpecLookup.register($OneStringFieldStruct);
+  SpecLookup.register($TwoStringFieldStruct);
+  SpecLookup.register($OneEnumFieldStruct);
+  SpecLookup.register($TwoEnumFieldStruct);
+  SpecLookup.register($NullableComprehensiveSchemaConsistent);
+  SpecLookup.register($RefInnerSchemaConsistent);
+  SpecLookup.register($RefOuterSchemaConsistent);
+  SpecLookup.register($RefInnerCompatible);
+  SpecLookup.register($RefOuterCompatible);
+  SpecLookup.register($CircularRefStruct);
+  _xlangSpecLookupReady = true;
+}
+
+void registerXlangStruct(
+  Fory fory,
+  Type type, {
+  int? typeId,
+  String? namespace,
+  String? typename,
+}) {
+  _ensureXlangSpecLookupReady();
+  fory.registerStruct(
+    type,
+    typeId: typeId,
+    namespace: namespace,
+    typename: typename,
+  );
+}
+
+void registerXlangEnum(
+  Fory fory,
+  Type type, {
+  int? typeId,
+  String? namespace,
+  String? typename,
+}) {
+  _ensureXlangSpecLookupReady();
+  fory.registerEnum(
+    type,
+    typeId: typeId,
+    namespace: namespace,
+    typename: typename,
+  );
+}
+
+@foryEnum
+enum TestEnum {
+  VALUE_A,
+  VALUE_B,
+  VALUE_C,
+}
+
+@foryClass
+class TwoEnumFieldStructEvolution {
+  TestEnum f1 = TestEnum.VALUE_A;
+
+  @ForyKey(includeFromFory: false)
+  TestEnum f2 = TestEnum.VALUE_A;
+}
+
+@foryClass
+class RefOverrideElement {
+  Int32 id = Int32(0);
+  String name = '';
+}
+
+@foryClass
+class RefOverrideContainer {
+  List<RefOverrideElement> listField = <RefOverrideElement>[];
+  Map<String, RefOverrideElement> mapField = <String, RefOverrideElement>{};
+}
+
+@foryClass
+class NullableComprehensiveCompatible {
+  double boxedDouble = 0.0;
+  double doubleField = 0.0;
+  Float32 boxedFloat = Float32(0);
+  Float32 floatField = Float32(0);
+  Int16 shortField = Int16(0);
+  Int8 byteField = Int8(0);
+  bool boolField = false;
+  bool boxedBool = false;
+  int boxedLong = 0;
+  int longField = 0;
+  Int32 boxedInt = Int32(0);
+  Int32 intField = Int32(0);
+
+  double? nullableDouble1;
+  Float32? nullableFloat1;
+  bool? nullableBool1;
+  int? nullableLong1;
+  Int32? nullableInt1;
+
+  String? nullableString2;
+  String stringField = '';
+  List<String?> listField = <String?>[];
+  List<String?>? nullableList2;
+  Set<String?>? nullableSet2;
+  Set<String?> setField = <String?>{};
+  Map<String?, String?> mapField = <String?, String?>{};
+  Map<String?, String?>? nullableMap2;
+
+  void normalizeForCompatibleRoundTrip() {
+    nullableDouble1 ??= 0.0;
+    nullableFloat1 ??= Float32(0);
+    nullableBool1 ??= false;
+    nullableLong1 ??= 0;
+    nullableInt1 ??= Int32(0);
+    nullableString2 ??= '';
+    nullableList2 ??= <String>[];
+    nullableSet2 ??= <String>{};
+    nullableMap2 ??= <String, String>{};
+  }
+}
+
+@foryEnum
+enum Color {
+  Green,
+  Red,
+  Blue,
+  White,
+}
+
+@foryClass
+class Item {
+  String name = '';
+}
+
+@foryClass
+class SimpleStruct {
+  Map<Int32?, double?> f1 = <Int32?, double?>{};
+  Int32 f2 = Int32(0);
+  Item f3 = Item();
+  String f4 = '';
+  Color f5 = Color.Green;
+  List<String> f6 = <String>[];
+  Int32 f7 = Int32(0);
+  Int32 f8 = Int32(0);
+  Int32 last = Int32(0);
+}
+
+@foryClass
+class Item1 {
+  Int32 f1 = Int32(0);
+  Int32 f2 = Int32(0);
+  Int32 f3 = Int32(0);
+  Int32 f4 = Int32(0);
+  Int32 f5 = Int32(0);
+  Int32 f6 = Int32(0);
+}
+
+@foryClass
+class StructWithList {
+  List<String?> items = <String?>[];
+}
+
+@foryClass
+class StructWithMap {
+  Map<String?, String?> data = <String?, String?>{};
+}
+
+@foryClass
+class VersionCheckStruct {
+  Int32 f1 = Int32(0);
+  String? f2 = '';
+  double f3 = 0.0;
+}
+
+@foryClass
+class OneStringFieldStruct {
+  String? f1 = '';
+}
+
+@foryClass
+class TwoStringFieldStruct {
+  String f1 = '';
+  String f2 = '';
+}
+
+@foryClass
+class OneEnumFieldStruct {
+  TestEnum f1 = TestEnum.VALUE_A;
+}
+
+@foryClass
+class TwoEnumFieldStruct {
+  TestEnum f1 = TestEnum.VALUE_A;
+  TestEnum f2 = TestEnum.VALUE_A;
+}
+
+@foryClass
+class NullableComprehensiveSchemaConsistent {
+  Int8 byteField = Int8(0);
+  Int16 shortField = Int16(0);
+  Int32 intField = Int32(0);
+  int longField = 0;
+  Float32 floatField = Float32(0);
+  double doubleField = 0.0;
+  bool boolField = false;
+  String stringField = '';
+  List<String?> listField = <String?>[];
+  Set<String?> setField = <String?>{};
+  Map<String?, String?> mapField = <String?, String?>{};
+  Int32? nullableInt;
+  int? nullableLong;
+  Float32? nullableFloat;
+  double? nullableDouble;
+  bool? nullableBool;
+  String? nullableString;
+  List<String?>? nullableList;
+  Set<String?>? nullableSet;
+  Map<String?, String?>? nullableMap;
+}
+
+@foryClass
+class RefInnerSchemaConsistent {
+  Int32 id = Int32(0);
+  String name = '';
+}
+
+@foryClass
+class RefOuterSchemaConsistent {
+  @ForyKey(ref: true)
+  RefInnerSchemaConsistent? inner1;
+
+  @ForyKey(ref: true)
+  RefInnerSchemaConsistent? inner2;
+}
+
+@foryClass
+class RefInnerCompatible {
+  Int32 id = Int32(0);
+  String name = '';
+}
+
+@foryClass
+class RefOuterCompatible {
+  @ForyKey(ref: true)
+  RefInnerCompatible? inner1;
+
+  @ForyKey(ref: true)
+  RefInnerCompatible? inner2;
+}
+
+@foryClass
+class CircularRefStruct {
+  String name = '';
+
+  @ForyKey(ref: true)
+  CircularRefStruct? selfRef;
+}
diff --git 
a/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart 
b/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
index 9763d6b67..a9e190f40 100644
--- a/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
+++ b/dart/packages/fory-test/test/codegen_test/simple_struct_codegen_test.dart
@@ -51,14 +51,13 @@ void main() {
       check(variables.equals(['\$EnumFoo', '\$EnumSubClass'])).isTrue();
     });
 
-    test('generates TypeSpec and mixin from time_obj.dart', () async {
+    test('generates TypeSpec without mixin from time_obj.dart', () async {
       // await runBuild();
       AssetId inputId = AssetId('fory-test', 'lib/entity/time_obj.dart');
       var lib = await resolveAsset(inputId, (resolver) async {
         return resolver.libraryFor(inputId);
       });
       List<String> variables = [];
-      List<String> mixins = [];
       for (var libPart in lib.children) {
         for (var ele in libPart.children) {
           if (ele is VariableElement) {
@@ -67,15 +66,12 @@ void main() {
               // print('found EnumSpec: ${ele.name}');
               variables.add(ele.name);
             }
-          } else if (ele is MixinElement) {
-            mixins.add(ele.name);
           }
         }
       }
       check(variables.equals([
         '\$TimeObj',
       ])).isTrue();
-      check(mixins).contains('_\$TimeObjFory');
     });
   });
 }
diff --git 
a/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
 
b/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
index 24e554996..7059910ab 100644
--- 
a/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
+++ 
b/dart/packages/fory-test/test/cross_lang_test/cross_lang_struct_serialization_test.dart
@@ -39,7 +39,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($SimpleStruct1, typename: "SimpleStruct1");
+      fory.register(SimpleStruct1, typename: "SimpleStruct1");
       SimpleStruct1 obj = SimpleStruct1();
       obj.a = Int32.maxValue;
       Uint8List lis = fory.serialize(obj);
@@ -51,7 +51,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject2, typename: "test.ComplexObject2");
+      fory.register(ComplexObject2, typename: "test.ComplexObject2");
       ComplexObject2 o = ComplexObject2(true, {Int8(-1): Int32(2)});
       CrossLangUtil.structRoundBack(fory, o, "test_serialize_simple_struct");
     },
@@ -62,8 +62,8 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject2, typename: "test.ComplexObject2");
-      fory.register($ComplexObject1, typename: "test.ComplexObject1");
+      fory.register(ComplexObject2, typename: "test.ComplexObject2");
+      fory.register(ComplexObject1, typename: "test.ComplexObject1");
       ComplexObject2 obj2 = ComplexObject2(true, {Int8(-1): Int32(2)});
       ComplexObject1 obj = ComplexObject1();
       obj.f1 = obj2;
@@ -119,7 +119,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject3, typename: "test.ComplexObject3");
+      fory.register(ComplexObject3, typename: "test.ComplexObject3");
       ComplexObject3 obj = ComplexObject3();
 
       Map<int, Float32> map1 = {
diff --git 
a/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart 
b/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
index 1ee145c66..a4559b41b 100644
--- a/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/cross_language_type_test.dart
@@ -105,10 +105,10 @@ void _basicTypeTest(bool ref) {
   check('2023年10月23日').equals(serDe(fory1, fory2, '2023年10月23日'));
   check(true).equals(CrossLangUtil.serDe(fory1, fory2, true));
 
-  fory1.register($EnumFoo);
-  fory2.register($EnumFoo);
-  fory1.register($EnumSubClass);
-  fory2.register($EnumSubClass);
+  fory1.register(EnumFoo);
+  fory2.register(EnumFoo);
+  fory1.register(EnumSubClass);
+  fory2.register(EnumSubClass);
 
   check(EnumFoo.A).equals(serDe(fory1, fory2, EnumFoo.A));
   check(EnumFoo.B).equals(serDe(fory1, fory2, EnumFoo.B));
diff --git 
a/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart 
b/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
index a766aa8d8..eef6a2ed0 100644
--- 
a/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
+++ 
b/dart/packages/fory-test/test/cross_lang_test/register_serialization_test.dart
@@ -59,7 +59,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject1, typename: "test.ComplexObject1");
+      fory.register(ComplexObject1, typename: "test.ComplexObject1");
       fory.registerSerializer(ComplexObject1, const 
ComplexObject1Serializer());
 
       ComplexObject1 obj = ComplexObject1();
diff --git 
a/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart 
b/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
index 19f05ce71..94a8de448 100644
--- a/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/units/algorithm_test.dart
@@ -51,7 +51,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject1, typename: "test.ComplexObject1");
+      fory.register(ComplexObject1, typename: "test.ComplexObject1");
       var hashPair = fory.structHashPairForTest(ComplexObject1);
       ByteData byteData = ByteData(4);
       byteData.setUint32(0, hashPair.fromForyHash, Endian.little);
diff --git 
a/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart 
b/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
index 48114eb39..9c3b1106a 100644
--- a/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/units/preserve_type_test.dart
@@ -180,7 +180,7 @@ void main() {
         TimeStamp(-1714490301000000),
       );
 
-      fory.register($TimeObj, typename: "test.TimeObj");
+      fory.register(TimeObj, typename: "test.TimeObj");
       Object? obj1 = _roundTrip(fory, timeObj);
       check(obj1).isNotNull().isA<TimeObj>();
       TimeObj timeObj1 = obj1 as TimeObj;
diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart 
b/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart
deleted file mode 100644
index 51bfcf9b8..000000000
--- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart
+++ /dev/null
@@ -1,1723 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-part of 'xlang_test_main.dart';
-
-enum TestEnum {
-  VALUE_A,
-  VALUE_B,
-  VALUE_C,
-}
-
-const EnumSpec _testEnumSpec = EnumSpec(
-  TestEnum,
-  TestEnum.values,
-);
-
-class TwoEnumFieldStructEvolution {
-  TestEnum f1 = TestEnum.VALUE_A;
-  TestEnum f2 = TestEnum.VALUE_A;
-}
-
-final TypeSpec _twoEnumFieldStructEvolutionSpec = TypeSpec(
-  TwoEnumFieldStructEvolution,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(
-        TestEnum,
-        ObjType.ENUM,
-        false,
-        true,
-        _testEnumSpec,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as TwoEnumFieldStructEvolution).f1,
-      (Object inst, dynamic v) =>
-          (inst as TwoEnumFieldStructEvolution).f1 = v as TestEnum,
-    ),
-    FieldSpec(
-      'f2',
-      const FieldTypeSpec(
-        TestEnum,
-        ObjType.ENUM,
-        false,
-        true,
-        _testEnumSpec,
-        [],
-      ),
-      false,
-      true,
-      (Object inst) => (inst as TwoEnumFieldStructEvolution).f2,
-      (Object inst, dynamic v) =>
-          (inst as TwoEnumFieldStructEvolution).f2 = v as TestEnum,
-    ),
-  ],
-  null,
-  () => TwoEnumFieldStructEvolution(),
-);
-
-class RefOverrideElement {
-  Int32 id = Int32(0);
-  String name = '';
-}
-
-class RefOverrideContainer {
-  List<RefOverrideElement> listField = <RefOverrideElement>[];
-  Map<String, RefOverrideElement> mapField = <String, RefOverrideElement>{};
-}
-
-final TypeSpec _refOverrideElementSpec = TypeSpec(
-  RefOverrideElement,
-  false,
-  true,
-  [
-    FieldSpec(
-      'id',
-      const FieldTypeSpec(
-        Int32,
-        ObjType.VAR_INT32,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as RefOverrideElement).id,
-      (Object inst, dynamic v) => (inst as RefOverrideElement).id = v as Int32,
-    ),
-    FieldSpec(
-      'name',
-      const FieldTypeSpec(
-        String,
-        ObjType.STRING,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as RefOverrideElement).name,
-      (Object inst, dynamic v) =>
-          (inst as RefOverrideElement).name = v as String,
-    ),
-  ],
-  null,
-  () => RefOverrideElement(),
-);
-
-final TypeSpec _refOverrideContainerSpec = TypeSpec(
-  RefOverrideContainer,
-  false,
-  true,
-  [
-    FieldSpec(
-      'list_field',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            RefOverrideElement,
-            ObjType.STRUCT,
-            false,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as RefOverrideContainer).listField,
-      (Object inst, dynamic v) => (inst as RefOverrideContainer).listField =
-          (v as List).cast<RefOverrideElement>(),
-    ),
-    FieldSpec(
-      'map_field',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-          FieldTypeSpec(
-            RefOverrideElement,
-            ObjType.STRUCT,
-            false,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as RefOverrideContainer).mapField,
-      (Object inst, dynamic v) =>
-          (inst as RefOverrideContainer).mapField = (v as Map).map(
-        (Object? k, Object? value) => MapEntry(
-          k as String,
-          value as RefOverrideElement,
-        ),
-      ),
-    ),
-  ],
-  null,
-  () => RefOverrideContainer(),
-);
-
-class NullableComprehensiveCompatible {
-  double boxedDouble = 0.0;
-  double doubleField = 0.0;
-  Float32 boxedFloat = Float32(0);
-  Float32 floatField = Float32(0);
-  Int16 shortField = Int16(0);
-  Int8 byteField = Int8(0);
-  bool boolField = false;
-  bool boxedBool = false;
-  int boxedLong = 0;
-  int longField = 0;
-  Int32 boxedInt = Int32(0);
-  Int32 intField = Int32(0);
-
-  double nullableDouble1 = 0.0;
-  Float32 nullableFloat1 = Float32(0);
-  bool nullableBool1 = false;
-  int nullableLong1 = 0;
-  Int32 nullableInt1 = Int32(0);
-
-  String nullableString2 = '';
-  String stringField = '';
-  List<String> listField = <String>[];
-  List<String> nullableList2 = <String>[];
-  Set<String> nullableSet2 = <String>{};
-  Set<String> setField = <String>{};
-  Map<String, String> mapField = <String, String>{};
-  Map<String, String> nullableMap2 = <String, String>{};
-}
-
-Map<String, String> _asStringMap(Object? value) {
-  if (value == null) {
-    return <String, String>{};
-  }
-  return (value as Map).map(
-    (Object? k, Object? v) => MapEntry(k as String, v as String),
-  );
-}
-
-final TypeSpec _nullableComprehensiveCompatibleSpec = TypeSpec(
-  NullableComprehensiveCompatible,
-  false,
-  true,
-  [
-    FieldSpec(
-      'boxed_double',
-      const FieldTypeSpec(
-        double,
-        ObjType.FLOAT64,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).boxedDouble,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).boxedDouble = v as double,
-    ),
-    FieldSpec(
-      'double_field',
-      const FieldTypeSpec(
-        double,
-        ObjType.FLOAT64,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).doubleField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).doubleField = v as double,
-    ),
-    FieldSpec(
-      'boxed_float',
-      const FieldTypeSpec(
-        Float32,
-        ObjType.FLOAT32,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).boxedFloat,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).boxedFloat = v as Float32,
-    ),
-    FieldSpec(
-      'float_field',
-      const FieldTypeSpec(
-        Float32,
-        ObjType.FLOAT32,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).floatField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).floatField = v as Float32,
-    ),
-    FieldSpec(
-      'short_field',
-      const FieldTypeSpec(
-        Int16,
-        ObjType.INT16,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).shortField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).shortField = v as Int16,
-    ),
-    FieldSpec(
-      'byte_field',
-      const FieldTypeSpec(
-        Int8,
-        ObjType.INT8,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).byteField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).byteField = v as Int8,
-    ),
-    FieldSpec(
-      'bool_field',
-      const FieldTypeSpec(
-        bool,
-        ObjType.BOOL,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).boolField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).boolField = v as bool,
-    ),
-    FieldSpec(
-      'boxed_bool',
-      const FieldTypeSpec(
-        bool,
-        ObjType.BOOL,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).boxedBool,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).boxedBool = v as bool,
-    ),
-    FieldSpec(
-      'boxed_long',
-      const FieldTypeSpec(
-        int,
-        ObjType.VAR_INT64,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).boxedLong,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).boxedLong = v as int,
-    ),
-    FieldSpec(
-      'long_field',
-      const FieldTypeSpec(
-        int,
-        ObjType.VAR_INT64,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).longField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).longField = v as int,
-    ),
-    FieldSpec(
-      'boxed_int',
-      const FieldTypeSpec(
-        Int32,
-        ObjType.VAR_INT32,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).boxedInt,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).boxedInt = v as Int32,
-    ),
-    FieldSpec(
-      'int_field',
-      const FieldTypeSpec(
-        Int32,
-        ObjType.VAR_INT32,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).intField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).intField = v as Int32,
-    ),
-    FieldSpec(
-      'nullable_double1',
-      const FieldTypeSpec(
-        double,
-        ObjType.FLOAT64,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveCompatible).nullableDouble1,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableDouble1 = (v as double?) ?? 0.0,
-    ),
-    FieldSpec(
-      'nullable_float1',
-      const FieldTypeSpec(
-        Float32,
-        ObjType.FLOAT32,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as 
NullableComprehensiveCompatible).nullableFloat1,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableFloat1 = (v as Float32?) ?? Float32(0),
-    ),
-    FieldSpec(
-      'nullable_bool1',
-      const FieldTypeSpec(
-        bool,
-        ObjType.BOOL,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).nullableBool1,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableBool1 = (v as bool?) ?? false,
-    ),
-    FieldSpec(
-      'nullable_long1',
-      const FieldTypeSpec(
-        int,
-        ObjType.VAR_INT64,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).nullableLong1,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableLong1 = (v as int?) ?? 0,
-    ),
-    FieldSpec(
-      'nullable_int1',
-      const FieldTypeSpec(
-        Int32,
-        ObjType.VAR_INT32,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).nullableInt1,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableInt1 = (v as Int32?) ?? Int32(0),
-    ),
-    FieldSpec(
-      'nullable_string2',
-      const FieldTypeSpec(
-        String,
-        ObjType.STRING,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveCompatible).nullableString2,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableString2 = (v as String?) ?? '',
-    ),
-    FieldSpec(
-      'string_field',
-      const FieldTypeSpec(
-        String,
-        ObjType.STRING,
-        false,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).stringField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).stringField = v as String,
-    ),
-    FieldSpec(
-      'list_field',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).listField,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .listField = (v as List).cast<String>(),
-    ),
-    FieldSpec(
-      'nullable_list2',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        true,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).nullableList2,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableList2 = v == null ? <String>[] : (v as List).cast<String>(),
-    ),
-    FieldSpec(
-      'nullable_set2',
-      const FieldTypeSpec(
-        Set,
-        ObjType.SET,
-        true,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).nullableSet2,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableSet2 = v == null ? <String>{} : (v as Set).cast<String>(),
-    ),
-    FieldSpec(
-      'set_field',
-      const FieldTypeSpec(
-        Set,
-        ObjType.SET,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).setField,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .setField = (v as Set).cast<String>(),
-    ),
-    FieldSpec(
-      'map_field',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).mapField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveCompatible).mapField = _asStringMap(v),
-    ),
-    FieldSpec(
-      'nullable_map2',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        true,
-        false,
-        null,
-        [
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-          FieldTypeSpec(
-            String,
-            ObjType.STRING,
-            true,
-            true,
-            null,
-            [],
-          ),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as NullableComprehensiveCompatible).nullableMap2,
-      (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible)
-          .nullableMap2 = _asStringMap(v),
-    ),
-  ],
-  null,
-  () => NullableComprehensiveCompatible(),
-);
-
-enum Color {
-  Green,
-  Red,
-  Blue,
-  White,
-}
-
-const EnumSpec _colorSpec = EnumSpec(
-  Color,
-  Color.values,
-);
-
-class Item {
-  String name = '';
-}
-
-final TypeSpec _itemSpec = TypeSpec(
-  Item,
-  false,
-  true,
-  [
-    FieldSpec(
-      'name',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item).name,
-      (Object inst, dynamic v) => (inst as Item).name = v as String,
-    ),
-  ],
-  null,
-  () => Item(),
-);
-
-class SimpleStruct {
-  Map<Int32, double> f1 = <Int32, double>{};
-  Int32 f2 = Int32(0);
-  Item f3 = Item();
-  String f4 = '';
-  Color f5 = Color.Green;
-  List<String> f6 = <String>[];
-  Int32 f7 = Int32(0);
-  Int32 f8 = Int32(0);
-  Int32 last = Int32(0);
-}
-
-Map<Int32, double> _asInt32DoubleMap(Object? value) {
-  if (value == null) {
-    return <Int32, double>{};
-  }
-  return (value as Map).map(
-    (Object? k, Object? v) => MapEntry(k as Int32, v as double),
-  );
-}
-
-final TypeSpec _simpleStructSpec = TypeSpec(
-  SimpleStruct,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(Int32, ObjType.VAR_INT32, true, true, null, []),
-          FieldTypeSpec(double, ObjType.FLOAT64, true, true, null, []),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f1,
-      (Object inst, dynamic v) =>
-          (inst as SimpleStruct).f1 = _asInt32DoubleMap(v),
-    ),
-    FieldSpec(
-      'f2',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f2,
-      (Object inst, dynamic v) => (inst as SimpleStruct).f2 = v as Int32,
-    ),
-    FieldSpec(
-      'f3',
-      const FieldTypeSpec(Item, ObjType.STRUCT, false, false, null, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f3,
-      (Object inst, dynamic v) => (inst as SimpleStruct).f3 = v as Item,
-    ),
-    FieldSpec(
-      'f4',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f4,
-      (Object inst, dynamic v) => (inst as SimpleStruct).f4 = v as String,
-    ),
-    FieldSpec(
-      'f5',
-      const FieldTypeSpec(Color, ObjType.ENUM, false, true, _colorSpec, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f5,
-      (Object inst, dynamic v) => (inst as SimpleStruct).f5 = v as Color,
-    ),
-    FieldSpec(
-      'f6',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f6,
-      (Object inst, dynamic v) =>
-          (inst as SimpleStruct).f6 = (v as List).cast<String>(),
-    ),
-    FieldSpec(
-      'f7',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f7,
-      (Object inst, dynamic v) => (inst as SimpleStruct).f7 = v as Int32,
-    ),
-    FieldSpec(
-      'f8',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).f8,
-      (Object inst, dynamic v) => (inst as SimpleStruct).f8 = v as Int32,
-    ),
-    FieldSpec(
-      'last',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as SimpleStruct).last,
-      (Object inst, dynamic v) => (inst as SimpleStruct).last = v as Int32,
-    ),
-  ],
-  null,
-  () => SimpleStruct(),
-);
-
-class Item1 {
-  Int32 f1 = Int32(0);
-  Int32 f2 = Int32(0);
-  Int32 f3 = Int32(0);
-  Int32 f4 = Int32(0);
-  Int32 f5 = Int32(0);
-  Int32 f6 = Int32(0);
-}
-
-final TypeSpec _item1Spec = TypeSpec(
-  Item1,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item1).f1,
-      (Object inst, dynamic v) => (inst as Item1).f1 = v as Int32,
-    ),
-    FieldSpec(
-      'f2',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item1).f2,
-      (Object inst, dynamic v) => (inst as Item1).f2 = v as Int32,
-    ),
-    FieldSpec(
-      'f3',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item1).f3,
-      (Object inst, dynamic v) => (inst as Item1).f3 = v as Int32,
-    ),
-    FieldSpec(
-      'f4',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item1).f4,
-      (Object inst, dynamic v) => (inst as Item1).f4 = v as Int32,
-    ),
-    FieldSpec(
-      'f5',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item1).f5,
-      (Object inst, dynamic v) => (inst as Item1).f5 = v as Int32,
-    ),
-    FieldSpec(
-      'f6',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as Item1).f6,
-      (Object inst, dynamic v) => (inst as Item1).f6 = v as Int32,
-    ),
-  ],
-  null,
-  () => Item1(),
-);
-
-class StructWithList {
-  List<String?> items = <String?>[];
-}
-
-final TypeSpec _structWithListSpec = TypeSpec(
-  StructWithList,
-  false,
-  true,
-  [
-    FieldSpec(
-      'items',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        false,
-        false,
-        null,
-        [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as StructWithList).items,
-      (Object inst, dynamic v) =>
-          (inst as StructWithList).items = (v as List).cast<String?>(),
-    ),
-  ],
-  null,
-  () => StructWithList(),
-);
-
-class StructWithMap {
-  Map<String?, String?> data = <String?, String?>{};
-}
-
-Map<String?, String?> _asNullableStringMap(Object? value) {
-  if (value == null) {
-    return <String?, String?>{};
-  }
-  return (value as Map).map(
-    (Object? k, Object? v) => MapEntry(k as String?, v as String?),
-  );
-}
-
-final TypeSpec _structWithMapSpec = TypeSpec(
-  StructWithMap,
-  false,
-  true,
-  [
-    FieldSpec(
-      'data',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as StructWithMap).data,
-      (Object inst, dynamic v) =>
-          (inst as StructWithMap).data = _asNullableStringMap(v),
-    ),
-  ],
-  null,
-  () => StructWithMap(),
-);
-
-class VersionCheckStruct {
-  Int32 f1 = Int32(0);
-  String f2 = '';
-  double f3 = 0.0;
-}
-
-final TypeSpec _versionCheckStructSpec = TypeSpec(
-  VersionCheckStruct,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as VersionCheckStruct).f1,
-      (Object inst, dynamic v) => (inst as VersionCheckStruct).f1 = v as Int32,
-    ),
-    FieldSpec(
-      'f2',
-      const FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as VersionCheckStruct).f2,
-      (Object inst, dynamic v) =>
-          (inst as VersionCheckStruct).f2 = (v as String?) ?? '',
-    ),
-    FieldSpec(
-      'f3',
-      const FieldTypeSpec(double, ObjType.FLOAT64, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as VersionCheckStruct).f3,
-      (Object inst, dynamic v) => (inst as VersionCheckStruct).f3 = v as 
double,
-    ),
-  ],
-  null,
-  () => VersionCheckStruct(),
-);
-
-class OneStringFieldStruct {
-  String f1 = '';
-}
-
-final TypeSpec _oneStringFieldStructSpec = TypeSpec(
-  OneStringFieldStruct,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as OneStringFieldStruct).f1,
-      (Object inst, dynamic v) =>
-          (inst as OneStringFieldStruct).f1 = (v as String?) ?? '',
-    ),
-  ],
-  null,
-  () => OneStringFieldStruct(),
-);
-
-class TwoStringFieldStruct {
-  String f1 = '';
-  String f2 = '';
-}
-
-final TypeSpec _twoStringFieldStructSpec = TypeSpec(
-  TwoStringFieldStruct,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as TwoStringFieldStruct).f1,
-      (Object inst, dynamic v) =>
-          (inst as TwoStringFieldStruct).f1 = v as String,
-    ),
-    FieldSpec(
-      'f2',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as TwoStringFieldStruct).f2,
-      (Object inst, dynamic v) =>
-          (inst as TwoStringFieldStruct).f2 = v as String,
-    ),
-  ],
-  null,
-  () => TwoStringFieldStruct(),
-);
-
-class OneEnumFieldStruct {
-  TestEnum f1 = TestEnum.VALUE_A;
-}
-
-final TypeSpec _oneEnumFieldStructSpec = TypeSpec(
-  OneEnumFieldStruct,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(
-          TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []),
-      true,
-      true,
-      (Object inst) => (inst as OneEnumFieldStruct).f1,
-      (Object inst, dynamic v) =>
-          (inst as OneEnumFieldStruct).f1 = v as TestEnum,
-    ),
-  ],
-  null,
-  () => OneEnumFieldStruct(),
-);
-
-class TwoEnumFieldStruct {
-  TestEnum f1 = TestEnum.VALUE_A;
-  TestEnum f2 = TestEnum.VALUE_A;
-}
-
-final TypeSpec _twoEnumFieldStructSpec = TypeSpec(
-  TwoEnumFieldStruct,
-  false,
-  true,
-  [
-    FieldSpec(
-      'f1',
-      const FieldTypeSpec(
-          TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []),
-      true,
-      true,
-      (Object inst) => (inst as TwoEnumFieldStruct).f1,
-      (Object inst, dynamic v) =>
-          (inst as TwoEnumFieldStruct).f1 = v as TestEnum,
-    ),
-    FieldSpec(
-      'f2',
-      const FieldTypeSpec(
-          TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []),
-      true,
-      true,
-      (Object inst) => (inst as TwoEnumFieldStruct).f2,
-      (Object inst, dynamic v) =>
-          (inst as TwoEnumFieldStruct).f2 = v as TestEnum,
-    ),
-  ],
-  null,
-  () => TwoEnumFieldStruct(),
-);
-
-class NullableComprehensiveSchemaConsistent {
-  Int8 byteField = Int8(0);
-  Int16 shortField = Int16(0);
-  Int32 intField = Int32(0);
-  int longField = 0;
-  Float32 floatField = Float32(0);
-  double doubleField = 0.0;
-  bool boolField = false;
-  String stringField = '';
-  List<String> listField = <String>[];
-  Set<String> setField = <String>{};
-  Map<String, String> mapField = <String, String>{};
-  Int32? nullableInt;
-  int? nullableLong;
-  Float32? nullableFloat;
-  double? nullableDouble;
-  bool? nullableBool;
-  String? nullableString;
-  List<String>? nullableList;
-  Set<String>? nullableSet;
-  Map<String, String>? nullableMap;
-}
-
-final TypeSpec _nullableComprehensiveSchemaConsistentSpec = TypeSpec(
-  NullableComprehensiveSchemaConsistent,
-  false,
-  true,
-  [
-    FieldSpec(
-      'byte_field',
-      const FieldTypeSpec(Int8, ObjType.INT8, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).byteField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).byteField = v as 
Int8,
-    ),
-    FieldSpec(
-      'short_field',
-      const FieldTypeSpec(Int16, ObjType.INT16, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).shortField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).shortField =
-              v as Int16,
-    ),
-    FieldSpec(
-      'int_field',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as 
NullableComprehensiveSchemaConsistent).intField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).intField = v as 
Int32,
-    ),
-    FieldSpec(
-      'long_field',
-      const FieldTypeSpec(int, ObjType.VAR_INT64, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).longField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).longField = v as int,
-    ),
-    FieldSpec(
-      'float_field',
-      const FieldTypeSpec(Float32, ObjType.FLOAT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).floatField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).floatField =
-              v as Float32,
-    ),
-    FieldSpec(
-      'double_field',
-      const FieldTypeSpec(double, ObjType.FLOAT64, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).doubleField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).doubleField =
-              v as double,
-    ),
-    FieldSpec(
-      'bool_field',
-      const FieldTypeSpec(bool, ObjType.BOOL, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).boolField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).boolField = v as 
bool,
-    ),
-    FieldSpec(
-      'string_field',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).stringField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).stringField =
-              v as String,
-    ),
-    FieldSpec(
-      'list_field',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        false,
-        false,
-        null,
-        [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
-      ),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).listField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).listField =
-              (v as List).cast<String>(),
-    ),
-    FieldSpec(
-      'set_field',
-      const FieldTypeSpec(
-        Set,
-        ObjType.SET,
-        false,
-        false,
-        null,
-        [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as 
NullableComprehensiveSchemaConsistent).setField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).setField =
-              (v as Set).cast<String>(),
-    ),
-    FieldSpec(
-      'map_field',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        false,
-        false,
-        null,
-        [
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as 
NullableComprehensiveSchemaConsistent).mapField,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).mapField =
-              _asStringMap(v),
-    ),
-    FieldSpec(
-      'nullable_int',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, true, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableInt,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableInt =
-              v as Int32?,
-    ),
-    FieldSpec(
-      'nullable_long',
-      const FieldTypeSpec(int, ObjType.VAR_INT64, true, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableLong,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableLong =
-              v as int?,
-    ),
-    FieldSpec(
-      'nullable_float',
-      const FieldTypeSpec(Float32, ObjType.FLOAT32, true, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableFloat,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableFloat =
-              v as Float32?,
-    ),
-    FieldSpec(
-      'nullable_double',
-      const FieldTypeSpec(double, ObjType.FLOAT64, true, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableDouble,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableDouble =
-              v as double?,
-    ),
-    FieldSpec(
-      'nullable_bool',
-      const FieldTypeSpec(bool, ObjType.BOOL, true, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableBool,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableBool =
-              v as bool?,
-    ),
-    FieldSpec(
-      'nullable_string',
-      const FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableString,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableString =
-              v as String?,
-    ),
-    FieldSpec(
-      'nullable_list',
-      const FieldTypeSpec(
-        List,
-        ObjType.LIST,
-        true,
-        false,
-        null,
-        [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
-      ),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableList,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableList =
-              v == null ? null : (v as List).cast<String>(),
-    ),
-    FieldSpec(
-      'nullable_set',
-      const FieldTypeSpec(
-        Set,
-        ObjType.SET,
-        true,
-        false,
-        null,
-        [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])],
-      ),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableSet,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableSet =
-              v == null ? null : (v as Set).cast<String>(),
-    ),
-    FieldSpec(
-      'nullable_map',
-      const FieldTypeSpec(
-        Map,
-        ObjType.MAP,
-        true,
-        false,
-        null,
-        [
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-          FieldTypeSpec(String, ObjType.STRING, true, true, null, []),
-        ],
-      ),
-      true,
-      true,
-      (Object inst) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableMap,
-      (Object inst, dynamic v) =>
-          (inst as NullableComprehensiveSchemaConsistent).nullableMap =
-              v == null ? null : _asStringMap(v),
-    ),
-  ],
-  null,
-  () => NullableComprehensiveSchemaConsistent(),
-);
-
-class RefInnerSchemaConsistent {
-  Int32 id = Int32(0);
-  String name = '';
-}
-
-class RefOuterSchemaConsistent {
-  RefInnerSchemaConsistent? inner1;
-  RefInnerSchemaConsistent? inner2;
-}
-
-final TypeSpec _refInnerSchemaConsistentSpec = TypeSpec(
-  RefInnerSchemaConsistent,
-  false,
-  true,
-  [
-    FieldSpec(
-      'id',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as RefInnerSchemaConsistent).id,
-      (Object inst, dynamic v) =>
-          (inst as RefInnerSchemaConsistent).id = v as Int32,
-    ),
-    FieldSpec(
-      'name',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as RefInnerSchemaConsistent).name,
-      (Object inst, dynamic v) =>
-          (inst as RefInnerSchemaConsistent).name = v as String,
-    ),
-  ],
-  null,
-  () => RefInnerSchemaConsistent(),
-);
-
-final TypeSpec _refOuterSchemaConsistentSpec = TypeSpec(
-  RefOuterSchemaConsistent,
-  false,
-  true,
-  [
-    FieldSpec(
-      'inner1',
-      const FieldTypeSpec(
-        RefInnerSchemaConsistent,
-        ObjType.STRUCT,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as RefOuterSchemaConsistent).inner1,
-      (Object inst, dynamic v) => (inst as RefOuterSchemaConsistent).inner1 =
-          v as RefInnerSchemaConsistent?,
-      trackingRef: true,
-    ),
-    FieldSpec(
-      'inner2',
-      const FieldTypeSpec(
-        RefInnerSchemaConsistent,
-        ObjType.STRUCT,
-        true,
-        true,
-        null,
-        [],
-      ),
-      true,
-      true,
-      (Object inst) => (inst as RefOuterSchemaConsistent).inner2,
-      (Object inst, dynamic v) => (inst as RefOuterSchemaConsistent).inner2 =
-          v as RefInnerSchemaConsistent?,
-      trackingRef: true,
-    ),
-  ],
-  null,
-  () => RefOuterSchemaConsistent(),
-);
-
-class RefInnerCompatible {
-  Int32 id = Int32(0);
-  String name = '';
-}
-
-class RefOuterCompatible {
-  RefInnerCompatible? inner1;
-  RefInnerCompatible? inner2;
-}
-
-final TypeSpec _refInnerCompatibleSpec = TypeSpec(
-  RefInnerCompatible,
-  false,
-  true,
-  [
-    FieldSpec(
-      'id',
-      const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as RefInnerCompatible).id,
-      (Object inst, dynamic v) => (inst as RefInnerCompatible).id = v as Int32,
-    ),
-    FieldSpec(
-      'name',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as RefInnerCompatible).name,
-      (Object inst, dynamic v) =>
-          (inst as RefInnerCompatible).name = v as String,
-    ),
-  ],
-  null,
-  () => RefInnerCompatible(),
-);
-
-final TypeSpec _refOuterCompatibleSpec = TypeSpec(
-  RefOuterCompatible,
-  false,
-  true,
-  [
-    FieldSpec(
-      'inner1',
-      const FieldTypeSpec(
-          RefInnerCompatible, ObjType.STRUCT, true, false, null, []),
-      true,
-      true,
-      (Object inst) => (inst as RefOuterCompatible).inner1,
-      (Object inst, dynamic v) =>
-          (inst as RefOuterCompatible).inner1 = v as RefInnerCompatible?,
-      trackingRef: true,
-    ),
-    FieldSpec(
-      'inner2',
-      const FieldTypeSpec(
-          RefInnerCompatible, ObjType.STRUCT, true, false, null, []),
-      true,
-      true,
-      (Object inst) => (inst as RefOuterCompatible).inner2,
-      (Object inst, dynamic v) =>
-          (inst as RefOuterCompatible).inner2 = v as RefInnerCompatible?,
-      trackingRef: true,
-    ),
-  ],
-  null,
-  () => RefOuterCompatible(),
-);
-
-class CircularRefStruct {
-  String name = '';
-  CircularRefStruct? selfRef;
-}
-
-final TypeSpec _circularRefStructSpec = TypeSpec(
-  CircularRefStruct,
-  false,
-  false,
-  [
-    FieldSpec(
-      'name',
-      const FieldTypeSpec(String, ObjType.STRING, false, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as CircularRefStruct).name,
-      (Object inst, dynamic v) =>
-          (inst as CircularRefStruct).name = v as String,
-    ),
-    FieldSpec(
-      'self_ref',
-      const FieldTypeSpec(
-          CircularRefStruct, ObjType.STRUCT, true, true, null, []),
-      true,
-      true,
-      (Object inst) => (inst as CircularRefStruct).selfRef,
-      (Object inst, dynamic v) =>
-          (inst as CircularRefStruct).selfRef = v as CircularRefStruct?,
-      trackingRef: true,
-    ),
-  ],
-  null,
-  () => CircularRefStruct(),
-);
-
-final Map<Type, TypeSpec> _structSpecByType = <Type, TypeSpec>{
-  TwoEnumFieldStructEvolution: _twoEnumFieldStructEvolutionSpec,
-  RefOverrideElement: _refOverrideElementSpec,
-  RefOverrideContainer: _refOverrideContainerSpec,
-  NullableComprehensiveCompatible: _nullableComprehensiveCompatibleSpec,
-  Item: _itemSpec,
-  SimpleStruct: _simpleStructSpec,
-  Item1: _item1Spec,
-  StructWithList: _structWithListSpec,
-  StructWithMap: _structWithMapSpec,
-  VersionCheckStruct: _versionCheckStructSpec,
-  OneStringFieldStruct: _oneStringFieldStructSpec,
-  TwoStringFieldStruct: _twoStringFieldStructSpec,
-  OneEnumFieldStruct: _oneEnumFieldStructSpec,
-  TwoEnumFieldStruct: _twoEnumFieldStructSpec,
-  NullableComprehensiveSchemaConsistent:
-      _nullableComprehensiveSchemaConsistentSpec,
-  RefInnerSchemaConsistent: _refInnerSchemaConsistentSpec,
-  RefOuterSchemaConsistent: _refOuterSchemaConsistentSpec,
-  RefInnerCompatible: _refInnerCompatibleSpec,
-  RefOuterCompatible: _refOuterCompatibleSpec,
-  CircularRefStruct: _circularRefStructSpec,
-};
-
-final Map<Type, EnumSpec> _enumSpecByType = <Type, EnumSpec>{
-  TestEnum: _testEnumSpec,
-  Color: _colorSpec,
-};
-
-void _registerStructType(
-  Fory fory,
-  Type type, {
-  int? typeId,
-  String? namespace,
-  String? typename,
-}) {
-  final TypeSpec? spec = _structSpecByType[type];
-  if (spec == null) {
-    throw StateError('No struct spec registered for $type');
-  }
-  fory.registerStruct(
-    spec,
-    typeId: typeId,
-    namespace: namespace,
-    typename: typename,
-  );
-}
-
-void _registerEnumType(
-  Fory fory,
-  Type type, {
-  int? typeId,
-  String? namespace,
-  String? typename,
-}) {
-  final EnumSpec? spec = _enumSpecByType[type];
-  if (spec == null) {
-    throw StateError('No enum spec registered for $type');
-  }
-  fory.registerEnum(
-    spec,
-    typeId: typeId,
-    namespace: namespace,
-    typename: typename,
-  );
-}
diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart 
b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
index 7d59be0c3..67733af6a 100644
--- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
@@ -20,8 +20,7 @@
 import 'dart:io';
 import 'dart:typed_data';
 import 'package:fory/fory.dart';
-
-part 'xlang_test_defs.dart';
+import 'package:fory_test/entity/xlang_test_models.dart';
 
 String _getDataFile() {
   final String? dataFile = Platform.environment['DATA_FILE'];
@@ -61,8 +60,8 @@ void _runEnumSchemaEvolutionCompatibleReverse() {
   final String dataFile = _getDataFile();
   final Uint8List data = _readFile(dataFile);
   final Fory fory = Fory(compatible: true);
-  _registerEnumType(fory, TestEnum, typeId: 210);
-  _registerStructType(fory, TwoEnumFieldStructEvolution, typeId: 211);
+  registerXlangEnum(fory, TestEnum, typeId: 210);
+  registerXlangStruct(fory, TwoEnumFieldStructEvolution, typeId: 211);
   final TwoEnumFieldStructEvolution obj =
       fory.deserialize(data) as TwoEnumFieldStructEvolution;
   if (obj.f1 != TestEnum.VALUE_C) {
@@ -75,9 +74,10 @@ void _runNullableFieldCompatibleNull() {
   final String dataFile = _getDataFile();
   final Uint8List data = _readFile(dataFile);
   final Fory fory = Fory(compatible: true);
-  _registerStructType(fory, NullableComprehensiveCompatible, typeId: 402);
+  registerXlangStruct(fory, NullableComprehensiveCompatible, typeId: 402);
   final NullableComprehensiveCompatible obj =
       fory.deserialize(data) as NullableComprehensiveCompatible;
+  obj.normalizeForCompatibleRoundTrip();
   _writeFile(dataFile, fory.serialize(obj));
 }
 
@@ -85,8 +85,8 @@ void _runCollectionElementRefOverride() {
   final String dataFile = _getDataFile();
   final Uint8List data = _readFile(dataFile);
   final Fory fory = Fory(ref: true);
-  _registerStructType(fory, RefOverrideElement, typeId: 701);
-  _registerStructType(fory, RefOverrideContainer, typeId: 702);
+  registerXlangStruct(fory, RefOverrideElement, typeId: 701);
+  registerXlangStruct(fory, RefOverrideContainer, typeId: 702);
 
   final RefOverrideContainer obj =
       fory.deserialize(data) as RefOverrideContainer;
@@ -104,15 +104,15 @@ void _runCollectionElementRefOverride() {
 }
 
 void _registerSimpleById(Fory fory) {
-  _registerEnumType(fory, Color, typeId: 101);
-  _registerStructType(fory, Item, typeId: 102);
-  _registerStructType(fory, SimpleStruct, typeId: 103);
+  registerXlangEnum(fory, Color, typeId: 101);
+  registerXlangStruct(fory, Item, typeId: 102);
+  registerXlangStruct(fory, SimpleStruct, typeId: 103);
 }
 
 void _registerSimpleByName(Fory fory) {
-  _registerEnumType(fory, Color, namespace: 'demo', typename: 'color');
-  _registerStructType(fory, Item, namespace: 'demo', typename: 'item');
-  _registerStructType(fory, SimpleStruct,
+  registerXlangEnum(fory, Color, namespace: 'demo', typename: 'color');
+  registerXlangStruct(fory, Item, namespace: 'demo', typename: 'item');
+  registerXlangStruct(fory, SimpleStruct,
       namespace: 'demo', typename: 'simple_struct');
 }
 
@@ -138,7 +138,7 @@ void _runRoundTripCase(String caseName) {
       return;
     case 'test_cross_language_serializer':
       final Fory fory = Fory(compatible: true);
-      _registerEnumType(fory, Color, typeId: 101);
+      registerXlangEnum(fory, Color, typeId: 101);
       _roundTripFory(fory);
       return;
     case 'test_simple_struct':
@@ -155,88 +155,88 @@ void _runRoundTripCase(String caseName) {
     case 'test_map':
     case 'test_item':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, Item, typeId: 102);
+      registerXlangStruct(fory, Item, typeId: 102);
       _roundTripFory(fory);
       return;
     case 'test_integer':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, Item1, typeId: 101);
+      registerXlangStruct(fory, Item1, typeId: 101);
       _roundTripFory(fory);
       return;
     case 'test_color':
       final Fory fory = Fory(compatible: true);
-      _registerEnumType(fory, Color, typeId: 101);
+      registerXlangEnum(fory, Color, typeId: 101);
       _roundTripFory(fory);
       return;
     case 'test_struct_with_list':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, StructWithList, typeId: 201);
+      registerXlangStruct(fory, StructWithList, typeId: 201);
       _roundTripFory(fory);
       return;
     case 'test_struct_with_map':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, StructWithMap, typeId: 202);
+      registerXlangStruct(fory, StructWithMap, typeId: 202);
       _roundTripFory(fory);
       return;
     case 'test_struct_version_check':
       final Fory fory = Fory();
-      _registerStructType(fory, VersionCheckStruct, typeId: 201);
+      registerXlangStruct(fory, VersionCheckStruct, typeId: 201);
       _roundTripFory(fory);
       return;
     case 'test_one_string_field_schema':
       final Fory fory = Fory();
-      _registerStructType(fory, OneStringFieldStruct, typeId: 200);
+      registerXlangStruct(fory, OneStringFieldStruct, typeId: 200);
       _roundTripFory(fory);
       return;
     case 'test_one_string_field_compatible':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, OneStringFieldStruct, typeId: 200);
+      registerXlangStruct(fory, OneStringFieldStruct, typeId: 200);
       _roundTripFory(fory);
       return;
     case 'test_two_string_field_compatible':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, TwoStringFieldStruct, typeId: 201);
+      registerXlangStruct(fory, TwoStringFieldStruct, typeId: 201);
       _roundTripFory(fory);
       return;
     case 'test_schema_evolution_compatible':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, TwoStringFieldStruct, typeId: 200);
+      registerXlangStruct(fory, TwoStringFieldStruct, typeId: 200);
       _roundTripFory(fory);
       return;
     case 'test_one_enum_field_schema':
       final Fory fory = Fory();
-      _registerEnumType(fory, TestEnum, typeId: 210);
-      _registerStructType(fory, OneEnumFieldStruct, typeId: 211);
+      registerXlangEnum(fory, TestEnum, typeId: 210);
+      registerXlangStruct(fory, OneEnumFieldStruct, typeId: 211);
       _roundTripFory(fory);
       return;
     case 'test_one_enum_field_compatible':
       final Fory fory = Fory(compatible: true);
-      _registerEnumType(fory, TestEnum, typeId: 210);
-      _registerStructType(fory, OneEnumFieldStruct, typeId: 211);
+      registerXlangEnum(fory, TestEnum, typeId: 210);
+      registerXlangStruct(fory, OneEnumFieldStruct, typeId: 211);
       _roundTripFory(fory);
       return;
     case 'test_two_enum_field_compatible':
       final Fory fory = Fory(compatible: true);
-      _registerEnumType(fory, TestEnum, typeId: 210);
-      _registerStructType(fory, TwoEnumFieldStruct, typeId: 212);
+      registerXlangEnum(fory, TestEnum, typeId: 210);
+      registerXlangStruct(fory, TwoEnumFieldStruct, typeId: 212);
       _roundTripFory(fory);
       return;
     case 'test_enum_schema_evolution_compatible':
       final Fory fory = Fory(compatible: true);
-      _registerEnumType(fory, TestEnum, typeId: 210);
-      _registerStructType(fory, TwoEnumFieldStruct, typeId: 211);
+      registerXlangEnum(fory, TestEnum, typeId: 210);
+      registerXlangStruct(fory, TwoEnumFieldStruct, typeId: 211);
       _roundTripFory(fory);
       return;
     case 'test_nullable_field_schema_consistent_not_null':
     case 'test_nullable_field_schema_consistent_null':
       final Fory fory = Fory();
-      _registerStructType(fory, NullableComprehensiveSchemaConsistent,
+      registerXlangStruct(fory, NullableComprehensiveSchemaConsistent,
           typeId: 401);
       _roundTripFory(fory);
       return;
     case 'test_nullable_field_compatible_not_null':
       final Fory fory = Fory(compatible: true);
-      _registerStructType(fory, NullableComprehensiveCompatible, typeId: 402);
+      registerXlangStruct(fory, NullableComprehensiveCompatible, typeId: 402);
       _roundTripFory(fory);
       return;
     case 'test_nullable_field_compatible_null':
@@ -244,14 +244,14 @@ void _runRoundTripCase(String caseName) {
       return;
     case 'test_ref_schema_consistent':
       final Fory fory = Fory(ref: true);
-      _registerStructType(fory, RefInnerSchemaConsistent, typeId: 501);
-      _registerStructType(fory, RefOuterSchemaConsistent, typeId: 502);
+      registerXlangStruct(fory, RefInnerSchemaConsistent, typeId: 501);
+      registerXlangStruct(fory, RefOuterSchemaConsistent, typeId: 502);
       _roundTripFory(fory);
       return;
     case 'test_ref_compatible':
       final Fory fory = Fory(compatible: true, ref: true);
-      _registerStructType(fory, RefInnerCompatible, typeId: 503);
-      _registerStructType(fory, RefOuterCompatible, typeId: 504);
+      registerXlangStruct(fory, RefInnerCompatible, typeId: 503);
+      registerXlangStruct(fory, RefOuterCompatible, typeId: 504);
       _roundTripFory(fory);
       return;
     case 'test_collection_element_ref_override':
@@ -259,12 +259,12 @@ void _runRoundTripCase(String caseName) {
       return;
     case 'test_circular_ref_schema_consistent':
       final Fory fory = Fory(ref: true);
-      _registerStructType(fory, CircularRefStruct, typeId: 601);
+      registerXlangStruct(fory, CircularRefStruct, typeId: 601);
       _roundTripFory(fory);
       return;
     case 'test_circular_ref_compatible':
       final Fory fory = Fory(compatible: true, ref: true);
-      _registerStructType(fory, CircularRefStruct, typeId: 602);
+      registerXlangStruct(fory, CircularRefStruct, typeId: 602);
       _roundTripFory(fory);
       return;
     case 'test_enum_schema_evolution_compatible_reverse':
diff --git a/dart/packages/fory-test/test/perf_test/serial_perf_test.dart 
b/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
index 1e61648dd..aa4f10a28 100644
--- a/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
+++ b/dart/packages/fory-test/test/perf_test/serial_perf_test.dart
@@ -63,7 +63,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject2, typename: "test.ComplexObject2");
+      fory.register(ComplexObject2, typename: "test.ComplexObject2");
       ComplexObject2 o = ComplexObject2(true, {Int8(-1): Int32(2)});
       _testPerfSerialize(fory, o, 1000000, 'Serialize simple struct');
     });
@@ -72,7 +72,7 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject2, typename: "test.ComplexObject2");
+      fory.register(ComplexObject2, typename: "test.ComplexObject2");
       ComplexObject2 o = ComplexObject2(true, {Int8(-1): Int32(2)});
       _testPerfDeserialize(fory, o, 1000000, 'Deserialize simple struct');
     });
@@ -81,8 +81,8 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject2, typename: "test.ComplexObject2");
-      fory.register($ComplexObject1, typename: "test.ComplexObject1");
+      fory.register(ComplexObject2, typename: "test.ComplexObject2");
+      fory.register(ComplexObject1, typename: "test.ComplexObject1");
       ComplexObject2 obj2 = ComplexObject2(true, {Int8(-1): Int32(2)});
       ComplexObject1 obj = ComplexObject1();
       obj.f1 = obj2;
@@ -104,8 +104,8 @@ void main() {
       Fory fory = Fory(
         ref: true,
       );
-      fory.register($ComplexObject2, typename: "test.ComplexObject2");
-      fory.register($ComplexObject1, typename: "test.ComplexObject1");
+      fory.register(ComplexObject2, typename: "test.ComplexObject2");
+      fory.register(ComplexObject1, typename: "test.ComplexObject1");
       ComplexObject2 obj2 = ComplexObject2(true, {Int8(-1): Int32(2)});
       ComplexObject1 obj = ComplexObject1();
       obj.f1 = obj2;
@@ -128,8 +128,8 @@ void main() {
     //   Fory fory = Fory(
     //     ref: true,
     //   );
-    //   fory.register($ComplexObject2, typename: "test.ComplexObject2");
-    //   fory.register($ComplexObject1, typename: "test.ComplexObject1");
+    //   fory.register(ComplexObject2, typename: "test.ComplexObject2");
+    //   fory.register(ComplexObject1, typename: "test.ComplexObject1");
     //   ComplexObject2 obj2 = ComplexObject2(true,{Int8(-1):Int32(2)});
     //   ComplexObject1 obj = ComplexObject1();
     //   obj.f1 = obj2;
@@ -151,8 +151,8 @@ void main() {
     //   Fory fory = Fory(
     //     ref: true,
     //   );
-    //   fory.register($ComplexObject2, typename: "test.ComplexObject2");
-    //   fory.register($ComplexObject1, typename: "test.ComplexObject1");
+    //   fory.register(ComplexObject2, typename: "test.ComplexObject2");
+    //   fory.register(ComplexObject1, typename: "test.ComplexObject1");
     //   ComplexObject2 obj2 = ComplexObject2(true,{Int8(-1):Int32(2)});
     //   ComplexObject1 obj = ComplexObject1();
     //   obj.f1 = obj2;
diff --git 
a/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart 
b/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
index c351dcab3..ffb3e40df 100644
--- a/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
+++ b/dart/packages/fory-test/test/struct_test/uint_annotated_struct_test.dart
@@ -39,7 +39,7 @@ void main() {
 
       // Serialize
       var fory = Fory();
-      fory.register($UIntAnnotatedStruct);
+      fory.register(UIntAnnotatedStruct);
       var bytes = fory.serialize(original);
 
       expect(bytes.isNotEmpty, isTrue);
@@ -69,7 +69,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntAnnotatedStruct);
+      fory.register(UIntAnnotatedStruct);
       var bytes = fory.serialize(original);
       var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
 
@@ -88,7 +88,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntAnnotatedStruct);
+      fory.register(UIntAnnotatedStruct);
       var bytes = fory.serialize(original);
       var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
 
@@ -107,7 +107,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntAnnotatedStruct);
+      fory.register(UIntAnnotatedStruct);
       var bytes = fory.serialize(original);
       var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
 
@@ -127,7 +127,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntAnnotatedStruct);
+      fory.register(UIntAnnotatedStruct);
       var bytes = fory.serialize(original);
       var decoded = fory.deserialize(bytes) as UIntAnnotatedStruct;
 
@@ -162,7 +162,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntAnnotatedStruct);
+      fory.register(UIntAnnotatedStruct);
 
       var smallBytes = fory.serialize(smallValues);
       var largeBytes = fory.serialize(largeValues);
diff --git a/dart/packages/fory-test/test/struct_test/uint_struct_test.dart 
b/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
index 89b340667..97aaa3e6c 100644
--- a/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
+++ b/dart/packages/fory-test/test/struct_test/uint_struct_test.dart
@@ -35,7 +35,7 @@ void main() {
 
       // Serialize
       var fory = Fory();
-      fory.register($UIntStruct);
+      fory.register(UIntStruct);
       var bytes = fory.serialize(original);
 
       expect(bytes.isNotEmpty, isTrue);
@@ -57,7 +57,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntStruct);
+      fory.register(UIntStruct);
       var bytes = fory.serialize(original);
       var decoded = fory.deserialize(bytes) as UIntStruct;
 
@@ -74,7 +74,7 @@ void main() {
       );
 
       var fory = Fory();
-      fory.register($UIntStruct);
+      fory.register(UIntStruct);
       var bytes = fory.serialize(original);
       var decoded = fory.deserialize(bytes) as UIntStruct;
 
diff --git a/dart/packages/fory/README.md b/dart/packages/fory/README.md
index 0e194eedc..8dce617e0 100644
--- a/dart/packages/fory/README.md
+++ b/dart/packages/fory/README.md
@@ -34,7 +34,7 @@ import 'package:fory/fory.dart';
 part 'example.g.dart';
 
 @foryClass
-class SomeClass with _$SomeClassFory {
+class SomeClass {
   late int id;
   late String name;
   late Map<String, double> map;
@@ -51,13 +51,13 @@ After annotating your class with `@foryClass`, run:
 dart run build_runner build
 ```
 
-This generates the necessary code in `example.g.dart` and creates the 
`_$SomeClassFory` mixin.
+This generates the necessary schema metadata in `example.g.dart`.
 
 ### Serializing and Deserializing
 
 ```dart
 Fory fory = Fory(ref: true);
-fory.register($SomeClass, typename: "example.SomeClass");
+fory.registerStruct(SomeClass, typename: "example.SomeClass");
 SomeClass obj = SomeClass(1, 'SomeClass', {'a': 1.0});
 
 // Serialize
@@ -84,7 +84,7 @@ enum EnumFoo {
 Registration is similar to classes:
 
 ```dart
-fory.register($EnumFoo, typename: "example.EnumFoo");
+fory.registerEnum(EnumFoo, typename: "example.EnumFoo");
 ```
 
 ## Type Support
diff --git a/dart/packages/fory/example/example.dart 
b/dart/packages/fory/example/example.dart
index 12b965991..44b88a6e5 100644
--- a/dart/packages/fory/example/example.dart
+++ b/dart/packages/fory/example/example.dart
@@ -24,7 +24,7 @@ import 'package:fory/fory.dart';
 part 'example.g.dart';
 
 @foryClass
-class Person with _$PersonFory {
+class Person {
   final String firstName, lastName;
   final int age;
   final LocalDate dateOfBirth;
@@ -34,7 +34,7 @@ class Person with _$PersonFory {
 
 void main() {
   Fory fory = Fory(ref: true);
-  fory.register($Person, typename: "example.Person");
+  fory.register(Person, typename: "example.Person");
   Person obj = Person('Leo', 'Leo', 21, LocalDate(2004, 1, 1));
 
   // Serialize
diff --git a/dart/packages/fory/example/example.g.dart 
b/dart/packages/fory/example/example.g.dart
index 31635b0ab..016177afb 100644
--- a/dart/packages/fory/example/example.g.dart
+++ b/dart/packages/fory/example/example.g.dart
@@ -99,8 +99,3 @@ final $Person = TypeSpec(
   ),
   null,
 );
-
-mixin _$PersonFory implements ForyTypeProvider {
-  @override
-  Type get foryType => Person;
-}
diff --git a/dart/packages/fory/lib/src/annotation/fory_key.dart 
b/dart/packages/fory/lib/src/annotation/fory_key.dart
index b6d9f34c0..28903a055 100644
--- a/dart/packages/fory/lib/src/annotation/fory_key.dart
+++ b/dart/packages/fory/lib/src/annotation/fory_key.dart
@@ -47,9 +47,13 @@ class ForyKey {
   /// A boolean value indicating whether to include this field during 
serialization.
   final bool includeToFory;
 
+  /// A boolean value indicating whether to track references for this field.
+  final bool ref;
+
   /// Both [includeFromFory] and [includeToFory] default to `true`.
   const ForyKey({
     this.includeFromFory = true,
     this.includeToFory = true,
+    this.ref = false,
   });
 }
diff --git 
a/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
 
b/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
index f8c210fe3..db0b9efa6 100644
--- 
a/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
+++ 
b/dart/packages/fory/lib/src/codegen/analyze/impl/annotation/key_annotation_analyzer.dart
@@ -56,9 +56,11 @@ class KeyAnnotationAnalyzer {
     // If there is no annotation, both includeFromFory and includeToFory 
default to true.
     bool includeFromFory = true;
     bool includeToFory = true;
+    bool ref = false;
     if (getMeta && anno != null) {
       includeFromFory = anno.getField("includeFromFory")!.toBoolValue()!;
       includeToFory = anno.getField("includeToFory")!.toBoolValue()!;
+      ref = anno.getField("ref")!.toBoolValue()!;
       // serializeToVar = anno.getField("serializeTo")?.variable;
       // deserializeFromVar = anno.getField("deserializeFrom")?.variable;
       // if (serializeToVar != null){
@@ -74,6 +76,7 @@ class KeyAnnotationAnalyzer {
       // deserializeFrom: deserializeFrom,
       includeFromFory: includeFromFory,
       includeToFory: includeToFory,
+      ref: ref,
     );
     return foryKey;
   }
diff --git 
a/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
 
b/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
index e7d5e83ec..c16f02862 100644
--- 
a/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
+++ 
b/dart/packages/fory/lib/src/codegen/analyze/impl/field/field_analyzer_impl.dart
@@ -128,6 +128,7 @@ class FieldAnalyzerImpl implements FieldAnalyzer {
         hasInitializer: element.hasInitializer,
         includeFromFory: key.includeFromFory,
         includeToFory: key.includeToFory,
+        trackingRef: key.ref,
       ),
     );
   }
diff --git 
a/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart 
b/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
index f629ec9d8..8d6a3b6dc 100644
--- a/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
+++ b/dart/packages/fory/lib/src/codegen/meta/impl/class_spec_generator.dart
@@ -57,21 +57,6 @@ class ClassSpecGenerator extends CustomTypeSpecGenerator {
     );
   }
 
-  void _genMixinPart(StringBuffer buf) {
-    buf.write("mixin ");
-    buf.write('_\$');
-    buf.write(name);
-    buf.write("Fory");
-    buf.write(" implements ForyTypeProvider {\n");
-    CodegenTool.writeIndent(buf, CodegenStyle.indent);
-    buf.write("@override\n");
-    CodegenTool.writeIndent(buf, CodegenStyle.indent);
-    buf.write("Type get foryType => ");
-    buf.write(name);
-    buf.write(";\n");
-    buf.write("}\n");
-  }
-
   @override
   void writeCode(StringBuffer buf, [int indentLevel = 0]) {
     int totalIndent = indentLevel * CodegenStyle.indent;
@@ -136,7 +121,5 @@ class ClassSpecGenerator extends CustomTypeSpecGenerator {
 
     // tail part
     buf.write(");\n\n");
-
-    _genMixinPart(buf);
   }
 }
diff --git 
a/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart 
b/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
index 8a628c602..0ad37a0dd 100644
--- a/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
+++ b/dart/packages/fory/lib/src/codegen/meta/impl/field_spec_immutable.dart
@@ -35,6 +35,7 @@ class FieldSpecImmutable extends GeneratedCodePart {
 
   final bool includeFromFory;
   final bool includeToFory;
+  final bool trackingRef;
 
   final bool isPublic;
 
@@ -65,6 +66,7 @@ class FieldSpecImmutable extends GeneratedCodePart {
     required this.hasInitializer,
     required this.includeFromFory,
     required this.includeToFory,
+    required this.trackingRef,
   }) : typeAdapter = TypeAdapter(typeSpec) {
     if (isPublic) {
       assert(name.isNotEmpty && name[0] != "_");
@@ -124,7 +126,7 @@ class FieldSpecImmutable extends GeneratedCodePart {
     // ForyFieldSpec::name part
     CodegenTool.writeIndent(buf, nextTotalIndent);
     buf.write("'");
-    buf.write(name);
+    buf.write(transName ?? name);
     buf.write("',\n");
 
     // ForyFieldSpec::type part
@@ -169,6 +171,11 @@ class FieldSpecImmutable extends GeneratedCodePart {
       buf.write("null,\n");
     }
 
+    if (trackingRef) {
+      CodegenTool.writeIndent(buf, nextTotalIndent);
+      buf.write("trackingRef: true,\n");
+    }
+
     // tail part
     CodegenTool.writeIndent(buf, totalIndent);
     buf.write("),\n");
diff --git a/dart/packages/fory/lib/src/fory_impl.dart 
b/dart/packages/fory/lib/src/fory_impl.dart
index 75a097323..d2298ad46 100644
--- a/dart/packages/fory/lib/src/fory_impl.dart
+++ b/dart/packages/fory/lib/src/fory_impl.dart
@@ -20,14 +20,10 @@
 import 'dart:typed_data';
 import 'package:fory/src/codegen/entity/struct_hash_pair.dart';
 import 'package:fory/src/config/fory_config.dart';
-import 'package:fory/src/const/types.dart';
 import 'package:fory/src/deserialization_dispatcher.dart';
 import 'package:fory/src/dev_annotation/optimize.dart';
 import 'package:fory/src/memory/byte_reader.dart';
 import 'package:fory/src/memory/byte_writer.dart';
-import 'package:fory/src/meta/specs/type_spec.dart';
-import 'package:fory/src/meta/specs/custom_type_spec.dart';
-import 'package:fory/src/meta/specs/enum_spec.dart';
 import 'package:fory/src/resolver/type_resolver.dart';
 import 'package:fory/src/serialization_dispatcher.dart';
 import 'package:fory/src/serializer/serializer.dart';
@@ -64,13 +60,13 @@ final class Fory {
 
   @inline
   void register(
-    CustomTypeSpec spec, {
+    Type type, {
     int? typeId,
     String? namespace,
     String? typename,
   }) {
     registerType(
-      spec,
+      type,
       typeId: typeId,
       namespace: namespace,
       typename: typename,
@@ -79,13 +75,13 @@ final class Fory {
 
   @inline
   void registerType(
-    CustomTypeSpec spec, {
+    Type type, {
     int? typeId,
     String? namespace,
     String? typename,
   }) {
     _typeResolver.registerType(
-      spec,
+      type,
       typeId: typeId,
       namespace: namespace,
       typename: typename,
@@ -94,13 +90,13 @@ final class Fory {
 
   @inline
   void registerStruct(
-    TypeSpec spec, {
+    Type type, {
     int? typeId,
     String? namespace,
     String? typename,
   }) {
-    register(
-      spec,
+    _typeResolver.registerStruct(
+      type,
       typeId: typeId,
       namespace: namespace,
       typename: typename,
@@ -109,13 +105,13 @@ final class Fory {
 
   @inline
   void registerEnum(
-    EnumSpec spec, {
+    Type type, {
     int? typeId,
     String? namespace,
     String? typename,
   }) {
-    register(
-      spec,
+    _typeResolver.registerEnum(
+      type,
       typeId: typeId,
       namespace: namespace,
       typename: typename,
@@ -124,23 +120,13 @@ final class Fory {
 
   @inline
   void registerUnion(
-    CustomTypeSpec spec, {
+    Type type, {
     int? typeId,
     String? namespace,
     String? typename,
   }) {
-    final ObjType objType = spec.objType;
-    if (objType != ObjType.UNION &&
-        objType != ObjType.TYPED_UNION &&
-        objType != ObjType.NAMED_UNION) {
-      throw ArgumentError.value(
-        objType,
-        'spec.objType',
-        'registerUnion only accepts union specs',
-      );
-    }
-    register(
-      spec,
+    _typeResolver.registerUnion(
+      type,
       typeId: typeId,
       namespace: namespace,
       typename: typename,
diff --git a/dart/packages/fory/lib/src/meta/specs/field_sorter.dart 
b/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
index fbf95b659..b6d615d05 100644
--- a/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
+++ b/dart/packages/fory/lib/src/meta/specs/field_sorter.dart
@@ -152,8 +152,10 @@ final class FieldSorter {
   }
 
   static bool _isCompressed(ObjType objType) {
-    return objType == ObjType.VAR_INT32 ||
+    return objType == ObjType.INT32 ||
+        objType == ObjType.VAR_INT32 ||
         objType == ObjType.VAR_UINT32 ||
+        objType == ObjType.INT64 ||
         objType == ObjType.VAR_INT64 ||
         objType == ObjType.SLI_INT64 ||
         objType == ObjType.VAR_UINT64 ||
diff --git a/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart 
b/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
index 4dee4f3d0..cb2ff6a52 100644
--- a/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
+++ b/dart/packages/fory/lib/src/resolver/impl/type_resolver_impl.dart
@@ -45,6 +45,7 @@ import 'package:fory/src/meta/specs/field_sorter.dart';
 import 'package:fory/src/meta/specs/field_type_spec.dart';
 import 'package:fory/src/resolver/dart_type_resolver.dart';
 import 'package:fory/src/resolver/meta_string_resolver.dart';
+import 'package:fory/src/resolver/spec_lookup.dart';
 import 'package:fory/src/resolver/tag_string_resolver.dart';
 import 'package:fory/src/resolver/struct_hash_resolver.dart';
 import 'package:fory/src/resolver/type_resolver.dart';
@@ -125,6 +126,82 @@ final class TypeResolverImpl extends TypeResolver {
 
   @override
   void registerType(
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  }) {
+    final CustomTypeSpec spec = _resolveSpec(type);
+    _registerResolvedSpec(spec,
+        typeId: typeId, namespace: namespace, typename: typename);
+  }
+
+  @override
+  void registerStruct(
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  }) {
+    final CustomTypeSpec spec = _resolveSpec(type);
+    if (!_isStructSpec(spec.objType)) {
+      throw RegistrationArgumentException(
+          'registerStruct requires a struct type, got ${spec.objType} for 
$type');
+    }
+    _registerResolvedSpec(spec,
+        typeId: typeId, namespace: namespace, typename: typename);
+  }
+
+  @override
+  void registerEnum(
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  }) {
+    final CustomTypeSpec spec = _resolveSpec(type);
+    if (!_isEnumSpec(spec.objType)) {
+      throw RegistrationArgumentException(
+          'registerEnum requires an enum type, got ${spec.objType} for $type');
+    }
+    _registerResolvedSpec(spec,
+        typeId: typeId, namespace: namespace, typename: typename);
+  }
+
+  @override
+  void registerUnion(
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  }) {
+    final CustomTypeSpec spec = _resolveSpec(type);
+    if (!_isUnionSpec(spec.objType)) {
+      throw RegistrationArgumentException(
+          'registerUnion requires a union type, got ${spec.objType} for 
$type');
+    }
+    _registerResolvedSpec(spec,
+        typeId: typeId, namespace: namespace, typename: typename);
+  }
+
+  CustomTypeSpec _resolveSpec(Type type) {
+    final CustomTypeSpec? cachedSpec = _type2Spec[type];
+    if (cachedSpec != null) {
+      return cachedSpec;
+    }
+    final CustomTypeSpec? lookedUpSpec = SpecLookup.resolve(type);
+    if (lookedUpSpec == null) {
+      throw RegistrationArgumentException(
+          'No generated schema found for type $type. Ensure generated code is 
available and imported.');
+    }
+    if (lookedUpSpec.dartType != type) {
+      throw RegistrationArgumentException(
+          'Resolved schema type mismatch for $type, got 
${lookedUpSpec.dartType}.');
+    }
+    return lookedUpSpec;
+  }
+
+  void _registerResolvedSpec(
     CustomTypeSpec spec, {
     int? typeId,
     String? namespace,
@@ -167,6 +244,23 @@ final class TypeResolverImpl extends TypeResolver {
     _regWithNamespace(spec, typename, simpleName, inferredNamespace);
   }
 
+  bool _isStructSpec(ObjType objType) {
+    return objType == ObjType.NAMED_STRUCT ||
+        objType == ObjType.STRUCT ||
+        objType == ObjType.NAMED_COMPATIBLE_STRUCT ||
+        objType == ObjType.COMPATIBLE_STRUCT;
+  }
+
+  bool _isEnumSpec(ObjType objType) {
+    return objType == ObjType.NAMED_ENUM || objType == ObjType.ENUM;
+  }
+
+  bool _isUnionSpec(ObjType objType) {
+    return objType == ObjType.UNION ||
+        objType == ObjType.TYPED_UNION ||
+        objType == ObjType.NAMED_UNION;
+  }
+
   @override
   void registerSerializer(Type type, Serializer serializer) {
     TypeInfo? typeInfo = _ctx.type2TypeInfo[type];
@@ -291,6 +385,15 @@ final class TypeResolverImpl extends TypeResolver {
     return tag;
   }
 
+  @override
+  Serializer getRegisteredSerializer(Type type) {
+    TypeInfo? typeInfo = _ctx.type2TypeInfo[type];
+    if (typeInfo == null) {
+      throw UnregisteredTypeException(type);
+    }
+    return typeInfo.serializer;
+  }
+
   @override
   void bindSerializers(List<TypeSpecWrap> typeWraps) {
     TypeSpecWrap wrap;
@@ -715,6 +818,10 @@ final class TypeResolverImpl extends TypeResolver {
       case ObjType.TYPED_UNION:
       case ObjType.NAMED_UNION:
         return ObjType.UNION.id;
+      case ObjType.INT32:
+        return ObjType.VAR_INT32.id;
+      case ObjType.INT64:
+        return ObjType.VAR_INT64.id;
       case ObjType.STRUCT:
       case ObjType.COMPATIBLE_STRUCT:
       case ObjType.NAMED_STRUCT:
diff --git a/dart/packages/fory/lib/src/resolver/spec_lookup.dart 
b/dart/packages/fory/lib/src/resolver/spec_lookup.dart
new file mode 100644
index 000000000..e87182066
--- /dev/null
+++ b/dart/packages/fory/lib/src/resolver/spec_lookup.dart
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import 'dart:collection';
+import 'package:fory/src/meta/specs/custom_type_spec.dart';
+import 'package:fory/src/resolver/spec_lookup_stub.dart'
+    if (dart.library.mirrors) 
'package:fory/src/resolver/spec_lookup_mirrors.dart'
+    as impl;
+
+final class SpecLookup {
+  static final Map<Type, CustomTypeSpec?> _resolvedCache =
+      HashMap<Type, CustomTypeSpec?>();
+  static final Map<Type, CustomTypeSpec> _manualSpecs =
+      HashMap<Type, CustomTypeSpec>();
+
+  static CustomTypeSpec? resolve(Type type) {
+    if (_resolvedCache.containsKey(type)) {
+      return _resolvedCache[type];
+    }
+    final CustomTypeSpec? spec =
+        _manualSpecs[type] ?? impl.resolveByMirrors(type);
+    _resolvedCache[type] = spec;
+    return spec;
+  }
+
+  static void register(CustomTypeSpec spec) {
+    _manualSpecs[spec.dartType] = spec;
+    _resolvedCache[spec.dartType] = spec;
+  }
+
+  static void registerAll(Iterable<CustomTypeSpec> specs) {
+    for (final CustomTypeSpec spec in specs) {
+      register(spec);
+    }
+  }
+}
diff --git a/dart/packages/fory/lib/src/resolver/spec_lookup_mirrors.dart 
b/dart/packages/fory/lib/src/resolver/spec_lookup_mirrors.dart
new file mode 100644
index 000000000..30d7634d1
--- /dev/null
+++ b/dart/packages/fory/lib/src/resolver/spec_lookup_mirrors.dart
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import 'dart:mirrors';
+import 'package:fory/src/meta/specs/custom_type_spec.dart';
+
+CustomTypeSpec? resolveByMirrors(Type type) {
+  final ClassMirror? classMirror = _classMirrorOf(type);
+  if (classMirror == null) {
+    return null;
+  }
+  final String simpleName = MirrorSystem.getName(classMirror.simpleName);
+  if (simpleName.isEmpty) {
+    return null;
+  }
+  final Symbol symbol = Symbol('\$$simpleName');
+  final LibraryMirror? ownerLibrary = _ownerLibraryOf(classMirror);
+  if (ownerLibrary != null) {
+    final CustomTypeSpec? inOwner = _readSpecFromLibrary(ownerLibrary, symbol);
+    if (inOwner != null && inOwner.dartType == type) {
+      return inOwner;
+    }
+  }
+  for (final LibraryMirror library in currentMirrorSystem().libraries.values) {
+    if (identical(library, ownerLibrary)) {
+      continue;
+    }
+    final CustomTypeSpec? candidate = _readSpecFromLibrary(library, symbol);
+    if (candidate != null && candidate.dartType == type) {
+      return candidate;
+    }
+  }
+  return null;
+}
+
+ClassMirror? _classMirrorOf(Type type) {
+  try {
+    final TypeMirror typeMirror = reflectType(type);
+    if (typeMirror is ClassMirror) {
+      return typeMirror;
+    }
+  } catch (_) {
+    return null;
+  }
+  return null;
+}
+
+LibraryMirror? _ownerLibraryOf(ClassMirror classMirror) {
+  DeclarationMirror? owner = classMirror.owner;
+  while (owner != null && owner is! LibraryMirror) {
+    if (owner is ClassMirror) {
+      owner = owner.owner;
+      continue;
+    }
+    return null;
+  }
+  return owner is LibraryMirror ? owner : null;
+}
+
+CustomTypeSpec? _readSpecFromLibrary(LibraryMirror library, Symbol symbol) {
+  if (!library.declarations.containsKey(symbol)) {
+    return null;
+  }
+  try {
+    final Object? reflectee = library.getField(symbol).reflectee;
+    if (reflectee is CustomTypeSpec) {
+      return reflectee;
+    }
+  } catch (_) {
+    return null;
+  }
+  return null;
+}
diff --git a/dart/example/nested_collection_example.dart 
b/dart/packages/fory/lib/src/resolver/spec_lookup_stub.dart
similarity index 77%
copy from dart/example/nested_collection_example.dart
copy to dart/packages/fory/lib/src/resolver/spec_lookup_stub.dart
index 805932705..0bcd0f0fd 100644
--- a/dart/example/nested_collection_example.dart
+++ b/dart/packages/fory/lib/src/resolver/spec_lookup_stub.dart
@@ -17,13 +17,8 @@
  * under the License.
  */
 
-import 'package:fory/fory.dart';
+import 'package:fory/src/meta/specs/custom_type_spec.dart';
 
-part 'nested_collection_example.g.dart';
-
-@foryClass
-class NestedObject with _$NestedObjectFory {
-  late final String name;
-  late final List<String> names;
-  late final Map<double, Map<String, int>> map;
+CustomTypeSpec? resolveByMirrors(Type type) {
+  return null;
 }
diff --git a/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart 
b/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
index b8feaed67..340f53ea4 100644
--- a/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
+++ b/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
@@ -87,6 +87,12 @@ class StructHashResolver {
   }
 
   int _fingerprintTypeId(ObjType objType) {
+    if (objType == ObjType.INT32) {
+      return ObjType.VAR_INT32.id;
+    }
+    if (objType == ObjType.INT64) {
+      return ObjType.VAR_INT64.id;
+    }
     if (objType == ObjType.UNKNOWN) {
       return ObjType.UNKNOWN.id;
     }
diff --git a/dart/packages/fory/lib/src/resolver/type_resolver.dart 
b/dart/packages/fory/lib/src/resolver/type_resolver.dart
index b65307cf3..dffeadc79 100644
--- a/dart/packages/fory/lib/src/resolver/type_resolver.dart
+++ b/dart/packages/fory/lib/src/resolver/type_resolver.dart
@@ -25,7 +25,6 @@ import 
'package:fory/src/resolver/impl/type_resolver_impl.dart';
 import 'package:fory/src/serializer/serializer.dart';
 import 'package:fory/src/config/fory_config.dart';
 import 'package:fory/src/memory/byte_writer.dart';
-import 'package:fory/src/meta/specs/custom_type_spec.dart';
 import 'package:fory/src/serialization_context.dart';
 
 abstract base class TypeResolver {
@@ -36,7 +35,28 @@ abstract base class TypeResolver {
   }
 
   void registerType(
-    CustomTypeSpec spec, {
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  });
+
+  void registerStruct(
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  });
+
+  void registerEnum(
+    Type type, {
+    int? typeId,
+    String? namespace,
+    String? typename,
+  });
+
+  void registerUnion(
+    Type type, {
     int? typeId,
     String? namespace,
     String? typename,
@@ -56,6 +76,8 @@ abstract base class TypeResolver {
 
   TypeInfo writeTypeInfo(ByteWriter bw, Object obj, SerializationContext pack);
 
+  Serializer getRegisteredSerializer(Type type);
+
   /*-----For test only------------------------------------------------*/
   StructHashPair getHashPairForTest(
     Type type,
diff --git a/dart/packages/fory/lib/src/serializer/class_serializer.dart 
b/dart/packages/fory/lib/src/serializer/class_serializer.dart
index 836efa970..750dbe215 100644
--- a/dart/packages/fory/lib/src/serializer/class_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/class_serializer.dart
@@ -133,6 +133,12 @@ final class ClassSerializer extends 
CustomSerializer<Object> {
       }
       late Object? fieldValue;
       Serializer? serializer = _fieldTypeWraps[i].serializer;
+      if (serializer == null &&
+          !_compatible &&
+          fieldSpec.trackingRef &&
+          typeWrap.objType != ObjType.UNKNOWN) {
+        serializer = pack.typeResolver.getRegisteredSerializer(typeWrap.type);
+      }
       if (serializer == null) {
         if (fieldSpec.trackingRef || typeWrap.nullable) {
           fieldValue =
@@ -183,6 +189,12 @@ final class ClassSerializer extends 
CustomSerializer<Object> {
       }
       Object? fieldValue = fieldSpec.getter!(v);
       Serializer? serializer = typeWrap.serializer;
+      if (serializer == null &&
+          !_compatible &&
+          fieldSpec.trackingRef &&
+          typeWrap.objType != ObjType.UNKNOWN) {
+        serializer = pack.typeResolver.getRegisteredSerializer(typeWrap.type);
+      }
       if (serializer == null) {
         if (fieldSpec.trackingRef || typeWrap.nullable) {
           pack.serializationDispatcher
@@ -216,6 +228,12 @@ final class ClassSerializer extends 
CustomSerializer<Object> {
         pack.typeWrapStack.push(typeWrap);
       }
       Serializer? serializer = typeWrap.serializer;
+      if (serializer == null &&
+          !_compatible &&
+          fieldSpec.trackingRef &&
+          typeWrap.objType != ObjType.UNKNOWN) {
+        serializer = pack.typeResolver.getRegisteredSerializer(typeWrap.type);
+      }
       if (serializer == null) {
         if (fieldSpec.trackingRef || typeWrap.nullable) {
           args[i] = pack.deserializationDispatcher.readDynamicWithRef(br, 
pack);
diff --git 
a/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart 
b/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
index 07628d002..55e75c43d 100644
--- a/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/collection/list/list_serializer.dart
@@ -58,7 +58,12 @@ abstract base class ListSerializer extends 
IterableSerializer {
           (flags & IterableSerializer.isDeclElementTypeFlag) ==
               IterableSerializer.isDeclElementTypeFlag;
       if (isDeclElemType) {
-        serializer = elemWrap?.serializer;
+        if (elemWrap == null) {
+          throw StateError(
+              'List element declared type flag set but element type is 
unavailable');
+        }
+        serializer = elemWrap.serializer ??
+            pack.typeResolver.getRegisteredSerializer(elemWrap.type);
       }
       if (serializer == null) {
         serializer = pack.typeResolver.readTypeInfo(br).serializer;
diff --git 
a/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart 
b/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
index e37efd492..27e698a16 100644
--- a/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/collection/map/map_serializer.dart
@@ -92,14 +92,24 @@ abstract base class MapSerializer<T extends Map<Object?, 
Object?>>
       int chunkSize = br.readUint8();
 
       Serializer keySerializer;
-      if (keyDeclaredType && keyWrap?.serializer != null) {
-        keySerializer = keyWrap!.serializer!;
+      if (keyDeclaredType) {
+        if (keyWrap == null) {
+          throw StateError(
+              'Map key declared type flag set but key type is unavailable');
+        }
+        keySerializer = keyWrap.serializer ??
+            pack.typeResolver.getRegisteredSerializer(keyWrap.type);
       } else {
         keySerializer = pack.typeResolver.readTypeInfo(br).serializer;
       }
       Serializer valueSerializer;
-      if (valueDeclaredType && valueWrap?.serializer != null) {
-        valueSerializer = valueWrap!.serializer!;
+      if (valueDeclaredType) {
+        if (valueWrap == null) {
+          throw StateError(
+              'Map value declared type flag set but value type is 
unavailable');
+        }
+        valueSerializer = valueWrap.serializer ??
+            pack.typeResolver.getRegisteredSerializer(valueWrap.type);
       } else {
         valueSerializer = pack.typeResolver.readTypeInfo(br).serializer;
       }
@@ -311,9 +321,14 @@ abstract base class MapSerializer<T extends Map<Object?, 
Object?>>
   ) {
     bool trackRef = (chunkHeader & _trackingKeyRef) != 0;
     bool keyDeclaredType = (chunkHeader & _keyDeclType) != 0;
-    if (keyDeclaredType && keyWrap?.serializer != null) {
-      return _readWithSerializer(
-          br, keyWrap!.serializer!, trackRef, pack, keyWrap);
+    if (keyDeclaredType) {
+      if (keyWrap == null) {
+        throw StateError(
+            'Map key declared type flag set but key type is unavailable');
+      }
+      Serializer keySerializer = keyWrap.serializer ??
+          pack.typeResolver.getRegisteredSerializer(keyWrap.type);
+      return _readWithSerializer(br, keySerializer, trackRef, pack, keyWrap);
     }
     return _readWithDynamic(br, trackRef, pack, keyWrap);
   }
@@ -326,9 +341,15 @@ abstract base class MapSerializer<T extends Map<Object?, 
Object?>>
   ) {
     bool trackRef = (chunkHeader & _trackingValueRef) != 0;
     bool valueDeclaredType = (chunkHeader & _valueDeclType) != 0;
-    if (valueDeclaredType && valueWrap?.serializer != null) {
+    if (valueDeclaredType) {
+      if (valueWrap == null) {
+        throw StateError(
+            'Map value declared type flag set but value type is unavailable');
+      }
+      Serializer valueSerializer = valueWrap.serializer ??
+          pack.typeResolver.getRegisteredSerializer(valueWrap.type);
       return _readWithSerializer(
-          br, valueWrap!.serializer!, trackRef, pack, valueWrap);
+          br, valueSerializer, trackRef, pack, valueWrap);
     }
     return _readWithDynamic(br, trackRef, pack, valueWrap);
   }
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java 
b/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
index 26fd0d0c1..f27cabf6b 100644
--- a/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
+++ b/java/fory-core/src/test/java/org/apache/fory/xlang/DartXlangTest.java
@@ -24,8 +24,10 @@ import java.io.IOException;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import org.apache.fory.test.TestUtils;
 import org.testng.SkipException;
 import org.testng.annotations.Test;
 
@@ -33,8 +35,18 @@ import org.testng.annotations.Test;
 @Test
 public class DartXlangTest extends XlangTestBase {
   private static final String DART_EXECUTABLE = "dart";
+  private static final int DART_SETUP_TIMEOUT_SECONDS = 300;
+  private static final File DART_WORK_DIR = new File("../../dart");
+  private static final File DART_FORY_TEST_WORK_DIR = new 
File("../../dart/packages/fory-test");
+  private static final File DART_XLANG_SOURCE_FILE =
+      new File(DART_FORY_TEST_WORK_DIR, "lib/entity/xlang_test_models.dart");
+  private static final File DART_XLANG_GENERATED_FILE =
+      new File(DART_FORY_TEST_WORK_DIR, 
"lib/generated/xlang_test_models.g.dart");
   private static final String DART_MODULE =
       "packages/fory-test/test/cross_lang_test/xlang_test_main.dart";
+  private static final List<String> DART_CODEGEN_COMMAND =
+      Arrays.asList(
+          DART_EXECUTABLE, "run", "build_runner", "build", 
"--delete-conflicting-outputs");
 
   private static final List<String> DART_BASE_COMMAND =
       Arrays.asList(DART_EXECUTABLE, "run", DART_MODULE, "<DART_TESTCASE>");
@@ -63,6 +75,7 @@ public class DartXlangTest extends XlangTestBase {
     if (!dartInstalled) {
       throw new SkipException("Skipping DartXlangTest: dart not installed");
     }
+    ensureGeneratedXlangSpecs();
   }
 
   @Override
@@ -71,7 +84,23 @@ public class DartXlangTest extends XlangTestBase {
     command.set(DART_TESTCASE_INDEX, caseName);
     Map<String, String> env = envBuilder(dataFile);
     env.put("ENABLE_FORY_DEBUG_OUTPUT", "1");
-    return new CommandContext(command, env, new File("../../dart"));
+    return new CommandContext(command, env, DART_WORK_DIR);
+  }
+
+  private static synchronized void ensureGeneratedXlangSpecs() {
+    if (DART_XLANG_GENERATED_FILE.isFile()
+        && DART_XLANG_GENERATED_FILE.lastModified() >= 
DART_XLANG_SOURCE_FILE.lastModified()) {
+      return;
+    }
+    if (!TestUtils.executeCommand(
+        DART_CODEGEN_COMMAND,
+        DART_SETUP_TIMEOUT_SECONDS,
+        Collections.emptyMap(),
+        DART_FORY_TEST_WORK_DIR)) {
+      throw new IllegalStateException(
+          "Failed to generate Dart xlang specs by command: "
+              + String.join(" ", DART_CODEGEN_COMMAND));
+    }
   }
 
   // 
============================================================================


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

Reply via email to