generateMapWriteInline generates inline map serialization code following the chunk-based format
(buf *bytes.Buffer, mapType *types.Map, fieldAccess string)
| 535 | |
| 536 | // generateMapWriteInline generates inline map serialization code following the chunk-based format |
| 537 | func generateMapWriteInline(buf *bytes.Buffer, mapType *types.Map, fieldAccess string) error { |
| 538 | keyType := mapType.Key() |
| 539 | valueType := mapType.Elem() |
| 540 | |
| 541 | // Check if key or value types are any (unwrap aliases like 'any') |
| 542 | keyIsInterface := false |
| 543 | valueIsInterface := false |
| 544 | unwrappedKey := types.Unalias(keyType) |
| 545 | unwrappedValue := types.Unalias(valueType) |
| 546 | if iface, ok := unwrappedKey.(*types.Interface); ok && iface.Empty() { |
| 547 | keyIsInterface = true |
| 548 | } |
| 549 | if iface, ok := unwrappedValue.(*types.Interface); ok && iface.Empty() { |
| 550 | valueIsInterface = true |
| 551 | } |
| 552 | |
| 553 | // In xlang mode, maps are NOT nullable by default (only pointer types are nullable). |
| 554 | // In native Go mode, maps can be nil and need null flags. |
| 555 | // Generate conditional code that respects the mode at runtime. |
| 556 | |
| 557 | // WriteData map with conditional null flag |
| 558 | fmt.Fprintf(buf, "\t{\n") |
| 559 | fmt.Fprintf(buf, "\t\tisXlang := ctx.TypeResolver().IsXlang()\n") |
| 560 | fmt.Fprintf(buf, "\t\tif isXlang {\n") |
| 561 | fmt.Fprintf(buf, "\t\t\t// xlang mode: maps are not nullable, write directly without null flag\n") |
| 562 | fmt.Fprintf(buf, "\t\t\tmapLen := 0\n") |
| 563 | fmt.Fprintf(buf, "\t\t\tif %s != nil {\n", fieldAccess) |
| 564 | fmt.Fprintf(buf, "\t\t\t\tmapLen = len(%s)\n", fieldAccess) |
| 565 | fmt.Fprintf(buf, "\t\t\t}\n") |
| 566 | fmt.Fprintf(buf, "\t\t\tbuf.WriteVarUint32(uint32(mapLen))\n") |
| 567 | |
| 568 | // Write map chunks in xlang mode |
| 569 | if err := writeMapChunksCode(buf, keyType, valueType, fieldAccess, keyIsInterface, valueIsInterface, "\t\t\t"); err != nil { |
| 570 | return err |
| 571 | } |
| 572 | |
| 573 | fmt.Fprintf(buf, "\t\t} else {\n") |
| 574 | fmt.Fprintf(buf, "\t\t\t// Native Go mode: maps are nullable, write null flag\n") |
| 575 | fmt.Fprintf(buf, "\t\t\tif %s == nil {\n", fieldAccess) |
| 576 | fmt.Fprintf(buf, "\t\t\t\tbuf.WriteInt8(-3) // NullFlag\n") |
| 577 | fmt.Fprintf(buf, "\t\t\t} else {\n") |
| 578 | fmt.Fprintf(buf, "\t\t\t\tbuf.WriteInt8(-1) // NotNullValueFlag\n") |
| 579 | fmt.Fprintf(buf, "\t\t\t\tmapLen := len(%s)\n", fieldAccess) |
| 580 | fmt.Fprintf(buf, "\t\t\t\tbuf.WriteVarUint32(uint32(mapLen))\n") |
| 581 | |
| 582 | // Write map chunks in native mode |
| 583 | if err := writeMapChunksCode(buf, keyType, valueType, fieldAccess, keyIsInterface, valueIsInterface, "\t\t\t\t"); err != nil { |
| 584 | return err |
| 585 | } |
| 586 | |
| 587 | fmt.Fprintf(buf, "\t\t\t}\n") // end else (not nil) |
| 588 | fmt.Fprintf(buf, "\t\t}\n") // end else (native mode) |
| 589 | fmt.Fprintf(buf, "\t}\n") // end block scope |
| 590 | |
| 591 | return nil |
| 592 | } |
| 593 | |
| 594 | func generateMapWriteInlineNoNull(buf *bytes.Buffer, mapType *types.Map, fieldAccess string) error { |
no test coverage detected