{
    "$schema": "http://json-schema.org/draft-06/schema#",
    "title": "Avro Schema Definition",
    "description": "Json-Schema definition for Avro AVSC files.",
    "definitions": {
        "avroSchema": {
            "title": "Avro Schema",
            "description": "Root Schema",
            "oneOf": [
                {
                    "$ref": "#/definitions/types"
                }
            ]
        },
        "types": {
            "title": "Avro Types",
            "description": "Allowed Avro types",
            "oneOf": [
                {
                    "$ref": "#/definitions/primitiveType"
                },
                {
                    "$ref": "#/definitions/customTypeReference"
                },
                {
                    "$ref": "#/definitions/avroRecord"
                },
                {
                    "$ref": "#/definitions/avroEnum"
                },
                {
                    "$ref": "#/definitions/avroArray"
                },
                {
                    "$ref": "#/definitions/avroMap"
                },
                {
                    "$ref": "#/definitions/avroFixed"
                },
                {
                    "$ref": "#/definitions/avroUnion"
                }
            ]
        },
        "primitiveType": {
            "title": "Primitive Type",
            "description": "Basic type primitives.",
            "type": "string",
            "enum": [
                "null",
                "boolean",
                "int",
                "long",
                "float",
                "double",
                "bytes",
                "string"
            ]
        },
        "customTypeReference": {
            "title": "Custom Type",
            "description": "Reference to a ComplexType",
            "not": {
                "$ref": "#/definitions/primitiveType"
            },
            "type": "string",
            "pattern": "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$"
        },
        "avroUnion": {
            "title": "Union",
            "description": "A Union of types",
            "type": "array",
            "items": {
                "$ref": "#/definitions/avroSchema"
            },
            "minItems": 1
        },
        "avroField": {
            "title": "Field",
            "description": "A field within a Record",
            "type": "object",
            "properties": {
                "name": {
                    "$ref": "#/definitions/name"
                },
                "type": {
                    "$ref": "#/definitions/types"
                },
                "doc": {
                    "type": "string"
                },
                "default": {},
                "order": {
                    "enum": [
                        "ascending",
                        "descending",
                        "ignore"
                    ]
                },
                "aliases": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                }
            },
            "required": [
                "name",
                "type"
            ]
        },
        "avroRecord": {
            "title": "Record",
            "description": "A Record",
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": [
                        "record"
                    ]
                },
                "name": {
                    "$ref": "#/definitions/name"
                },
                "namespace": {
                    "$ref": "#/definitions/namespace"
                },
                "doc": {
                    "type": "string"
                },
                "aliases": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                },
                "fields": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/avroField"
                    }
                }
            },
            "required": [
                "type",
                "name",
                "fields"
            ]
        },
        "avroEnum": {
            "title": "Enum",
            "description": "An enumeration",
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": [
                        "enum"
                    ]
                },
                "name": {
                    "$ref": "#/definitions/name"
                },
                "namespace": {
                    "$ref": "#/definitions/namespace"
                },
                "doc": {
                    "type": "string"
                },
                "aliases": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                },
                "symbols": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                }
            },
            "required": [
                "type",
                "name",
                "symbols"
            ]
        },
        "avroArray": {
            "title": "Array",
            "description": "An array",
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": [
                        "array"
                    ]
                },
                "name": {
                    "$ref": "#/definitions/name"
                },
                "namespace": {
                    "$ref": "#/definitions/namespace"
                },
                "doc": {
                    "type": "string"
                },
                "aliases": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                },
                "items": {
                    "$ref": "#/definitions/types"
                }
            },
            "required": [
                "type",
                "items"
            ]
        },
        "avroMap": {
            "title": "Map",
            "description": "A map of values",
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": [
                        "map"
                    ]
                },
                "name": {
                    "$ref": "#/definitions/name"
                },
                "namespace": {
                    "$ref": "#/definitions/namespace"
                },
                "doc": {
                    "type": "string"
                },
                "aliases": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                },
                "values": {
                    "$ref": "#/definitions/types"
                }
            },
            "required": [
                "type",
                "values"
            ]
        },
        "avroFixed": {
            "title": "Fixed",
            "description": "A fixed sized array of bytes",
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": [
                        "fixed"
                    ]
                },
                "name": {
                    "$ref": "#/definitions/name"
                },
                "namespace": {
                    "$ref": "#/definitions/namespace"
                },
                "doc": {
                    "type": "string"
                },
                "aliases": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/name"
                    }
                },
                "size": {
                    "type": "number"
                }
            },
            "required": [
                "type",
                "name",
                "size"
            ]
        },
        "name": {
            "type": "string",
            "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
        },
        "namespace": {
            "type": "string",
            "pattern": "^([A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*)*$"
        }
    },
    "oneOf": [
        {
            "$ref": "#/definitions/avroSchema"
        }
    ]
}