Skip to content

Commit

Permalink
Feature/schema gen/enum value outputs (#37)
Browse files Browse the repository at this point in the history
Co-authored-by: Tit Petric <tit@tyk.io>
  • Loading branch information
titpetric and Tit Petric authored Feb 12, 2025
1 parent 44165ff commit 8ef9047
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 2 deletions.
18 changes: 18 additions & 0 deletions cmd/schema-gen/_example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ import (
"os"
)

// Status is an enum type.
type Status int

const (
Active Status = iota
Inactive
Suspended
)

// Role is an enum type for user roles.
type Role string

const (
Admin Role = "admin"
User Role = "user"
Guest Role = "guest"
)

// Type declaration doc, File is an alias of os.File.
type File = os.File

Expand Down
8 changes: 8 additions & 0 deletions cmd/schema-gen/_example/example.go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,13 @@ type (

NamedRequests = map[string]KeyRequest

// Role is an enum type for user roles.

Role = string

// Status is an enum type.

Status = int

keyRequest struct{}
)
48 changes: 48 additions & 0 deletions cmd/schema-gen/_example/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,54 @@
}
]
},
{
"doc": "Role is an enum type for user roles.",
"types": [
{
"name": "Role",
"doc": "Role is an enum type for user roles.",
"type": "string",
"enums": [
{
"name": "Admin",
"value": "admin"
},
{
"name": "User",
"value": "user"
},
{
"name": "Guest",
"value": "guest"
}
]
}
]
},
{
"doc": "Status is an enum type.",
"types": [
{
"name": "Status",
"doc": "Status is an enum type.",
"type": "int",
"enums": [
{
"name": "Active",
"value": 0
},
{
"name": "Inactive",
"value": 1
},
{
"name": "Suspended",
"value": 2
}
]
}
]
},
{
"doc": "Type declaration doc, File is an alias of os.File.",
"types": [
Expand Down
67 changes: 65 additions & 2 deletions cmd/schema-gen/extract/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ func (p *objParser) GetDeclarations(options *ExtractOptions) (*PackageInfo, erro

for _, spec := range genDecl.Specs {
switch obj := spec.(type) {
case *ast.ValueSpec, *ast.ImportSpec:
case *ast.TypeSpec:
typeInfo, err := NewTypeSpecInfo(obj)
if err != nil {
Expand All @@ -247,14 +248,75 @@ func (p *objParser) GetDeclarations(options *ExtractOptions) (*PackageInfo, erro
p.parseStruct(typeInfo.Name, typeInfo.Name, typeInfo, options)

info.Types.Append(typeInfo)
default:
fmt.Fprintf(os.Stderr, "INFO: Unhandled AST %T\n", spec)
}
}

sort.Stable(info.Types)

if info.Valid() {
result.Declarations.Append(info)
}

var currentType string
var currentValue any = 0

for _, spec := range genDecl.Specs {
switch obj := spec.(type) {
case *ast.TypeSpec, *ast.ImportSpec:
case *ast.ValueSpec:
if ident, ok := obj.Type.(*ast.Ident); ok {
currentType = ident.Name
}

if currentType == "" {
break
}

typeMap := result.Declarations.TypeMap()
typeInfo, ok := typeMap[currentType]
if !ok || typeInfo == nil {
// fmt.Fprintf(os.Stderr, "INFO: Unknown type in TypeMap: looking for %q\n", currentType)
continue
}

for i, name := range obj.Names {
enumValue := &EnumInfo{
Name: name.Name,
Doc: TrimSpace(obj.Doc),
Value: currentValue,
}

if len(obj.Values) > i {
if basicLit, ok := obj.Values[i].(*ast.BasicLit); ok {
switch basicLit.Kind {
case token.INT:
var val int
fmt.Sscanf(basicLit.Value, "%d", &val)
currentValue = val
enumValue.Value = val
case token.STRING:
val := strings.Trim(basicLit.Value, "\"")
currentValue = val
enumValue.Value = val
}
}
}

// Increment only if currentValue is int.
// This doesn't handle `1 << enum` type declarations.
if v, ok := currentValue.(int); ok {
currentValue = v + 1
}

typeInfo.Enums = append(typeInfo.Enums, enumValue)
}
default:
// Type already logged in first loop.
}
}

sort.Stable(info.Types)

}
}

Expand Down Expand Up @@ -287,6 +349,7 @@ func NewTypeSpecInfo(from *ast.TypeSpec) (*TypeInfo, error) {
Name: getTypeDeclaration(from.Name),
Doc: TrimSpace(from.Doc),
Comment: TrimSpace(from.Comment),
Enums: []*EnumInfo{},
}

structObj, ok := from.Type.(*ast.StructType)
Expand Down

0 comments on commit 8ef9047

Please sign in to comment.