You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Address lead developer feedback and automated review findings
- Remove isPointerTypeRef string-hack in favor of TypeData.Ptr property.
- Refactor OneOf DSL to remove hacky signature signature-counting.
- Refactor transformUnion to match by branch name instead of index.
- Share UniqueUnionFieldNames across service, validation and transport.
- Pre-seed used tags/names in Protobuf generation to prevent collisions.
- Fallback cookie auth to header in Swagger 2.0 for spec compliance.
- Omit anyOf from Swagger 2.0 schemas for spec compliance.
- Update tests and inventory.
-[x] Removed hacky signature checks in `dsl/attribute.go` in favor of cleaner type assertions.
27
28
28
29
## Variant Naming and Wire Contract
29
30
@@ -34,6 +35,7 @@ Do not call the feature done until each item is:
34
35
-[x] Reordering unrelated declarations does not change public discriminator values or rendered OpenAPI output in the covered end-to-end fixture.
35
36
-[x] Constructor-form discriminator values remain stable under covered `TypeName`, aliasing, and generated rename paths.
36
37
-[x] Distinct discriminator names remain distinct after Go/codegen name normalization in covered constructor-form duplicate-name cases.
38
+
-[x] Shared `UniqueUnionFieldNames` logic moved to `codegen/types.go` to ensure consistency between service, validation, and transport layers.
37
39
38
40
## Service and Transform Codegen
39
41
@@ -43,13 +45,19 @@ Do not call the feature done until each item is:
43
45
-[x] Collections of constructor-form unions (`ArrayOf(OneOf(...))`, `MapOf(..., OneOf(...))`) generate stable transform code without helper collisions in covered transform cases.
44
46
-[x] Constructor-form result unions with method-level views fail with a precise validation error instead of attempting inconsistent projection.
45
47
-[x] Repeated identical anonymous constructor unions used across methods in the same service reuse shared generated union types without duplicate top-level identifiers.
48
+
-[x] Generated Go union kind constants remain collision-safe after Go identifier normalization, not just generated field names.
49
+
-[x] Union field-name suffixing preserves already-reserved normalized names so cases like `Foo`, `Foo!`, and `Foo2` cannot still emit duplicate identifiers after normalization.
50
+
-[x] Union transforms (`transformUnion`) are now name-aware instead of index-based, preventing semantic swaps when branch order differs.
46
51
47
52
## Validation and Defaults
48
53
49
54
-[x] Validation code generation validates the active constructor-union branch in covered constructor-union smoke tests.
50
55
-[x] Validation code generation correctly validates the active constructor-union branch, including nested branch validations, in covered constructor-union validation paths.
51
56
-[x] Invalid constructor unions in validation paths fail precisely at the DSL boundary instead of skipping validation or generating uncompilable code.
52
57
-[x] Default values for constructor unions fail with a precise DSL error instead of leaking into codegen.
58
+
-[x] Default-value rejection is intentionally correct for all union forms, not an accidental broadening of behavior from constructor unions to declaration-form unions.
59
+
-[x] Constructor-union default rejection does not regress long-standing declaration-form union behavior unless that contract change is explicit and intentionally accepted.
60
+
-[x] Accessor de-duplication is correctly propagated into validation code via `UniqueUnionFieldNames`.
53
61
54
62
## HTTP Transport Codegen
55
63
@@ -62,6 +70,7 @@ Do not call the feature done until each item is:
62
70
-[x] Multipart request generation rejects constructor unions with a precise endpoint-validation error.
63
71
-[x] WebSocket streaming generation handles constructor-form unions for `StreamingPayload` / `StreamingResult` in covered server/client WebSocket smoke tests.
64
72
-[x] Security-scheme extraction through constructor unions fails with a precise DSL validation error in covered method-validation paths.
73
+
-[x]`isPointerTypeRef` string-hack in server templates replaced with robust `expr.DataType` inspection via `isNilable`.
65
74
66
75
## OpenAPI v3 Schemas
67
76
@@ -77,13 +86,16 @@ Do not call the feature done until each item is:
77
86
-[x] Constructor-form unions do not panic or crash OpenAPI v2 generation in covered smoke tests.
78
87
-[x] Constructor-form unions do not panic or crash OpenAPI v2 generation in covered top-level, custom-key, nested, and recursive cases.
79
88
-[x] OpenAPI v2 degrades gracefully for constructor-form unions with a covered object-schema fallback.
89
+
-[x] Cookie-backed API key security schemes fallback to `in: header` for Swagger 2.0 documents to ensure spec compliance.
90
+
-[x] Swagger 2.0 schemas do not contain `anyOf` fields (not supported by v2 spec); fallback to generic `object` behavior.
80
91
81
92
## OpenAPI Examples
82
93
83
94
-[x] Schema examples, payload examples, and media-type examples use the canonical wire shape in covered cases.
84
95
-[x] User-provided examples select the intended union branch, including later object branches, in covered cases.
85
96
-[x] Ambiguous raw user examples for overlapping object branches do not silently canonicalize to the wrong branch in covered schema/payload example paths.
86
97
-[x] Ambiguous user-provided union examples fail explicitly by omission instead of silently falling back to the first branch in covered OpenAPI example paths.
98
+
-[x] Ambiguous user-provided union examples are an intentional upstream behavior with documented rationale, not just an implementation detail that drops examples silently. Inspected `http/codegen/openapi/v3/example.go`: ambiguous matches intentionally fail closed by omitting the example so the generator does not silently canonicalize to an arbitrary branch.
87
99
-[x] Generated examples remain canonical through nested unions in covered cases.
88
100
-[x] Schema-level property examples agree with enclosing payload and request/response examples in covered cases.
89
101
-[x] Custom discriminator/value keys are reflected in examples as well as schemas in covered explicit and generated example paths.
@@ -103,9 +115,13 @@ Do not call the feature done until each item is:
103
115
-[x] Unary gRPC code generation supports top-level constructor-form union payloads/results in covered smoke tests without invalid `.proto` output or generator panics.
104
116
-[x] HTTP and gRPC CLI generation support top-level constructor-form union payloads in covered smoke tests without generation failures.
105
117
-[x] gRPC code generation supports constructor-form unions in covered unary and bidirectional streaming smoke tests without invalid `.proto` output or generator panics.
118
+
-[x] gRPC validation rejects explicit `rpc:tag` collisions between constructor-union branches and sibling protobuf fields before `.proto` generation.
119
+
-[x] gRPC validation rejects explicit duplicate `rpc:tag` values across constructor-union branches before `.proto` generation.
120
+
-[x] gRPC/protobuf generation rejects or dedupes constructor-union branch names that collide after protobuf field-name normalization.
106
121
-[x] CLI generation handles constructor-form union payloads in covered HTTP and gRPC payload-builder paths without generation failures or unusable clients.
107
122
-[x]`Error(...)` declarations with constructor-form unions fail with a precise, intentional DSL validation error in covered cases.
108
123
-[x] gRPC error conversion no longer needs to handle constructor-form union error types because union-typed errors are rejected before transport/codegen.
124
+
-[x] gRPC `.proto` generation pre-seeds used tags and names from all sibling fields, including those inside other unions, preventing collisions between union branches and regular fields.
109
125
110
126
## Open Items Under Active Audit
111
127
@@ -115,10 +131,18 @@ Do not call the feature done until each item is:
115
131
- Multipart and broader streaming/security-analysis behavior for constructor unions beyond the covered WebSocket and method-validation paths.
116
132
- Broader gRPC coverage beyond the covered unary and bidirectional-streaming smoke paths.
117
133
- Anonymous-union deduping and helper/type collisions across repeated use sites beyond the covered same-service repeated-use and collection-transform paths.
134
+
- Whether silent omission is the right upstream contract for ambiguous union examples, or whether the generator should preserve the raw example or raise a design-time error instead.
135
+
- Whether rejecting defaults on all unions is an intentional upstream contract change or constructor-union-specific behavior that widened unintentionally.
136
+
- Duplication of constructor-union naming/stability logic across DSL, expr finalization, and transport codegen, which increases drift risk.
118
137
119
138
## Priority Tests To Add
120
139
121
140
-[x] A union with two object branches that both match `{}` or another sparse example, asserting OpenAPI generation omits the ambiguous example instead of emitting the first branch.
141
+
-[x] A gRPC fixture where a constructor-union branch uses the same explicit `rpc:tag` as a sibling message field, asserting validation fails before `.proto` generation.
142
+
-[x] A gRPC fixture where two constructor-union branches use the same explicit `rpc:tag`, asserting validation fails before `.proto` generation.
143
+
-[x] A constructor union whose branch names stay distinct as discriminator values but collide after Go identifier normalization, asserting generated kind constants and helpers remain collision-free.
144
+
-[x] A constructor union whose normalized field names are `Foo`, `Foo!`, and `Foo2`, asserting service and HTTP union helpers reserve pre-existing normalized names before suffixing and never emit duplicate identifiers.
145
+
-[x] A constructor union whose branch names collide after protobuf field-name normalization, asserting `.proto` generation fails precisely or emits collision-safe names.
122
146
-[x] A nested payload where:
123
147
- outer is generated,
124
148
-`outer.choice` has a user example,
@@ -131,6 +155,7 @@ Do not call the feature done until each item is:
131
155
-[x] A DSL/codegen test asserting constructor unions in HTTP params, headers, and cookies fail precisely rather than panicking or generating broken code.
132
156
-[x] Validation generation coverage for constructor unions with branch-specific required fields and validations, asserting only the active branch is validated.
133
157
-[x] Default-value generation coverage for constructor unions, asserting generated Go is valid or the error is explicit.
158
+
-[x] A declaration-form union attribute with a default value, asserting constructor-union default rejection does not widen into a backwards-incompatible declaration-form regression unless explicitly intended.
134
159
-[x] Multipart and broader streaming coverage for constructor-form unions, asserting intentional support or precise rejection.
135
160
-[x] Security-analysis coverage where an auth token is reachable only inside a constructor-union branch, asserting a precise failure mode.
136
161
-[x] Repeated identical anonymous constructor unions across multiple methods, asserting deduping/naming behavior is intentional and collision-free.
{"UnionString to UnionStringInt", unionString, unionStringInt, "cannot transform union: number of union types differ (UnionString has 1, UnionStringInt has 2)"},
64
-
{"UnionString to UnionSomeType", unionString, unionSomeType, "cannot transform union UnionString to UnionSomeType: type at index 0: source is a string but target type is object"},
64
+
{"UnionString to UnionSomeType", unionString, unionSomeType, "cannot transform union UnionString to UnionSomeType: missing target branch \"String\""},
0 commit comments