Skip to content

Commit efec490

Browse files
committed
Fix external reference propagation
1 parent 9155677 commit efec490

2 files changed

Lines changed: 65 additions & 4 deletions

File tree

internal/test/issues/issue-1202/pkg1/pkg1.gen.go

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/codegen/codegen.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"io/fs"
2525
"net/http"
2626
"os"
27+
"reflect"
2728
"runtime/debug"
2829
"sort"
2930
"strings"
@@ -109,6 +110,7 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) {
109110
globalState.importMapping = constructImportMapping(opts.ImportMapping)
110111

111112
filterOperationsByTag(spec, opts)
113+
fixExternalRefPropagation(spec)
112114
if !opts.OutputOptions.SkipPrune {
113115
pruneUnusedComponents(spec)
114116
}
@@ -1160,3 +1162,58 @@ func GetParametersImports(params map[string]*openapi3.ParameterRef) (map[string]
11601162
func SetGlobalStateSpec(spec *openapi3.T) {
11611163
globalState.spec = spec
11621164
}
1165+
1166+
func fixExternalRefPropagation(doc *openapi3.T) {
1167+
visited := make(map[interface{}]struct{})
1168+
fixExternalRefPropagationCore(reflect.ValueOf(doc), visited, "")
1169+
}
1170+
1171+
func fixExternalRefPropagationCore(vObj reflect.Value, visited map[interface{}]struct{}, curUri string) {
1172+
if !vObj.IsValid() {
1173+
return
1174+
}
1175+
1176+
switch vObj.Kind() {
1177+
case reflect.Pointer:
1178+
if !vObj.IsNil() && vObj.Elem().Kind() == reflect.Struct && vObj.CanInterface() {
1179+
iObj := vObj.Interface()
1180+
if _, exist := visited[iObj]; exist {
1181+
return
1182+
}
1183+
visited[iObj] = struct{}{}
1184+
}
1185+
fallthrough
1186+
case reflect.Interface:
1187+
fixExternalRefPropagationCore(vObj.Elem(), visited, curUri)
1188+
case reflect.Map:
1189+
iter := vObj.MapRange()
1190+
for iter.Next() {
1191+
fixExternalRefPropagationCore(iter.Value(), visited, curUri)
1192+
}
1193+
case reflect.Slice:
1194+
for i := 0; i < vObj.Len(); i++ {
1195+
fixExternalRefPropagationCore(vObj.Index(i), visited, curUri)
1196+
}
1197+
case reflect.Struct:
1198+
vRef := vObj.FieldByName("Ref")
1199+
vValue := vObj.FieldByName("Value")
1200+
if vRef.IsValid() && (vValue.IsValid() || vObj.Type() == reflect.TypeOf(openapi3.PathItem{})) {
1201+
ref := vRef.String()
1202+
if ref != "" {
1203+
split := strings.SplitN(ref, "#", 2)
1204+
if len(split) == 2 {
1205+
if split[0] != "" {
1206+
curUri = split[0]
1207+
} else {
1208+
vRef.SetString(curUri + "#" + split[1])
1209+
}
1210+
} else {
1211+
curUri = split[0]
1212+
}
1213+
}
1214+
}
1215+
for i := 0; i < vObj.NumField(); i++ {
1216+
fixExternalRefPropagationCore(vObj.Field(i), visited, curUri)
1217+
}
1218+
}
1219+
}

0 commit comments

Comments
 (0)