chaokunyang commented on code in PR #2587:
URL: https://github.com/apache/fory/pull/2587#discussion_r2331945295


##########
go/fory/codegen/encoder.go:
##########
@@ -140,3 +152,166 @@ func generateFieldWriteTyped(buf *bytes.Buffer, field 
*FieldInfo) error {
        fmt.Fprintf(buf, "\t// TODO: unsupported type %s\n", 
field.Type.String())
        return nil
 }
+
+// generateSliceWrite generates code to serialize a slice field
+func generateSliceWrite(buf *bytes.Buffer, fieldAccess string, slice 
*types.Slice) error {
+       elemType := slice.Elem()
+
+       fmt.Fprintf(buf, "\t// Write slice length\n")
+       fmt.Fprintf(buf, "\tbuf.WriteInt32(int32(len(%s)))\n", fieldAccess)
+       fmt.Fprintf(buf, "\t// Write slice elements\n")
+       fmt.Fprintf(buf, "\tfor _, elem := range %s {\n", fieldAccess)
+
+       // Generate element writing code based on element type
+       if err := generateElementWrite(buf, "elem", elemType); err != nil {
+               return err
+       }
+
+       fmt.Fprintf(buf, "\t}\n")
+       return nil
+}
+
+// generateElementWrite generates code to write a single element of any 
supported type
+func generateElementWrite(buf *bytes.Buffer, elemAccess string, elemType 
types.Type) error {
+       // Handle pointer types
+       if _, ok := elemType.(*types.Pointer); ok {
+               fmt.Fprintf(buf, "\t\tf.WriteReferencable(buf, 
reflect.ValueOf(%s))\n", elemAccess)
+               return nil
+       }
+
+       // Handle nested slice types
+       if slice, ok := elemType.(*types.Slice); ok {
+               return generateSliceWrite(buf, elemAccess, slice)
+       }
+
+       // Handle special named types
+       if named, ok := elemType.(*types.Named); ok {
+               typeStr := named.String()
+               switch typeStr {
+               case "time.Time":
+                       fmt.Fprintf(buf, 
"\t\tbuf.WriteInt64(fory.GetUnixMicro(%s))\n", elemAccess)
+                       return nil
+               case "github.com/apache/fory/go/fory.Date":
+                       fmt.Fprintf(buf, "\t\t// Handle zero date specially\n")
+                       fmt.Fprintf(buf, "\t\tif %s.Year == 0 && %s.Month == 0 
&& %s.Day == 0 {\n", elemAccess, elemAccess, elemAccess)
+                       fmt.Fprintf(buf, 
"\t\t\tbuf.WriteInt32(int32(-2147483648)) // Special marker for zero date\n")
+                       fmt.Fprintf(buf, "\t\t} else {\n")
+                       fmt.Fprintf(buf, "\t\t\tdiff := time.Date(%s.Year, 
%s.Month, %s.Day, 0, 0, 0, 0, time.Local).Sub(time.Date(1970, 1, 1, 0, 0, 0, 0, 
time.Local))\n", elemAccess, elemAccess, elemAccess)
+                       fmt.Fprintf(buf, 
"\t\t\tbuf.WriteInt32(int32(diff.Hours() / 24))\n")
+                       fmt.Fprintf(buf, "\t\t}\n")
+                       return nil
+               }
+       }
+
+       // Handle struct types
+       if _, ok := elemType.Underlying().(*types.Struct); ok {
+               fmt.Fprintf(buf, "\t\tf.WriteReferencable(buf, 
reflect.ValueOf(%s))\n", elemAccess)
+               return nil
+       }
+
+       // Handle basic types
+       if basic, ok := elemType.Underlying().(*types.Basic); ok {
+               switch basic.Kind() {
+               case types.Bool:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteBool(%s)\n", elemAccess)
+               case types.Int8:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt8(%s)\n", elemAccess)
+               case types.Int16:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt16(%s)\n", elemAccess)
+               case types.Int32:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt32(%s)\n", elemAccess)
+               case types.Int:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt64(int64(%s))\n", 
elemAccess)
+               case types.Int64:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt64(%s)\n", elemAccess)
+               case types.Uint8:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteByte_(%s)\n", elemAccess)
+               case types.Uint16:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt16(int16(%s))\n", 
elemAccess)
+               case types.Uint32:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt32(int32(%s))\n", 
elemAccess)
+               case types.Uint, types.Uint64:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteInt64(int64(%s))\n", 
elemAccess)
+               case types.Float32:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteFloat32(%s)\n", 
elemAccess)
+               case types.Float64:
+                       fmt.Fprintf(buf, "\t\tbuf.WriteFloat64(%s)\n", 
elemAccess)
+               case types.String:
+                       fmt.Fprintf(buf, "\t\tfory.WriteString(buf, %s)\n", 
elemAccess)
+               default:
+                       fmt.Fprintf(buf, "\t\t// TODO: unsupported basic type 
%s\n", basic.String())
+               }
+               return nil
+       }
+
+       fmt.Fprintf(buf, "\t\t// TODO: unsupported element type %s\n", 
elemType.String())
+       return nil
+}
+
+// generateMapWrite generates code to serialize a map field
+func generateMapWrite(buf *bytes.Buffer, fieldAccess string, mapType 
*types.Map) error {
+       keyType := mapType.Key()
+       valueType := mapType.Elem()
+
+       fmt.Fprintf(buf, "\t// Write map length\n")
+       fmt.Fprintf(buf, "\tbuf.WriteInt32(int32(len(%s)))\n", fieldAccess)
+       fmt.Fprintf(buf, "\t// Write map entries in key-sorted order for 
deterministic serialization\n")
+       fmt.Fprintf(buf, "\tif len(%s) > 0 {\n", fieldAccess)
+
+       // Generate key sorting code based on key type
+       if err := generateMapKeySort(buf, fieldAccess, keyType); err != nil {
+               return err
+       }
+
+       fmt.Fprintf(buf, "\t\t// Write key-value pairs in sorted order\n")
+       fmt.Fprintf(buf, "\t\tfor _, key := range sortedKeys {\n")
+       fmt.Fprintf(buf, "\t\t\tvalue := %s[key]\n", fieldAccess)
+
+       // Generate key writing code
+       if err := generateElementWrite(buf, "key", keyType); err != nil {

Review Comment:
   Map writing use chunk by chunk format, it seems that we don't follow that 
here. 
   
   FYI, map format: 
https://fory.apache.org/docs/next/specification/fory_xlang_serialization_spec#map



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to