ast

package
v0.9.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 27, 2025 License: Apache-2.0 Imports: 5 Imported by: 8

Documentation

Overview

Package ast provides a universal, format-agnostic Abstract Syntax Tree (AST) representation for both validation schemas and parsed data structures.

The AST serves dual purposes:

  1. Schema Validation: TypeNode, FunctionNode define constraints
  2. Data Representation: LiteralNode, ObjectNode hold parsed values from any format

This unified representation enables:

  • Source position tracking for precise error messages
  • Structural queries (JSONPath, XPath) via conversion to Go types
  • Document diffing and comparison
  • Programmatic construction of JSON/XML/YAML
  • Format transformations and conversions
  • Cross-format validation with consistent semantics

Supported formats: JSON, XML, YAML, CSV, and custom formats.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InternString

func InternString(s string) string

InternString returns an interned version of the string. For type and function names, this reduces memory usage by reusing string instances.

func PrettyPrint

func PrettyPrint(node SchemaNode) string

PrettyPrint returns a human-readable, indented representation of the AST.

func ReleaseArrayDataNode

func ReleaseArrayDataNode(n *ArrayDataNode)

ReleaseArrayDataNode returns an array data node to the pool for reuse. This should be called after the node is no longer needed (e.g., after conversion to interface{}). The node must not be used after calling this function.

func ReleaseLiteralNode

func ReleaseLiteralNode(n *LiteralNode)

ReleaseLiteralNode returns a literal node to the pool for reuse. This should be called after the node is no longer needed (e.g., after conversion to interface{}). The node must not be used after calling this function.

func ReleaseObjectNode

func ReleaseObjectNode(n *ObjectNode)

ReleaseObjectNode returns an object node to the pool for reuse. This should be called after the node is no longer needed (e.g., after conversion to interface{}). The node must not be used after calling this function.

func TreePrint

func TreePrint(node SchemaNode) string

TreePrint returns a tree-style representation of the AST.

func Walk

func Walk(node SchemaNode, visitor Visitor) error

Walk traverses the AST starting from the given node using the provided visitor.

Types

type ArrayDataNode

type ArrayDataNode struct {
	// contains filtered or unexported fields
}

ArrayDataNode represents actual array data with elements. This is distinct from ArrayNode which represents array schema validation.

func NewArrayDataNode

func NewArrayDataNode(elements []SchemaNode, pos Position) *ArrayDataNode

NewArrayDataNode creates a new array data node using object pooling.

func (*ArrayDataNode) Accept

func (n *ArrayDataNode) Accept(visitor Visitor) error

Accept implements the visitor pattern.

func (*ArrayDataNode) Elements

func (n *ArrayDataNode) Elements() []SchemaNode

Elements returns the array elements.

func (*ArrayDataNode) Get

func (n *ArrayDataNode) Get(index int) SchemaNode

Get returns the element at the specified index. Returns nil if index is out of bounds.

func (*ArrayDataNode) Len

func (n *ArrayDataNode) Len() int

Len returns the number of elements in the array.

func (*ArrayDataNode) MarshalJSON

func (n *ArrayDataNode) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for ArrayDataNode.

func (*ArrayDataNode) Position

func (n *ArrayDataNode) Position() Position

Position returns the source position.

func (*ArrayDataNode) String

func (n *ArrayDataNode) String() string

String returns a string representation.

func (*ArrayDataNode) Type

func (n *ArrayDataNode) Type() NodeType

Type returns NodeTypeArrayData.

type ArrayNode

type ArrayNode struct {
	// contains filtered or unexported fields
}

ArrayNode represents array validation with element schema.

func NewArrayNode

func NewArrayNode(elementSchema SchemaNode, pos Position) *ArrayNode

NewArrayNode creates a new array node.

func (*ArrayNode) Accept

func (n *ArrayNode) Accept(visitor Visitor) error

Accept implements the visitor pattern.

func (*ArrayNode) ElementSchema

func (n *ArrayNode) ElementSchema() SchemaNode

ElementSchema returns the element schema.

func (*ArrayNode) MarshalJSON

func (n *ArrayNode) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for ArrayNode.

func (*ArrayNode) Position

func (n *ArrayNode) Position() Position

Position returns the source position.

func (*ArrayNode) String

func (n *ArrayNode) String() string

