Documentation
¶
Index ¶
- Constants
- func DiagnoseJSONError(src []byte) string
- func RegisterCustomValidator(tag string, v CustomValidator)
- type CustomValidator
- type Diagnostic
- type DiagnosticContext
- type DiagnosticList
- type JsonMLDocument
- type JsonMLNode
- type JsonMLValidationResult
- type Lexer
- type Position
- type Range
- type SchemaV2
- type Severity
- type TagSchema
- type Token
- type TokenKind
- type TypeSpec
Constants ¶
const ( SourceJSONSyntax = "json-syntax" SourceJSONMLGrammar = "jsonml-grammar" SourceJSONMLSchema = "jsonml-schema" )
Source 常量。
const ( CodeJSONSyntaxUnexpectedToken = "JSON_SYNTAX_UNEXPECTED_TOKEN" CodeJSONSyntaxUnterminatedStr = "JSON_SYNTAX_UNTERMINATED_STRING" CodeJSONSyntaxInvalidEscape = "JSON_SYNTAX_INVALID_ESCAPE" CodeJSONSyntaxTrailingData = "JSON_SYNTAX_TRAILING_DATA" )
Layer 0: JSON Syntax errors (reported by jsontext.Decoder).
const ( CodeJSONMLSyntaxNotArray = "JSONML_SYNTAX_NOT_ARRAY" CodeJSONMLSyntaxEmptyElement = "JSONML_SYNTAX_EMPTY_ELEMENT" CodeJSONMLSyntaxTagNotString = "JSONML_SYNTAX_TAG_NOT_STRING" CodeJSONMLSyntaxInvalidContent = "JSONML_SYNTAX_INVALID_CONTENT" CodeJSONMLSyntaxUnexpectedEOF = "JSONML_SYNTAX_UNEXPECTED_EOF" CodeJSONMLSyntaxMaxDepth = "JSONML_SYNTAX_MAX_DEPTH" )
Layer 1: JSONML Grammar errors (structural violations).
const ( CodeJSONMLSchemaUnknownTag = "JSONML_SCHEMA_UNKNOWN_TAG" CodeJSONMLSchemaUnknownAttr = "JSONML_SCHEMA_UNKNOWN_ATTR" CodeJSONMLSchemaAttrAlias = "JSONML_SCHEMA_ATTR_ALIAS" CodeJSONMLSchemaTypeMismatch = "JSONML_SCHEMA_TYPE_MISMATCH" CodeJSONMLSchemaRequiredMissing = "JSONML_SCHEMA_REQUIRED_MISSING" CodeJSONMLSchemaChildNotAllowed = "JSONML_SCHEMA_CHILD_NOT_ALLOWED" CodeJSONMLSchemaEnumInvalid = "JSONML_SCHEMA_ENUM_INVALID" CodeJSONMLSchemaDeprecatedAttr = "JSONML_SCHEMA_DEPRECATED_ATTR" CodeJSONMLSchemaNumberRange = "JSONML_SCHEMA_NUMBER_RANGE" )
Layer 2: JSONML Schema errors (semantic violations).
const ( CodeJSONMLSchemaTableMissingColsWidth = "JSONML_SCHEMA_TABLE_MISSING_COLSWIDTH" CodeJSONMLSchemaTableColsWidthMismatch = "JSONML_SCHEMA_TABLE_COLSWIDTH_MISMATCH" CodeJSONMLSchemaListStartInvalid = "JSONML_SCHEMA_LIST_START_INVALID" CodeJSONMLSchemaTocContentShape = "JSONML_SCHEMA_TOC_CONTENT_SHAPE" )
Layer 2: CustomValidator-specific codes.
const MaxDepth = 64
MaxDepth 是 JSONML 节点嵌套的最大深度。
Variables ¶
This section is empty.
Functions ¶
func DiagnoseJSONError ¶
DiagnoseJSONError uses the Layer 0 Lexer (jsontext.Decoder) to provide detailed positional diagnostics when standard json.Unmarshal fails. Returns a human-readable multi-line report with line:col information. If parsing succeeds (no errors), returns empty string.
This is designed to be called from the pipeline when json.Unmarshal reports a generic error like "unexpected end of JSON input" — we re-parse with our position-aware lexer to give the user actionable info.
func RegisterCustomValidator ¶
func RegisterCustomValidator(tag string, v CustomValidator)
RegisterCustomValidator registers a custom validator for a specific tag. Validators are invoked in registration order after standard schema checks.
Types ¶
type CustomValidator ¶
type CustomValidator func(node *JsonMLNode, attrs map[string]any, schema *TagSchema, emit func(Diagnostic))
CustomValidator is a custom validation function invoked after declarative schema validation. It handles cross-field relationships, conditional requirements, and other logic that cannot be expressed declaratively.
type Diagnostic ¶
type Diagnostic struct {
Range Range // 源位置
Severity Severity // 严重程度
Code string // 错误码 (见 error code 常量)
Source string // "json-syntax" | "jsonml-grammar" | "jsonml-schema"
Message string // 人可读描述
Suggestion string // 可粘贴的最小合法片段 (可选)
Context *DiagnosticContext // schema 上下文 (可选, Layer 2 填充)
}
Diagnostic 表示一条诊断信息(错误/警告/提示)。
func (Diagnostic) String ¶
func (d Diagnostic) String() string
String 返回单条诊断的格式化输出。 格式: "L{line}:{col} {severity}[{Code}]: {Message}"
type DiagnosticContext ¶
type DiagnosticContext struct {
TagName string // 当前/期望 tag
Description string // P1: tag description from schema
AllowedChildren []string // 父节点合法子节点全集
AllValidTags []string // schema 全量 tag 列表(unknown tag 时填充)
AllValidAttrs []string // 当前 tag 全量 attr 列表(unknown attr 时填充)
AttrSpec *TypeSpec // 当前属性的 schema 定义
}
DiagnosticContext 附加的 schema 上下文信息。
type DiagnosticList ¶
type DiagnosticList []Diagnostic
DiagnosticList 诊断列表。
func ValidateWithSchema ¶
func ValidateWithSchema(doc *JsonMLDocument, schema *SchemaV2) DiagnosticList
ValidateWithSchema 使用 schema 对 AST 进行语义校验 (Layer 2)。 仅遍历 IsError == false 的节点。
func (DiagnosticList) ErrorCount ¶
func (dl DiagnosticList) ErrorCount() int
ErrorCount 返回 Error 级别诊断数量。
func (DiagnosticList) Filter ¶
func (dl DiagnosticList) Filter(source string) DiagnosticList
Filter 按 Source 过滤诊断。
func (DiagnosticList) HasErrors ¶
func (dl DiagnosticList) HasErrors() bool
HasErrors 返回列表中是否包含 Error 级别诊断。
func (DiagnosticList) ToLegacyResult ¶
func (dl DiagnosticList) ToLegacyResult() *JsonMLValidationResult
ToLegacyResult 将 DiagnosticList 转为旧 JsonMLValidationResult 格式,保持对外兼容。
func (DiagnosticList) WarningCount ¶
func (dl DiagnosticList) WarningCount() int
WarningCount 返回 Warning 级别诊断数量。
type JsonMLDocument ¶
type JsonMLDocument struct {
Nodes []*JsonMLNode // 顶层节点列表
Source []byte // 原始输入
Diagnostics DiagnosticList // Layer 0 + Layer 1 诊断
}
JsonMLDocument 表示一次 Parse 的完整结果。
func Parse ¶
func Parse(src []byte) *JsonMLDocument
Parse 解析 JSONML 源文本,返回 AST + 诊断(Layer 0 + Layer 1)。
func (*JsonMLDocument) ToAnySlice ¶
func (doc *JsonMLDocument) ToAnySlice() []any
ToAnySlice 将顶层节点列表转为 []any(body 形态),兼容 ValidateJsonMLBodyV2。
type JsonMLNode ¶
type JsonMLNode struct {
Tag string // tag 名称(IsText 时为空)
Attrs map[string]any // 属性 map(无 attrs 时为 nil)
Children []*JsonMLNode // 子节点列表
Text string // 文本内容(仅 IsText == true 时有值)
IsText bool // true = 文本节点
IsError bool // true = 错误占位节点 (error recovery 产生)
Range Range // 整个节点的源位置
TagRange Range // tag string 的源位置
}
JsonMLNode 表示 AST 中的一个节点。
func (*JsonMLNode) ToAny ¶
func (n *JsonMLNode) ToAny() any
ToAny 将 AST 节点转回 []any/string 形式。IsError 节点返回 nil。
func (*JsonMLNode) Walk ¶
func (n *JsonMLNode) Walk(fn func(node *JsonMLNode, depth int) bool)
Walk 深度优先遍历。fn 返回 false 时跳过子树。
type JsonMLValidationResult ¶
JsonMLValidationResult holds errors and warnings from validation.
func ValidateJsonMLBodyV2 ¶
func ValidateJsonMLBodyV2(body []any) *JsonMLValidationResult
ValidateJsonMLBodyV2 validates a JSONML body using schema-v2. This implementation delegates to the new Parse → ValidateWithSchema pipeline, providing position-aware diagnostics. The signature is unchanged for backward compatibility (SPEC §8.4).
Note: Since input is already []any, we marshal it back to JSON bytes to feed the parser. Positions are relative to the marshaled output. The full pipeline (parsing raw input directly) provides original-source positions.
Behavioral note: The old implementation interprets a body whose first element is an unknown tag (not "root", not a known schema tag) as an "array of blocks" and would error on each non-array element. The new Parse-based implementation correctly interprets ["unknownTag", ...] as a single JSONML element with an unknown tag (warning). This is semantically more correct for JSONML.
func ValidateJsonMLNodeV2 ¶
func ValidateJsonMLNodeV2(node any) *JsonMLValidationResult
ValidateJsonMLNodeV2 validates a single JSONML node using schema-v2. Delegates to the new Parse → ValidateWithSchema pipeline.
func ValidateJsonMLSource ¶
func ValidateJsonMLSource(src []byte) *JsonMLValidationResult
ValidateJsonMLSource validates raw JSONML source bytes directly, preserving original line/column positions in diagnostics. This should be preferred over ValidateJsonMLBodyV2 when the original source bytes are available (e.g., from a file).
The input can be:
- A bare JSONML array: ["root", {}, ...]
- A wrapped object: {"jsonml": [...]}
func (*JsonMLValidationResult) HasErrors ¶
func (r *JsonMLValidationResult) HasErrors() bool
HasErrors returns true if there are blocking errors.
func (*JsonMLValidationResult) Summary ¶
func (r *JsonMLValidationResult) Summary() string
Summary returns a human-readable report.
type Lexer ¶
type Lexer struct {
// contains filtered or unexported fields
}
Lexer 封装 jsontext.Decoder,提供位置感知的 token 流。
func (*Lexer) Diagnostics ¶
func (l *Lexer) Diagnostics() DiagnosticList
Diagnostics 返回 Layer 0 收集的所有诊断。
type Position ¶
type Position struct {
Line int // 1-based 行号
Col int // 1-based 列号 (UTF-8 byte offset within line)
Offset int64 // 0-based 字节偏移 (相对于整个输入)
}
Position 表示源文本中的一个位置点。
type SchemaV2 ¶
type SchemaV2 struct {
Version string `json:"_version"`
Description string `json:"_description"`
Tags map[string]*TagSchema `json:"tags"`
// contains filtered or unexported fields
}
SchemaV2 is the top-level schema structure.
func (*SchemaV2) AllTagNames ¶
AllTagNames 返回 schema 中所有已知 tag 名称(排序)。
func (*SchemaV2) IsKnownTag ¶
IsKnownTag returns true if the tag is declared in the schema.
func (*SchemaV2) TagSchemaFor ¶
TagSchemaFor returns the schema for a tag, or nil if unknown.
type Severity ¶
type Severity int
Severity 诊断严重程度,值对齐 LSP Diagnostic (1=Error, 2=Warning, 3=Info, 4=Hint)。
type TagSchema ¶
type TagSchema struct {
AllowedChildren []string `json:"allowed_children"`
Attrs map[string]TypeSpec `json:"attrs"`
Aliases map[string]string `json:"aliases,omitempty"` // P1: aliasName → canonicalAttrName
Description string `json:"description,omitempty"` // P1: tag description for diagnostics
// contains filtered or unexported fields
}
TagSchema defines the schema for a single JSONML tag.
func (*TagSchema) AllAttrCandidates ¶
AllAttrCandidates 返回 canonical attr names + alias names(排序)。 用于 did-you-mean 候选集,当 attr 既不在 Attrs 也不在 Aliases 时,将两者合并提供近似建议。
func (*TagSchema) IsAllowedChild ¶
IsAllowedChild returns true if childTag is in the parent's allowed_children.
type Token ¶
type Token struct {
Kind TokenKind
Value []byte // 原始字节(string 含引号, number 含原始文本)
Range Range // 精确源位置
}
Token 表示一个带位置的 JSON token。
func (Token) StringValue ¶
StringValue 返回解码后的 string 值。仅 TokenString 有效。 对于非 string token 返回空串。
type TypeSpec ¶
type TypeSpec struct {
Type string `json:"type"` // string|number|boolean|array|object|any|enum|union
Min *float64 `json:"min,omitempty"` // for number
Max *float64 `json:"max,omitempty"` // for number
Values []string `json:"values,omitempty"` // for enum
Types []string `json:"types,omitempty"` // for union: pass silently
WarnTypes []string `json:"warn_types,omitempty"` // for union: match → warning (not error)
Fields map[string]TypeSpec `json:"fields,omitempty"` // for object (deep validation)
// P1:
Required bool `json:"required,omitempty"` // mandatory attribute marker
Deprecated bool `json:"deprecated,omitempty"` // deprecated attribute marker
}
TypeSpec represents a type constraint for an attribute value. Parsed from the schema JSON's unified object format: { "type": "...", ... }