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 ff0946e60 refactor(xlang): use 0 for unknow type id (#2985)
ff0946e60 is described below
commit ff0946e60b5702d4d904c3f20d9b1b2f9d60bf07
Author: Shawn Yang <[email protected]>
AuthorDate: Thu Dec 4 13:07:31 2025 +0800
refactor(xlang): use 0 for unknow type id (#2985)
## Why?
## What does this PR do?
use 0 for unknow type id
## Related issues
## Does this PR introduce any user-facing change?
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
---
cpp/fory/type/type.h | 7 ++++---
.../fory-test/test/codegen_test/struct_codegen_test.dart | 2 +-
.../packages/fory/lib/src/codegen/analyze/analysis_wrappers.dart | 2 +-
dart/packages/fory/lib/src/const/dart_type.dart | 4 ++--
dart/packages/fory/lib/src/const/obj_type.dart | 5 +++--
dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart | 2 +-
go/fory/fory.go | 9 +++++++++
go/fory/type.go | 9 +++++----
.../src/main/java/org/apache/fory/resolver/XtypeResolver.java | 2 +-
java/fory-core/src/main/java/org/apache/fory/type/Types.java | 6 +++++-
javascript/packages/fory/lib/type.ts | 2 ++
python/pyfory/_registry.py | 2 +-
python/pyfory/_struct.py | 3 +--
python/pyfory/includes/libformat.pxd | 2 +-
python/pyfory/type.py | 8 +++-----
rust/fory-core/src/resolver/type_resolver.rs | 8 ++++----
rust/fory-core/src/types.rs | 9 +++++++--
17 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/cpp/fory/type/type.h b/cpp/fory/type/type.h
index cface254e..4cf0765ff 100644
--- a/cpp/fory/type/type.h
+++ b/cpp/fory/type/type.h
@@ -23,6 +23,8 @@
namespace fory {
enum class TypeId : int32_t {
+ // Unknown/polymorphic type marker.
+ UNKNOWN = 0,
// a boolean value (true or false).
BOOL = 1,
// an 8-bit signed integer.
@@ -101,9 +103,8 @@ enum class TypeId : int32_t {
FLOAT32_ARRAY = 36,
// one-dimensional float64 array.
FLOAT64_ARRAY = 37,
- // Unknown/polymorphic type marker.
- UNKNOWN = 64,
- // Bound value, typically used as a sentinel value.
+ // Bound value for range checks (types with id >= BOUND are not internal
+ // types).
BOUND = 64
};
diff --git a/dart/packages/fory-test/test/codegen_test/struct_codegen_test.dart
b/dart/packages/fory-test/test/codegen_test/struct_codegen_test.dart
index 93adcfc14..7ea77da5c 100644
--- a/dart/packages/fory-test/test/codegen_test/struct_codegen_test.dart
+++ b/dart/packages/fory-test/test/codegen_test/struct_codegen_test.dart
@@ -34,7 +34,7 @@ void main(){
[
FieldSpec(
'f1',
- TypeSpec(Object, ObjType.UNKNOWN_YET, false, false, null, const
[],),
+ TypeSpec(Object, ObjType.UNKNOWN, false, false, null, const [],),
true,
true,
(Object inst) => (inst as ComplexObject2).f1,
diff --git a/dart/packages/fory/lib/src/codegen/analyze/analysis_wrappers.dart
b/dart/packages/fory/lib/src/codegen/analyze/analysis_wrappers.dart
index 0129767db..3eae799a1 100644
--- a/dart/packages/fory/lib/src/codegen/analyze/analysis_wrappers.dart
+++ b/dart/packages/fory/lib/src/codegen/analyze/analysis_wrappers.dart
@@ -25,7 +25,7 @@ typedef TypeDecision = ({InterfaceType type, bool
forceNullable});
class ObjTypeWrapper{
static const namedEnum = ObjTypeWrapper(ObjType.NAMED_ENUM, true,);
static const namedStruct = ObjTypeWrapper(ObjType.NAMED_STRUCT, false);
- static const unknownStruct = ObjTypeWrapper(ObjType.UNKNOWN_YET, false);
+ static const unknownStruct = ObjTypeWrapper(ObjType.UNKNOWN, false);
final ObjType objType; // null means unsupported
final bool certainForSer;
diff --git a/dart/packages/fory/lib/src/const/dart_type.dart
b/dart/packages/fory/lib/src/const/dart_type.dart
index 2ec9c7e16..41561402e 100644
--- a/dart/packages/fory/lib/src/const/dart_type.dart
+++ b/dart/packages/fory/lib/src/const/dart_type.dart
@@ -75,7 +75,7 @@ enum DartTypeEnum{
DECIMAL(Decimal,true, 'Decimal', 'package', 'decimal/decimal.dart', null,
true, 'package:decimal/decimal.dart@Decimal'),
DURATION(Duration,true, 'Duration', 'dart', 'core', null,
true,'dart:core@Duration'),;
- // NUM(num, false, 'num', 'dart', 'core', ObjType.UNKNOWN_YET,
'dart:core@num'),
+ // NUM(num, false, 'num', 'dart', 'core', ObjType.UNKNOWN, 'dart:core@num'),
final String scheme;
final String path;
@@ -108,7 +108,7 @@ enum DartTypeEnum{
@Deprecated('use find')
// TODO: Using this method requires that all DartTypeEnum names be unique
and sorted in strict string order
/// Returning null indicates it is definitely a Dart built-in type, which is
unsupported
- /// Returning UNKNOWN_YET means uncertain
+ /// Returning UNKNOWN means uncertain
// TODO: Attempt to record the Dart analyzer's ID to achieve a numerical
comparison
static DartTypeEnum? _findDeprecated(String name, String scheme, String
path){
int l = 0;
diff --git a/dart/packages/fory/lib/src/const/obj_type.dart
b/dart/packages/fory/lib/src/const/obj_type.dart
index 7183875cf..2bedcd7ec 100644
--- a/dart/packages/fory/lib/src/const/obj_type.dart
+++ b/dart/packages/fory/lib/src/const/obj_type.dart
@@ -22,8 +22,9 @@
library;
enum ObjType {
- /// A NULL type having no physical storage
- UNKNOWN_YET(0, false), // This value is not meaningless. For example, a
field is a parent class/non-specific class, which cannot be analyzed during
static code generation.
+ /// Unknown/polymorphic type marker. For example, a field is a parent
class/non-specific class,
+ /// which cannot be analyzed during static code generation.
+ UNKNOWN(0, false),
// x
/// Boolean as 1 bit, LSB bit-packed ordering
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 3debee9e4..bd6a94d67 100644
--- a/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
+++ b/dart/packages/fory/lib/src/resolver/struct_hash_resolver.dart
@@ -71,7 +71,7 @@ class StructHashResolver{
case ObjType.MAP:
id = ObjType.MAP.id;
break;
- case ObjType.UNKNOWN_YET:
+ case ObjType.UNKNOWN:
id = 0;
break;
default:
diff --git a/go/fory/fory.go b/go/fory/fory.go
index c55b26f4f..1d1068217 100644
--- a/go/fory/fory.go
+++ b/go/fory/fory.go
@@ -559,6 +559,15 @@ func (f *Fory) readData(buffer *ByteBuffer, value
reflect.Value, serializer Seri
default:
concrete = value
type_ = concrete.Type()
+ // For slice types with concrete element types, prefer
type-specific serializer
+ // to ensure format compatibility between serialization
and deserialization.
+ // This is needed because LIST typeID is shared across
all slice types,
+ // but different slice types may use different
serializers with different formats.
+ if type_.Kind() == reflect.Slice &&
!isDynamicType(type_.Elem()) {
+ if typeSpecific, err :=
f.typeResolver.getSerializerByType(type_, false); err == nil && typeSpecific !=
nil {
+ serializer = typeSpecific
+ }
+ }
}
if err := serializer.Read(f, buffer, type_, concrete); err !=
nil {
return err
diff --git a/go/fory/type.go b/go/fory/type.go
index 8834dcc5e..384323ec0 100644
--- a/go/fory/type.go
+++ b/go/fory/type.go
@@ -33,8 +33,8 @@ import (
type TypeId = int16
const (
- // NA A NullFlag type having no physical storage
- NA TypeId = iota // NA = 0
+ // UNKNOWN Unknown/polymorphic type marker
+ UNKNOWN = 0
// BOOL Boolean as 1 bit LSB bit-packed ordering
BOOL = 1
// INT8 Signed 8-bit little-endian integer
@@ -113,8 +113,6 @@ const (
ARROW_RECORD_BATCH = 38
// ARROW_TABLE an arrow table object
ARROW_TABLE = 39
- // UNKNOWN an unknown type
- UNKNOWN = 63
// UINT8 Unsigned 8-bit little-endian integer
UINT8 = 100 // Not in mapping table, assign a higher value
@@ -671,6 +669,9 @@ func (r *typeResolver) getTypeInfo(value reflect.Value,
create bool) (TypeInfo,
} else if isMultiDimensionaSlice(value) {
typeID = LIST
return r.typeIDToTypeInfo[typeID], nil
+ } else if value.Kind() == reflect.Slice {
+ // Regular slices are treated as LIST
+ typeID = LIST
}
// Register the type with full metadata
diff --git
a/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
b/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
index 284b31803..60a6ce913 100644
--- a/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
+++ b/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
@@ -494,7 +494,7 @@ public class XtypeResolver extends TypeResolver {
}
public ClassInfo getUserTypeInfo(int userTypeId) {
- Preconditions.checkArgument((userTypeId & 0xff) < Types.UNKNOWN);
+ Preconditions.checkArgument((userTypeId & 0xff) < Types.BOUND);
return xtypeIdToClassMap.get(userTypeId);
}
diff --git a/java/fory-core/src/main/java/org/apache/fory/type/Types.java
b/java/fory-core/src/main/java/org/apache/fory/type/Types.java
index 88212144d..051a2ea00 100644
--- a/java/fory-core/src/main/java/org/apache/fory/type/Types.java
+++ b/java/fory-core/src/main/java/org/apache/fory/type/Types.java
@@ -26,6 +26,9 @@ import org.apache.fory.util.Preconditions;
public class Types {
+ /** Unknown/polymorphic type marker. */
+ public static final int UNKNOWN = 0;
+
/** bool: a boolean value (true or false). */
public static final int BOOL = 1;
@@ -156,7 +159,8 @@ public class Types {
/** One dimensional float64 array. */
public static final int FLOAT64_ARRAY = 37;
- public static final int UNKNOWN = 63;
+ /** Bound value for range checks (types with id >= BOUND are not internal
types). */
+ public static final int BOUND = 64;
// Helper methods
public static boolean isNamedType(int value) {
diff --git a/javascript/packages/fory/lib/type.ts
b/javascript/packages/fory/lib/type.ts
index abd1a27a7..b4aaa0a25 100644
--- a/javascript/packages/fory/lib/type.ts
+++ b/javascript/packages/fory/lib/type.ts
@@ -20,6 +20,8 @@
import { StructTypeInfo } from "./typeInfo";
export const TypeId = {
+ // Unknown/polymorphic type marker.
+ UNKNOWN: 0,
// a boolean value (true or false).
BOOL: 1,
// a 8-bit signed integer.
diff --git a/python/pyfory/_registry.py b/python/pyfory/_registry.py
index 7590cf238..f37c17830 100644
--- a/python/pyfory/_registry.py
+++ b/python/pyfory/_registry.py
@@ -254,7 +254,7 @@ class TypeResolver:
def _initialize_common(self):
register = functools.partial(self._register_type, internal=True)
- register(None, type_id=TypeId.NA, serializer=NoneSerializer)
+ register(None, type_id=TypeId.UNKNOWN, serializer=NoneSerializer)
register(bool, type_id=TypeId.BOOL, serializer=BooleanSerializer)
register(int8, type_id=TypeId.INT8, serializer=ByteSerializer)
register(int16, type_id=TypeId.INT16, serializer=Int16Serializer)
diff --git a/python/pyfory/_struct.py b/python/pyfory/_struct.py
index d31fe5bb5..f5edc9d47 100644
--- a/python/pyfory/_struct.py
+++ b/python/pyfory/_struct.py
@@ -189,8 +189,7 @@ def group_fields(type_resolver, field_names, serializers,
nullable_map=None):
}:
container = other_types
else:
- assert TypeId.LOWER_BOUND < type_id < TypeId.UNKNOWN, (type_id,)
- assert type_id != TypeId.UNKNOWN, serializer
+ assert TypeId.UNKNOWN < type_id < TypeId.BOUND, (type_id,)
container = internal_types
container.append((type_id, serializer, field_name))
diff --git a/python/pyfory/includes/libformat.pxd
b/python/pyfory/includes/libformat.pxd
index abb0e3930..8baff7e78 100755
--- a/python/pyfory/includes/libformat.pxd
+++ b/python/pyfory/includes/libformat.pxd
@@ -77,7 +77,7 @@ cdef extern from "fory/type/type.h" namespace "fory" nogil:
FLOAT16_ARRAY = 35
FLOAT32_ARRAY = 36
FLOAT64_ARRAY = 37
- UNKNOWN = 64
+ UNKNOWN = 0
BOUND = 64
diff --git a/python/pyfory/type.py b/python/pyfory/type.py
index 3b842ae89..6df38111b 100644
--- a/python/pyfory/type.py
+++ b/python/pyfory/type.py
@@ -142,9 +142,8 @@ class TypeId:
See `org.apache.fory.types.Type`
"""
- LOWER_BOUND = 0
- # null value
- NA = 0
+ # Unknown/polymorphic type marker.
+ UNKNOWN = 0
# a boolean value (true or false).
BOOL = 1
# a 8-bit signed integer.
@@ -224,9 +223,8 @@ class TypeId:
FLOAT32_ARRAY = 36
# one dimensional float64 array.
FLOAT64_ARRAY = 37
- UNKNOWN = 63
- # BOUND id remains at 64
+ # Bound value for range checks (types with id >= BOUND are not internal
types).
BOUND = 64
@staticmethod
diff --git a/rust/fory-core/src/resolver/type_resolver.rs
b/rust/fory-core/src/resolver/type_resolver.rs
index d39dde005..22adaed20 100644
--- a/rust/fory-core/src/resolver/type_resolver.rs
+++ b/rust/fory-core/src/resolver/type_resolver.rs
@@ -726,10 +726,10 @@ impl TypeResolver {
// Check if type_id conflicts with any already registered type
// Skip check for:
- // 1. Internal types (type_id <= TypeId::UNKNOWN) as they can be shared
+ // 1. Internal types (type_id < TypeId::BOUND) as they can be shared
// 2. Types registered by name (they use shared type IDs like
NAMED_STRUCT)
if !register_by_name
- && actual_type_id > TypeId::UNKNOWN as u32
+ && actual_type_id >= TypeId::BOUND as u32
&& self.type_info_map_by_id.contains_key(&actual_type_id)
{
return Err(Error::type_error(format!(
@@ -917,8 +917,8 @@ impl TypeResolver {
}
// Check if type_id conflicts with any already registered type
- // Skip check for internal types (type_id <= TypeId::UNKNOWN) as they
can be shared
- if actual_type_id > TypeId::UNKNOWN as u32
+ // Skip check for internal types (type_id < TypeId::BOUND) as they can
be shared
+ if actual_type_id >= TypeId::BOUND as u32
&& self.type_info_map_by_id.contains_key(&actual_type_id)
{
return Err(Error::type_error(format!(
diff --git a/rust/fory-core/src/types.rs b/rust/fory-core/src/types.rs
index 669bb333d..6090a493e 100644
--- a/rust/fory-core/src/types.rs
+++ b/rust/fory-core/src/types.rs
@@ -42,6 +42,8 @@ pub enum RefFlag {
#[allow(non_camel_case_types)]
#[repr(i16)]
pub enum TypeId {
+ // Unknown/polymorphic type marker.
+ UNKNOWN = 0,
BOOL = 1,
INT8 = 2,
INT16 = 3,
@@ -93,7 +95,8 @@ pub enum TypeId {
U64_ARRAY = 75,
USIZE_ARRAY = 76,
U128_ARRAY = 77,
- UNKNOWN = 78,
+ // Bound value for range checks (types with id >= BOUND are not internal
types).
+ BOUND = 78,
}
pub const BOOL: u32 = TypeId::BOOL as u32;
@@ -148,6 +151,7 @@ pub const U64_ARRAY: u32 = TypeId::U64_ARRAY as u32;
pub const USIZE_ARRAY: u32 = TypeId::USIZE_ARRAY as u32;
pub const U128_ARRAY: u32 = TypeId::U128_ARRAY as u32;
pub const UNKNOWN: u32 = TypeId::UNKNOWN as u32;
+pub const BOUND: u32 = TypeId::BOUND as u32;
const MAX_UNT32: u64 = (1 << 31) - 1;
@@ -289,9 +293,10 @@ pub const fn is_primitive_type_id(type_id: TypeId) -> bool
{
}
/// Keep as const fn for compile time evaluation or constant folding
+/// Internal types are all types in `0 < id < BOUND` that are not
struct/ext/enum types.
#[inline(always)]
pub const fn is_internal_type(type_id: u32) -> bool {
- if type_id == 0 || type_id >= TypeId::UNKNOWN as u32 {
+ if type_id == UNKNOWN || type_id >= BOUND {
return false;
}
!matches!(
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]