Files
libopenapi/datamodel/low/reference.go
Dave Shanley aa4422fa74 Mutation method updated to return new copy
with value node (pointer) and value (non pointer) returned.
2022-09-13 09:32:08 -04:00

124 lines
2.6 KiB
Go

package low
import (
"fmt"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
)
type HasNode interface {
GetNode() *yaml.Node
}
type Buildable[T any] interface {
Build(node *yaml.Node, idx *index.SpecIndex) error
*T
}
type NodeReference[T any] struct {
Value T
ValueNode *yaml.Node
KeyNode *yaml.Node
}
type KeyReference[T any] struct {
Value T
KeyNode *yaml.Node
}
type ValueReference[T any] struct {
Value T
ValueNode *yaml.Node
}
func (n NodeReference[T]) IsEmpty() bool {
return n.KeyNode == nil && n.ValueNode == nil
}
func (n NodeReference[T]) GenerateMapKey() string {
return fmt.Sprintf("%d:%d", n.ValueNode.Line, n.ValueNode.Column)
}
func (n NodeReference[T]) Mutate(value T) NodeReference[T] {
n.ValueNode.Value = fmt.Sprintf("%v", value)
n.Value = value
return n
}
func (n ValueReference[T]) IsEmpty() bool {
return n.ValueNode == nil
}
func (n ValueReference[T]) GenerateMapKey() string {
return fmt.Sprintf("%d:%d", n.ValueNode.Line, n.ValueNode.Column)
}
func (n KeyReference[T]) IsEmpty() bool {
return n.KeyNode == nil
}
func (n KeyReference[T]) GenerateMapKey() string {
return fmt.Sprintf("%d:%d", n.KeyNode.Line, n.KeyNode.Column)
}
func (n ValueReference[T]) Mutate(value T) ValueReference[T] {
n.ValueNode.Value = fmt.Sprintf("%v", value)
n.Value = value
return n
}
func IsCircular(node *yaml.Node, idx *index.SpecIndex) bool {
if idx == nil {
return false // no index! nothing we can do.
}
refs := idx.GetCircularReferences()
for i := range idx.GetCircularReferences() {
if refs[i].LoopPoint.Node == node {
return true
}
for k := range refs[i].Journey {
if refs[i].Journey[k].Node == node {
return true
}
}
}
// check mapped references in case we didn't find it.
_, nv := utils.FindKeyNode("$ref", node.Content)
if nv != nil {
ref := idx.GetMappedReferences()[nv.Value]
if ref != nil {
return ref.Circular
}
}
return false
}
func GetCircularReferenceResult(node *yaml.Node, idx *index.SpecIndex) *index.CircularReferenceResult {
if idx == nil {
return nil // no index! nothing we can do.
}
refs := idx.GetCircularReferences()
for i := range refs {
if refs[i].LoopPoint.Node == node {
return refs[i]
}
for k := range refs[i].Journey {
if refs[i].Journey[k].Node == node {
return refs[i]
}
}
}
// check mapped references in case we didn't find it.
_, nv := utils.FindKeyNode("$ref", node.Content)
if nv != nil {
for i := range refs {
if refs[i].LoopPoint.Definition == nv.Value {
return refs[i]
}
}
}
return nil
}