Skip to content

Commit 345dc3f

Browse files
committed
support x-go-type and x-go-type-import with ref
1 parent 9feb303 commit 345dc3f

7 files changed

Lines changed: 89 additions & 13 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# yaml-language-server: $schema=../../../../configuration-schema.json
2+
package: xgotype
3+
generate:
4+
models: true
5+
output: issue.gen.go
6+
output-options:
7+
skip-prune: true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package xgotype
2+
3+
//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml

internal/test/extensions/x-go-type/issue.gen.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
components:
2+
schemas:
3+
SomeInteger:
4+
type: integer
5+
x-go-type-import:
6+
name: rate
7+
path: golang.org/x/time/rate
8+
SomeObject:
9+
type: object
10+
required:
11+
- int_as_string
12+
- int_as_big_int
13+
properties:
14+
int_as_string:
15+
$ref: '#/components/schemas/SomeInteger'
16+
x-go-type: string
17+
int_as_rate_limit:
18+
$ref: '#/components/schemas/SomeInteger'
19+
x-go-type: rate.Limit
20+
int_as_uuid:
21+
$ref: '#/components/schemas/SomeInteger'
22+
x-go-type: googleuuid.UUID
23+
x-go-type-import:
24+
path: github.com/google/uuid
25+
name: googleuuid

pkg/codegen/codegen.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,15 +1092,18 @@ func GetTypeDefinitionsImports(swagger *openapi3.T, excludeSchemas []string) (ma
10921092
func GoSchemaImports(schemas ...*openapi3.SchemaRef) (map[string]goImport, error) {
10931093
res := map[string]goImport{}
10941094
for _, sref := range schemas {
1095-
if sref == nil || sref.Value == nil || IsGoTypeReference(sref.Ref) {
1095+
if sref == nil {
10961096
return nil, nil
10971097
}
1098+
10981099
if gi, err := ParseGoImportExtension(sref); err != nil {
10991100
return nil, err
1100-
} else {
1101-
if gi != nil {
1102-
res[gi.String()] = *gi
1103-
}
1101+
} else if gi != nil {
1102+
res[gi.String()] = *gi
1103+
}
1104+
1105+
if sref.Value == nil || IsGoTypeReference(sref.Ref) {
1106+
continue
11041107
}
11051108
schemaVal := sref.Value
11061109

pkg/codegen/schema.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,24 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
257257
// If Ref is set on the SchemaRef, it means that this type is actually a reference to
258258
// another type. We're not de-referencing, so simply use the referenced type.
259259
if IsGoTypeReference(sref.Ref) {
260-
// Convert the reference path to Go type
261-
refType, err := RefPathToGoType(sref.Ref)
262-
if err != nil {
263-
return Schema{}, fmt.Errorf("error turning reference (%s) into a Go type: %s",
264-
sref.Ref, err)
260+
var refType string
261+
262+
// check if there is an x-go-type extension next to the $ref and use that over the overrided type.
263+
if extension, ok := sref.Extensions[extPropGoType]; ok {
264+
var ok bool
265+
refType, ok = extension.(string)
266+
if !ok {
267+
return Schema{}, fmt.Errorf("error turning '%s: %v' into string",
268+
extPropGoType, extension)
269+
}
270+
} else {
271+
// Convert the reference path to Go type
272+
var err error
273+
refType, err = RefPathToGoType(sref.Ref)
274+
if err != nil {
275+
return Schema{}, fmt.Errorf("error turning reference (%s) into a Go type: %s",
276+
sref.Ref, err)
277+
}
265278
}
266279
return Schema{
267280
GoType: refType,

pkg/codegen/utils.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,12 +1039,18 @@ func findSchemaNameByRefPath(refPath string, spec *openapi3.T) (string, error) {
10391039
}
10401040

10411041
func ParseGoImportExtension(v *openapi3.SchemaRef) (*goImport, error) {
1042-
if v.Value.Extensions[extPropGoImport] == nil || v.Value.Extensions[extPropGoType] == nil {
1042+
var goTypeImportExt any
1043+
1044+
// check extensions next to the $ref before checking the schema itself
1045+
// values next to $ref will be used before those in the actual schema
1046+
if v.Extensions[extPropGoImport] != nil {
1047+
goTypeImportExt = v.Extensions[extPropGoImport]
1048+
} else if v.Value.Extensions[extPropGoImport] != nil {
1049+
goTypeImportExt = v.Value.Extensions[extPropGoImport]
1050+
} else {
10431051
return nil, nil
10441052
}
10451053

1046-
goTypeImportExt := v.Value.Extensions[extPropGoImport]
1047-
10481054
importI, ok := goTypeImportExt.(map[string]interface{})
10491055
if !ok {
10501056
return nil, fmt.Errorf("failed to convert type: %T", goTypeImportExt)

0 commit comments

Comments
 (0)