{
  "$schema": "http://json-schema.org/schema#",
  "id": "http://volatilityfoundation.org/intermediate-format/schema",
  "title": "Symbol Container",
  "type": "object",
  "definitions": {
    "element_metadata": {
      "type": "object",
      "properties": {
        "format": {
          "type": "string",
          "pattern": "^2.[0-9]+.[0-9]+$"
        },
        "source": {
          "type": "object",
          "properties": {
            "type": {
              "type": "string"
            }
          }
        },
        "producer": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "version": {
              "type": "string"
            },
            "datetime": {
              "type": "string",
              "format": "date-time"
            }
          }
        }
      },
      "required": [
        "format"
      ],
      "additionalProperties": false
    },
    "element_enum": {
      "properties": {
        "size": {
          "type": "integer"
        },
        "base": {
          "type": "string"
        },
        "constants": {
          "type": "object",
          "additionalProperties": {
            "type": "integer"
          }
        }
      },
      "required": [
        "size",
        "base",
        "constants"
      ],
      "additionalProperties": false
    },
    "element_symbol": {
      "properties": {
        "address": {
          "type": "number"
        },
        "linkage_name": {
          "type": "string"
        }
      },
      "required": [
        "address"
      ],
      "additionalProperties": false
    },
    "element_base_type": {
      "properties": {
        "size": {
          "type": "integer"
        }
      },
      "required": [
        "size"
      ],
      "additionalProperties": false
    },
    "element_user_type": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^(struct|union|class)$"
        },
        "size": {
          "type": "integer"
        },
        "fields": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/field"
          }
        }
      },
      "required": [
        "kind",
        "size",
        "fields"
      ],
      "additionalProperties": false
    },
    "field": {
      "properties": {
        "type": {
          "$ref": "#/definitions/type_descriptor"
        },
        "offset": {
          "type": "integer"
        }
      },
      "required": [
        "type",
        "offset"
      ],
      "additionalProperties": false
    },
    "type_descriptor": {
      "oneOf": [
        {
          "$ref": "#/definitions/type_pointer"
        },
        {
          "$ref": "#/definitions/type_base"
        },
        {
          "$ref": "#/definitions/type_array"
        },
        {
          "$ref": "#/definitions/type_struct"
        },
        {
          "$ref": "#/definitions/type_enum"
        },
        {
          "$ref": "#/definitions/type_function"
        },
        {
          "$ref": "#/definitions/type_bitfield"
        }
      ]
    },
    "type_pointer": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^pointer$"
        },
        "subtype": {
          "$ref": "#/definitions/type_descriptor"
        }
      },
      "required": [
        "kind",
        "subtype"
      ],
      "additionalProperties": false
    },
    "type_base": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^base$"
        },
        "name": {
          "type": "string"
        }
      },
      "required": [
        "kind",
        "name"
      ],
      "additionalProperties": false
    },
    "type_array": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^array$"
        },
        "subtype": {
          "$ref": "#/definitions/type_descriptor"
        },
        "count": {
          "type": "integer"
        }
      },
      "required": [
        "kind",
        "subtype",
        "count"
      ],
      "additionalProperties": false
    },
    "type_struct": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^(struct|class|union)$"
        },
        "name": {
          "type": "string"
        }
      },
      "required": [
        "kind",
        "name"
      ],
      "additionalProperties": false
    },
    "type_enum": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^enum$"
        },
        "name": {
          "type": "string"
        }
      },
      "required": [
        "kind",
        "name"
      ],
      "additionalProperties": false
    },
    "type_function": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^function$"
        }
      },
      "required": [
        "kind"
      ],
      "additionalProperties": false
    },
    "type_bitfield": {
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^bitfield$"
        },
        "bit_position": {
          "type": "integer"
        },
        "bit_length": {
          "type": "integer"
        },
        "type": {
          "$ref": "#/definitions/type_base"
        }
      },
      "required": [
        "kind",
        "bit_position",
        "bit_length",
        "type"
      ],
      "additionalProperties": false
    }
  },
  "properties": {
    "metadata": {
      "$ref": "#/definitions/element_metadata"
    },
    "base_types": {
      "additionalProperties": {
        "$ref": "#/definitions/element_base_type"
      }
    },
    "user_types": {
      "additionalProperties": {
        "$ref": "#/definitions/element_user_type"
      }
    },
    "enums": {
      "additionalProperties": {
        "$ref": "#/definitions/element_enum"
      }
    },
    "symbols": {
      "additionalProperties": {
        "$ref": "#/definitions/element_symbol"
      }
    }
  },
  "required": [
    "metadata",
    "base_types",
    "user_types",
    "enums",
    "symbols"
  ],
  "additionalProperties": false
}
