generateFieldWriteTyped generates field writing code for the typed method
(buf *bytes.Buffer, field *FieldInfo)
| 73 | |
| 74 | // generateFieldWriteTyped generates field writing code for the typed method |
| 75 | func generateFieldWriteTyped(buf *bytes.Buffer, field *FieldInfo) error { |
| 76 | fmt.Fprintf(buf, "\t// Field: %s (%s)\n", field.GoName, field.Type.String()) |
| 77 | |
| 78 | fieldAccess := fmt.Sprintf("v.%s", field.GoName) |
| 79 | if field.IsOptional { |
| 80 | return generateOptionWriteTyped(buf, field, fieldAccess) |
| 81 | } |
| 82 | |
| 83 | // Handle special named types first |
| 84 | // According to new spec, time types are "other internal types" and need WriteValue |
| 85 | if named, ok := field.Type.(*types.Named); ok { |
| 86 | typeStr := named.String() |
| 87 | switch typeStr { |
| 88 | case "time.Time", "github.com/apache/fory/go/fory.Date": |
| 89 | // These types are "other internal types" in the new spec |
| 90 | // They use: | null flag | value data | format |
| 91 | fmt.Fprintf(buf, "\tctx.WriteValue(reflect.ValueOf(%s), fory.RefModeTracking, true)\n", fieldAccess) |
| 92 | return nil |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | // Handle pointer types |
| 97 | if _, ok := field.Type.(*types.Pointer); ok { |
| 98 | // For all pointer types, use WriteValue |
| 99 | fmt.Fprintf(buf, "\tctx.WriteValue(reflect.ValueOf(%s), fory.RefModeTracking, true)\n", fieldAccess) |
| 100 | return nil |
| 101 | } |
| 102 | |
| 103 | // Handle basic types |
| 104 | // Note: primitive serializers write values directly without NotNullValueFlag |
| 105 | if basic, ok := field.Type.Underlying().(*types.Basic); ok { |
| 106 | switch basic.Kind() { |
| 107 | case types.Bool: |
| 108 | fmt.Fprintf(buf, "\tbuf.WriteBool(%s)\n", fieldAccess) |
| 109 | case types.Int8: |
| 110 | fmt.Fprintf(buf, "\tbuf.WriteByte_(byte(%s))\n", fieldAccess) |
| 111 | case types.Int16: |
| 112 | fmt.Fprintf(buf, "\tbuf.WriteInt16(%s)\n", fieldAccess) |
| 113 | case types.Int32: |
| 114 | fmt.Fprintf(buf, "\tbuf.WriteVarint32(%s)\n", fieldAccess) |
| 115 | case types.Int, types.Int64: |
| 116 | fmt.Fprintf(buf, "\tbuf.WriteVarint64(%s)\n", fieldAccess) |
| 117 | case types.Uint8: |
| 118 | fmt.Fprintf(buf, "\tbuf.WriteByte_(%s)\n", fieldAccess) |
| 119 | case types.Uint16: |
| 120 | fmt.Fprintf(buf, "\tbuf.WriteInt16(int16(%s))\n", fieldAccess) |
| 121 | case types.Uint32: |
| 122 | fmt.Fprintf(buf, "\tbuf.WriteInt32(int32(%s))\n", fieldAccess) |
| 123 | case types.Uint, types.Uint64: |
| 124 | fmt.Fprintf(buf, "\tbuf.WriteInt64(int64(%s))\n", fieldAccess) |
| 125 | case types.Float32: |
| 126 | fmt.Fprintf(buf, "\tbuf.WriteFloat32(%s)\n", fieldAccess) |
| 127 | case types.Float64: |
| 128 | fmt.Fprintf(buf, "\tbuf.WriteFloat64(%s)\n", fieldAccess) |
| 129 | case types.String: |
| 130 | // In xlang mode, nullable=false is the default for struct fields. |
| 131 | // With nullable=false, RefMode = RefModeNone, so no ref flag is written. |
| 132 | // This matches reflection behavior in struct.go where refMode is calculated as: |
no test coverage detected