Phase 5 Plan 3: Empty Behavior Implementation Summary

Empty behavior encoding across go-http, go-client, and openapiv3 generators with PRESERVE/{}/NULL/null/OMIT/delete semantics and proto.Size() == 0 empty detection

Performance#

  • Duration: 7 min
  • Started: 2026-02-06T09:58:43Z
  • Completed: 2026-02-06T10:06:22Z
  • Tasks: 3/3
  • Files modified: 13

Accomplishments#

  • Implemented empty_behavior MarshalJSON/UnmarshalJSON in both go-http and go-client generators
  • Added oneOf schema for empty_behavior=NULL message fields in OpenAPI generator
  • Created comprehensive test proto with all 3 behaviors and golden file tests across all generators

Task Commits#

Each task was committed atomically:

  1. Task 1: Implement empty_behavior in Go generators - c77bdc3 (feat)
  2. Task 2: Implement empty_behavior in OpenAPI generator - 1157bab (feat)
  3. Task 3: Add empty_behavior test proto and golden file tests - f45b750 (test)

Files Created/Modified#

  • internal/httpgen/empty_behavior.go - Generates MarshalJSON/UnmarshalJSON for empty_behavior fields (NULL, OMIT, PRESERVE)
  • internal/httpgen/generator.go - Added generateEmptyBehaviorEncodingFile call
  • internal/clientgen/empty_behavior.go - Identical to httpgen for server/client consistency
  • internal/clientgen/generator.go - Added generateEmptyBehaviorEncodingFile call
  • internal/openapiv3/types.go - Added makeNullableOneOfSchema for empty_behavior=NULL fields
  • internal/httpgen/testdata/proto/empty_behavior.proto - Test proto with PRESERVE, NULL, OMIT modes
  • internal/httpgen/testdata/golden/empty_behavior_empty_behavior.pb.go - Golden file showing generated encoding
  • internal/openapiv3/testdata/golden/yaml/EmptyBehaviorService.openapi.yaml - OpenAPI golden with oneOf
  • internal/openapiv3/testdata/golden/json/EmptyBehaviorService.openapi.json - JSON variant
  • internal/tsclientgen/testdata/golden/empty_behavior_client.ts - TS client golden

Decisions Made#

  • D-05-03-01: Identical empty_behavior.go in httpgen and clientgen - guarantees server/client JSON match
  • D-05-03-02: OpenAPI 3.1 oneOf schema for NULL fields - proper semantic representation vs deprecated nullable:true
  • D-05-03-03: OMIT fields use standard $ref in OpenAPI - OMIT only affects serialization, not type definition
  • D-05-03-04: Added explicit EMPTY_BEHAVIOR_UNSPECIFIED case in switch to satisfy exhaustive linter

Deviations from Plan#

Auto-fixed Issues#

1. [Rule 1 - Bug] Fixed exhaustive switch lint for EmptyBehavior enum

  • Found during: Task 1 (lint check)
  • Issue: Switch on EmptyBehavior missing EMPTY_BEHAVIOR_UNSPECIFIED case
  • Fix: Added explicit case for EMPTY_BEHAVIOR_UNSPECIFIED in both httpgen and clientgen
  • Files modified: internal/httpgen/empty_behavior.go, internal/clientgen/empty_behavior.go
  • Verification: make lint-fix shows 0 issues
  • Committed in: c77bdc3 (Task 1 commit)

Total deviations: 1 auto-fixed (1 bug) Impact on plan: Lint compliance fix, no scope creep.

Issues Encountered#

None.

User Setup Required#

None - no external service configuration required.

Next Phase Readiness#

  • Empty behavior encoding complete across all generators
  • Ready for plan 05-04 (cross-generator consistency tests) and 05-05 (integration tests)
  • All existing tests continue to pass (zero regression)

Phase: 05-json-nullable-empty Completed: 2026-02-06