String returns a string representation.

func (*ArrayNode) Type

func (n *ArrayNode) Type() NodeType

Type returns NodeTypeArray.

type BaseVisitor

type BaseVisitor struct{}

BaseVisitor provides default implementations for the Visitor interface. Embed this in your visitor to only override the methods you need.

func (*BaseVisitor) VisitArray

func (v *BaseVisitor) VisitArray(node *ArrayNode) error

VisitArray is the default implementation for visiting array nodes.

func (*BaseVisitor) VisitArrayData

func (v *BaseVisitor) VisitArrayData(node *ArrayDataNode) error

VisitArrayData is the default implementation for visiting array data nodes.

func (*BaseVisitor) VisitFunction

func (v *BaseVisitor) VisitFunction(node *FunctionNode) error

VisitFunction is the default implementation for visiting function nodes.

func (*BaseVisitor) VisitLiteral

func (v *BaseVisitor) VisitLiteral(node *LiteralNode) error

VisitLiteral is the default implementation for visiting literal nodes.

func (*BaseVisitor) VisitObject

func (v *BaseVisitor) VisitObject(node *ObjectNode) error

VisitObject is the default implementation for visiting object nodes.

func (*BaseVisitor) VisitType

func (v *BaseVisitor) VisitType(node *TypeNode) error

VisitType is the default implementation for visiting type nodes.

type FunctionNode

type FunctionNode struct {
	// contains filtered or unexported fields
}

FunctionNode represents function-based validation with arguments. Examples: Integer(1, 100), String(5+), Enum("M", "F", "O")

func NewFunctionNode

func NewFunctionNode(name string, arguments []interface{}, pos Position) *FunctionNode

NewFunctionNode creates a new function node. The function name is automatically interned to reduce memory allocations.

func (*FunctionNode) Accept

func (n *FunctionNode) Accept(visitor Visitor) error

Accept implements the visitor pattern.

func (*FunctionNode) Arguments

func (n *FunctionNode) Arguments() []interface{}

Arguments returns the function arguments.

func (*FunctionNode) MarshalJSON

func (n *FunctionNode) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for FunctionNode.

func (*FunctionNode) Name

func (n *FunctionNode) Name() string

Name returns the function name.

func (*FunctionNode) Position

func (n *FunctionNode) Position() Position

Position returns the source position.

func (*FunctionNode) String

func (n *FunctionNode) String() string

String returns a string representation.

func (*FunctionNode) Type

func (n *FunctionNode) Type() NodeType

Type returns NodeTypeFunction.

type LiteralNode

type LiteralNode struct {
	// contains filtered or unexported fields
}

LiteralNode represents an exact match validation (literal values from JSON/XML/etc.).

func NewLiteralNode

func NewLiteralNode(value interface{}, pos Position) *LiteralNode

NewLiteralNode creates a new literal node using object pooling.

func (*LiteralNode) Accept

func (n *LiteralNode) Accept(visitor Visitor) error

Accept implements the visitor pattern.

func (*LiteralNode) MarshalJSON

func (n *LiteralNode) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for LiteralNode.

func (*LiteralNode) Position

func (n *LiteralNode) Position() Position

Position returns the source position.

func (*LiteralNode) String

func (n *LiteralNode) String() string

String returns a string representation.

func (*LiteralNode) Type

func (n *LiteralNode) Type() NodeType

Type returns NodeTypeLiteral.

func (*LiteralNode) Value

func (n *LiteralNode) Value() interface{}

Value returns the literal value.

type NodeType

type NodeType int

NodeType represents the type of an AST node.

const (
	// NodeTypeLiteral represents a literal value (string, number, bool, null)
	NodeTypeLiteral NodeType = iota

	// NodeTypeType represents a type identifier (UUID, Email, ISO-8601, etc.)
	NodeTypeType

	// NodeTypeFunction represents a function call (Integer(1, 100), String(5+), etc.)
	NodeTypeFunction

	// NodeTypeObject represents an object with properties
	NodeTypeObject

	// NodeTypeArray represents an array with element schema
	NodeTypeArray

	// NodeTypeArrayData represents actual array data with elements
	NodeTypeArrayData
)

func (NodeType) String

func (nt NodeType) String() string

String returns the string representation of the node type.

