Skip to content

Commit

Permalink
refactor(generator): restructure OpenAPI loading
Browse files Browse the repository at this point in the history
  • Loading branch information
coryan committed Nov 1, 2024
1 parent 9386ff4 commit 60bf768
Showing 1 changed file with 58 additions and 63 deletions.
121 changes: 58 additions & 63 deletions generator/internal/genclient/translator/openapi/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (t *Translator) makeAPI() (*genclient.API, error) {
if err != nil {
return nil, err
}
fields, err := makeMessageFields(name, schema)
fields, err := t.makeMessageFields(name, schema)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -117,7 +117,7 @@ func (t *Translator) Translate() (*genclient.GenerateRequest, error) {
}, nil
}

func makeMessageFields(messageName string, message *base.Schema) ([]*genclient.Field, error) {
func (t *Translator) makeMessageFields(messageName string, message *base.Schema) ([]*genclient.Field, error) {
var fields []*genclient.Field
for name, f := range message.Properties.FromOldest() {
schema, err := f.BuildSchema()
Expand All @@ -131,7 +131,7 @@ func makeMessageFields(messageName string, message *base.Schema) ([]*genclient.F
break
}
}
field, err := makeField(messageName, name, optional, schema)
field, err := t.makeField(messageName, name, optional, schema)
if err != nil {
return nil, err
}
Expand All @@ -140,55 +140,40 @@ func makeMessageFields(messageName string, message *base.Schema) ([]*genclient.F
return fields, nil
}

func makeField(messageName, name string, optional bool, field *base.Schema) (*genclient.Field, error) {
func (t *Translator) makeField(messageName, name string, optional bool, field *base.Schema) (*genclient.Field, error) {
if len(field.AllOf) != 0 {
return makeAllOfField(messageName, name, field)
// Simple object fields name an AllOf attribute, but no `Type` attribute.
return t.makeObjectField(messageName, name, field)
}
if len(field.Type) == 0 {
return nil, fmt.Errorf("missing field type for field %s.%s", messageName, name)
}
type_name := field.Type[0]
switch type_name {
switch field.Type[0] {
case "boolean":
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.BOOL_TYPE,
Optional: optional,
}, nil
return t.makeBooleanField(name, optional, field)
case "string":
return makeStringType(messageName, name, field.Format, optional, field)
return t.makeStringField(messageName, name, field.Format, optional, field)
case "integer":
return makeIntegerField(messageName, name, field.Format, optional, field)
return t.makeIntegerField(messageName, name, field.Format, optional, field)
case "object":
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.MESSAGE_TYPE,
Optional: true,
}, nil
return t.makeObjectField(messageName, name, field)
case "array":
return makeArrayField(messageName, name, field)
return t.makeArrayField(messageName, name, field)
default:
return nil, fmt.Errorf("unknown type for field %q", name)
}
}

func makeAllOfField(messageName, name string, field *base.Schema) (*genclient.Field, error) {
for _, proxy := range field.AllOf {
typezID := strings.TrimPrefix(proxy.GetReference(), "#/components/schemas/")
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.MESSAGE_TYPE,
TypezID: typezID,
Optional: true,
}, nil
}
return nil, fmt.Errorf("cannot build any AllOf schema for field %s.%s", messageName, name)
func (t *Translator) makeBooleanField(name string, optional bool, field *base.Schema) (*genclient.Field, error) {
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.BOOL_TYPE,
Optional: optional,
}, nil
}

func makeStringType(messageName, name, format string, optional bool, field *base.Schema) (*genclient.Field, error) {
func (t *Translator) makeStringField(messageName, name, format string, optional bool, field *base.Schema) (*genclient.Field, error) {
switch format {
case "":
return &genclient.Field{
Expand Down Expand Up @@ -247,7 +232,7 @@ func makeStringType(messageName, name, format string, optional bool, field *base
}
}

func makeIntegerField(messageName, name, format string, optional bool, field *base.Schema) (*genclient.Field, error) {
func (t *Translator) makeIntegerField(messageName, name, format string, optional bool, field *base.Schema) (*genclient.Field, error) {
switch format {
case "int32":
return &genclient.Field{
Expand Down Expand Up @@ -282,48 +267,58 @@ func makeIntegerField(messageName, name, format string, optional bool, field *ba
}
}

func makeArrayField(messageName, name string, field *base.Schema) (*genclient.Field, error) {
func (t *Translator) makeObjectField(messageName, name string, field *base.Schema) (*genclient.Field, error) {
if len(field.AllOf) != 0 {
return t.makeObjectFieldAllOf(messageName, name, field)
}
// TODO(#62) - this is an Any or a map<string, T>, needs a TypezID
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.MESSAGE_TYPE,
Optional: true,
}, nil
}

func (t *Translator) makeArrayField(messageName, name string, field *base.Schema) (*genclient.Field, error) {
if !field.Items.IsA() {
return nil, fmt.Errorf("cannot handle arrays without an `Items` field for %s.%s", messageName, name)
}
schema, err := field.Items.A.BuildSchema()
if err != nil {
return nil, fmt.Errorf("cannot build schema for %s.%s error=%q", messageName, name, err)
}
var result *genclient.Field
switch schema.Type[0] {
case "boolean":
result, err = t.makeBooleanField(name, false, field)
case "string":
field, err := makeStringType(messageName, name, schema.Format, false, field)
if err != nil {
return nil, err
}
field.Repeated = true
field.Optional = false
return field, nil
result, err = t.makeStringField(messageName, name, schema.Format, false, field)
case "integer":
field, err := makeIntegerField(messageName, name, schema.Format, false, field)
if err != nil {
return nil, err
}
field.Repeated = true
field.Optional = false
return field, nil
case "boolean":
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.BOOL_TYPE,
Optional: false,
Repeated: true,
}, nil
result, err = t.makeIntegerField(messageName, name, schema.Format, false, field)
case "object":
result, err = t.makeObjectField(messageName, name, field)
default:
return nil, fmt.Errorf("unknown array field type for %s.%s %q", messageName, name, schema.Type[0])
}
if err != nil {
return nil, err
}
result.Repeated = true
result.Optional = false
return result, nil
}

func (t *Translator) makeObjectFieldAllOf(messageName, name string, field *base.Schema) (*genclient.Field, error) {
for _, proxy := range field.AllOf {
typezID := strings.TrimPrefix(proxy.GetReference(), "#/components/schemas/")
return &genclient.Field{
Name: name,
Documentation: field.Description,
Typez: genclient.MESSAGE_TYPE,
Optional: false,
Repeated: true,
TypezID: typezID,
Optional: true,
}, nil
default:
return nil, fmt.Errorf("unknown array field type for %s.%s %q", messageName, name, schema.Type[0])
}
return nil, fmt.Errorf("cannot build any AllOf schema for field %s.%s", messageName, name)
}

0 comments on commit 60bf768

Please sign in to comment.