Skip to content

Commit f2f27c7

Browse files
authored
codegen: unify GoTypeDef variants via goTypeDefWithPkgOverride; rename helper; fix JSON-RPC integration harness; tidy executor assertions; ensure integration tests pass (#3762)
1 parent ae04222 commit f2f27c7

6 files changed

Lines changed: 66 additions & 32 deletions

File tree

codegen/scope.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,25 +106,38 @@ func (s *NameScope) GoTypeDef(att *expr.AttributeExpr, ptr, useDefault bool) str
106106
return s.goTypeDef(att, ptr, useDefault, pkg)
107107
}
108108

109-
func (s *NameScope) goTypeDef(att *expr.AttributeExpr, ptr, useDefault bool, pkg string) string {
109+
// GoTypeDefWithTargetPkg returns the Go type definition string, qualifying any
110+
// user types inside inline structs with the provided target package. This helps
111+
// when generating JSON-RPC client types that embed inline structs referencing
112+
// user types defined in a separate package (e.g., gen/types).
113+
func (s *NameScope) GoTypeDefWithTargetPkg(att *expr.AttributeExpr, ptr, useDefault bool, targetPkg string) string {
114+
return s.goTypeDefWithPkgOverride(att, ptr, useDefault, "", targetPkg)
115+
}
116+
117+
// goTypeDefWithPkgOverride generates the Go type definition string for the attribute.
118+
// When targetPkg is not empty, user types referenced inside inline structs are
119+
// qualified against targetPkg unless they are defined in a different package,
120+
// in which case their own package is used. When targetPkg is empty, the
121+
// package qualification falls back to pkg and the user type location.
122+
func (s *NameScope) goTypeDefWithPkgOverride(att *expr.AttributeExpr, ptr, useDefault bool, pkg, targetPkg string) string {
110123
switch actual := att.Type.(type) {
111124
case expr.Primitive:
112125
if t, _ := GetMetaType(att); t != "" {
113126
return t
114127
}
115128
return GoNativeTypeName(actual)
116129
case *expr.Array:
117-
d := s.goTypeDef(actual.ElemType, ptr, useDefault, pkg)
130+
d := s.goTypeDefWithPkgOverride(actual.ElemType, ptr, useDefault, pkg, targetPkg)
118131
if expr.IsObject(actual.ElemType.Type) {
119132
d = "*" + d
120133
}
121134
return "[]" + d
122135
case *expr.Map:
123-
keyDef := s.goTypeDef(actual.KeyType, ptr, useDefault, pkg)
136+
keyDef := s.goTypeDefWithPkgOverride(actual.KeyType, ptr, useDefault, pkg, targetPkg)
124137
if expr.IsObject(actual.KeyType.Type) {
125138
keyDef = "*" + keyDef
126139
}
127-
elemDef := s.goTypeDef(actual.ElemType, ptr, useDefault, pkg)
140+
elemDef := s.goTypeDefWithPkgOverride(actual.ElemType, ptr, useDefault, pkg, targetPkg)
128141
if expr.IsObject(actual.ElemType.Type) {
129142
elemDef = "*" + elemDef
130143
}
@@ -145,7 +158,7 @@ func (s *NameScope) goTypeDef(att *expr.AttributeExpr, ptr, useDefault bool, pkg
145158
)
146159
{
147160
fn = GoifyAtt(at, name, true)
148-
tdef = s.goTypeDef(at, ptr, useDefault, pkg)
161+
tdef = s.goTypeDefWithPkgOverride(at, ptr, useDefault, pkg, targetPkg)
149162
if expr.IsObject(at.Type) ||
150163
att.IsPrimitivePointer(name, useDefault) ||
151164
(ptr && expr.IsPrimitive(at.Type) && at.Type.Kind() != expr.AnyKind && at.Type.Kind() != expr.BytesKind) {
@@ -165,15 +178,29 @@ func (s *NameScope) goTypeDef(att *expr.AttributeExpr, ptr, useDefault bool, pkg
165178
return "struct {}"
166179
}
167180
var prefix string
168-
if loc := UserTypeLocation(actual); loc != nil && loc.PackageName() != pkg {
169-
prefix = loc.PackageName() + "."
181+
if loc := UserTypeLocation(actual); loc != nil {
182+
if targetPkg != "" {
183+
if loc.PackageName() != targetPkg {
184+
prefix = loc.PackageName() + "."
185+
} else {
186+
prefix = targetPkg + "."
187+
}
188+
} else if loc.PackageName() != pkg {
189+
prefix = loc.PackageName() + "."
190+
}
191+
} else if targetPkg != "" {
192+
prefix = targetPkg + "."
170193
}
171194
return prefix + s.GoTypeName(att)
172195
default:
173196
panic(fmt.Sprintf("unknown data type %T", actual)) // bug
174197
}
175198
}
176199

200+
func (s *NameScope) goTypeDef(att *expr.AttributeExpr, ptr, useDefault bool, pkg string) string {
201+
return s.goTypeDefWithPkgOverride(att, ptr, useDefault, pkg, "")
202+
}
203+
177204
// GoVar returns the Go code that returns the address of a variable of the Go type
178205
// which matches the given attribute type.
179206
func (*NameScope) GoVar(varName string, dt expr.DataType) string {

codegen/transformer.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,11 @@ func (a *AttributeScope) Name(att *expr.AttributeExpr, pkg string, ptr, useDefau
257257
// in fact the struct typedef. In this case we need to force the
258258
// generation of the fields as pointers if needed as the default
259259
// GoTransform algorithm does not allow for an override.
260-
return a.scope.GoTypeDef(att, ptr, useDefault)
260+
// Use the target package context so that user types referenced inside
261+
// the inline struct are qualified against the correct package (e.g.,
262+
// use "types.UUID" instead of incorrectly qualifying with the service
263+
// package alias).
264+
return a.scope.GoTypeDefWithTargetPkg(att, ptr, useDefault, pkg)
261265
}
262266
if n, ok := att.Meta["struct:type:name"]; ok {
263267
// If the attribute has a "struct:type:name" meta then use it as the

go.work.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss=
22
cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
3+
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
34
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
45
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
6+
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
57
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc=
68
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY=
79
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k=
810
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
11+
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
912
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
1013
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
1114
github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=
@@ -19,6 +22,7 @@ github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3
1922
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
2023
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
2124
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
25+
github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
2226
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
2327
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
2428
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@@ -40,11 +44,13 @@ github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
4044
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
4145
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA=
4246
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
47+
go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k=
4348
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
4449
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
4550
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
4651
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
4752
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
53+
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
4854
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk=
4955
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
5056
golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsOKwuR5X/m0QFOJpSZvAxFfkQT+Erd9D4=
@@ -55,3 +61,4 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV
5561
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5662
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM=
5763
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
64+
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=

jsonrpc/integration_tests/framework/executor.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ func NewExecutor(serverURL string, opts ...ExecutorOption) *Executor {
3939
func (e *Executor) Execute(t *testing.T, scenario Scenario) {
4040
t.Helper()
4141

42-
4342
// Handle different scenario types
4443
switch {
4544
case len(scenario.Sequence) > 0:
@@ -257,7 +256,7 @@ func (e *Executor) executeWebSocketSequence(ctx context.Context, t *testing.T, s
257256
Params: reqData["params"],
258257
ID: reqData["id"],
259258
}
260-
259+
261260
// Handle custom jsonrpc field if specified
262261
if jsonrpcVal, ok := reqData["jsonrpc"]; ok {
263262
if jsonrpcStr, ok := jsonrpcVal.(string); ok {
@@ -282,7 +281,6 @@ func (e *Executor) executeWebSocketSequence(ctx context.Context, t *testing.T, s
282281
var response map[string]any
283282
err = json.Unmarshal(msg, &response)
284283
require.NoErrorf(t, err, "Step %d: failed to unmarshal response", i)
285-
286284

287285
// Compare the response with expected
288286
if expected, ok := step.Expect.(map[string]any); ok {
@@ -589,5 +587,3 @@ func (e *Executor) compareValues(t *testing.T, actual, expected any, path string
589587
assert.EqualValues(t, expected, actual, "%s mismatch", path)
590588
}
591589
}
592-
593-

jsonrpc/integration_tests/harness/server.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import (
1414

1515
// Server manages a test server process
1616
type Server struct {
17-
cmd *exec.Cmd
18-
port int
19-
logFile *os.File
20-
workDir string
17+
cmd *exec.Cmd
18+
port int
19+
logFile *os.File
20+
workDir string
2121
}
2222

2323
// StartServer starts a test server
@@ -47,36 +47,36 @@ func StartServer(ctx context.Context, workDir string, port int) (*Server, error)
4747
filepath.Join(workDir, "cmd", "test", "main.go"),
4848
filepath.Join(workDir, "cmd", "api", "main.go"),
4949
}
50-
50+
5151
for _, path := range candidates {
5252
if _, err := os.Stat(path); err == nil {
5353
serverPath = path
5454
break
5555
}
5656
}
57-
57+
5858
if serverPath == "" {
5959
return nil, fmt.Errorf("server main.go not found in any expected location")
6060
}
61-
61+
6262
// Ensure dependencies are downloaded before running
6363
downloadCmd := exec.Command("go", "mod", "download")
6464
downloadCmd.Dir = workDir
65-
downloadCmd.Env = append(os.Environ(),
65+
downloadCmd.Env = append(os.Environ(),
6666
"GO111MODULE=on",
6767
"GOWORK=off",
6868
)
6969
if output, err := downloadCmd.CombinedOutput(); err != nil {
7070
return nil, fmt.Errorf("go mod download failed: %w\nOutput: %s", err, output)
7171
}
72-
73-
// Run all Go files in the cmd directory, not just main.go
72+
73+
// Run all files in the package so helpers generated alongside main.go are included
7474
serverDir := filepath.Dir(serverPath)
7575
cmd := exec.CommandContext(ctx, "go", "run", ".", "--http-port", fmt.Sprintf("%d", port))
7676
cmd.Dir = serverDir
7777
cmd.Stdout = logFile
7878
cmd.Stderr = logFile
79-
cmd.Env = append(os.Environ(),
79+
cmd.Env = append(os.Environ(),
8080
"GO111MODULE=on",
8181
"GOWORK=off",
8282
)
@@ -115,13 +115,13 @@ func (s *Server) URL() string {
115115
func (s *Server) Stop() error {
116116
if s.cmd != nil && s.cmd.Process != nil {
117117
s.cmd.Process.Kill() //nolint:errcheck
118-
s.cmd.Wait() //nolint:errcheck
118+
s.cmd.Wait() //nolint:errcheck
119119
}
120-
120+
121121
if s.logFile != nil {
122122
s.logFile.Close() //nolint:errcheck
123123
}
124-
124+
125125
return nil
126126
}
127127

@@ -135,8 +135,8 @@ func (s *Server) waitForReady(ctx context.Context) error {
135135
go func() {
136136
for logScanner.Scan() {
137137
line := logScanner.Text()
138-
if strings.Contains(line, "HTTP server listening") ||
139-
strings.Contains(line, fmt.Sprintf(":%d", s.port)) {
138+
if strings.Contains(line, "HTTP server listening") ||
139+
strings.Contains(line, fmt.Sprintf(":%d", s.port)) {
140140
readyChan <- true
141141
return
142142
}
@@ -154,7 +154,7 @@ func (s *Server) waitForReady(ctx context.Context) error {
154154
go func() {
155155
ticker := time.NewTicker(100 * time.Millisecond)
156156
defer ticker.Stop()
157-
157+
158158
for {
159159
select {
160160
case <-ctx.Done():
@@ -181,4 +181,4 @@ func (s *Server) waitForReady(ctx context.Context) error {
181181
case <-ctx.Done():
182182
return ctx.Err()
183183
}
184-
}
184+
}

jsonrpc/integration_tests/tests/jsonrpc_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ func TestJSONRPC(t *testing.T) {
1919
}
2020

2121
runner.Run(t)
22-
}
22+
}

0 commit comments

Comments
 (0)