MCPcopy Create free account
hub / github.com/apache/fory / generateSliceWriteInline

Function generateSliceWriteInline

go/fory/codegen/encoder.go:400–483  ·  view source on GitHub ↗

generateSliceWriteInline generates inline slice serialization code to match reflection behavior exactly

(buf *bytes.Buffer, sliceType *types.Slice, fieldAccess string)

Source from the content-addressed store, hash-verified

398
399// generateSliceWriteInline generates inline slice serialization code to match reflection behavior exactly
400func generateSliceWriteInline(buf *bytes.Buffer, sliceType *types.Slice, fieldAccess string) error {
401 elemType := sliceType.Elem()
402
403 // Check if element type is referencable (needs ref tracking)
404 elemIsReferencable := isReferencableType(elemType)
405
406 // In xlang mode, slices are NOT nullable by default (only pointer types are nullable).
407 // In native Go mode, slices can be nil and need null flags.
408 // Generate conditional code that respects the mode at runtime.
409
410 // WriteData slice with conditional null flag - use block scope to avoid variable name conflicts
411 fmt.Fprintf(buf, "\t{\n")
412 // Check if xlang mode - in xlang mode, slices are not nullable by default
413 fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n")
414 fmt.Fprintf(buf, "\t\tif isXlang {\n")
415 fmt.Fprintf(buf, "\t\t\t// xlang mode: slices are not nullable, write directly without null flag\n")
416 fmt.Fprintf(buf, "\t\t\tsliceLen := 0\n")
417 fmt.Fprintf(buf, "\t\t\tif %s != nil {\n", fieldAccess)
418 fmt.Fprintf(buf, "\t\t\t\tsliceLen = len(%s)\n", fieldAccess)
419 fmt.Fprintf(buf, "\t\t\t}\n")
420 fmt.Fprintf(buf, "\t\t\tbuf.WriteVarUint32(uint32(sliceLen))\n")
421 // Write elements in xlang mode
422 fmt.Fprintf(buf, "\t\t\tif sliceLen > 0 {\n")
423 fmt.Fprintf(buf, "\t\t\t\tcollectFlag := 12 // CollectionIsSameType | CollectionIsDeclElementType\n")
424 if elemIsReferencable {
425 fmt.Fprintf(buf, "\t\t\t\tif ctx.TrackRef() {\n")
426 fmt.Fprintf(buf, "\t\t\t\t\tcollectFlag |= 1 // CollectionTrackingRef for referencable element type\n")
427 fmt.Fprintf(buf, "\t\t\t\t}\n")
428 }
429 fmt.Fprintf(buf, "\t\t\t\tbuf.WriteInt8(int8(collectFlag))\n")
430 fmt.Fprintf(buf, "\t\t\t\tfor _, elem := range %s {\n", fieldAccess)
431 if elemIsReferencable {
432 fmt.Fprintf(buf, "\t\t\t\t\tif ctx.TrackRef() {\n")
433 fmt.Fprintf(buf, "\t\t\t\t\t\tbuf.WriteInt8(-1) // NotNullValueFlag for element\n")
434 fmt.Fprintf(buf, "\t\t\t\t\t}\n")
435 }
436 if err := generateSliceElementWriteInlineIndented(buf, elemType, "elem", "\t\t\t\t\t"); err != nil {
437 return err
438 }
439 fmt.Fprintf(buf, "\t\t\t\t}\n") // end for loop
440 fmt.Fprintf(buf, "\t\t\t}\n") // end if sliceLen > 0
441 fmt.Fprintf(buf, "\t\t} else {\n")
442 fmt.Fprintf(buf, "\t\t\t// Native Go mode: slices are nullable, write null flag\n")
443 // Write null flag for slices in native mode
444 fmt.Fprintf(buf, "\t\t\tif %s == nil {\n", fieldAccess)
445 fmt.Fprintf(buf, "\t\t\t\tbuf.WriteInt8(-3) // NullFlag\n")
446 fmt.Fprintf(buf, "\t\t\t} else {\n")
447 fmt.Fprintf(buf, "\t\t\t\tbuf.WriteInt8(-1) // NotNullValueFlag\n")
448 fmt.Fprintf(buf, "\t\t\t\tsliceLen := len(%s)\n", fieldAccess)
449 fmt.Fprintf(buf, "\t\t\t\tbuf.WriteVarUint32(uint32(sliceLen))\n")
450
451 // WriteData collection header and elements for non-empty slice in native mode
452 fmt.Fprintf(buf, "\t\t\t\tif sliceLen > 0 {\n")
453
454 // For codegen, follow reflection's behavior for struct fields:
455 // Set both CollectionIsSameType and CollectionIsDeclElementType
456 // Add CollectionTrackingRef when ref tracking is enabled AND element is referencable
457 fmt.Fprintf(buf, "\t\t\t\t\tcollectFlag := 12 // CollectionIsSameType | CollectionIsDeclElementType\n")

Callers 1

generateFieldWriteTypedFunction · 0.85

Calls 2

isReferencableTypeFunction · 0.85

Tested by

no test coverage detected