Skip to content

Syntax Validation (08_07_00)

Validates JSON syntax, types, and required fields in plugin manifests.

Components

1. JSONSchemaValidator

Validates JSON documents against JSON Schema (Draft 7).

Features: - Schema loading from file/string - Type validation (object, array, string, number, boolean, null) - Required field checking - Enum validation - Numeric constraints (min/max/multipleOf) - String constraints (minLength/maxLength/pattern) - Array constraints (minItems/maxItems/uniqueItems)

Example:

JSONSchemaValidator validator;
validator.loadSchema("schemas/plugin_manifest_v1.json");

auto result = validator.validate("my_plugin.json");
if (!result.isValid()) {
    for (const auto& issue : result.getIssues()) {
        std::cerr << issue.path << ": " << issue.message << "\n";
    }
}

2. TypeChecker

Advanced type checking including semantic types.

Features: - Basic JSON type detection - Semantic type validation (UUID, URL, semver, email) - Audio-specific validation (sample rates, buffer sizes, channel counts) - Plugin-specific validation (plugin IDs, component types) - Type coercion utilities - Custom semantic type registration

Example:

TypeChecker checker;

// Basic type check
JsonType type = checker.getType(R"("hello")"); // STRING

// Semantic validation
bool valid = TypeChecker::isValidUUID("550e8400-e29b-41d4-a716-446655440000");
bool validSR = TypeChecker::isValidSampleRate(48000.0);

// Custom type
checker.registerSemanticType("even_number", [](const std::string& value) {
    int num = std::stoi(value);
    return num % 2 == 0;
});

3. RequiredFieldsValidator

Validates presence of required fields with nested path support.

Features: - Mandatory vs optional field specification - Nested field paths (dot notation) - Field groups (at-least-one semantics) - Predefined field sets for plugin/suite manifests - Load specifications from config files

Example:

RequiredFieldsValidator validator;

// Manual field specification
validator.addField("metadata.name", true, "Plugin name");
validator.addField("metadata.author", false, "Author (recommended)");

// Or use presets
validator.loadPluginManifestDefaults(); // L4 plugins
validator.loadL5SuiteDefaults();        // L5 suites

auto result = validator.validate("manifest.json");

Predefined Schemas

plugin_manifest_v1.json

Schema for L4 plugin manifests with: - Metadata (id, name, version, manufacturer) - Audio config (inputs, outputs, sample rates) - Components (DSP component array) - Parameters (plugin parameters) - Routing (signal connections) - UI (interface configuration)

suite_manifest_v1.json

Schema for L5 suite manifests with: - Suite info (id, name, version) - Plugin list (included plugins) - Shared resources (presets, wavetables, IRs) - Installation config (formats, platforms)

Testing

cd tests
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
./test_syntax_validation

Dependencies

  • nlohmann/json - JSON parsing and manipulation
  • Catch2 - Testing framework (tests only)
  • C++20 - Standard library features

Integration

add_subdirectory(08_07_00_syntax_validation)
target_link_libraries(your_target PRIVATE syntax_validation)
#include <JSONSchemaValidator.hpp>
#include <TypeChecker.hpp>
#include <RequiredFieldsValidator.hpp>

using namespace audiolab::plugins::validation;

Validation Pipeline

Typical validation workflow:

  1. Schema Validation - Basic JSON structure

    JSONSchemaValidator schemaValidator;
    schemaValidator.loadSchema("schemas/plugin_manifest_v1.json");
    auto schemaResult = schemaValidator.validate("manifest.json");
    

  2. Type Checking - Semantic type validation

    TypeChecker typeChecker;
    // Check specific fields for semantic correctness
    typeChecker.checkSemanticType(pluginId, "plugin_id");
    typeChecker.checkSemanticType(version, "semver");
    

  3. Required Fields - Completeness check

    RequiredFieldsValidator fieldsValidator;
    fieldsValidator.loadL4PluginDefaults();
    auto fieldsResult = fieldsValidator.validate("manifest.json");
    

  4. Report Results

    if (!schemaResult.isValid()) {
        std::cout << schemaResult.getSummary() << "\n";
        // Handle errors...
    }
    

Error Handling

All validators return ValidationResult:

struct ValidationResult {
    bool isValid() const;
    bool hasWarnings() const;
    size_t getErrorCount() const;
    size_t getWarningCount() const;
    const std::vector<ValidationIssue>& getIssues() const;
    std::string getSummary() const;
};

Each issue contains: - severity - ERROR, WARNING, or INFO - path - JSON path to problematic field - message - Human-readable description - expected / actual - Expected vs actual values

Status

COMPLETE - Ready for integration

Phase: FASE 1 Next: 08_07_01 (Dependency Validation)