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:
- Task 1: Implement empty_behavior in Go generators -
c77bdc3(feat) - Task 2: Implement empty_behavior in OpenAPI generator -
1157bab(feat) - 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 callinternal/clientgen/empty_behavior.go- Identical to httpgen for server/client consistencyinternal/clientgen/generator.go- Added generateEmptyBehaviorEncodingFile callinternal/openapiv3/types.go- Added makeNullableOneOfSchema for empty_behavior=NULL fieldsinternal/httpgen/testdata/proto/empty_behavior.proto- Test proto with PRESERVE, NULL, OMIT modesinternal/httpgen/testdata/golden/empty_behavior_empty_behavior.pb.go- Golden file showing generated encodinginternal/openapiv3/testdata/golden/yaml/EmptyBehaviorService.openapi.yaml- OpenAPI golden with oneOfinternal/openapiv3/testdata/golden/json/EmptyBehaviorService.openapi.json- JSON variantinternal/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
