@@ -102,16 +102,50 @@ func (c *schemaContext) ForInfo(info *markers.TypeInfo) *schemaContext {
102102// requestSchema asks for the schema for a type in the package with the
103103// given import path.
104104func (c * schemaContext ) requestSchema (pkgPath , typeName string ) {
105+ c .requestSchemaWithPkg (pkgPath , typeName , nil )
106+ }
107+
108+ func (c * schemaContext ) requestSchemaWithPkg (pkgPath , typeName string , typesPkg * types.Package ) {
105109 pkg := c .pkg
106110 if pkgPath != "" {
107111 pkg = c .pkg .Imports ()[pkgPath ]
112+ if pkg == nil && typesPkg != nil {
113+ pkg = c .findPackageRecursive (typesPkg .Path ())
114+ }
115+ if pkg == nil {
116+ c .pkg .AddError (fmt .Errorf ("unable to find package %q for type %s (not in direct imports)" , pkgPath , typeName ))
117+ return
118+ }
108119 }
109120 c .schemaRequester .NeedSchemaFor (TypeIdent {
110121 Package : pkg ,
111122 Name : typeName ,
112123 })
113124}
114125
126+ func (c * schemaContext ) findPackageRecursive (pkgPath string ) * loader.Package {
127+ visited := make (map [* loader.Package ]bool )
128+ queue := []* loader.Package {c .pkg }
129+
130+ for len (queue ) > 0 {
131+ current := queue [0 ]
132+ queue = queue [1 :]
133+
134+ if visited [current ] {
135+ continue
136+ }
137+ visited [current ] = true
138+
139+ for importPath , importPkg := range current .Imports () {
140+ if loader .NonVendorPath (importPath ) == loader .NonVendorPath (pkgPath ) {
141+ return importPkg
142+ }
143+ queue = append (queue , importPkg )
144+ }
145+ }
146+ return nil
147+ }
148+
115149// infoToSchema creates a schema for the type in the given set of type information.
116150func infoToSchema (ctx * schemaContext ) * apiextensionsv1.JSONSchemaProps {
117151 if obj := ctx .pkg .Types .Scope ().Lookup (ctx .info .Name ); obj != nil {
@@ -310,7 +344,7 @@ func localNamedToSchema(ctx *schemaContext, ident *ast.Ident) *apiextensionsv1.J
310344 if pkg == ctx .pkg .Types {
311345 pkgPath = ""
312346 }
313- ctx .requestSchema (pkgPath , typeNameInfo .Name ())
347+ ctx .requestSchemaWithPkg (pkgPath , typeNameInfo .Name (), pkg )
314348 link := TypeRefLink (pkgPath , typeNameInfo .Name ())
315349
316350 // In cases where we have a named type, apply the type and format from the named schema
@@ -352,8 +386,9 @@ func namedToSchema(ctx *schemaContext, named *ast.SelectorExpr) *apiextensionsv1
352386 }
353387 typeInfo := typeInfoRaw .(interface { Obj () * types.TypeName })
354388 typeNameInfo := typeInfo .Obj ()
355- nonVendorPath := loader .NonVendorPath (typeNameInfo .Pkg ().Path ())
356- ctx .requestSchema (nonVendorPath , typeNameInfo .Name ())
389+ typesPkg := typeNameInfo .Pkg ()
390+ nonVendorPath := loader .NonVendorPath (typesPkg .Path ())
391+ ctx .requestSchemaWithPkg (nonVendorPath , typeNameInfo .Name (), typesPkg )
357392 link := TypeRefLink (nonVendorPath , typeNameInfo .Name ())
358393 return & apiextensionsv1.JSONSchemaProps {
359394 Ref : & link ,
0 commit comments