diff --git a/datamodel/low/base/schema.go b/datamodel/low/base/schema.go index 536be2b9..340d2bb4 100644 --- a/datamodel/low/base/schema.go +++ b/datamodel/low/base/schema.go @@ -1015,23 +1015,25 @@ func buildPropertyMap(ctx context.Context, root *yaml.Node, idx *index.SpecIndex } foundCtx := ctx + foundIdx := idx // check our prop isn't reference refString := "" var refNode *yaml.Node if h, _, l := utils.IsNodeRefValue(prop); h { - ref, _, _, fctx := low.LocateRefNodeWithContext(ctx, prop, idx) + ref, fIdx, _, fctx := low.LocateRefNodeWithContext(ctx, prop, idx) if ref != nil { refNode = prop prop = ref refString = l foundCtx = fctx + foundIdx = fIdx } else { return nil, fmt.Errorf("schema properties build failed: cannot find reference %s, line %d, col %d", prop.Content[1].Value, prop.Content[1].Line, prop.Content[1].Column) } } - sp := &SchemaProxy{ctx: foundCtx, kn: currentProp, vn: prop, idx: idx} + sp := &SchemaProxy{ctx: foundCtx, kn: currentProp, vn: prop, idx: foundIdx} sp.SetReference(refString, refNode) propertyMap.Set(low.KeyReference[string]{ @@ -1200,14 +1202,16 @@ func ExtractSchema(ctx context.Context, root *yaml.Node, idx *index.SpecIndex) ( refLocation := "" var refNode *yaml.Node + foundIndex := idx + foundCtx := ctx if rf, rl, _ := utils.IsNodeRefValue(root); rf { // locate reference in index. ref, fIdx, _, nCtx := low.LocateRefNodeWithContext(ctx, root, idx) if ref != nil { schNode = ref schLabel = rl - ctx = nCtx - idx = fIdx + foundCtx = nCtx + foundIndex = fIdx } else { v := root.Content[1].Value if root.Content[1].Value == "" { @@ -1227,18 +1231,19 @@ func ExtractSchema(ctx context.Context, root *yaml.Node, idx *index.SpecIndex) ( } if idx.GetSpecAbsolutePath() != specPath && (!strings.HasPrefix(refLocation, "http") && !strings.HasPrefix(idx.GetSpecAbsolutePath(), "http")) { - ctx = context.WithValue(ctx, index.CurrentPathKey, idx.GetSpecAbsolutePath()) + if !strings.HasSuffix(idx.GetSpecAbsolutePath(), "root.yaml") { + ctx = context.WithValue(ctx, index.CurrentPathKey, idx.GetSpecAbsolutePath()) + } } - ref, _, _, nCtx := low.LocateRefNodeWithContext(ctx, schNode, idx) + ref, fIdx, _, nCtx := low.LocateRefNodeWithContext(ctx, schNode, idx) if ref != nil { refNode = schNode schNode = ref - //if foundIdx != nil { - // TODO: check on this - // idx = foundIdx - //} - ctx = nCtx + if fIdx != nil { + foundIndex = fIdx + } + foundCtx = nCtx } else { v := schNode.Content[1].Value if schNode.Content[1].Value == "" { @@ -1253,7 +1258,7 @@ func ExtractSchema(ctx context.Context, root *yaml.Node, idx *index.SpecIndex) ( if schNode != nil { // check if schema has already been built. - schema := &SchemaProxy{kn: schLabel, vn: schNode, idx: idx, ctx: ctx} + schema := &SchemaProxy{kn: schLabel, vn: schNode, idx: foundIndex, ctx: foundCtx} schema.SetReference(refLocation, refNode) n := &low.NodeReference[*SchemaProxy]{ diff --git a/index/extract_refs.go b/index/extract_refs.go index 8cbffa91..3eb516ee 100644 --- a/index/extract_refs.go +++ b/index/extract_refs.go @@ -6,14 +6,13 @@ package index import ( "errors" "fmt" + "github.com/pb33f/libopenapi/utils" + "golang.org/x/exp/slices" + "gopkg.in/yaml.v3" "net/url" "os" "path/filepath" "strings" - - "github.com/pb33f/libopenapi/utils" - "golang.org/x/exp/slices" - "gopkg.in/yaml.v3" ) // ExtractRefs will return a deduplicated slice of references for every unique ref found in the document. @@ -606,38 +605,54 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc } locate := func(ref *Reference, refIndex int, sequence []*ReferenceMapped) { - located := index.FindComponent(ref.FullDefinition) - if located != nil { - - // have we already mapped this? - index.refLock.Lock() - if index.allMappedRefs[ref.FullDefinition] == nil { - found = append(found, located) - index.allMappedRefs[located.FullDefinition] = located - } + index.refLock.Lock() + if index.allMappedRefs[ref.FullDefinition] != nil { rm := &ReferenceMapped{ OriginalReference: ref, - Reference: located, - Definition: located.Definition, - FullDefinition: located.FullDefinition, + Reference: index.allMappedRefs[ref.FullDefinition], + Definition: index.allMappedRefs[ref.FullDefinition].Definition, + FullDefinition: index.allMappedRefs[ref.FullDefinition].FullDefinition, } sequence[refIndex] = rm + if !index.config.ExtractRefsSequentially { + c <- true + } index.refLock.Unlock() - } else { + index.refLock.Unlock() + located := index.FindComponent(ref.FullDefinition) + if located != nil { + + // have we already mapped this? + index.refLock.Lock() + if index.allMappedRefs[ref.FullDefinition] == nil { + found = append(found, located) + index.allMappedRefs[located.FullDefinition] = located + } + rm := &ReferenceMapped{ + OriginalReference: ref, + Reference: located, + Definition: located.Definition, + FullDefinition: located.FullDefinition, + } + sequence[refIndex] = rm + index.refLock.Unlock() - _, path := utils.ConvertComponentIdIntoFriendlyPathSearch(ref.Definition) - indexError := &IndexingError{ - Err: fmt.Errorf("component '%s' does not exist in the specification", ref.Definition), - Node: ref.Node, - Path: path, + } else { + + _, path := utils.ConvertComponentIdIntoFriendlyPathSearch(ref.Definition) + indexError := &IndexingError{ + Err: fmt.Errorf("component '%s' does not exist in the specification", ref.Definition), + Node: ref.Node, + Path: path, + } + index.errorLock.Lock() + index.refErrors = append(index.refErrors, indexError) + index.errorLock.Unlock() + } + if !index.config.ExtractRefsSequentially { + c <- true } - index.errorLock.Lock() - index.refErrors = append(index.refErrors, indexError) - index.errorLock.Unlock() - } - if !index.config.ExtractRefsSequentially { - c <- true } } @@ -653,7 +668,6 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc } else { locate(refsToCheck[r], r, mappedRefsInSequence) // run synchronously } - } if !index.config.ExtractRefsSequentially { diff --git a/index/search_index.go b/index/search_index.go index 524f97c7..607acee6 100644 --- a/index/search_index.go +++ b/index/search_index.go @@ -152,7 +152,7 @@ func (index *SpecIndex) SearchIndexForReferenceByReferenceWithContext(ctx contex Index: rFile.GetIndex(), Node: node.Content[0], ParentNode: node, - }, rFile.GetIndex(), ctx + }, rFile.GetIndex(), context.WithValue(ctx, CurrentPathKey, rFile.GetFullPath()) } else { return nil, index, ctx }