{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://files.pvs-studio.com/media/custom_annotations/v3/cpp-annotations.schema.json",
  "type": "object",
  "title": "PVS-Studio annotations for C and C++ analyzer",
  "description": "JSON Schema to check validity of annotation files.",
  "properties": {
    "$schema": {
      "description": "Schema for current json file. See https://pvs-studio.com/en/docs/manual/6810/#json_schemas for details",
      "type": "string"
    },
    "version": {
      "description": "Version of the annotation file",
      "type": "integer",
      "minimum": 4
    },
    "language": {
      "description": "Current language for annotations. Supported: c, cpp",
      "type": "string",
      "enum": [
        "cpp",
        "c"
      ]
    },
    "annotations": {
      "type": "array",
      "description": "Array of type or function annotations.",
      "uniqueItems": true,
      "items": {
        "oneOf": [
          {
            "$ref": "#/$defs/type_annotation"
          },
          {
            "$ref": "#/$defs/function_annotation"
          }
        ]
      }
    }
  },
  "additionalProperties": false,
  "required": [
    "version",
    "language",
    "annotations"
  ],
  "$defs": {
    "function_annotation": {
      "type": "object",
      "description": "Function annotation.",
      "additionalProperties": false,
      "properties": {
        "type": {
          "description": "Annotation type.",
          "enum": [
            "function",
            "ctor"
          ]
        },
        "name": {
          "type": "string",
          "description": "Function name. The qualified (full) name is specified for top-level annotations, and the unqualified name for other annotations. This field is required if \"type\" == \"function\", otherwise it should be omitted."
        },
        "attributes": {
          "type": "array",
          "description": "Function attributes. A detailed description of each attribute is described in the documentation.",
          "items": {
            "anyOf": [
              {
                "const": "pure",
                "description": "The function is pure. Supported since version 7.31."
              },
              {
                "const": "noreturn",
                "description": "The function does not return control flow to the caller function. Supported since version 7.31."
              },
              {
                "const": "nodiscard",
                "description": "The result of the function should be used. Supported since version 7.31."
              },
              {
                "const": "nullable_uninitialized",
                "description": "A custom nullable-type member function puts the object in the 'invalid' state. Supported since version 7.31."
              },
              {
                "const": "nullable_initialized",
                "description": "A custom nullable-type member function puts the object in the 'valid' state. Supported since version 7.31."
              },
              {
                "const": "nullable_checker",
                "description": "The function checks the state of the user nullable type. If the function returns true, the object is considered to be in a 'valid' state; if not, it is 'invalid'. The result of the function is to be implicitly converted to the 'bool' type. Supported since version 7.31."
              },
              {
                "const": "nullable_getter",
                "description": "The function performs access to internal data of the user nullable type. The object must be in the 'valid' state. Supported since version 7.31."
              },
              {
                "const": "nullable_resetter",
                "description": "The function of a custom nullable type modifies an object state. If the function doesn't take parameters, the object will be set to an invalid state. If the function takes one or more parameters, the object's new state and value are determined based on the arguments passed. Supported since version 7.43."
              },
              {
                "const": "dangerous",
                "description": "The function is marked as dangerous, and the program code must not contain its call. Supported since version 7.31."
              },
              {
                "const": "memory_allocator",
                "description": "The function that allocates memory. Supported since version 7.40."
              },
              {
                "const": "constructor_like",
                "description": "The function, which initializes class data members and handled by analyzer as a class constructor(initializer). Supported since version 7.39."
              },
              {
                "type": "string",
                "pattern": "^alloc-group\\s*\\(\\s*[a-zA-Z_]+(?:\\s*,\\s*[a-zA-Z_]+)*\\s*\\)$",
                "description": "The attribute that specifies allocator/deallocator pairs. Supported since version 7.40."
              }
            ]
          }
        },
        "params": {
          "type": "array",
          "description": "Array of objects describing formal parameters of the function. Participates in forming the function signature to be searched by the analyzer.",
          "items": {
            "type": "object",
            "description": "Object describing a formal parameter of the function.",
            "additionalProperties": false,
            "properties": {
              "type": {
                "type": "string",
                "description": "Type of formal parameter in the form of a string. It is allowed to use placeholders - '*' or '?'.",
                "minLength": 1
              },
              "attributes": {
                "type": "array",
                "description": "Attributes of formal parameters. Detailed description of each attribute is described in the documentation",
                "items": {
                  "anyOf":
                  [
                    {
                      "const": "immutable",
                      "description": "It is indicates to the analyzer that the passed argument has not been modified after the function call. For example, the 'printf' function has side effects (printing to stdout) but does not modify passed arguments. Supported since version 7.31."
                    },
                    {
                      "const": "not_null",
                      "description": "It is valid only for nullable-type parameters. An argument in the 'valid' state should be passed to the function. Supported since version 7.31."
                    },
                    {
                      "const": "unique_arg",
                      "description": "The arguments passed should be different. For example, it doesn't make sense to pass two identical arguments to 'std::swap'. Supported since version 7.31."
                    },
                    {
                      "const": "format_arg",
                      "description": "The parameter denotes a format string. The analyzer checks the arguments according to the 'printf' format specification. Supported since version 7.31."
                    },
                    {
                      "const": "pointer_to_free",
                      "description": "A pointer by which memory is released in the function by using 'free'. The pointer can be null. Supported since version 7.31."
                    },
                    {
                      "const": "pointer_to_gfree",
                      "description": "A pointer by which memory is released in the function by using 'g_free'. The pointer can be null. Supported since version 7.31."
                    },
                    {
                      "const": "pointer_to_delete",
                      "description": "A pointer by which memory is released in the function by using 'operator delete'. The pointer can be null. Supported since version 7.31."
                    },
                    {
                      "const": "pointer_to_delete[]",
                      "description": "A pointer by which memory is released in the function by using 'operator delete[]'. The pointer can be null. Supported since version 7.31."
                    },
                    {
                      "const": "pointer_to_unmap",
                      "description": "A pointer by which memory is released in the function by using 'munmap'. The pointer can be null. Supported since version 7.31."
                    },
                    {
                      "const": "taint_source",
                      "description": "Data returned via a parameter is from a tainted source. Supported since version 7.33."
                    },
                    {
                      "const": "taint_sink",
                      "description": "Data passed via a parameter can lead to vulnerability exploitation if it is obtained from a tainted source. Supported since version 7.33."
                    },
                    {
                      "const": "non_empty_string",
                      "description": "The parameter that must take any non-empty string. Supported since version 7.33."
                    },
                    {
                      "const": "lower_bound",
                      "description": "The parameter represents the lower boundary of some range, e.g. the second parameter of the 'std::clamp'. Supported since version 7.33."
                    },
                    {
                      "const": "upper_bound",
                      "description": "The parameter represents the upper boundary of some range, e.g. the third parameter of the 'std::clamp'. Supported since version 7.33."
                    },
                    {
                      "const": "in_range_value",
                      "description": "The value passed to the parameter is checked to be within range, e.g. the first parameter of the 'std::clamp'. The range is specified by parameters annotated as 'lower_bound' and 'upper_bound'. Supported since version 7.33."
                    }
                  ]
                }
              }
            },
            "required": [
              "type"
            ]
          }
        },
        "returns": {
          "type": "object",
          "description": "Object describing the attributes of the function return value",
          "additionalProperties": false,
          "properties": {
            "attributes": {
              "type": "array",
              "description": "Attributes of return value. Detailed description of each attribute is described in the documentation.",
              "items": {
                "anyOf":
                [
                  {
                    "const": "not_null",
                    "description": "The function always returns an object of a nullable-type in the 'valid' state. Supported since version 7.31."
                  },
                  {
                    "const": "maybe_null",
                    "description": "The function may return an object of a nullable-type in the 'invalid' state. An object should be checked before dereferencing. Supported since version 7.31."
                  },
                  {
                    "const": "always_null",
                    "description": "The function always returns a nullable object in the 'invalid' state. Supported since version 7.31."
                  },
                  {
                    "const": "taint_source",
                    "description": "The function may return data from a tainted source. Supported since version 7.33."
                  }
                ]
              }
            }
          },
          "required": [
            "attributes"
          ]
        },
        "template_params": {
          "type": "array",
          "description": "An array of strings that enables specifying the template parameters of the function.",
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "qualifiers": {
          "type": "array",
          "description": "An array of string that enables to apply the annotation only to a member function with a specific set of cvref-qualifiers.",
          "items": {
            "enum": [
              "const",
              "volatile",
              "&",
              "&&"
            ]
          }
        }
      },
      "anyOf": [
        {
          "allOf": [
            {
              "properties": {
                "type": {
                  "const": "ctor"
                }
              }
            },
            {
              "not": {
                "required": [
                  "name",
                  "qualifiers"
                ]
              }
            }
          ]
        },
        {
          "allOf": [
            {
              "properties": {
                "type": {
                  "const": "function"
                }
              }
            },
            {
              "required": [
                "name"
              ]
            }
          ]
        }
      ]
    },
    "type_annotation": {
      "type": "object",
      "description": "Type annotation.",
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "description": "Annotation type. The values 'class', 'struct' and 'union' are aliases for 'record'.",
          "enum": [
            "record",
            "class",
            "struct",
            "union"
          ]
        },
        "name": {
          "type": "string",
          "description": "Type name. The qualified (full) name is specified for top-level annotations, and the unqualified name for other annotations. This field is required if \"type\" == \"function\", otherwise it should be omitted."
        },
        "members": {
          "type": "array",
          "description": "Array of nested annotations.",
          "items": {
            "anyOf": [
              {
                "$ref": "#/$defs/function_annotation"
              },
              {
                "$ref": "#/$defs/type_annotation"
              }
            ]
          }
        },
        "attributes": {
          "type": "array",
          "description": "Type attributes. A detailed description of each attribute is described in the documentation.",
          "items": {
            "anyOf":
            [
              {
                "const": "array",
                "description": "The type has the 'std::array' interface. Supported since version 7.31."
              },
              {
                "const": "auto_ptr",
                "description": "The type has the 'std::auto_ptr' interface. Supported since version 7.31."
              },
              {
                "const": "cheap_to_copy",
                "description": "An object of the type can be passed to a function by copy with zero overhead. Supported since version 7.31."
              },
              {
                "const": "copy_on_write",
                "description": "The type has the copy-on-write semantics. Supported since version 7.31."
              },
              {
                "const": "exception",
                "description": "A type used to create an object that will be thrown as an exception. Supported since version 7.33."
              },
              {
                "const": "expensive_to_copy",
                "description": "An object of the type should be passed to a function only by pointer/reference. Supported since version 7.31."
              },
              {
                "const": "iterator",
                "description": "The type has the 'std::iterator' interface. Supported since version 7.39."
              },
              {
                "const": "list",
                "description": "The type has the 'std::list' interface. Supported since version 7.31."
              },
              {
                "const": "map",
                "description": "The type has the 'std::map' interface. Supported since version 7.31."
              },
              {
                "const": "multi",
                "description": "In combination with 'set' or 'map' sets the type interface to 'std::multiset' or 'std::multimap', respectively. If 'unordered' is included, the type is given the 'std::unordered_multiset' or 'std::unordered_multimap' semantics. Supported since version 7.31."
              },
              {
                "const": "nullable",
                "description": "The type has the semantics of a nullable type. Objects of these types can have one of two states: 'valid' or 'invalid'. Accessing an object in the 'invalid' state results in an error. Pointers, iterators, and 'std::optional' are examples of such types. Supported since version 7.31."
              },
              {
                "const": "set",
                "description": "The type has the 'std::set' interface. Supported since version 7.31."
              },
              {
                "const": "shared_ptr",
                "description": "The type has the 'std::shared_ptr' interface. Supported since version 7.31."
              },
              {
                "const": "string_view",
                "description": "The type has the 'std::basic_string_view' interface. Supported since version 7.31."
              },
              {
                "const": "string",
                "description": "The type has the 'std::basic_string' interface. Supported since version 7.31."
              },
              {
                "const": "unique_ptr",
                "description": "The type has the 'std::unique_ptr' interface. Supported since version 7.31."
              },
              {
                "const": "unordered",
                "description": "In combination with 'set' or 'map' sets the type interface to 'std::unordered_set' or 'std::unordered_map', respectively. Supported since version 7.31."
              },
              {
                "const": "vector",
                "description": "The type has the 'std::vector' interface. Supported since version 7.31."
              }
            ]
          }
        }
      },
      "required": [
        "type",
        "name"
      ]
    }
  }
}