@@ -26,6 +26,7 @@ type ExpandOptions struct {
2626 SkipSchemas bool
2727 ContinueOnError bool
2828 AbsoluteCircularRef bool
29+ PathLoader func (string ) (json.RawMessage , error ) `json:"-"`
2930}
3031
3132// ResolveRefWithBase resolves a reference against a context root with preservation of base path
@@ -81,6 +82,7 @@ func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*
8182 if err != nil {
8283 return nil , err
8384 }
85+
8486 specBasePath := ""
8587 if opts != nil && opts .RelativeBase != "" {
8688 specBasePath , _ = absPath (opts .RelativeBase )
@@ -126,10 +128,12 @@ func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error
126128 if err != nil {
127129 return nil , err
128130 }
131+
129132 basePath := ""
130133 if opts .RelativeBase != "" {
131134 basePath = opts .RelativeBase
132135 }
136+
133137 result := new (Items )
134138 if err := resolver .Resolve (& ref , result , basePath ); err != nil {
135139 return nil , err
@@ -143,10 +147,12 @@ func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem,
143147 if err != nil {
144148 return nil , err
145149 }
150+
146151 basePath := ""
147152 if opts .RelativeBase != "" {
148153 basePath = opts .RelativeBase
149154 }
155+
150156 result := new (PathItem )
151157 if err := resolver .Resolve (& ref , result , basePath ); err != nil {
152158 return nil , err
@@ -157,7 +163,7 @@ func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem,
157163// ExpandSpec expands the references in a swagger spec
158164func ExpandSpec (spec * Swagger , options * ExpandOptions ) error {
159165 resolver , err := defaultSchemaLoader (spec , options , nil , nil )
160- // Just in case this ever returns an error.
166+ // just in case this ever returns an error
161167 if resolver .shouldStopOnError (err ) {
162168 return err
163169 }
@@ -212,28 +218,31 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
212218
213219const rootBase = ".root"
214220
215- // baseForRoot loads in the cache the root document and produces a fake "root" base path entry
221+ // baseForRoot loads in the cache the root document and produces a fake ". root" base path entry
216222// for further $ref resolution
223+ //
224+ // Setting the cache is optional and this parameter may safely be left to nil.
217225func baseForRoot (root interface {}, cache ResolutionCache ) string {
226+ if root == nil {
227+ return ""
228+ }
229+
218230 // cache the root document to resolve $ref's
219- if root != nil {
220- base , _ := absPath (rootBase )
221- normalizedBase := normalizeAbsPath (base )
222- debugLog ("setting root doc in cache at: %s" , normalizedBase )
223- if cache == nil {
224- onceCache .Do (initResolutionCache )
225- cache = resCache
226- }
227- cache .Set (normalizedBase , root )
228- return normalizedBase
229- }
230- return ""
231+ base , _ := absPath (rootBase )
232+ normalizedBase := normalizeAbsPath (base )
233+ debugLog ("setting root doc in cache at: %s" , normalizedBase )
234+ cache .Set (normalizedBase , root )
235+
236+ return normalizedBase
231237}
232238
233239// ExpandSchema expands the refs in the schema object with reference to the root object
234240// go-openapi/validate uses this function
235241// notice that it is impossible to reference a json schema in a different file other than root
242+ //
243+ // Setting the cache is optional and this parameter may safely be left to nil.
236244func ExpandSchema (schema * Schema , root interface {}, cache ResolutionCache ) error {
245+ cache = cacheOrDefault (cache )
237246 opts := & ExpandOptions {
238247 // when a root is specified, cache the root as an in-memory document for $ref retrieval
239248 RelativeBase : baseForRoot (root , cache ),
@@ -245,12 +254,16 @@ func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error
245254 return ExpandSchemaWithBasePath (schema , cache , opts )
246255}
247256
248- // ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options
257+ // ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options.
258+ //
259+ // Setting the cache is optional and this parameter may safely be left to nil.
249260func ExpandSchemaWithBasePath (schema * Schema , cache ResolutionCache , opts * ExpandOptions ) error {
250261 if schema == nil {
251262 return nil
252263 }
253264
265+ cache = cacheOrDefault (cache )
266+
254267 var basePath string
255268 if opts .RelativeBase != "" {
256269 basePath , _ = absPath (opts .RelativeBase )
@@ -314,7 +327,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
314327 basePath = normalizePaths (refPath , basePath )
315328
316329 // store found IDs for possible future reuse in $ref
317- resCache .Set (basePath , target )
330+ resolver . cache .Set (basePath , target )
318331 }
319332
320333 var t * Schema
@@ -529,15 +542,18 @@ func expandOperation(op *Operation, resolver *schemaLoader, basePath string) err
529542}
530543
531544// ExpandResponseWithRoot expands a response based on a root document, not a fetchable document
545+ //
546+ // Setting the cache is optional and this parameter may safely be left to nil.
532547func ExpandResponseWithRoot (response * Response , root interface {}, cache ResolutionCache ) error {
548+ cache = cacheOrDefault (cache )
533549 opts := & ExpandOptions {
534550 RelativeBase : baseForRoot (root , cache ),
535551 SkipSchemas : false ,
536552 ContinueOnError : false ,
537553 // when no base path is specified, remaining $ref (circular) are rendered with an absolute path
538554 AbsoluteCircularRef : false ,
539555 }
540- resolver , err := defaultSchemaLoader (root , opts , nil , nil )
556+ resolver , err := defaultSchemaLoader (root , opts , cache , nil )
541557 if err != nil {
542558 return err
543559 }
@@ -566,14 +582,15 @@ func ExpandResponse(response *Response, basePath string) error {
566582
567583// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document
568584func ExpandParameterWithRoot (parameter * Parameter , root interface {}, cache ResolutionCache ) error {
585+ cache = cacheOrDefault (cache )
569586 opts := & ExpandOptions {
570587 RelativeBase : baseForRoot (root , cache ),
571588 SkipSchemas : false ,
572589 ContinueOnError : false ,
573590 // when no base path is specified, remaining $ref (circular) are rendered with an absolute path
574591 AbsoluteCircularRef : false ,
575592 }
576- resolver , err := defaultSchemaLoader (root , opts , nil , nil )
593+ resolver , err := defaultSchemaLoader (root , opts , cache , nil )
577594 if err != nil {
578595 return err
579596 }
0 commit comments