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 47a284686 refactor(go): refine collection header bitmap (#2656)
47a284686 is described below
commit 47a2846867eafc5957fbcfd56365ddbe3212f926
Author: Zhong Junjie <[email protected]>
AuthorDate: Fri Sep 26 17:24:45 2025 +0800
refactor(go): refine collection header bitmap (#2656)
<!--
**Thanks for contributing to Apache Fory™.**
**If this is your first time opening a PR on fory, you can refer to
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).**
Contribution Checklist
- The **Apache Fory™** community has requirements on the naming of pr
titles. You can also find instructions in
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).
- Apache Fory™ has a strong focus on performance. If the PR you submit
will have an impact on performance, please benchmark it first and
provide the benchmark result here.
-->
## Why?
<!-- Describe the purpose of this PR. -->
Refine collection header bitmap to make it more understandable.
## What does this PR do?
<!-- Describe the details of this PR. -->
* Change the CollectionNotDeclElementType bit to
CollectionIsDeclElementType, so now 0b100 represents declared type.
* Fix several bugs inside writeSameType of collection serializer
* Remove references tracking on string
## Related issues
#2642
<!--
Is there any related issue? If this PR closes them you say say
fix/closes:
- #xxxx0
- #xxxx1
- Fixes #xxxx2
-->
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fory/issues/new/choose) describing the
need to do so and update the document if necessary.
Delete section if not applicable.
-->
- [x] Does this PR introduce any public API change? no
- [x] Does this PR introduce any binary protocol compatibility change?
no
## Benchmark
<!--
When the PR has an impact on performance (if you don't know whether the
PR will have an impact on performance, you can submit the PR first, and
if it will have impact on performance, the code reviewer will explain
it), be sure to attach a benchmark data here.
Delete section if not applicable.
-->
---
ci/run_ci.py | 2 +-
ci/run_ci.sh | 10 ++---
go/fory/fory.go | 15 +++++++-
go/fory/fory_test.go | 28 --------------
go/fory/reference.go | 5 ---
go/fory/reference_test.go | 2 +-
go/fory/serializer.go | 4 +-
go/fory/set.go | 16 ++++----
go/fory/slice.go | 94 +++++++++++++++++++++++++++++------------------
go/fory/struct.go | 53 +++++++++++++-------------
go/fory/type.go | 22 +++++++----
go/fory/type_def.go | 9 ++---
12 files changed, 136 insertions(+), 124 deletions(-)
diff --git a/ci/run_ci.py b/ci/run_ci.py
index cdd8f7fbc..7818a9e60 100644
--- a/ci/run_ci.py
+++ b/ci/run_ci.py
@@ -293,7 +293,7 @@ def parse_args():
if USE_PYTHON_GO:
func()
else:
- # run_shell_script("go")
+ run_shell_script("go")
pass
elif command == "format":
if USE_PYTHON_FORMAT:
diff --git a/ci/run_ci.sh b/ci/run_ci.sh
index bbc09feeb..e18e02728 100755
--- a/ci/run_ci.sh
+++ b/ci/run_ci.sh
@@ -356,11 +356,11 @@ case $1 in
;;
go)
echo "Executing fory go tests for go"
- cd "$ROOT/go/fory"
- go install ./cmd/fory
- cd "$ROOT/go/fory/tests"
- go generate
- go test -v
+ # cd "$ROOT/go/fory"
+ # go install ./cmd/fory
+ # cd "$ROOT/go/fory/tests"
+ # go generate
+ # go test -v
cd "$ROOT/go/fory"
go test -v
echo "Executing fory go tests succeeds"
diff --git a/go/fory/fory.go b/go/fory/fory.go
index abae4ef9b..3751452c8 100644
--- a/go/fory/fory.go
+++ b/go/fory/fory.go
@@ -374,7 +374,20 @@ func (f *Fory) writeValue(buffer *ByteBuffer, value
reflect.Value, serializer Se
if err != nil {
return fmt.Errorf("cannot write typeinfo for value %v: %v",
value, err)
}
- serializer = typeInfo.Serializer
+ // if compatible mode enable, use declared serializer to write value
+ if IsNamespacedType(TypeId(typeInfo.TypeID)) && f.compatible {
+ if declaredTypeDef, err :=
f.typeResolver.getTypeDef(typeInfo.Type, false); err != nil {
+ return err
+ } else {
+ ti, err := declaredTypeDef.buildTypeInfo()
+ if err != nil {
+ return err
+ }
+ serializer = ti.Serializer
+ }
+ } else {
+ serializer = typeInfo.Serializer
+ }
// Serialize the actual value using the serializer
return serializer.Write(f, buffer, value)
}
diff --git a/go/fory/fory_test.go b/go/fory/fory_test.go
index cf1fdfb73..9c4981617 100644
--- a/go/fory/fory_test.go
+++ b/go/fory/fory_test.go
@@ -314,34 +314,6 @@ func TestSerializeStruct(t *testing.T) {
}
}
-func TestSerializeStringReference(t *testing.T) {
- fory := NewFory(true)
- strSlice := []string{"str1", "str1", "", "", "str2"}
- strSlice = append(strSlice, strSlice[0])
- serde(t, fory, strSlice)
- type A struct {
- F1 string
- F2 string
- }
- require.Nil(t, fory.RegisterTagType("example.A", A{}))
- serde(t, fory, A{})
- serde(t, fory, A{F1: "str", F2: "str"})
- var strData []byte
- for i := 0; i < 1000; i++ {
- strData = append(strData, 100)
- }
- x := string(strData)
- serde(t, fory, &x)
- strSlice2 := []string{x, x, x}
- bytes, err := fory.Marshal(strSlice2)
- require.Nil(t, err)
- require.Less(t, len(bytes), 2*len(strData))
- strSlice23 := []*string{&x, &x, &x}
- bytes, err = fory.Marshal(strSlice23)
- require.Nil(t, err)
- require.Less(t, len(bytes), 2*len(strData))
-}
-
func TestSerializeCircularReference(t *testing.T) {
fory := NewFory(true)
{
diff --git a/go/fory/reference.go b/go/fory/reference.go
index 389a01085..e0b89bc00 100644
--- a/go/fory/reference.go
+++ b/go/fory/reference.go
@@ -95,11 +95,6 @@ func (r *RefResolver) WriteRefOrNull(buffer *ByteBuffer,
value reflect.Value) (r
case reflect.Interface:
value = value.Elem()
return r.WriteRefOrNull(buffer, value)
- case reflect.String:
- isNil = false
- str := unsafeGetBytes(value.Interface().(string))
- value = reflect.ValueOf(str)
- length = len(str)
case reflect.Invalid:
isNil = true
case reflect.Struct:
diff --git a/go/fory/reference_test.go b/go/fory/reference_test.go
index 2cb333513..5f7329b3e 100644
--- a/go/fory/reference_test.go
+++ b/go/fory/reference_test.go
@@ -32,7 +32,7 @@ func TestReferenceResolver(t *testing.T) {
values = append(values, commonMap()...)
foo := newFoo()
bar := Bar{}
- values = append(values, "", "str", &foo, &bar)
+ values = append(values, &foo, &bar)
for _, data := range values {
refWritten, err := refResolver.WriteRefOrNull(buf,
reflect.ValueOf(data))
require.Nil(t, err)
diff --git a/go/fory/serializer.go b/go/fory/serializer.go
index 222083a2f..47afdb9b1 100644
--- a/go/fory/serializer.go
+++ b/go/fory/serializer.go
@@ -232,7 +232,7 @@ func (s stringSerializer) TypeId() TypeId {
}
func (s stringSerializer) NeedWriteRef() bool {
- return true
+ return false
}
func (s stringSerializer) Write(f *Fory, buf *ByteBuffer, value reflect.Value)
error {
@@ -468,7 +468,7 @@ func (s *ptrToValueSerializer) Read(f *Fory, buf
*ByteBuffer, type_ reflect.Type
}
func writeBySerializer(f *Fory, buf *ByteBuffer, value reflect.Value,
serializer Serializer, referencable bool) error {
- if referencable {
+ if referencable && (serializer == nil || serializer.NeedWriteRef()) {
return f.writeReferencableBySerializer(buf, value, serializer)
} else {
return f.writeNonReferencableBySerializer(buf, value,
serializer)
diff --git a/go/fory/set.go b/go/fory/set.go
index d64982b6a..e18d8dd7a 100644
--- a/go/fory/set.go
+++ b/go/fory/set.go
@@ -55,7 +55,7 @@ func (s setSerializer) Write(f *Fory, buf *ByteBuffer, value
reflect.Value) erro
collectFlag, elemTypeInfo := s.writeHeader(f, buf, keys)
// Check if all elements are of same type
- if (collectFlag & CollectionNotSameType) == 0 {
+ if (collectFlag & CollectionIsSameType) != 0 {
// Optimized path for same-type elements
return s.writeSameType(f, buf, keys, elemTypeInfo, collectFlag)
}
@@ -72,7 +72,7 @@ func (s setSerializer) writeHeader(f *Fory, buf *ByteBuffer,
keys []reflect.Valu
collectFlag := CollectionDefaultFlag
var elemTypeInfo TypeInfo
hasNull := false
- hasDifferentType := false
+ hasSameType := true
// Check elements to detect types
// Initialize element type information from first non-null element
@@ -97,7 +97,7 @@ func (s setSerializer) writeHeader(f *Fory, buf *ByteBuffer,
keys []reflect.Valu
// Compare each element's type with the reference type
currentTypeInfo, _ := f.typeResolver.getTypeInfo(key, true)
if currentTypeInfo.TypeID != elemTypeInfo.TypeID {
- hasDifferentType = true
+ hasSameType = false
}
}
@@ -105,8 +105,8 @@ func (s setSerializer) writeHeader(f *Fory, buf
*ByteBuffer, keys []reflect.Valu
if hasNull {
collectFlag |= CollectionHasNull // Mark if collection contains
null values
}
- if hasDifferentType {
- collectFlag |= CollectionNotSameType // Mark if elements have
different types
+ if hasSameType {
+ collectFlag |= CollectionIsSameType // Mark if elements have
different types
}
// Enable reference tracking if configured
@@ -119,7 +119,7 @@ func (s setSerializer) writeHeader(f *Fory, buf
*ByteBuffer, keys []reflect.Valu
buf.WriteInt8(int8(collectFlag)) // Collection flags
// Write element type ID if all elements have same type
- if !hasDifferentType {
+ if hasSameType {
buf.WriteVarInt32(elemTypeInfo.TypeID)
}
@@ -206,7 +206,7 @@ func (s setSerializer) Read(f *Fory, buf *ByteBuffer, type_
reflect.Type, value
var elemTypeInfo TypeInfo
// If all elements are same type, read the shared type info
- if (collectFlag & CollectionNotSameType) == 0 {
+ if (collectFlag & CollectionIsSameType) != 0 {
typeID := buf.ReadVarInt32()
elemTypeInfo, _ = f.typeResolver.getTypeInfoById(int16(typeID))
}
@@ -219,7 +219,7 @@ func (s setSerializer) Read(f *Fory, buf *ByteBuffer, type_
reflect.Type, value
f.refResolver.Reference(value)
// Choose appropriate deserialization path based on type consistency
- if (collectFlag & CollectionNotSameType) == 0 {
+ if (collectFlag & CollectionIsSameType) != 0 {
return s.readSameType(f, buf, value, elemTypeInfo, collectFlag,
length)
}
return s.readDifferentTypes(f, buf, value, length)
diff --git a/go/fory/slice.go b/go/fory/slice.go
index ef3810abd..3aae29fb3 100644
--- a/go/fory/slice.go
+++ b/go/fory/slice.go
@@ -23,15 +23,19 @@ import (
)
const (
- CollectionDefaultFlag = 0b0000
- CollectionTrackingRef = 0b0001
- CollectionHasNull = 0b0010
- CollectionNotDeclElementType = 0b0100
- CollectionNotSameType = 0b1000
+ CollectionDefaultFlag = 0b0000
+ CollectionTrackingRef = 0b0001
+ CollectionHasNull = 0b0010
+ CollectionIsDeclElementType = 0b0100
+ CollectionIsSameType = 0b1000
+ CollectionDeclSameType = CollectionIsSameType |
CollectionIsDeclElementType
)
+// sliceSerializer provides the dynamic slice implementation(e.g.
[]interface{}) that inspects
+// element values at runtime
type sliceSerializer struct {
- elemInfo TypeInfo
+ elemInfo TypeInfo
+ declaredType reflect.Type
}
func (s sliceSerializer) TypeId() TypeId {
@@ -55,7 +59,7 @@ func (s sliceSerializer) Write(f *Fory, buf *ByteBuffer,
value reflect.Value) er
collectFlag, elemTypeInfo := s.writeHeader(f, buf, value)
// Choose serialization path based on type consistency
- if (collectFlag & CollectionNotSameType) == 0 {
+ if (collectFlag & CollectionIsSameType) != 0 {
return s.writeSameType(f, buf, value, elemTypeInfo,
collectFlag) // Optimized path for same-type elements
}
return s.writeDifferentTypes(f, buf, value) // Fallback path for
mixed-type elements
@@ -69,27 +73,38 @@ func (s sliceSerializer) writeHeader(f *Fory, buf
*ByteBuffer, value reflect.Val
collectFlag := CollectionDefaultFlag
var elemTypeInfo TypeInfo
hasNull := false
- hasDifferentType := false
+ hasSameType := true
- // Get type information for the first element
- elemTypeInfo, _ = f.typeResolver.getTypeInfo(value, true)
- collectFlag |= CollectionNotDeclElementType
+ // Seed elemTypeInfo from the first element so writeSameType can reuse
it.
+ // Empty slices leave elemTypeInfo zero-value, which is also fine
because
+ // writeSameType won't do anything in that case.
+ if value.Len() > 0 {
+ elemTypeInfo, _ = f.typeResolver.getTypeInfo(value.Index(0),
true)
+ }
- // Iterate through elements to check for nulls and type consistency
- for i := 0; i < value.Len(); i++ {
- elem := value.Index(i)
- if elem.Kind() == reflect.Interface || elem.Kind() ==
reflect.Ptr {
- elem = elem.Elem()
- }
- if isNull(elem) {
- hasNull = true
- continue
- }
+ if s.declaredType != nil {
+ collectFlag |= CollectionIsDeclElementType |
CollectionIsSameType
+ } else {
+ // Iterate through elements to check for nulls and type
consistency
+ var firstType reflect.Type
+ for i := 0; i < value.Len(); i++ {
+ elem := value.Index(i)
+ if elem.Kind() == reflect.Interface || elem.Kind() ==
reflect.Ptr {
+ elem = elem.Elem()
+ }
+ if isNull(elem) {
+ hasNull = true
+ continue
+ }
- // Compare each element's type with the first element's type
- currentTypeInfo, _ := f.typeResolver.getTypeInfo(elem, true)
- if currentTypeInfo.TypeID != elemTypeInfo.TypeID {
- hasDifferentType = true
+ // Compare each element's type with the first element's
type
+ if firstType == nil {
+ firstType = elem.Type()
+ } else {
+ if firstType != elem.Type() {
+ hasSameType = false
+ }
+ }
}
}
@@ -97,12 +112,12 @@ func (s sliceSerializer) writeHeader(f *Fory, buf
*ByteBuffer, value reflect.Val
if hasNull {
collectFlag |= CollectionHasNull // Mark if collection contains
null values
}
- if hasDifferentType {
- collectFlag |= CollectionNotSameType // Mark if elements have
different types
+ if hasSameType {
+ collectFlag |= CollectionIsSameType // Mark if elements have
same types
}
- // Enable reference tracking if configured
- if f.refTracking {
+ // Enable reference tracking if configured and element type supports it
+ if f.refTracking && (elemTypeInfo.Serializer == nil ||
elemTypeInfo.Serializer.NeedWriteRef()) {
collectFlag |= CollectionTrackingRef
}
@@ -110,8 +125,8 @@ func (s sliceSerializer) writeHeader(f *Fory, buf
*ByteBuffer, value reflect.Val
buf.WriteVarUint32(uint32(value.Len())) // Collection size
buf.WriteInt8(int8(collectFlag)) // Collection flags
- // Write element type ID if all elements have same type
- if !hasDifferentType {
+ // Write element type ID if all elements have same type and not using
declared type
+ if hasSameType && (collectFlag&CollectionIsDeclElementType == 0) {
buf.WriteVarInt32(elemTypeInfo.TypeID)
}
@@ -124,7 +139,10 @@ func (s sliceSerializer) writeSameType(f *Fory, buf
*ByteBuffer, value reflect.V
trackRefs := (flag & CollectionTrackingRef) != 0 // Check if reference
tracking is enabled
for i := 0; i < value.Len(); i++ {
- elem := value.Index(i).Elem()
+ elem := value.Index(i)
+ if elem.Kind() == reflect.Interface || elem.Kind() ==
reflect.Ptr {
+ elem = elem.Elem()
+ }
if isNull(elem) {
buf.WriteInt8(NullFlag) // Write null marker
continue
@@ -214,10 +232,14 @@ func (s sliceSerializer) Read(f *Fory, buf *ByteBuffer,
type_ reflect.Type, valu
collectFlag := buf.ReadInt8()
var elemTypeInfo TypeInfo
// Read element type information if all elements are same type
- if (collectFlag & CollectionNotSameType) == 0 {
- if (collectFlag & CollectionNotDeclElementType) != 0 {
+ if (collectFlag & CollectionIsSameType) != 0 {
+ if (collectFlag & CollectionIsDeclElementType) == 0 {
typeID := buf.ReadVarInt32()
- elemTypeInfo, _ =
f.typeResolver.getTypeInfoById(int16(typeID))
+ var err error
+ elemTypeInfo, err =
f.typeResolver.getTypeInfoById(int16(typeID))
+ if err != nil {
+ elemTypeInfo = s.elemInfo
+ }
} else {
elemTypeInfo = s.elemInfo
}
@@ -241,7 +263,7 @@ func (s sliceSerializer) Read(f *Fory, buf *ByteBuffer,
type_ reflect.Type, valu
f.refResolver.Reference(value)
// Choose appropriate deserialization path based on type consistency
- if (collectFlag & CollectionNotSameType) == 0 {
+ if (collectFlag & CollectionIsSameType) != 0 {
return s.readSameType(f, buf, value, elemTypeInfo, collectFlag)
}
return s.readDifferentTypes(f, buf, value)
diff --git a/go/fory/struct.go b/go/fory/struct.go
index 77e5b8056..9833c4b0b 100644
--- a/go/fory/struct.go
+++ b/go/fory/struct.go
@@ -44,6 +44,28 @@ func (s *structSerializer) NeedWriteRef() bool {
return true
}
+func (s *structSerializer) ensureFieldsInfo(f *Fory, fallbackType
reflect.Type) error {
+ if s.fieldsInfo != nil {
+ return nil
+ }
+
+ var (
+ infos structFieldsInfo
+ err error
+ )
+ if len(s.fieldDefs) == 0 {
+ infos, err = createStructFieldInfos(f, s.type_)
+ } else {
+ infos, err = createStructFieldInfosFromFieldDefs(f,
s.fieldDefs, fallbackType)
+ }
+ if err != nil {
+ return err
+ }
+
+ s.fieldsInfo = infos
+ return nil
+}
+
func (s *structSerializer) Write(f *Fory, buf *ByteBuffer, value
reflect.Value) error {
// If we have a codegen delegate, use it for optimal performance
if s.codegenDelegate != nil {
@@ -51,13 +73,8 @@ func (s *structSerializer) Write(f *Fory, buf *ByteBuffer,
value reflect.Value)
}
// Fall back to reflection-based serialization
- // TODO support fields back and forward compatible. need to serialize
fields name too.
- if s.fieldsInfo == nil {
- if fieldsInfo, err := createStructFieldInfos(f, s.type_); err
!= nil {
- return err
- } else {
- s.fieldsInfo = fieldsInfo
- }
+ if err := s.ensureFieldsInfo(f, value.Type()); err != nil {
+ return err
}
if s.structHash == 0 {
if hash, err := computeStructHash(s.fieldsInfo,
f.typeResolver); err != nil {
@@ -99,22 +116,8 @@ func (s *structSerializer) Read(f *Fory, buf *ByteBuffer,
type_ reflect.Type, va
}
value = value.Elem()
}
- if s.fieldsInfo == nil {
- if len(s.fieldDefs) == 0 {
- // Normal case: create from reflection
- if infos, err := createStructFieldInfos(f, s.type_);
err != nil {
- return err
- } else {
- s.fieldsInfo = infos
- }
- } else {
- // Create from fieldDefs for forward/backward
compatibility
- if infos, err := createStructFieldInfosFromFieldDefs(f,
s.fieldDefs, type_); err != nil {
- return err
- } else {
- s.fieldsInfo = infos
- }
- }
+ if err := s.ensureFieldsInfo(f, type_); err != nil {
+ return err
}
if s.structHash == 0 {
if hash, err := computeStructHash(s.fieldsInfo,
f.typeResolver); err != nil {
@@ -188,7 +191,7 @@ func createStructFieldInfos(f *Fory, type_ reflect.Type)
(structFieldsInfo, erro
// so it has the potential and capability to
use readSameTypes function.
if field.Type.Elem().Kind() !=
reflect.Interface {
fieldSerializer = sliceSerializer{
-
f.typeResolver.typesInfo[field.Type.Elem()],
+ elemInfo:
f.typeResolver.typesInfo[field.Type.Elem()],
}
}
}
@@ -280,7 +283,7 @@ func createStructFieldInfosFromFieldDefs(f *Fory, fieldDefs
[]FieldDef, type_ re
fieldType = fieldTypeFromDef
}
- fieldSerializer, err := def.fieldType.getSerializer(f)
+ fieldSerializer, err := getFieldTypeSerializer(f, def.fieldType)
if err != nil {
return nil, fmt.Errorf("failed to get serializer for
field %s: %w", def.name, err)
}
diff --git a/go/fory/type.go b/go/fory/type.go
index 7d0508af7..d754a258e 100644
--- a/go/fory/type.go
+++ b/go/fory/type.go
@@ -540,6 +540,10 @@ func (r *typeResolver) getSerializerByTypeTag(typeTag
string) (Serializer, error
func (r *typeResolver) getTypeInfo(value reflect.Value, create bool)
(TypeInfo, error) {
// First check if type info exists in cache
+ if value.Kind() == reflect.Interface {
+ // make sure the concrete value don't miss its real typeInfo
+ value = value.Elem()
+ }
typeString := value.Type()
if info, ok := r.typesInfo[typeString]; ok {
if info.Serializer == nil {
@@ -563,9 +567,6 @@ func (r *typeResolver) getTypeInfo(value reflect.Value,
create bool) (TypeInfo,
if !create {
fmt.Errorf("type %v not registered and create=false",
value.Type())
}
- if value.Kind() == reflect.Interface {
- value = value.Elem()
- }
type_ := value.Type()
// Get package path and type name for registration
var typeName string
@@ -804,7 +805,7 @@ func (r *typeResolver) writeSharedTypeMeta(buffer
*ByteBuffer, typeInfo TypeInfo
buffer.WriteVarUint32(newIndex)
context.typeMap[typ] = newIndex
- typeDef, err := r.getOrCreateTypeDef(typeInfo.Type)
+ typeDef, err := r.getTypeDef(typeInfo.Type, true)
if err != nil {
return err
}
@@ -812,11 +813,15 @@ func (r *typeResolver) writeSharedTypeMeta(buffer
*ByteBuffer, typeInfo TypeInfo
return nil
}
-func (r *typeResolver) getOrCreateTypeDef(typ reflect.Type) (*TypeDef, error) {
+func (r *typeResolver) getTypeDef(typ reflect.Type, create bool) (*TypeDef,
error) {
if existingTypeDef, exists := r.typeToTypeDef[typ]; exists {
return existingTypeDef, nil
}
+ if !create {
+ return nil, fmt.Errorf("TypeDef not found for type %s", typ)
+ }
+
zero := reflect.Zero(typ)
typeDef, err := buildTypeDef(r.fory, zero)
if err != nil {
@@ -1234,8 +1239,11 @@ func (r *typeResolver) getTypeById(id int16)
(reflect.Type, error) {
}
func (r *typeResolver) getTypeInfoById(id int16) (TypeInfo, error) {
- typeInfo := r.typeIDToTypeInfo[int32(id)]
- return typeInfo, nil
+ if typeInfo, exists := r.typeIDToTypeInfo[int32(id)]; exists {
+ return typeInfo, nil
+ } else {
+ return TypeInfo{}, fmt.Errorf("typeInfo of typeID %d not
found", id)
+ }
}
func (r *typeResolver) writeMetaString(buffer *ByteBuffer, str string) error {
diff --git a/go/fory/type_def.go b/go/fory/type_def.go
index a7ab52f22..d0f9bf5c9 100644
--- a/go/fory/type_def.go
+++ b/go/fory/type_def.go
@@ -165,7 +165,7 @@ func buildFieldDefs(fory *Fory, value reflect.Value)
([]FieldDef, error) {
serializers := make([]Serializer, len(fieldDefs))
fieldNames := make([]string, len(fieldDefs))
for i, fieldDef := range fieldDefs {
- serializer, err :=
fieldDef.fieldType.getSerializer(fory)
+ serializer, err := getFieldTypeSerializer(fory,
fieldDef.fieldType)
if err != nil {
// If we can't get serializer, use nil (will be
handled by sortFields)
serializers[i] = nil
@@ -199,7 +199,6 @@ func buildFieldDefs(fory *Fory, value reflect.Value)
([]FieldDef, error) {
type FieldType interface {
TypeId() TypeId
write(*ByteBuffer)
- getSerializer(*Fory) (Serializer, error)
getTypeInfo(*Fory) (TypeInfo, error) // some serializer need typeinfo
as well
}
@@ -213,8 +212,8 @@ func (b *BaseFieldType) write(buffer *ByteBuffer) {
buffer.WriteVarUint32Small7(uint32(b.typeId))
}
-func (b *BaseFieldType) getSerializer(fory *Fory) (Serializer, error) {
- typeInfo, err := b.getTypeInfo(fory)
+func getFieldTypeSerializer(fory *Fory, ft FieldType) (Serializer, error) {
+ typeInfo, err := ft.getTypeInfo(fory)
if err != nil {
return nil, err
}
@@ -284,7 +283,7 @@ func (c *CollectionFieldType) getTypeInfo(f *Fory)
(TypeInfo, error) {
if err != nil {
return TypeInfo{}, err
}
- sliceSerializer := &sliceSerializer{elemInfo: elemInfo}
+ sliceSerializer := &sliceSerializer{elemInfo: elemInfo, declaredType:
elemInfo.Type}
return TypeInfo{Type: collectionType, Serializer: sliceSerializer}, nil
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]