Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental support for generating Lakeview widgets - oneOf and anyOf #774

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions openapi/code/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type Entity struct {
IsString bool
IsByteStream bool
IsEmpty bool
Const any

// this field does not have a concrete type
IsAny bool
Expand All @@ -87,6 +88,9 @@ type Entity struct {

// Schema references the OpenAPI schema this entity was created from.
Schema *openapi.Schema

ChildTypes ChildTypes
AbstractType *Entity
}

// Whether the Entity contains a basic GoLang type which is not required
Expand Down
14 changes: 12 additions & 2 deletions openapi/code/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@ func NewFromFile(ctx context.Context, name string) (*Batch, error) {

// NewFromSpec converts OpenAPI spec to intermediate representation
func NewFromSpec(ctx context.Context, spec *openapi.Specification) (*Batch, error) {
batch := Batch{
batch := &Batch{
packages: map[string]*Package{},
}
poly := newPolymorphism(spec.Components)
err := poly.Load()
if err != nil {
return nil, fmt.Errorf("polymorphic types: %w", err)
}
for _, tag := range spec.Tags {
pkg, ok := batch.packages[tag.Package]
if !ok {
Expand All @@ -41,6 +46,7 @@ func NewFromSpec(ctx context.Context, spec *openapi.Specification) (*Batch, erro
Components: spec.Components,
services: map[string]*Service{},
types: map[string]*Entity{},
poly: poly,
}
batch.packages[tag.Package] = pkg
}
Expand All @@ -49,6 +55,10 @@ func NewFromSpec(ctx context.Context, spec *openapi.Specification) (*Batch, erro
return nil, fmt.Errorf("fail to load %s: %w", tag.Name, err)
}
}
err = poly.Link(batch)
if err != nil {
return nil, fmt.Errorf("link: %w", err)
}
// add some packages at least some description
for _, pkg := range batch.packages {
if len(pkg.services) > 1 {
Expand All @@ -59,7 +69,7 @@ func NewFromSpec(ctx context.Context, spec *openapi.Specification) (*Batch, erro
pkg.Description = svc.Summary()
}
}
return &batch, nil
return batch, nil
}

func (b *Batch) FullName() string {
Expand Down
32 changes: 29 additions & 3 deletions openapi/code/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Package struct {
types map[string]*Entity
emptyTypes []*Named
extImports map[string]*Entity
poly *polymorphism
}

// FullName just returns pacakge name
Expand Down Expand Up @@ -52,12 +53,28 @@ func (pkg *Package) MainService() *Service {
}

// Types returns sorted slice of types
func (pkg *Package) Types() (types []*Entity) {
func (pkg *Package) Types() (out []*Entity) {
types := []*Entity{}
for _, v := range pkg.types {
types = append(types, v)
}
pascalNameSort(types)
return types
// Python doesn't support forward-references for base classes,
// so that's why we have to pull abstract types first.
// topological sort is not required, as Databricks doesn't have (yet)
// complicated type hierarchy with oneOf/anyOf references. toposort
// could easily be added here later.
for _, v := range types {
if v.ChildTypes != nil {
out = append(out, v)
}
}
for _, v := range types {
if v.ChildTypes == nil {
out = append(out, v)
}
}
return out
}

// EmptyTypes returns sorted list of types without fields
Expand Down Expand Up @@ -99,6 +116,14 @@ func (pkg *Package) ImportedPackages() (res []string) {
}

func (pkg *Package) schemaToEntity(s *openapi.Schema, path []string, hasName bool) *Entity {
if s.IsOneOf() || s.IsAnyOf() {
entity, err := pkg.poly.Resolve(pkg.Name, path[0])
if err != nil {
err = fmt.Errorf("poly: %w", err)
panic(err)
}
return pkg.define(entity)
}
if s.IsRef() {
pair := strings.Split(s.Component(), ".")
if len(pair) == 2 && pair[0] != pkg.Name {
Expand Down Expand Up @@ -172,7 +197,8 @@ func (pkg *Package) schemaToEntity(s *openapi.Schema, path []string, hasName boo
e.IsString = s.Type == "string"
e.IsInt64 = s.Type == "integer" && s.Format == "int64"
e.IsFloat64 = s.Type == "number" && s.Format == "double"
e.IsInt = s.Type == "integer" || s.Type == "int"
e.IsInt = s.Type == "integer" || s.Type == "int" || s.Type == "number"
e.Const = s.Const
return e
}

Expand Down
Loading
Loading