Skip to content

Commit

Permalink
Merge pull request #1183 from tdakkota/fix-1182
Browse files Browse the repository at this point in the history
fix(gen): use response ref as key for wrapped type lookup
  • Loading branch information
ernado authored Feb 20, 2024
2 parents 3526cfa + 6383038 commit 2a652ad
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 14 deletions.
66 changes: 66 additions & 0 deletions _testdata/positive/issue1182.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
openapi: 3.0.1
info:
title: "REST API"
version: 0.0.1

servers:
- url: "http://localhost:8888"

paths:
/api/auth:
post:
operationId: auth
tags:
- auth
responses:
"200":
$ref: "#/components/responses/AuthOk"
/api/alive:
get:
operationId: alive
tags:
- system
responses:
"200":
$ref: "#/components/responses/Alive"

components:
headers:
setCookie:
required: true
schema:
type: string
accessControlAllowCredentials:
required: false
schema:
type: string

schemas:
Ok:
type: object
required:
- ok
properties:
ok:
type: boolean
example: true

responses:
AuthOk:
description: "Ok"
headers:
Set-Cookie:
$ref: "#/components/headers/setCookie"
content:
application/json:
schema:
$ref: "#/components/schemas/Ok"
Alive:
description: "Alive"
headers:
Access-Control-Allow-Credentials:
$ref: "#/components/headers/accessControlAllowCredentials"
content:
application/json:
schema:
$ref: "#/components/schemas/Ok"
11 changes: 7 additions & 4 deletions gen/gen_responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ogen-go/ogen/gen/ir"
"github.com/ogen-go/ogen/internal/xmaps"
"github.com/ogen-go/ogen/jsonschema"
"github.com/ogen-go/ogen/openapi"
)

Expand Down Expand Up @@ -211,7 +212,7 @@ func (g *Generator) responseToIR(
},
}
}
t, err := wrapResponseType(ctx, name, media.Type, headers, withStatusCode)
t, err := wrapResponseType(ctx, name, resp.Ref, media.Type, headers, withStatusCode)
if err != nil {
return nil, errors.Wrapf(err, "content: %q: wrap response type", contentType)
}
Expand All @@ -234,6 +235,7 @@ func (g *Generator) responseToIR(
func wrapResponseType(
ctx *genctx,
name string,
respRef jsonschema.Ref,
t *ir.Type,
headers map[string]*ir.Parameter,
withStatusCode bool,
Expand All @@ -243,7 +245,7 @@ func wrapResponseType(
}

if schema := t.Schema; schema != nil && !schema.Ref.IsZero() {
if t, ok := ctx.lookupWType(schema.Ref); ok {
if t, ok := ctx.lookupWType(respRef, schema.Ref); ok {
return t, nil
}

Expand All @@ -252,7 +254,7 @@ func wrapResponseType(
return
}

if err := ctx.saveWType(schema.Ref, ret); err != nil {
if err := ctx.saveWType(respRef, schema.Ref, ret); err != nil {
rerr = err
ret = nil
}
Expand All @@ -270,7 +272,8 @@ func wrapResponseType(
}()
}

if t.Name != "" {
// Prefer response name to schema name in case of wrapping.
if respRef.IsZero() && t.Name != "" {
name = t.Name
}

Expand Down
11 changes: 6 additions & 5 deletions gen/genctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func (g *genctx) saveResponse(ref jsonschema.Ref, r *ir.Response) error {
return g.local.saveResponse(ref, r)
}

func (g *genctx) saveWType(ref jsonschema.Ref, t *ir.Type) error {
return g.local.saveWType(ref, t)
func (g *genctx) saveWType(parent, ref jsonschema.Ref, t *ir.Type) error {
return g.local.saveWType(parent, ref, t)
}

func (g *genctx) lookupResponse(ref jsonschema.Ref) (*ir.Response, bool) {
Expand All @@ -48,11 +48,12 @@ func (g *genctx) lookupResponse(ref jsonschema.Ref) (*ir.Response, bool) {
return nil, false
}

func (g *genctx) lookupWType(ref jsonschema.Ref) (*ir.Type, bool) {
if t, ok := g.global.wtypes[ref]; ok {
func (g *genctx) lookupWType(parent, ref jsonschema.Ref) (*ir.Type, bool) {
key := [2]jsonschema.Ref{parent, ref}
if t, ok := g.global.wtypes[key]; ok {
return t, true
}
if t, ok := g.local.wtypes[ref]; ok {
if t, ok := g.local.wtypes[key]; ok {
return t, true
}
return nil, false
Expand Down
11 changes: 6 additions & 5 deletions gen/tstorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ type tstorage struct {
// * [T]StatusCode
// * [T]Headers
// * [T]StatusCodeWithHeaders
wtypes map[jsonschema.Ref]*ir.Type // Key: ref
wtypes map[[2]jsonschema.Ref]*ir.Type // Key: parent ref + ref
}

func newTStorage() *tstorage {
return &tstorage{
refs: map[schemaKey]*ir.Type{},
types: map[string]*ir.Type{},
responses: map[jsonschema.Ref]*ir.Response{},
wtypes: map[jsonschema.Ref]*ir.Type{},
wtypes: map[[2]jsonschema.Ref]*ir.Type{},
}
}

Expand Down Expand Up @@ -106,15 +106,16 @@ func (s *tstorage) saveResponse(ref jsonschema.Ref, r *ir.Response) error {
return nil
}

func (s *tstorage) saveWType(ref jsonschema.Ref, t *ir.Type) error {
if _, ok := s.wtypes[ref]; ok {
func (s *tstorage) saveWType(parent, ref jsonschema.Ref, t *ir.Type) error {
key := [2]jsonschema.Ref{parent, ref}
if _, ok := s.wtypes[key]; ok {
return errors.Errorf("reference conflict: %q", ref)
}
if _, ok := s.types[t.Name]; ok {
return errors.Errorf("reference %q type name conflict: %q", ref, t.Name)
}

s.wtypes[ref] = t
s.wtypes[key] = t
s.types[t.Name] = t
return nil
}
Expand Down

0 comments on commit 2a652ad

Please sign in to comment.