type ObjectNode

type ObjectNode struct {
	// contains filtered or unexported fields
}

ObjectNode represents object/map validation with property schemas.

func NewObjectNode

func NewObjectNode(properties map[string]SchemaNode, pos Position) *ObjectNode

NewObjectNode creates a new object node using object pooling.

func (*ObjectNode) Accept

func (n *ObjectNode) Accept(visitor Visitor) error

Accept implements the visitor pattern.

func (*ObjectNode) GetProperty

func (n *ObjectNode) GetProperty(name string) (SchemaNode, bool)

GetProperty returns the schema for a specific property.

func (*ObjectNode) MarshalJSON

func (n *ObjectNode) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for ObjectNode.

func (*ObjectNode) Position

func (n *ObjectNode) Position() Position

Position returns the source position.

func (*ObjectNode) Properties

func (n *ObjectNode) Properties() map[string]SchemaNode

Properties returns the property schemas.

func (*ObjectNode) String

func (n *ObjectNode) String() string

String returns a string representation.

func (*ObjectNode) Type

func (n *ObjectNode) Type() NodeType

Type returns NodeTypeObject.

type Position

type Position struct {
	Offset int // Byte offset (0-indexed)
	Line   int // Line number (1-indexed)
	Column int // Column number (1-indexed)
}

Position represents a location in the source text.

func NewPosition

func NewPosition(offset, line, column int) Position

NewPosition creates a new Position with the given offset, line, and column.

func ZeroPosition

func ZeroPosition() Position

ZeroPosition returns a zero/invalid position.

func (Position) IsValid

func (p Position) IsValid() bool

IsValid returns true if the position has been set (not default zero values).

func (Position) String

func (p Position) String() string

String returns a string representation of the position.

type SchemaNode

type SchemaNode interface {
	// Type returns the node type (literal, type, function, object, array)
	Type() NodeType

	// Accept allows visitor pattern traversal
	Accept(visitor Visitor) error

	// String returns a human-readable representation
	String() string

	// Position returns the source location for error messages
	Position() Position
}

SchemaNode is the root interface for all AST nodes. All validation schema elements implement this interface.

func UnmarshalSchemaNode

func UnmarshalSchemaNode(data []byte) (SchemaNode, error)

UnmarshalSchemaNode unmarshals JSON into a SchemaNode.

type SerializableNode

type SerializableNode struct {
	Type       string                 `json:"type"`
	Value      interface{}            `json:"value,omitempty"`
	TypeName   string                 `json:"typeName,omitempty"`
	Name       string                 `json:"name,omitempty"`
	Arguments  []interface{}          `json:"arguments,omitempty"`
	Properties map[string]interface{} `json:"properties,omitempty"`
	Element    interface{}            `json:"element,omitempty"`
	Elements   []interface{}          `json:"elements,omitempty"`
	Position   *Position              `json:"position,omitempty"`
}

SerializableNode is a helper struct for JSON serialization.

type TypeNode

type TypeNode struct {
	// contains filtered or unexported fields
}

TypeNode represents type validation (built-in type identifiers like UUID, Email, etc.).

func NewTypeNode

func NewTypeNode(typeName string, pos Position) *TypeNode

NewTypeNode creates a new type node. The type name is automatically interned to reduce memory allocations.

func (*TypeNode) Accept

func (n *TypeNode) Accept(visitor Visitor) error

Accept implements the visitor pattern.

func (*TypeNode) MarshalJSON

func (n *TypeNode) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for TypeNode.

func (*TypeNode) Position

func (n *TypeNode) Position() Position

Position returns the source position.

func (*TypeNode) String

func (n *TypeNode) String() string

String returns a string representation.

func (*TypeNode) Type

func (n *TypeNode) Type() NodeType

Type returns NodeTypeType.

func (*TypeNode) TypeName

func (n *TypeNode) TypeName() string

TypeName returns the type identifier name.

type Visitor

type Visitor interface {
	VisitLiteral(node *LiteralNode) error
	VisitType(node *TypeNode) error
	VisitFunction(node *FunctionNode) error
	VisitObject(node *ObjectNode) error
	VisitArray(node *ArrayNode) error
	VisitArrayData(node *ArrayDataNode) error
}

Visitor is the interface for traversing the AST using the visitor pattern.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL