Skip to content

Commit b67cb17

Browse files
committed
Change tag register to namesapce + typename register
1 parent 4d00f64 commit b67cb17

File tree

10 files changed

+77
-45
lines changed

10 files changed

+77
-45
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ func main() {
293293
F3 map[string]string
294294
}
295295
fory := forygo.NewFory(true)
296-
if err := fory.RegisterTagType("example.SomeClass", SomeClass{}); err != nil {
296+
if err := fory.Register(SomeClass{}, "example.SomeClass"); err != nil {
297297
panic(err)
298298
}
299299
value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}}

docs/guide/xlang_serialization_guide.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,10 @@ func main() {
289289
F2 map[int8]int32
290290
}
291291
fory := forygo.NewFory()
292-
if err := fory.RegisterTagType("example.SomeClass1", SomeClass1{}); err != nil {
292+
if err := fory.Register(SomeClass1{}, "example.SomeClass1"); err != nil {
293293
panic(err)
294294
}
295-
if err := fory.RegisterTagType("example.SomeClass2", SomeClass2{}); err != nil {
295+
if err := fory.Register(SomeClass2{}, "example.SomeClass2"); err != nil {
296296
panic(err)
297297
}
298298
obj1 := &SomeClass1{}
@@ -481,7 +481,7 @@ func main() {
481481
F3 map[string]string
482482
}
483483
fory := forygo.NewFory(true)
484-
if err := fory.RegisterTagType("example.SomeClass", SomeClass{}); err != nil {
484+
if err := fory.Register(SomeClass{}, "example.SomeClass"); err != nil {
485485
panic(err)
486486
}
487487
value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}}

go/fory/fory.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,19 @@ type Fory struct {
174174
metaContext *MetaContext
175175
}
176176

177-
func (f *Fory) RegisterTagType(tag string, v interface{}) error {
178-
return f.typeResolver.RegisterTypeTag(reflect.ValueOf(v), tag)
177+
func (f *Fory) RegisterType(
178+
v interface{},
179+
namespace string,
180+
typeName string,
181+
) error {
182+
return f.typeResolver.RegisterNamedType(reflect.TypeOf(v), namespace, typeName)
183+
}
184+
185+
func (f *Fory) Register(
186+
v interface{},
187+
typeName string,
188+
) error {
189+
return f.typeResolver.RegisterNamedType(reflect.TypeOf(v), "", typeName)
179190
}
180191

181192
func (f *Fory) Marshal(v interface{}) ([]byte, error) {

go/fory/fory_metashare_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,13 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
284284
Inner: SimpleDataClass{Name: "inner", Age: 18, Active: true},
285285
},
286286
writerSetup: func(f *Fory) error {
287-
if err := f.RegisterTagType("SimpleDataClass", SimpleDataClass{}); err != nil {
287+
if err := f.Register(SimpleDataClass{}, "SimpleDataClass"); err != nil {
288288
return err
289289
}
290290
return nil
291291
},
292292
readerSetup: func(f *Fory) error {
293-
if err := f.RegisterTagType("SimpleDataClass", SimpleDataClass{}); err != nil {
293+
if err := f.Register(SimpleDataClass{}, "SimpleDataClass"); err != nil {
294294
return err
295295
}
296296
return nil
@@ -312,13 +312,13 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
312312
Inner: SimpleDataClass{Name: "inner", Age: 18, Active: true},
313313
},
314314
writerSetup: func(f *Fory) error {
315-
if err := f.RegisterTagType("SimpleDataClass", SimpleDataClass{}); err != nil {
315+
if err := f.Register(SimpleDataClass{}, "SimpleDataClass"); err != nil {
316316
return err
317317
}
318318
return nil
319319
},
320320
readerSetup: func(f *Fory) error {
321-
if err := f.RegisterTagType("SimpleDataClass", InconsistentDataClass{}); err != nil {
321+
if err := f.Register(InconsistentDataClass{}, "SimpleDataClass"); err != nil {
322322
return err
323323
}
324324
return nil
@@ -360,7 +360,7 @@ func runCompatibilityCase(t *testing.T, tc compatibilityCase) {
360360
err := tc.writerSetup(writer)
361361
assert.NoError(t, err)
362362
}
363-
err := writer.RegisterTagType(tc.tag, tc.writeType)
363+
err := writer.Register(tc.writeType, tc.tag)
364364
assert.NoError(t, err)
365365

366366
data, err := writer.Marshal(tc.input)
@@ -371,7 +371,7 @@ func runCompatibilityCase(t *testing.T, tc compatibilityCase) {
371371
err = tc.readerSetup(reader)
372372
assert.NoError(t, err)
373373
}
374-
err = reader.RegisterTagType(tc.tag, tc.readType)
374+
err = reader.Register(tc.readType, tc.tag)
375375
assert.NoError(t, err)
376376

377377
target := reflect.New(reflect.TypeOf(tc.readType))

go/fory/fory_test.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ package fory
1919

2020
import (
2121
"fmt"
22-
"github.com/stretchr/testify/require"
2322
"reflect"
2423
"testing"
2524
"unsafe"
25+
26+
"github.com/stretchr/testify/require"
2627
)
2728

2829
func primitiveData() []interface{} {
@@ -221,7 +222,7 @@ func TestSerializeStructSimple(t *testing.T) {
221222
type A struct {
222223
F1 []string
223224
}
224-
require.Nil(t, fory.RegisterTagType("example.A", A{}))
225+
require.Nil(t, fory.Register(A{}, "example.A"))
225226
serde(t, fory, A{})
226227
serde(t, fory, &A{})
227228
serde(t, fory, A{F1: []string{"str1", "", "str2"}})
@@ -231,7 +232,7 @@ func TestSerializeStructSimple(t *testing.T) {
231232
F1 []string
232233
F2 map[string]int32
233234
}
234-
require.Nil(t, fory.RegisterTagType("example.B", B{}))
235+
require.Nil(t, fory.Register(B{}, "example.B"))
235236
serde(t, fory, B{})
236237
serde(t, fory, B{
237238
F1: []string{"str1", "", "str2"},
@@ -291,7 +292,7 @@ func newFoo() Foo {
291292
func TestSerializeStruct(t *testing.T) {
292293
for _, referenceTracking := range []bool{false, true} {
293294
fory := NewFory(referenceTracking)
294-
require.Nil(t, fory.RegisterTagType("example.Bar", Bar{}))
295+
require.Nil(t, fory.Register(Bar{}, "example.Bar"))
295296
serde(t, fory, &Bar{})
296297
bar := Bar{F1: 1, F2: "str"}
297298
serde(t, fory, bar)
@@ -301,13 +302,13 @@ func TestSerializeStruct(t *testing.T) {
301302
F1 Bar
302303
F2 interface{}
303304
}
304-
require.Nil(t, fory.RegisterTagType("example.A", A{}))
305+
require.Nil(t, fory.Register(A{}, "example.A"))
305306
serde(t, fory, A{})
306307
serde(t, fory, &A{})
307308
serde(t, fory, A{F1: Bar{F1: 1, F2: "str"}, F2: -1})
308309
serde(t, fory, &A{F1: Bar{F1: 1, F2: "str"}, F2: -1})
309310

310-
require.Nil(t, fory.RegisterTagType("example.Foo", Foo{}))
311+
require.Nil(t, fory.Register(Foo{}, "example.Foo"))
311312
foo := newFoo()
312313
serde(t, fory, foo)
313314
serde(t, fory, &foo)
@@ -320,7 +321,7 @@ func TestSerializeCircularReference(t *testing.T) {
320321
type A struct {
321322
A1 *A
322323
}
323-
require.Nil(t, fory.RegisterTagType("example.A", A{}))
324+
require.Nil(t, fory.Register(A{}, "example.A"))
324325
// If use `A{}` instead of `&A{}` and pass `a` instead of `&a`, there will be serialization data duplication
325326
// and can't be deserialized by other languages too.
326327
// TODO(chaokunyang) If pass by value(have a copy) and there are some inner value reference, return a readable
@@ -340,7 +341,7 @@ func TestSerializeCircularReference(t *testing.T) {
340341
F2 *B
341342
F3 *B
342343
}
343-
require.Nil(t, fory.RegisterTagType("example.B", B{}))
344+
require.Nil(t, fory.Register(B{}, "example.B"))
344345
b := &B{F1: "str"}
345346
b.F2 = b
346347
b.F3 = b
@@ -368,8 +369,8 @@ func TestSerializeComplexReference(t *testing.T) {
368369
F3 *A
369370
F4 *B
370371
}
371-
require.Nil(t, fory.RegisterTagType("example.A", A{}))
372-
require.Nil(t, fory.RegisterTagType("example.B", B{}))
372+
require.Nil(t, fory.Register(A{}, "example.A"))
373+
require.Nil(t, fory.Register(B{}, "example.B"))
373374

374375
a := &A{F1: "str"}
375376
a.F2 = a
@@ -484,8 +485,8 @@ func serde(t *testing.T, fory *Fory, value interface{}) {
484485

485486
func BenchmarkMarshal(b *testing.B) {
486487
fory := NewFory(true)
487-
require.Nil(b, fory.RegisterTagType("example.Foo", Foo{}))
488-
require.Nil(b, fory.RegisterTagType("example.Bar", Bar{}))
488+
require.Nil(b, fory.Register(Foo{}, "example.Foo"))
489+
require.Nil(b, fory.Register(Bar{}, "example.Bar"))
489490
value := benchData()
490491
for i := 0; i < b.N; i++ {
491492
_, err := fory.Marshal(value)
@@ -497,8 +498,8 @@ func BenchmarkMarshal(b *testing.B) {
497498

498499
func BenchmarkUnmarshal(b *testing.B) {
499500
fory := NewFory(true)
500-
require.Nil(b, fory.RegisterTagType("example.Foo", Foo{}))
501-
require.Nil(b, fory.RegisterTagType("example.Bar", Bar{}))
501+
require.Nil(b, fory.Register(Foo{}, "example.Foo"))
502+
require.Nil(b, fory.Register(Bar{}, "example.Bar"))
502503
value := benchData()
503504
data, err := fory.Marshal(value)
504505
if err != nil {
@@ -610,10 +611,10 @@ func TestStructWithNestedSlice(t *testing.T) {
610611
}
611612

612613
fory := NewFory(true)
613-
if err := fory.RegisterTagType("Example", Example{}); err != nil {
614+
if err := fory.Register(Example{}, "Example"); err != nil {
614615
panic(err)
615616
}
616-
if err := fory.RegisterTagType("Item", Item{}); err != nil {
617+
if err := fory.Register(Item{}, "Item"); err != nil {
617618
panic(err)
618619
}
619620

go/fory/fory_xlang_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func TestSerializeSimpleStruct(t *testing.T) {
228228
// Temporarily disabled
229229
// t.Skip()
230230
fory_ := fory.NewFory(true)
231-
require.Nil(t, fory_.RegisterTagType("test.ComplexObject2", ComplexObject2{}))
231+
require.Nil(t, fory_.Register(ComplexObject2{}, "test.ComplexObject2"))
232232
obj2 := ComplexObject2{}
233233
obj2.F1 = true
234234
obj2.F2 = map[int8]int32{-1: 2}
@@ -239,8 +239,8 @@ func TestSerializeComplexStruct(t *testing.T) {
239239
// Temporarily disabled
240240
// t.Skip()
241241
fory_ := fory.NewFory(true)
242-
require.Nil(t, fory_.RegisterTagType("test.ComplexObject1", ComplexObject1{}))
243-
require.Nil(t, fory_.RegisterTagType("test.ComplexObject2", ComplexObject2{}))
242+
require.Nil(t, fory_.Register(ComplexObject1{}, "test.ComplexObject1"))
243+
require.Nil(t, fory_.Register(ComplexObject2{}, "test.ComplexObject2"))
244244
obj2 := ComplexObject2{}
245245
obj2.F1 = true
246246
obj2.F2 = map[int8]int32{-1: 2}

go/fory/tests/generator_xlang_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func TestValidationDemoXlang(t *testing.T) {
6666

6767
// Reflect mode (register with full name)
6868
foryForReflect := forygo.NewFory(true)
69-
err := foryForReflect.RegisterTagType(expectedTypeTag, ReflectStruct{})
69+
err := foryForReflect.Register(ReflectStruct{}, expectedTypeTag)
7070
require.NoError(t, err, "Should be able to register ReflectStruct with full name")
7171

7272
// Serialization test
@@ -131,7 +131,7 @@ func TestSliceDemoXlang(t *testing.T) {
131131

132132
// Reflect mode - enable reference tracking
133133
foryForReflect := forygo.NewFory(true)
134-
err := foryForReflect.RegisterTagType(expectedTypeTag, ReflectSliceStruct{})
134+
err := foryForReflect.Register(ReflectSliceStruct{}, expectedTypeTag)
135135
require.NoError(t, err, "Should be able to register ReflectSliceStruct with full name")
136136

137137
// Serialization test
@@ -204,7 +204,7 @@ func TestDynamicSliceDemoXlang(t *testing.T) {
204204

205205
// Reflect mode - enable reference tracking
206206
foryForReflect := forygo.NewFory(true)
207-
err := foryForReflect.RegisterTagType(expectedTypeTag, ReflectDynamicStruct{})
207+
err := foryForReflect.Register(ReflectDynamicStruct{}, expectedTypeTag)
208208
require.NoError(t, err, "Should be able to register ReflectDynamicStruct with full name")
209209

210210
// Serialization test

go/fory/type.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -479,11 +479,26 @@ func (r *typeResolver) RegisterSerializer(type_ reflect.Type, s Serializer) erro
479479
return nil
480480
}
481481

482-
func (r *typeResolver) RegisterTypeTag(value reflect.Value, tag string) error {
483-
type_ := value.Type()
482+
func (r *typeResolver) RegisterNamedType(
483+
type_ reflect.Type,
484+
namespace string,
485+
typeName string,
486+
) error {
484487
if prev, ok := r.typeToSerializers[type_]; ok {
485488
return fmt.Errorf("type %s already has a serializer %s registered", type_, prev)
486489
}
490+
if namespace == "" {
491+
if idx := strings.LastIndex(typeName, "."); idx != -1 {
492+
namespace = typeName[:idx]
493+
typeName = typeName[idx+1:]
494+
}
495+
}
496+
var tag string
497+
if namespace == "" {
498+
tag = typeName
499+
} else {
500+
tag = namespace + "." + typeName
501+
}
487502
serializer := &structSerializer{type_: type_, typeTag: tag}
488503
r.typeToSerializers[type_] = serializer
489504
// multiple struct with same name defined inside function will have same `type_.String()`, but they are
@@ -492,22 +507,27 @@ func (r *typeResolver) RegisterTypeTag(value reflect.Value, tag string) error {
492507
r.typeToTypeInfo[type_] = "@" + tag
493508
r.typeInfoToType["@"+tag] = type_
494509

495-
ptrType := reflect.PtrTo(type_)
496-
ptrValue := reflect.New(type_)
510+
ptrType := reflect.PointerTo(type_)
497511
ptrSerializer := &ptrToStructSerializer{structSerializer: *serializer, type_: ptrType}
498512
r.typeToSerializers[ptrType] = ptrSerializer
499513
// use `ptrToStructSerializer` as default deserializer when deserializing data from other languages.
500514
r.typeTagToSerializers[tag] = ptrSerializer
501515
r.typeToTypeInfo[ptrType] = "*@" + tag
502516
r.typeInfoToType["*@"+tag] = ptrType
517+
var typeId int32
518+
if r.metaShareEnabled() {
519+
typeId = NAMED_COMPATIBLE_STRUCT
520+
} else {
521+
typeId = NAMED_STRUCT
522+
}
503523
// For named structs, directly register both their value and pointer types
504-
info, err := r.getTypeInfo(value, true)
524+
_, err := r.registerType(type_, typeId, namespace, typeName, nil, false)
505525
if err != nil {
506-
return fmt.Errorf("failed to register named structs: info is %v", info)
526+
return fmt.Errorf("failed to register named structs: %w", err)
507527
}
508-
info, err = r.getTypeInfo(ptrValue, true)
528+
_, err = r.registerType(ptrType, -typeId, namespace, typeName, nil, false)
509529
if err != nil {
510-
return fmt.Errorf("failed to register named structs: info is %v", info)
530+
return fmt.Errorf("failed to register named structs: %w", err)
511531
}
512532
return nil
513533
}

go/fory/type_def_encoder_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func TestTypeDefEncodingDecoding(t *testing.T) {
108108
t.Run(tt.name, func(t *testing.T) {
109109
fory := NewFory(false)
110110

111-
if err := fory.RegisterTagType(tt.tagName, tt.testStruct); err != nil {
111+
if err := fory.Register(tt.testStruct, tt.tagName); err != nil {
112112
t.Fatalf("Failed to register tag type: %v", err)
113113
}
114114

go/fory/type_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func TestTypeResolver(t *testing.T) {
3434
type A struct {
3535
F1 string
3636
}
37-
require.Nil(t, typeResolver.RegisterTypeTag(reflect.ValueOf(A{}), "example.A"))
38-
require.Error(t, typeResolver.RegisterTypeTag(reflect.ValueOf(A{}), "example.A"))
37+
require.Nil(t, typeResolver.RegisterNamedType(reflect.TypeOf(A{}), "example", "A"))
38+
require.Error(t, typeResolver.RegisterNamedType(reflect.TypeOf(A{}), "example", "A"))
3939

4040
var tests = []struct {
4141
type_ reflect.Type

0 commit comments

Comments
 (0)