using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; using System.Text.Json; using System.Text.Json.Nodes; using Json.Schema; namespace Questionable.Validation.Validators; internal abstract class DefinitionSchemaValidator : IDefinitionSchemaValidator { protected const string BaseUri = "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main"; private readonly SchemaRegistrar _schemaRegistrar; private readonly Dictionary _nodes = new Dictionary(); private JsonSchema? _schema; protected abstract EPathType PathType { get; } protected abstract string MainSchemaUri { get; } protected DefinitionSchemaValidator(SchemaRegistrar schemaRegistrar) { _schemaRegistrar = schemaRegistrar; } public void Enqueue(ushort id, JsonNode node) { _nodes[id] = node; } public void Reset() { _nodes.Clear(); } public IEnumerable Validate() { if (_nodes.Count == 0) { yield break; } if (_schema == null) { _schema = _schemaRegistrar.Get(MainSchemaUri); } foreach (var (id, node) in _nodes) { foreach (ValidationIssue item in ValidateImmediate(id, node)) { yield return item; } } } public List ValidateImmediate(ushort id, JsonNode node) { if (_schema == null) { _schema = _schemaRegistrar.Get(MainSchemaUri); } EvaluationResults evaluationResults = _schema.Evaluate(JsonSerializer.SerializeToElement(node), new EvaluationOptions { Culture = CultureInfo.InvariantCulture, OutputFormat = OutputFormat.Hierarchical }); if (evaluationResults.IsValid) { return new List(); } List list = new List(); SchemaValidationHelper.CollectLeafErrors(evaluationResults, list); if (list.Count == 0) { int num = 1; List list2 = new List(num); CollectionsMarshal.SetCount(list2, num); CollectionsMarshal.AsSpan(list2)[0] = new ValidationIssue { PathType = PathType, Id = id.ToString(CultureInfo.InvariantCulture), Location = null, Type = EIssueType.InvalidJsonSchema, Severity = EIssueSeverity.Error, Description = "JSON schema validation failed" }; return list2; } return list.Select((SchemaValidationHelper.ParsedError error) => new ValidationIssue { PathType = PathType, Id = id.ToString(CultureInfo.InvariantCulture), Location = (string.IsNullOrEmpty(error.PropertyPath) ? null : error.PropertyPath), Type = EIssueType.InvalidJsonSchema, Severity = EIssueSeverity.Error, Description = (string.IsNullOrEmpty(error.PropertyPath) ? error.Message : (error.PropertyPath + ": " + error.Message)) }).ToList(); } }