mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-08 20:47:43 +00:00
We-worked model to remove resolver.
lookups are performed inline now. keeps things simpler, however it has a performance knock, so it's time to refine async building were possible.
This commit is contained in:
@@ -2,6 +2,7 @@ package v3
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"strconv"
|
||||
@@ -9,6 +10,13 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var KnownSchemas map[string]low.NodeReference[*Schema]
|
||||
|
||||
func init() {
|
||||
KnownSchemas = make(map[string]low.NodeReference[*Schema])
|
||||
|
||||
}
|
||||
|
||||
func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]low.ValueReference[T]) *low.ValueReference[T] {
|
||||
for n, o := range collection {
|
||||
if n.Value == item {
|
||||
@@ -18,15 +26,34 @@ func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]l
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExtractSchema(root *yaml.Node) (*low.NodeReference[*Schema], error) {
|
||||
_, schLabel, schNode := utils.FindKeyNodeFull(SchemaLabel, root.Content)
|
||||
func ExtractSchema(root *yaml.Node, idx *index.SpecIndex) (*low.NodeReference[*Schema], error) {
|
||||
var schLabel, schNode *yaml.Node
|
||||
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||
// locate reference in index.
|
||||
ref := LocateRefNode(root, idx)
|
||||
if ref != nil {
|
||||
schNode = ref
|
||||
schLabel = rl
|
||||
}
|
||||
} else {
|
||||
_, schLabel, schNode = utils.FindKeyNodeFull(SchemaLabel, root.Content)
|
||||
if schNode != nil {
|
||||
if h, _, _ := utils.IsNodeRefValue(schNode); h {
|
||||
ref := LocateRefNode(schNode, idx)
|
||||
if ref != nil {
|
||||
schNode = ref
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if schNode != nil {
|
||||
var schema Schema
|
||||
err := BuildModel(schNode, &schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = schema.Build(schNode)
|
||||
err = schema.Build(schNode, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -37,21 +64,49 @@ func ExtractSchema(root *yaml.Node) (*low.NodeReference[*Schema], error) {
|
||||
|
||||
var mapLock sync.Mutex
|
||||
|
||||
func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node) (T, error) {
|
||||
func LocateRefNode(root *yaml.Node, idx *index.SpecIndex) *yaml.Node {
|
||||
if rf, _, rv := utils.IsNodeRefValue(root); rf {
|
||||
found := idx.GetMappedReferences()
|
||||
if found != nil && found[rv] != nil {
|
||||
return found[rv].Node
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (T, error) {
|
||||
var n T = new(N)
|
||||
err := BuildModel(root, n)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
err = n.Build(root)
|
||||
err = n.Build(root, idx)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node) (low.NodeReference[T], error) {
|
||||
_, ln, vn := utils.FindKeyNodeFull(label, root.Content)
|
||||
func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (low.NodeReference[T], error) {
|
||||
var ln, vn *yaml.Node
|
||||
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||
// locate reference in index.
|
||||
ref := LocateRefNode(root, idx)
|
||||
if ref != nil {
|
||||
vn = ref
|
||||
ln = rl
|
||||
}
|
||||
} else {
|
||||
_, ln, vn = utils.FindKeyNodeFull(label, root.Content)
|
||||
if vn != nil {
|
||||
if h, _, _ := utils.IsNodeRefValue(vn); h {
|
||||
ref := LocateRefNode(vn, idx)
|
||||
if ref != nil {
|
||||
vn = ref
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var n T = new(N)
|
||||
err := BuildModel(vn, n)
|
||||
if err != nil {
|
||||
@@ -60,7 +115,7 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node) (lo
|
||||
if ln == nil {
|
||||
return low.NodeReference[T]{}, nil
|
||||
}
|
||||
err = n.Build(vn)
|
||||
err = n.Build(vn, idx)
|
||||
if err != nil {
|
||||
return low.NodeReference[T]{}, err
|
||||
}
|
||||
@@ -71,17 +126,41 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node) (lo
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node) ([]low.ValueReference[T], *yaml.Node, *yaml.Node, error) {
|
||||
_, ln, vn := utils.FindKeyNodeFull(label, root.Content)
|
||||
func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) ([]low.ValueReference[T], *yaml.Node, *yaml.Node, error) {
|
||||
var ln, vn *yaml.Node
|
||||
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||
// locate reference in index.
|
||||
ref := LocateRefNode(root, idx)
|
||||
if ref != nil {
|
||||
vn = ref
|
||||
ln = rl
|
||||
}
|
||||
} else {
|
||||
_, ln, vn = utils.FindKeyNodeFull(label, root.Content)
|
||||
if vn != nil {
|
||||
if h, _, _ := utils.IsNodeRefValue(vn); h {
|
||||
ref := LocateRefNode(vn, idx)
|
||||
if ref != nil {
|
||||
vn = ref
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var items []low.ValueReference[T]
|
||||
if vn != nil && ln != nil {
|
||||
for _, node := range vn.Content {
|
||||
if rf, _, _ := utils.IsNodeRefValue(node); rf {
|
||||
ref := LocateRefNode(node, idx)
|
||||
if ref != nil {
|
||||
node = ref
|
||||
}
|
||||
}
|
||||
var n T = new(N)
|
||||
err := BuildModel(node, n)
|
||||
if err != nil {
|
||||
return []low.ValueReference[T]{}, ln, vn, err
|
||||
}
|
||||
berr := n.Build(node)
|
||||
berr := n.Build(node, idx)
|
||||
if berr != nil {
|
||||
return nil, ln, vn, berr
|
||||
}
|
||||
@@ -94,7 +173,7 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node) ([]l
|
||||
return items, ln, vn, nil
|
||||
}
|
||||
|
||||
func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node) (map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
||||
func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
||||
if utils.IsNodeMap(root) {
|
||||
var currentKey *yaml.Node
|
||||
@@ -108,7 +187,7 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node) (map[lo
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
berr := n.Build(node)
|
||||
berr := n.Build(node, idx)
|
||||
if berr != nil {
|
||||
return nil, berr
|
||||
}
|
||||
@@ -124,8 +203,26 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node) (map[lo
|
||||
return valueMap, nil
|
||||
}
|
||||
|
||||
func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[low.KeyReference[string]]low.ValueReference[PT], *yaml.Node, *yaml.Node, error) {
|
||||
_, labelNode, valueNode := utils.FindKeyNodeFull(label, root.Content)
|
||||
func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], *yaml.Node, *yaml.Node, error) {
|
||||
var labelNode, valueNode *yaml.Node
|
||||
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||
// locate reference in index.
|
||||
ref := LocateRefNode(root, idx)
|
||||
if ref != nil {
|
||||
valueNode = ref
|
||||
labelNode = rl
|
||||
}
|
||||
} else {
|
||||
_, labelNode, valueNode = utils.FindKeyNodeFull(label, root.Content)
|
||||
if valueNode != nil {
|
||||
if h, _, _ := utils.IsNodeRefValue(valueNode); h {
|
||||
ref := LocateRefNode(valueNode, idx)
|
||||
if ref != nil {
|
||||
valueNode = ref
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if valueNode != nil {
|
||||
var currentLabelNode *yaml.Node
|
||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
||||
@@ -134,6 +231,15 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (
|
||||
currentLabelNode = en
|
||||
continue
|
||||
}
|
||||
|
||||
// check our valueNode isn't a reference still.
|
||||
if h, _, _ := utils.IsNodeRefValue(en); h {
|
||||
ref := LocateRefNode(en, idx)
|
||||
if ref != nil {
|
||||
en = ref
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(strings.ToLower(currentLabelNode.Value), "x-") {
|
||||
continue // yo, don't pay any attention to extensions, not here anyway.
|
||||
}
|
||||
@@ -142,7 +248,7 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (
|
||||
if err != nil {
|
||||
return nil, labelNode, valueNode, err
|
||||
}
|
||||
berr := n.Build(en)
|
||||
berr := n.Build(en, idx)
|
||||
if berr != nil {
|
||||
return nil, labelNode, valueNode, berr
|
||||
}
|
||||
@@ -159,8 +265,19 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node) (
|
||||
return nil, labelNode, valueNode, nil
|
||||
}
|
||||
|
||||
func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
||||
_, labelNode, valueNode := utils.FindKeyNodeFull(label, root.Content)
|
||||
func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT], error) {
|
||||
var labelNode, valueNode *yaml.Node
|
||||
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
|
||||
// locate reference in index.
|
||||
ref := LocateRefNode(root, idx)
|
||||
if ref != nil {
|
||||
valueNode = ref
|
||||
labelNode = rl
|
||||
}
|
||||
} else {
|
||||
_, labelNode, valueNode = utils.FindKeyNodeFull(label, root.Content)
|
||||
}
|
||||
|
||||
if valueNode != nil {
|
||||
var currentLabelNode *yaml.Node
|
||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
|
||||
@@ -177,7 +294,7 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
berr := n.Build(en)
|
||||
berr := n.Build(en, idx)
|
||||
if berr != nil {
|
||||
return nil, berr
|
||||
}
|
||||
@@ -199,16 +316,13 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func ExtractExtensions(root *yaml.Node) (map[low.KeyReference[string]]low.ValueReference[any], error) {
|
||||
func ExtractExtensions(root *yaml.Node) map[low.KeyReference[string]]low.ValueReference[any] {
|
||||
extensions := utils.FindExtensionNodes(root.Content)
|
||||
extensionMap := make(map[low.KeyReference[string]]low.ValueReference[any])
|
||||
for _, ext := range extensions {
|
||||
if utils.IsNodeMap(ext.Value) {
|
||||
var v interface{}
|
||||
err := ext.Value.Decode(&v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = ext.Value.Decode(&v)
|
||||
extensionMap[low.KeyReference[string]{
|
||||
Value: ext.Key.Value,
|
||||
KeyNode: ext.Key,
|
||||
@@ -243,15 +357,12 @@ func ExtractExtensions(root *yaml.Node) (map[low.KeyReference[string]]low.ValueR
|
||||
}
|
||||
if utils.IsNodeArray(ext.Value) {
|
||||
var v []interface{}
|
||||
err := ext.Value.Decode(&v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = ext.Value.Decode(&v)
|
||||
extensionMap[low.KeyReference[string]{
|
||||
Value: ext.Key.Value,
|
||||
KeyNode: ext.Key,
|
||||
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value}
|
||||
}
|
||||
}
|
||||
return extensionMap, nil
|
||||
return extensionMap
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user