@@ -134,6 +134,7 @@ type loader struct {
134
134
nodes map [string ]nodectx
135
135
dynamicRefs []refctx
136
136
refs []refctx
137
+ dialect * uri.URI
137
138
}
138
139
139
140
func (l * loader ) load (ctx context.Context , location uri.URI , ek Kind , openapi * semver.Version , dialect * uri.URI ) (Node , error ) {
@@ -144,6 +145,10 @@ func (l *loader) load(ctx context.Context, location uri.URI, ek Kind, openapi *s
144
145
if err != nil {
145
146
return nil , err
146
147
}
148
+ if openapi == nil && l .doc != nil {
149
+ openapi = l .doc .OpenAPI
150
+ }
151
+
147
152
switch k {
148
153
case KindDocument :
149
154
return l .loadDocument (ctx , data , location )
@@ -196,6 +201,8 @@ func (l *loader) loadDocument(ctx context.Context, data []byte, u uri.URI) (*Doc
196
201
if err != nil {
197
202
return nil , NewError (fmt .Errorf ("failed to determine OpenAPI schema dialect: %w" , err ), u )
198
203
}
204
+ l .dialect = sd
205
+
199
206
if sd == nil {
200
207
return nil , NewError (fmt .Errorf ("failed to determine OpenAPI schema dialect" ), u )
201
208
}
@@ -229,7 +236,7 @@ func (l *loader) loadDocument(ctx context.Context, data []byte, u uri.URI) (*Doc
229
236
dc .anchors = anchors
230
237
231
238
l .nodes [u .String ()] = dc
232
- if err = l .init (& dc , & dc , doc .nodes (), * v , * sd ); err != nil {
239
+ if err = l .traverse (& dc , & dc , doc .nodes (), * v , * sd ); err != nil {
233
240
return nil , err
234
241
}
235
242
// we only traverse the references after the top-level document is fully
@@ -258,7 +265,7 @@ func (l *loader) loadDocument(ctx context.Context, data []byte, u uri.URI) (*Doc
258
265
r .root .resolvedRefs = append (r .root .resolvedRefs , r )
259
266
}
260
267
for _ , n := range nodes {
261
- if err = l .init (& dc , n .root , n .nodes (), n .openapi , n .jsonschema ); err != nil {
268
+ if err = l .traverse (& dc , n .root , n .nodes (), n .openapi , n .jsonschema ); err != nil {
262
269
return nil , err
263
270
}
264
271
}
@@ -315,17 +322,25 @@ func (l *loader) resolveRemoteRef(ctx context.Context, r refctx) (*nodectx, erro
315
322
return nil , NewError (fmt .Errorf ("openapi: ref URI not found: %s" , u ), r .AbsoluteLocation ())
316
323
}
317
324
} else {
318
- // we need to load the root resource first we need to load the resource
319
- // we need to check to see if there is a reference pointing to the root first
320
- // so we know what the expected type is
321
325
rus := rooturi .String ()
322
- for _ , x := range l .refs {
323
- if x .URI ().String () == rus {
324
- // found it. we load that one first.
325
- if _ , err := l .load (ctx , rooturi , x .RefKind (), nil , nil ); err != nil {
326
- return nil , err
326
+
327
+ // if this is ref points to the root of a file, we need to load it
328
+ if u .String () == rus {
329
+ // the ref is the root so we need to load it
330
+ if _ , err := l .load (ctx , * u , r .RefKind (), nil , nil ); err != nil {
331
+ return nil , err
332
+ }
333
+ } else {
334
+ // otherwise we need to check to see if there is a ref pointing to
335
+ // the root so we know what the expected kind is
336
+ for _ , x := range l .refs {
337
+ if x .URI ().String () == rus {
338
+ // found it. we load that one first.
339
+ if _ , err := l .load (ctx , rooturi , x .RefKind (), nil , nil ); err != nil {
340
+ return nil , err
341
+ }
342
+ break
327
343
}
328
- break
329
344
}
330
345
}
331
346
@@ -504,7 +519,7 @@ func (l *loader) getDocumentSchemaDialect(doc *Document) (*uri.URI, error) {
504
519
return nil , fmt .Errorf ("failed to determine OpenAPI schema dialect" )
505
520
}
506
521
507
- func (l * loader ) init (node * nodectx , root * nodectx , nodes []node , openapi semver.Version , jsonschema uri.URI ) error {
522
+ func (l * loader ) traverse (node * nodectx , root * nodectx , nodes []node , openapi semver.Version , jsonschema uri.URI ) error {
508
523
for _ , n := range nodes {
509
524
nc , err := newNodeCtx (n , root , & openapi , & jsonschema )
510
525
if err != nil {
@@ -518,9 +533,9 @@ func (l *loader) init(node *nodectx, root *nodectx, nodes []node, openapi semver
518
533
if ! r .IsResolved () {
519
534
l .refs = append (l .refs , refctx {root : root , in : node , ref : r , openapi : nc .openapi , jsonschema : nc .jsonschema })
520
535
}
521
- return nil
536
+ continue
522
537
}
523
- if err := l .init (& nc , root , n .nodes (), nc .openapi , nc .jsonschema ); err != nil {
538
+ if err := l .traverse (& nc , root , n .nodes (), nc .openapi , nc .jsonschema ); err != nil {
524
539
return err
525
540
}
526
541
}
@@ -539,6 +554,7 @@ func (l *loader) loadSchema(ctx context.Context, data []byte, u uri.URI, v semve
539
554
s .setLocation (loc )
540
555
nc := nodectx {node : & s , openapi : v , jsonschema : u }
541
556
nc .root = & nc
557
+
542
558
a , err := s .Anchors ()
543
559
if err != nil {
544
560
return nil , fmt .Errorf ("failed to load anchors: %w" , err )
@@ -555,6 +571,15 @@ func (l *loader) loadSchema(ctx context.Context, data []byte, u uri.URI, v semve
555
571
} else {
556
572
l .nodes [u .String ()] = nc
557
573
}
574
+
575
+ d := s .Schema
576
+ if d == nil {
577
+ d = l .dialect
578
+ }
579
+ if err = l .traverse (& nc , & nc , s .nodes (), * l .doc .OpenAPI , * d ); err != nil {
580
+ return nil , err
581
+ }
582
+
558
583
return & s , nil
559
584
}
560
585
0 commit comments