{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "StructSpec Schema",
    "description": "This is a schema that defines binary packet formats.",
    "definitions": {
        "title": {
            "type": "string",
            "maxLength": 65
        },
        "description": {
            "type": "string"
        },
        "version": {
            "type": [
                "string",
                "number"
            ]
        },
        "type": {
            "anyOf": [
                {
                    "type": "string",
                    "enum": [
                        "char",
                        "signed char",
                        "unsigned char",
                        "short",
                        "signed short",
                        "unsigned short",
                        "short int",
                        "signed short int",
                        "unsigned short int",
                        "int",
                        "signed int",
                        "unsigned int",
                        "long",
                        "signed long",
                        "unsigned long",
                        "long int",
                        "signed long int",
                        "unsigned long int",
                        "long long",
                        "signed long long",
                        "unsigned long long",
                        "long long int",
                        "signed long long int",
                        "unsigned long long int",
                        "float",
                        "double",
                        "long double",
                        "bool",
                        "boolean",
                        "_Bool",
                        "int8_t",
                        "uint8_t",
                        "int16_t",
                        "uint16_t",
                        "int24_t",
                        "uint24_t",
                        "int32_t",
                        "uint32_t",
                        "int64_t",
                        "uint64_t",
                        "hollerith",
                        "string",
                        "str",
                        "pascal",
                        "pointer",
                        "void",
                        "padding"
                    ]
                },
                {
                    "type": "string",
                    "pattern": "^#/"
                }
            ]
        },
        "endianness": {
            "anyOf": [
                {
                    "type": "string",
                    "enum": [
                        "big",
                        "little",
                        "network",
                        "native"
                    ],
                    "default": "native"
                },
                {
                    "type": "string",
                    "pattern": "^#/"
                }
            ]
        }
    },
    "type": "object",
    "properties": {
        "id": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z_0-9]+$"
        },
        "title": {
            "$ref": "#/definitions/title"
        },
        "description": {
            "$ref": "#/definitions/description"
        },
        "endianness": {
            "$ref": "#/definitions/endianness"
        },
        "version": {
            "$ref": "#/definitions/version"
        },
        "date": {
            "type": "string",
            "format": "date-time"
        },
        "author": {
            "type": "string",
            "maxLength": 65
        },
        "documentation": {
            "type": "string",
            "format": "uri"
        },
        "metadata": {
            "type": "string",
            "format": "uri"
        },
        "enums": {
            "type": "object",
            "description": "Enumerated type definitions.",
            "minProperties": 1,
            "additionalProperties": {
                "type": "object",
                "properties": {
                    "title": {
                        "$ref": "#/definitions/title"
                    },
                    "description": {
                        "$ref": "#/definitions/description"
                    },
                    "version": {
                        "$ref": "#/definitions/version"
                    },
                    "preprocessor": {
                        "type": "boolean",
                        "default": false
                    },
                    "type": {
                        "$ref": "#/definitions/type"
                    },
                    "options": {
                        "type": "object",
                        "description": "Individual enumeration definitions.",
                        "minProperties": 1,
                        "additionalProperties": {
                            "type": "object",
                            "properties": {
                                "title": {
                                    "$ref": "#/definitions/title"
                                },
                                "description": {
                                    "$ref": "#/definitions/description"
                                },
                                "type": {
                                    "$ref": "#/definitions/type"
                                },
                                "value": {
                                    "type": [
                                        "string",
                                        "number",
                                        "boolean",
                                        "null"
                                    ]
                                }
                            }
                        }
                    }
                },
                "required": [
                    "options"
                ],
                "additionalProperties": false
            }
        },
        "packets": {
            "type": "object",
            "description": "Individual packet definitions.",
            "minProperties": 1,
            "additionalProperties": {
                "type": "object",
                "properties": {
                    "title": {
                        "$ref": "#/definitions/title"
                    },
                    "description": {
                        "$ref": "#/definitions/description"
                    },
                    "version": {
                        "$ref": "#/definitions/version"
                    },
                    "intermediate": {
                        "type": "boolean",
                        "default": false
                    },
                    "identifier": {
                        "type": "boolean",
                        "default": false
                    },
                    "endianness": {
                        "$ref": "#/definitions/endianness"
                    },
                    "structure": {
                        "type": "object",
                        "description": "Packet component definitions.",
                        "minProperties": 1,
                        "additionalProperties": {
                            "type": "object",
                            "properties": {
                                "title": {
                                    "$ref": "#/definitions/title"
                                },
                                "description": {
                                    "$ref": "#/definitions/description"
                                },
                                "type": {
                                    "$ref": "#/definitions/type"
                                },
                                "count": {
                                    "anyOf": [
                                        {
                                            "type": "integer",
                                            "minimum": 2,
                                            "multipleOf": 1.0
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^#/.+/value$"
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^(.+)$"
                                        }
                                    ]
                                },
                                "size": {
                                    "anyOf": [
                                        {
                                            "type": "integer",
                                            "minimum": 1,
                                            "multipleOf": 1.0
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^#/.+/value$"
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^(.+)$"
                                        }
                                    ]
                                },
                                "endianness": {
                                    "$ref": "#/definitions/endianness"
                                },
                                "max": {
                                    "anyOf": [
                                        {
                                            "type": "number"
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^#/.+/value$"
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^(.+)$"
                                        }
                                    ]
                                },
                                "min": {
                                    "anyOf": [
                                        {
                                            "type": "number"
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^#/.+/value$"
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^(.+)$"
                                        }
                                    ]
                                },
                                "member": {
                                    "anyOf": [
                                        {
                                            "type": "array",
                                            "minItems": 1,
                                            "items": {
                                                "type": [
                                                    "string",
                                                    "number",
                                                    "boolean",
                                                    "null"
                                                ]
                                            },
                                            "_uniqueItems": true
                                        },
                                        {
                                            "type": "string",
                                            "pattern": "^#/"
                                        }
                                    ]
                                }
                            },
                            "required": [
                                "type"
                            ],
                            "additionalProperties": false
                        }
                    }
                },
                "required": [
                    "structure"
                ],
                "additionalProperties": false
            }
        }
    },
    "required": [
        "id",
        "title",
        "packets"
    ],
    "additionalProperties": false
}