Skip to content

Commit

Permalink
Merge pull request #461 from tdakkota/feat/pass-location-to-openapi-s…
Browse files Browse the repository at this point in the history
…tructs

feat(parser): pass location via `openapi` structs
  • Loading branch information
ernado authored Jul 7, 2022
2 parents a70e61c + aa8767f commit ae203f1
Show file tree
Hide file tree
Showing 27 changed files with 181 additions and 106 deletions.
7 changes: 3 additions & 4 deletions dsl.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/go-faster/jx"
jsonv2 "github.com/go-json-experiment/json"

"github.com/ogen-go/ogen/gen/ir"
"github.com/ogen-go/ogen/jsonschema"
"github.com/ogen-go/ogen/openapi"
)
Expand Down Expand Up @@ -244,7 +243,7 @@ func (r *RequestBody) AddContent(mt string, s *Schema) *RequestBody {

// SetJSONContent sets the given Schema under the JSON MediaType to the Content of the Response.
func (r *RequestBody) SetJSONContent(s *Schema) *RequestBody {
return r.AddContent(string(ir.ContentTypeJSON), s)
return r.AddContent("application/json", s)
}

// initContent ensures the Content map is allocated.
Expand Down Expand Up @@ -597,7 +596,7 @@ func (p *Parameter) SetIn(i string) *Parameter {
return p
}

// InPath sets the In of the Parameter to "PathItem".
// InPath sets the In of the Parameter to "path".
func (p *Parameter) InPath() *Parameter {
return p.SetIn(string(openapi.LocationPath))
}
Expand Down Expand Up @@ -724,7 +723,7 @@ func (r *Response) AddContent(mt string, s *Schema) *Response {

// SetJSONContent sets the given Schema under the JSON MediaType to the Content of the Response.
func (r *Response) SetJSONContent(s *Schema) *Response {
return r.AddContent(string(ir.ContentTypeJSON), s)
return r.AddContent("application/json", s)
}

// initContent ensures the Content map is allocated.
Expand Down
1 change: 1 addition & 0 deletions gen/gen_contents.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ func (g *Generator) generateContents(
}

g.log.Info(`Content type is unsupported, set "format" to "binary" to use io.Reader`,
g.zapLocation(media),
zap.String("contentType", contentType),
)
unsupported = append(unsupported, contentType)
Expand Down
12 changes: 9 additions & 3 deletions gen/gen_headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import (
"net/http"

"github.com/go-faster/errors"
"go.uber.org/zap"

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

func (g *Generator) generateHeaders(ctx *genctx, name string, headers map[string]*openapi.Header) (_ map[string]*ir.Parameter, err error) {
func (g *Generator) generateHeaders(
ctx *genctx,
name string,
headers map[string]*openapi.Header,
) (_ map[string]*ir.Parameter, err error) {
if len(headers) == 0 {
return nil, nil
}
Expand All @@ -19,7 +22,10 @@ func (g *Generator) generateHeaders(ctx *genctx, name string, headers map[string
for hname, header := range headers {
ctx := ctx.appendPath(hname)
if http.CanonicalHeaderKey(hname) == "Content-Type" {
g.log.Warn("Content-Type is described separately and will be ignored in this section.", zap.String("pointer", ctx.JSONPointer()))
g.log.Warn(
"Content-Type is described separately and will be ignored in this section.",
g.zapLocation(header),
)
continue
}

Expand Down
5 changes: 3 additions & 2 deletions gen/gen_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func saveSchemaTypes(ctx *genctx, gen *schemaGen) error {
}

func (g *Generator) generateSchema(ctx *genctx, name string, schema *jsonschema.Schema, optional bool) (*ir.Type, error) {
gen := newSchemaGen(ctx.lookupRef)
gen := newSchemaGen(g.opt.Filename, ctx.lookupRef)
gen.log = g.log.Named("schemagen")

t, err := gen.generate(name, schema, optional)
Expand Down Expand Up @@ -99,7 +99,8 @@ func GenerateSchema(schema *jsonschema.Schema, fs FileSystem, opts GenerateSchem
local: newTStorage(),
}

gen := newSchemaGen(func(ref string) (*ir.Type, bool) {
// TODO(tdakkota): pass input filename
gen := newSchemaGen("", func(ref string) (*ir.Type, bool) {
return nil, false
})
gen.log = opts.Logger.Named("schemagen")
Expand Down
8 changes: 2 additions & 6 deletions gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,10 @@ func (g *Generator) makeIR(ops []*openapi.Operation) error {

for _, spec := range ops {
routePath := spec.Path.String()
log := g.log.With(
zap.String("path", routePath),
zap.String("method", spec.HTTPMethod),
zap.String("operationID", spec.OperationID),
)
log := g.log.With(g.zapLocation(spec))

if !g.opt.Filters.accept(spec) {
g.log.Info("Skipping filtered operation")
log.Info("Skipping filtered operation")
continue
}

Expand Down
7 changes: 0 additions & 7 deletions gen/panic.go

This file was deleted.

11 changes: 7 additions & 4 deletions gen/schema_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ type schemaGen struct {
localRefs map[string]*ir.Type
lookupRef func(ref string) (*ir.Type, bool)
nameRef func(ref string) (string, error)
log *zap.Logger

filename string
log *zap.Logger
}

func newSchemaGen(lookupRef func(ref string) (*ir.Type, bool)) *schemaGen {
func newSchemaGen(filename string, lookupRef func(ref string) (*ir.Type, bool)) *schemaGen {
return &schemaGen{
side: nil,
localRefs: map[string]*ir.Type{},
Expand All @@ -32,7 +34,8 @@ func newSchemaGen(lookupRef func(ref string) (*ir.Type, bool)) *schemaGen {
}
return name, nil
},
log: zap.NewNop(),
filename: filename,
log: zap.NewNop(),
}
}

Expand Down Expand Up @@ -276,8 +279,8 @@ func (g *schemaGen) generate2(name string, schema *jsonschema.Schema) (ret *ir.T
return g.regtype(name, t), nil
case jsonschema.Empty:
g.log.Info("Type is not defined, using any",
g.zapLocation(schema),
zap.String("name", name),
zap.String("ref", schema.Ref),
)
return g.regtype(name, ir.Any(schema)), nil
default:
Expand Down
2 changes: 1 addition & 1 deletion gen/schema_gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestSchemaGenAnyWarn(t *testing.T) {
a := require.New(t)

core, ob := observer.New(zap.InfoLevel)
s := newSchemaGen(func(ref string) (*ir.Type, bool) {
s := newSchemaGen("", func(ref string) (*ir.Type, bool) {
return nil, false
})
s.log = zap.New(core)
Expand Down
27 changes: 27 additions & 0 deletions gen/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ import (
"fmt"
"net/http"

"go.uber.org/zap"

"github.com/ogen-go/ogen/gen/ir"
ogenjson "github.com/ogen-go/ogen/json"
"github.com/ogen-go/ogen/jsonschema"
)

func unreachable(v interface{}) string {
return fmt.Sprintf("unreachable: %v", v)
}

func isBinary(s *jsonschema.Schema) bool {
if s == nil {
return false
Expand Down Expand Up @@ -67,3 +74,23 @@ func statusText(code int) string {
}
return fmt.Sprintf("Code%d", code)
}

func (g *Generator) zapLocation(l interface {
Location() (ogenjson.Location, bool)
}) zap.Field {
loc, ok := l.Location()
if !ok {
return zap.Skip()
}
return zap.String("at", loc.WithFilename(g.opt.Filename))
}

func (g *schemaGen) zapLocation(l interface {
Location() (ogenjson.Location, bool)
}) zap.Field {
loc, ok := l.Location()
if !ok {
return zap.Skip()
}
return zap.String("at", loc.WithFilename(g.filename))
}
23 changes: 21 additions & 2 deletions json/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"sort"
"strconv"

"github.com/go-json-experiment/json"
)
Expand Down Expand Up @@ -94,11 +93,31 @@ type Location struct {
// String implements fmt.Stringer.
func (l Location) String() string {
if l.Line == 0 {
return strconv.Quote(l.JSONPointer)
return l.JSONPointer
}
return fmt.Sprintf("%d:%d", l.Line, l.Column)
}

// WithFilename prints the location with the given filename.
//
// If filename is empty, the location is printed as is.
func (l Location) WithFilename(filename string) string {
if filename != "" {
switch {
case l.Line != 0:
// Line is set, so return "${filename}:".
filename += ":"
case l.JSONPointer != "":
// Line is not set, but JSONPointer is set, so return "${filename}#${JSONPointer}".
filename += "#"
default:
// Neither line nor JSONPointer is set, so return empty string.
return ""
}
}
return filename + l.String()
}

// Locatable is an interface for JSON value location store.
type Locatable interface {
setLocation(Location)
Expand Down
2 changes: 2 additions & 0 deletions jsonschema/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ func (p *Parser) extendInfo(schema *RawSchema, s *Schema) *Schema {
Mapping: d.Mapping,
}
}

s.Locator = schema.Locator
return s
}

Expand Down
4 changes: 4 additions & 0 deletions jsonschema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"regexp"

"github.com/go-json-experiment/json"

ogenjson "github.com/ogen-go/ogen/json"
)

// SchemaType is a JSON Schema type.
Expand Down Expand Up @@ -81,6 +83,8 @@ type Schema struct {
// Default schema value.
Default interface{}
DefaultSet bool

ogenjson.Locator
}

// AddExample adds example for this Schema.
Expand Down
19 changes: 13 additions & 6 deletions openapi/example.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package openapi

import "github.com/go-json-experiment/json"
import (
"github.com/go-json-experiment/json"

ogenjson "github.com/ogen-go/ogen/json"
)

// Example is an OpenAPI Example.
type Example struct {
Ref string `json:"$ref,omitempty"` // ref object
Summary string `json:"summary,omitempty"`
Description string `json:"description,omitempty"`
Value json.RawValue `json:"value,omitempty"`
ExternalValue string `json:"externalValue,omitempty"`
Ref string

Summary string
Description string
Value json.RawValue
ExternalValue string

ogenjson.Locator
}
5 changes: 5 additions & 0 deletions openapi/mediatype.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package openapi
import (
"github.com/go-json-experiment/json"

ogenjson "github.com/ogen-go/ogen/json"
"github.com/ogen-go/ogen/jsonschema"
)

Expand All @@ -12,6 +13,8 @@ type MediaType struct {
Example json.RawValue
Examples map[string]*Example
Encoding map[string]*Encoding

ogenjson.Locator
}

// Encoding is Encoding Type Object.
Expand All @@ -21,4 +24,6 @@ type Encoding struct {
Style ParameterStyle
Explode bool
AllowReserved bool

ogenjson.Locator
}
10 changes: 10 additions & 0 deletions openapi/operation.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package openapi

import (
ogenjson "github.com/ogen-go/ogen/json"
)

// Operation is an OpenAPI Operation.
type Operation struct {
OperationID string // optional
Expand All @@ -23,6 +27,8 @@ type Operation struct {
// * default
// * 1XX, 2XX, 3XX, 4XX, 5XX
Responses map[string]*Response

ogenjson.Locator
}

// Path is an operation path.
Expand Down Expand Up @@ -52,6 +58,8 @@ type RequestBody struct {
Description string
Required bool
Content map[string]*MediaType

ogenjson.Locator
}

// Header is an OpenAPI Header definition.
Expand All @@ -64,4 +72,6 @@ type Response struct {
Headers map[string]*Header
Content map[string]*MediaType
// Links map[string]*Link

ogenjson.Locator
}
12 changes: 9 additions & 3 deletions openapi/parameter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package openapi

import "github.com/ogen-go/ogen/jsonschema"
import (
ogenjson "github.com/ogen-go/ogen/json"
"github.com/ogen-go/ogen/jsonschema"
)

// ParameterLocation defines where OpenAPI parameter is located.
type ParameterLocation string
Expand Down Expand Up @@ -30,16 +33,19 @@ func (l ParameterLocation) Cookie() bool { return l == LocationCookie }

// Parameter is an OpenAPI Operation Parameter.
type Parameter struct {
Ref string
Ref string

Name string
Description string
Deprecated bool
Schema *jsonschema.Schema
Content *ParameterContent
In ParameterLocation
Style ParameterStyle
Explode bool
Required bool
Deprecated bool

ogenjson.Locator
}

// ParameterContent describes OpenAPI Parameter content field.
Expand Down
Loading

0 comments on commit ae203f1

Please sign in to comment.