/* Copyright (c) 2015-2016 The Khronos Group Inc.
 * Copyright (c) 2015-2016 Valve Corporation
 * Copyright (c) 2015-2016 LunarG, Inc.
 * Copyright (C) 2015-2016 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Dustin Graves <dustin@lunarg.com>
 */

#ifndef PARAMETER_VALIDATION_UTILS_H
#define PARAMETER_VALIDATION_UTILS_H

#include <algorithm>
#include <cstdlib>
#include <string>
#include <sstream>
#include <bitset>
#include <mutex>
#include <unordered_map>
#include <unordered_set>

#include "vulkan/vulkan.h"
#include "vk_enum_string_helper.h"
#include "vk_layer_logging.h"
#include "vk_validation_error_messages.h"
#include "vk_extension_helper.h"


#include "parameter_name.h"

namespace parameter_validation {

extern const uint32_t GeneratedHeaderVersion;
extern const std::unordered_map<std::string, void*> name_to_funcptr_map;

extern const VkQueryPipelineStatisticFlags AllVkQueryPipelineStatisticFlagBits;
extern const VkColorComponentFlags AllVkColorComponentFlagBits;
extern const VkShaderStageFlags AllVkShaderStageFlagBits;
extern const VkQueryControlFlags AllVkQueryControlFlagBits;

extern const std::vector<VkCompareOp> AllVkCompareOpEnums;
extern const std::vector<VkStencilOp> AllVkStencilOpEnums;
extern const std::vector<VkBlendFactor> AllVkBlendFactorEnums;
extern const std::vector<VkBlendOp> AllVkBlendOpEnums;
extern const std::vector<VkLogicOp> AllVkLogicOpEnums;
extern const std::vector<VkBorderColor> AllVkBorderColorEnums;
extern const std::vector<VkImageLayout> AllVkImageLayoutEnums;

struct instance_layer_data {
    VkInstance instance = VK_NULL_HANDLE;

    debug_report_data *report_data = nullptr;
    std::vector<VkDebugReportCallbackEXT> logging_callback;

    // The following are for keeping track of the temporary callbacks that can
    // be used in vkCreateInstance and vkDestroyInstance:
    uint32_t num_tmp_callbacks = 0;
    VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos = nullptr;
    VkDebugReportCallbackEXT *tmp_callbacks = nullptr;
    InstanceExtensions extensions = {};
    VkLayerInstanceDispatchTable dispatch_table = {};
};

struct layer_data {
    debug_report_data *report_data = nullptr;
    // Map for queue family index to queue count
    std::unordered_map<uint32_t, uint32_t> queueFamilyIndexMap;
    VkPhysicalDeviceLimits device_limits = {};
    VkPhysicalDeviceFeatures physical_device_features = {};
    VkPhysicalDevice physical_device = VK_NULL_HANDLE;
    VkDevice device = VK_NULL_HANDLE;
    DeviceExtensions extensions;

    struct SubpassesUsageStates {
        std::unordered_set<uint32_t> subpasses_using_color_attachment;
        std::unordered_set<uint32_t> subpasses_using_depthstencil_attachment;
    };

    std::unordered_map<VkRenderPass, SubpassesUsageStates> renderpasses_states;

    VkLayerDispatchTable dispatch_table = {};
};

enum ErrorCode {
    NONE,                   // Used for INFO & other non-error messages
    INVALID_USAGE,          // The value of a parameter is not consistent
                            // with the valid usage criteria defined in
                            // the Vulkan specification.
    INVALID_STRUCT_STYPE,   // The sType field of a Vulkan structure does
                            // not contain the value expected for a structure
                            // of that type.
    INVALID_STRUCT_PNEXT,   // The pNext field of a Vulkan structure references
                            // a value that is not compatible with a structure of
                            // that type or is not NULL when a structure of that
                            // type has no compatible pNext values.
    REQUIRED_PARAMETER,     // A required parameter was specified as 0 or NULL.
    RESERVED_PARAMETER,     // A parameter reserved for future use was not
                            // specified as 0 or NULL.
    UNRECOGNIZED_VALUE,     // A Vulkan enumeration, VkFlags, or VkBool32 parameter
                            // contains a value that is not recognized as valid for
                            // that type.
    DEVICE_LIMIT,           // A specified parameter exceeds the limits returned
                            // by the physical device
    DEVICE_FEATURE,         // Use of a requested feature is not supported by
                            // the device
    FAILURE_RETURN_CODE,    // A Vulkan return code indicating a failure condition
                            // was encountered.
    EXTENSION_NOT_ENABLED,  // An extension entrypoint was called, but the required
                            // extension was not enabled at CreateInstance or
                            // CreateDevice time.
};

struct GenericHeader {
    VkStructureType sType;
    const void *pNext;
};

// Layer name string to be logged with validation messages.
const char LayerName[] = "ParameterValidation";

// String returned by string_VkStructureType for an unrecognized type.
const std::string UnsupportedStructureTypeString = "Unhandled VkStructureType";

// String returned by string_VkResult for an unrecognized type.
const std::string UnsupportedResultString = "Unhandled VkResult";

// The base value used when computing the offset for an enumeration token value that is added by an extension.
// When validating enumeration tokens, any value >= to this value is considered to be provided by an extension.
// See Appendix C.10 "Assigning Extension Token Values" from the Vulkan specification
const uint32_t ExtEnumBaseValue = 1000000000;

// The value of all VK_xxx_MAX_ENUM tokens
const uint32_t MaxEnumValue = 0x7FFFFFFF;

// Misc parameters of log_msg that are likely constant per command (or low frequency change)
struct LogMiscParams {
    const debug_report_data *debug_data;
    VkDebugReportObjectTypeEXT objectType;
    uint64_t srcObject;
    const char *pLayerPrefix;
    const char *api_name;
};

/**
* Validate a minimum value.
*
* Verify that the specified value is greater than the specified lower bound.
*
* @param report_data debug_report_data object for routing validation messages.
* @param api_name Name of API call being validated.
* @param parameter_name Name of parameter being validated.
* @param value Value to validate.
* @param lower_bound Lower bound value to use for validation.
* @return Boolean value indicating that the call should be skipped.
*/
template <typename T>
bool ValidateGreaterThan(const T value, const T lower_bound, const ParameterName &parameter_name,
                         const UNIQUE_VALIDATION_ERROR_CODE vuid, const LogMiscParams &misc) {
    bool skip_call = false;

    if (value <= lower_bound) {
        std::ostringstream ss;
        ss << misc.api_name << ": parameter " << parameter_name.get_name() << " (= " << value << ") is greater than " << lower_bound
           << ". " << validation_error_map[vuid];
        skip_call |= log_msg(misc.debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, misc.objectType, misc.srcObject, __LINE__, vuid,
                             misc.pLayerPrefix, "%s", ss.str().c_str());
    }

    return skip_call;
}

template <typename T>
bool ValidateGreaterThanZero(const T value, const ParameterName &parameter_name, const UNIQUE_VALIDATION_ERROR_CODE vuid,
                             const LogMiscParams &misc) {
    return ValidateGreaterThan(value, T{0}, parameter_name, vuid, misc);
}
/**
 * Validate a required pointer.
 *
 * Verify that a required pointer is not NULL.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param parameterName Name of parameter being validated.
 * @param value Pointer to validate.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_required_pointer(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                                      const void *value, UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;

    if (value == NULL) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             vuid, LayerName, "%s: required parameter %s specified as NULL. %s", apiName,
                             parameterName.get_name().c_str(), validation_error_map[vuid]);
    }

    return skip_call;
}

/**
 * Validate array count and pointer to array.
 *
 * Verify that required count and array parameters are not 0 or NULL.  If the
 * count parameter is not optional, verify that it is not 0.  If the array
 * parameter is NULL, and it is not optional, verify that count is 0.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param count Number of elements in the array.
 * @param array Array to validate.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                    const ParameterName &arrayName, T count, const void *array, bool countRequired, bool arrayRequired,
                    UNIQUE_VALIDATION_ERROR_CODE count_required_vuid, UNIQUE_VALIDATION_ERROR_CODE array_required_vuid) {
    bool skip_call = false;

    // Count parameters not tagged as optional cannot be 0
    if (countRequired && (count == 0)) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
            count_required_vuid, LayerName, "%s: parameter %s must be greater than 0. %s", apiName,
                             countName.get_name().c_str(), validation_error_map[count_required_vuid]);
    }

    // Array parameters not tagged as optional cannot be NULL, unless the count is 0
    if ((array == NULL) && arrayRequired && (count != 0)) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
            array_required_vuid, LayerName, "%s: required parameter %s specified as NULL. %s", apiName,
                             arrayName.get_name().c_str(), validation_error_map[array_required_vuid]);
    }

    return skip_call;
}

/**
* Validate pointer to array count and pointer to array.
*
* Verify that required count and array parameters are not NULL.  If count
* is not NULL and its value is not optional, verify that it is not 0.  If the
* array parameter is NULL, and it is not optional, verify that count is 0.
* The array parameter will typically be optional for this case (where count is
* a pointer), allowing the caller to retrieve the available count.
*
* @param report_data debug_report_data object for routing validation messages.
* @param apiName Name of API call being validated.
* @param countName Name of count parameter.
* @param arrayName Name of array parameter.
* @param count Pointer to the number of elements in the array.
* @param array Array to validate.
* @param countPtrRequired The 'count' parameter may not be NULL when true.
* @param countValueRequired The '*count' value may not be 0 when true.
* @param arrayRequired The 'array' parameter may not be NULL when true.
* @return Boolean value indicating that the call should be skipped.
*/
template <typename T>
bool validate_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                    const ParameterName &arrayName, const T *count, const void *array, bool countPtrRequired,
                    bool countValueRequired, bool arrayRequired, UNIQUE_VALIDATION_ERROR_CODE count_required_vuid,
                    UNIQUE_VALIDATION_ERROR_CODE array_required_vuid) {
    bool skip_call = false;

    if (count == NULL) {
        if (countPtrRequired) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName,
                                 countName.get_name().c_str());
        }
    } else {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, array ? (*count) : 0, array, countValueRequired,
                                    arrayRequired, count_required_vuid, array_required_vuid);
    }

    return skip_call;
}

/**
 * Validate a pointer to a Vulkan structure.
 *
 * Verify that a required pointer to a structure is not NULL.  If the pointer is
 * not NULL, verify that each structure's sType field is set to the correct
 * VkStructureType value.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param parameterName Name of struct parameter being validated.
 * @param sTypeName Name of expected VkStructureType value.
 * @param value Pointer to the struct to validate.
 * @param sType VkStructureType for structure validation.
 * @param required The parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_struct_type(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                          const char *sTypeName, const T *value, VkStructureType sType, bool required,
                          UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;

    if (value == NULL) {
        if (required) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName,
                                 parameterName.get_name().c_str());
        }
    } else if (value->sType != sType) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid,
                             LayerName, "%s: parameter %s->sType must be %s. %s", apiName, parameterName.get_name().c_str(),
                             sTypeName, validation_error_map[vuid]);
    }

    return skip_call;
}

/**
 * Validate an array of Vulkan structures
 *
 * Verify that required count and array parameters are not 0 or NULL.  If
 * the array contains 1 or more structures, verify that each structure's
 * sType field is set to the correct VkStructureType value.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param sTypeName Name of expected VkStructureType value.
 * @param count Number of elements in the array.
 * @param array Array to validate.
 * @param sType VkStructureType for structure validation.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                const ParameterName &arrayName, const char *sTypeName, uint32_t count, const T *array,
                                VkStructureType sType, bool countRequired, bool arrayRequired, UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired,
                                    VALIDATION_ERROR_UNDEFINED, vuid);
    } else {
        // Verify that all structs in the array have the correct type
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i].sType != sType) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, INVALID_STRUCT_STYPE, LayerName, "%s: parameter %s[%d].sType must be %s", apiName,
                                     arrayName.get_name().c_str(), i, sTypeName);
            }
        }
    }

    return skip_call;
}

/**
 * Validate an array of Vulkan structures.
 *
 * Verify that required count and array parameters are not NULL.  If count
 * is not NULL and its value is not optional, verify that it is not 0.
 * If the array contains 1 or more structures, verify that each structure's
 * sType field is set to the correct VkStructureType value.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param sTypeName Name of expected VkStructureType value.
 * @param count Pointer to the number of elements in the array.
 * @param array Array to validate.
 * @param sType VkStructureType for structure validation.
 * @param countPtrRequired The 'count' parameter may not be NULL when true.
 * @param countValueRequired The '*count' value may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                const ParameterName &arrayName, const char *sTypeName, uint32_t *count, const T *array,
                                VkStructureType sType, bool countPtrRequired, bool countValueRequired, bool arrayRequired,
                                UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;

    if (count == NULL) {
        if (countPtrRequired) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName,
                                 countName.get_name().c_str());
        }
    } else {
        skip_call |= validate_struct_type_array(report_data, apiName, countName, arrayName, sTypeName, (*count), array, sType,
                                                countValueRequired, arrayRequired, vuid);
    }

    return skip_call;
}

/**
* Validate a Vulkan handle.
*
* Verify that the specified handle is not VK_NULL_HANDLE.
*
* @param report_data debug_report_data object for routing validation messages.
* @param api_name Name of API call being validated.
* @param parameter_name Name of struct parameter being validated.
* @param value Handle to validate.
* @return Boolean value indicating that the call should be skipped.
*/
template <typename T>
bool validate_required_handle(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name, T value) {
    bool skip_call = false;

    if (value == VK_NULL_HANDLE) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as VK_NULL_HANDLE", api_name,
                             parameter_name.get_name().c_str());
    }

    return skip_call;
}

/**
* Validate an array of Vulkan handles.
*
* Verify that required count and array parameters are not NULL.  If count
* is not NULL and its value is not optional, verify that it is not 0.
* If the array contains 1 or more handles, verify that no handle is set to
* VK_NULL_HANDLE.
*
* @note This function is only intended to validate arrays of handles when none
*       of the handles are allowed to be VK_NULL_HANDLE.  For arrays of handles
*       that are allowed to contain VK_NULL_HANDLE, use validate_array() instead.
*
* @param report_data debug_report_data object for routing validation messages.
* @param api_name Name of API call being validated.
* @param count_name Name of count parameter.
* @param array_name Name of array parameter.
* @param count Number of elements in the array.
* @param array Array to validate.
* @param count_required The 'count' parameter may not be 0 when true.
* @param array_required The 'array' parameter may not be NULL when true.
* @return Boolean value indicating that the call should be skipped.
*/
template <typename T>
bool validate_handle_array(debug_report_data *report_data, const char *api_name, const ParameterName &count_name,
                           const ParameterName &array_name, uint32_t count, const T *array, bool count_required,
                           bool array_required) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, api_name, count_name, array_name, count, array, count_required, array_required,
                                    VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
    } else {
        // Verify that no handles in the array are VK_NULL_HANDLE
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i] == VK_NULL_HANDLE) {
                skip_call |=
                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                            REQUIRED_PARAMETER, LayerName, "%s: required parameter %s[%d] specified as VK_NULL_HANDLE", api_name,
                            array_name.get_name().c_str(), i);
            }
        }
    }

    return skip_call;
}

/**
 * Validate string array count and content.
 *
 * Verify that required count and array parameters are not 0 or NULL.  If the
 * count parameter is not optional, verify that it is not 0.  If the array
 * parameter is NULL, and it is not optional, verify that count is 0.  If the
 * array parameter is not NULL, verify that none of the strings are NULL.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param count Number of strings in the array.
 * @param array Array of strings to validate.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_string_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                  const ParameterName &arrayName, uint32_t count, const char *const *array, bool countRequired,
                                  bool arrayRequired, UNIQUE_VALIDATION_ERROR_CODE count_required_vuid,
                                  UNIQUE_VALIDATION_ERROR_CODE array_required_vuid) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired,
                                    count_required_vuid, array_required_vuid);
    } else {
        // Verify that strings in the array are not NULL
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i] == NULL) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, REQUIRED_PARAMETER, LayerName, "%s: required parameter %s[%d] specified as NULL",
                                     apiName, arrayName.get_name().c_str(), i);
            }
        }
    }

    return skip_call;
}

/**
 * Validate a structure's pNext member.
 *
 * Verify that the specified pNext value points to the head of a list of
 * allowed extension structures.  If no extension structures are allowed,
 * verify that pNext is null.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param parameter_name Name of parameter being validated.
 * @param allowed_struct_names Names of allowed structs.
 * @param next Pointer to validate.
 * @param allowed_type_count Total number of allowed structure types.
 * @param allowed_types Array of strcuture types allowed for pNext.
 * @param header_version Version of header defining the pNext validation rules.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_struct_pnext(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                                  const char *allowed_struct_names, const void *next, size_t allowed_type_count,
                                  const VkStructureType *allowed_types, uint32_t header_version,
                                  UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;
    std::unordered_set<const void *> cycle_check;
    std::unordered_set<VkStructureType, std::hash<int>> unique_stype_check;

    const char disclaimer[] =
        "This warning is based on the Valid Usage documentation for version %d of the Vulkan header.  It "
        "is possible that you are using a struct from a private extension or an extension that was added "
        "to a later version of the Vulkan header, in which case your use of %s is perfectly valid but "
        "is not guaranteed to work correctly with validation enabled";

    // TODO: The valid pNext structure types are not recursive. Each structure has its own list of valid sTypes for pNext.
    // Codegen a map of vectors containing the allowable pNext types for each struct and use that here -- also simplifies parms.
    if (next != NULL) {
        if (allowed_type_count == 0) {
            std::string message = "%s: value of %s must be NULL. %s ";
            message += disclaimer;
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 vuid, LayerName, message.c_str(), api_name, parameter_name.get_name().c_str(),
                                 validation_error_map[vuid], header_version, parameter_name.get_name().c_str());
        } else {
            const VkStructureType *start = allowed_types;
            const VkStructureType *end = allowed_types + allowed_type_count;
            const GenericHeader *current = reinterpret_cast<const GenericHeader *>(next);

            cycle_check.insert(next);

            while (current != NULL) {
                if (cycle_check.find(current->pNext) != cycle_check.end()) {
                    std::string message = "%s: %s chain contains a cycle -- pNext pointer " PRIx64 " is repeated.";
                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                         __LINE__, INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name,
                                         parameter_name.get_name().c_str(), reinterpret_cast<uint64_t>(next));
                    break;
                } else {
                    cycle_check.insert(current->pNext);
                }

                std::string type_name = string_VkStructureType(current->sType);
                if (unique_stype_check.find(current->sType) != unique_stype_check.end()) {
                    std::string message = "%s: %s chain contains duplicate structure types: %s appears multiple times.";
                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                         __LINE__, INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name,
                                         parameter_name.get_name().c_str(), type_name.c_str());
                } else {
                    unique_stype_check.insert(current->sType);
                }

                if (std::find(start, end, current->sType) == end) {
                    if (type_name == UnsupportedStructureTypeString) {
                        std::string message =
                            "%s: %s chain includes a structure with unknown VkStructureType (%d); Allowed structures are [%s]. %s ";
                        message += disclaimer;
                        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
                                             0, __LINE__, vuid, LayerName, message.c_str(), api_name,
                                             parameter_name.get_name().c_str(), current->sType, allowed_struct_names,
                                             validation_error_map[vuid], header_version, parameter_name.get_name().c_str());
                    } else {
                        std::string message =
                            "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures are [%s]. "
                            "%s ";
                        message += disclaimer;
                        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
                                             0, __LINE__, vuid, LayerName, message.c_str(), api_name,
                                             parameter_name.get_name().c_str(), type_name.c_str(), allowed_struct_names,
                                             validation_error_map[vuid], header_version, parameter_name.get_name().c_str());
                    }
                }
                current = reinterpret_cast<const GenericHeader *>(current->pNext);
            }
        }
    }

    return skip_call;
}

/**
* Validate a VkBool32 value.
*
* Generate a warning if a VkBool32 value is neither VK_TRUE nor VK_FALSE.
*
* @param report_data debug_report_data object for routing validation messages.
* @param apiName Name of API call being validated.
* @param parameterName Name of parameter being validated.
* @param value Boolean value to validate.
* @return Boolean value indicating that the call should be skipped.
*/
static bool validate_bool32(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                            VkBool32 value) {
    bool skip_call = false;

    if ((value != VK_TRUE) && (value != VK_FALSE)) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             UNRECOGNIZED_VALUE, LayerName, "%s: value of %s (%d) is neither VK_TRUE nor VK_FALSE", apiName,
                             parameterName.get_name().c_str(), value);
    }

    return skip_call;
}

/**
* Validate a Vulkan enumeration value.
*
* Generate a warning if an enumeration token value does not fall within the core enumeration
* begin and end token values, and was not added to the enumeration by an extension.  Extension
* provided enumerations use the equation specified in Appendix C.10 of the Vulkan specification,
* with 1,000,000,000 as the base token value.
*
* @note This function does not expect to process enumerations defining bitmask flag bits.
*
* @param report_data debug_report_data object for routing validation messages.
* @param apiName Name of API call being validated.
* @param parameterName Name of parameter being validated.
* @param enumName Name of the enumeration being validated.
* @param valid_values The list of valid values for the enumeration.
* @param value Enumeration value to validate.
* @return Boolean value indicating that the call should be skipped.
*/
template <typename T>
bool validate_ranged_enum(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                          const char *enumName, const std::vector<T> &valid_values, T value, UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip = false;

    if (std::find(valid_values.begin(), valid_values.end(), value) == valid_values.end()) {
        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, vuid,
                        LayerName,
                        "%s: value of %s (%d) does not fall within the begin..end range of the core %s "
                        "enumeration tokens and is not an extension added token. %s",
                        apiName, parameterName.get_name().c_str(), value, enumName, validation_error_map[vuid]);
    }

    return skip;
}

/**
* Validate an array of Vulkan enumeration value.
*
* Process all enumeration token values in the specified array and generate a warning if a value
* does not fall within the core enumeration begin and end token values, and was not added to
* the enumeration by an extension.  Extension provided enumerations use the equation specified
* in Appendix C.10 of the Vulkan specification, with 1,000,000,000 as the base token value.
*
* @note This function does not expect to process enumerations defining bitmask flag bits.
*
* @param report_data debug_report_data object for routing validation messages.
* @param apiName Name of API call being validated.
* @param countName Name of count parameter.
* @param arrayName Name of array parameter.
* @param enumName Name of the enumeration being validated.
* @param valid_values The list of valid values for the enumeration.
* @param count Number of enumeration values in the array.
* @param array Array of enumeration values to validate.
* @param countRequired The 'count' parameter may not be 0 when true.
* @param arrayRequired The 'array' parameter may not be NULL when true.
* @return Boolean value indicating that the call should be skipped.
*/
template <typename T>
static bool validate_ranged_enum_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                       const ParameterName &arrayName, const char *enumName, const std::vector<T> &valid_values,
                                       uint32_t count, const T *array, bool countRequired, bool arrayRequired) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired,
                                    VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
    } else {
        for (uint32_t i = 0; i < count; ++i) {
            if (std::find(valid_values.begin(), valid_values.end(), array[i]) == valid_values.end()) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, UNRECOGNIZED_VALUE, LayerName,
                                     "%s: value of %s[%d] (%d) does not fall within the begin..end range of the core %s "
                                     "enumeration tokens and is not an extension added token",
                                     apiName, arrayName.get_name().c_str(), i, array[i], enumName);
            }
        }
    }

    return skip_call;
}

/**
* Verify that a reserved VkFlags value is zero.
*
* Verify that the specified value is zero, to check VkFlags values that are reserved for
* future use.
*
* @param report_data debug_report_data object for routing validation messages.
* @param api_name Name of API call being validated.
* @param parameter_name Name of parameter being validated.
* @param value Value to validate.
* @return Boolean value indicating that the call should be skipped.
*/
static bool validate_reserved_flags(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                                    VkFlags value, UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;

    if (value != 0) {
        skip_call |=
            log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                    vuid, LayerName, "%s: parameter %s must be 0. %s", api_name, parameter_name.get_name().c_str(),
                    validation_error_map[vuid]);
    }

    return skip_call;
}

/**
* Validate a Vulkan bitmask value.
*
* Generate a warning if a value with a VkFlags derived type does not contain valid flag bits
* for that type.
*
* @param report_data debug_report_data object for routing validation messages.
* @param api_name Name of API call being validated.
* @param parameter_name Name of parameter being validated.
* @param flag_bits_name Name of the VkFlags type being validated.
* @param all_flags A bit mask combining all valid flag bits for the VkFlags type being validated.
* @param value VkFlags value to validate.
* @param flags_required The 'value' parameter may not be 0 when true.
* @param singleFlag The 'value' parameter may not contain more than one bit from all_flags.
* @return Boolean value indicating that the call should be skipped.
*/
static bool validate_flags(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                           const char *flag_bits_name, VkFlags all_flags, VkFlags value, bool flags_required, bool singleFlag,
                           UNIQUE_VALIDATION_ERROR_CODE vuid) {
    bool skip_call = false;

    if (value == 0) {
        if (flags_required) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 vuid, LayerName, "%s: value of %s must not be 0. %s", api_name,
                                 parameter_name.get_name().c_str(), validation_error_map[vuid]);
        }
    } else if ((value & (~all_flags)) != 0) {
        skip_call |=
            log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                    UNRECOGNIZED_VALUE, LayerName, "%s: value of %s contains flag bits that are not recognized members of %s",
                    api_name, parameter_name.get_name().c_str(), flag_bits_name);
    } else if (singleFlag && (std::bitset<sizeof(VkFlags) * 8>(value).count() > 1)) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             UNRECOGNIZED_VALUE, LayerName,
                             "%s: value of %s contains multiple members of %s when only a single value is allowed", api_name,
                             parameter_name.get_name().c_str(), flag_bits_name);
    }

    return skip_call;
}

/**
* Validate an array of Vulkan bitmask values.
*
* Generate a warning if a value with a VkFlags derived type does not contain valid flag bits
* for that type.
*
* @param report_data debug_report_data object for routing validation messages.
* @param api_name Name of API call being validated.
* @param count_name Name of parameter being validated.
* @param array_name Name of parameter being validated.
* @param flag_bits_name Name of the VkFlags type being validated.
* @param all_flags A bitmask combining all valid flag bits for the VkFlags type being validated.
* @param count Number of VkFlags values in the array.
* @param array Array of VkFlags value to validate.
* @param count_required The 'count' parameter may not be 0 when true.
* @param array_required The 'array' parameter may not be NULL when true.
* @return Boolean value indicating that the call should be skipped.
*/
static bool validate_flags_array(debug_report_data *report_data, const char *api_name, const ParameterName &count_name,
                                 const ParameterName &array_name, const char *flag_bits_name, VkFlags all_flags, uint32_t count,
                                 const VkFlags *array, bool count_required, bool array_required) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, api_name, count_name, array_name, count, array, count_required, array_required,
                                    VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
    } else {
        // Verify that all VkFlags values in the array
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i] == 0) {
                // Current XML registry logic for validity generation uses the array parameter's optional tag to determine if
                // elements in the array are allowed be 0
                if (array_required) {
                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                         __LINE__, REQUIRED_PARAMETER, LayerName, "%s: value of %s[%d] must not be 0", api_name,
                                         array_name.get_name().c_str(), i);
                }
            } else if ((array[i] & (~all_flags)) != 0) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, UNRECOGNIZED_VALUE, LayerName,
                                     "%s: value of %s[%d] contains flag bits that are not recognized members of %s", api_name,
                                     array_name.get_name().c_str(), i, flag_bits_name);
            }
        }
    }

    return skip_call;
}

/**
* Get VkResult code description.
*
* Returns a string describing the specified VkResult code.  The description is based on the language in the Vulkan API
* specification.
*
* @param value VkResult code to process.
* @return String describing the specified VkResult code.
*/
static std::string get_result_description(VkResult result) {
    // clang-format off
    switch (result) {
        case VK_SUCCESS:                        return "a command completed successfully";
        case VK_NOT_READY:                      return "a fence or query has not yet completed";
        case VK_TIMEOUT:                        return "a wait operation has not completed in the specified time";
        case VK_EVENT_SET:                      return "an event is signaled";
        case VK_EVENT_RESET:                    return "an event is unsignalled";
        case VK_INCOMPLETE:                     return "a return array was too small for the result";
        case VK_ERROR_OUT_OF_HOST_MEMORY:       return "a host memory allocation has failed";
        case VK_ERROR_OUT_OF_DEVICE_MEMORY:     return "a device memory allocation has failed";
        case VK_ERROR_INITIALIZATION_FAILED:    return "initialization of an object has failed";
        case VK_ERROR_DEVICE_LOST:              return "the logical device has been lost";
        case VK_ERROR_MEMORY_MAP_FAILED:        return "mapping of a memory object has failed";
        case VK_ERROR_LAYER_NOT_PRESENT:        return "the specified layer does not exist";
        case VK_ERROR_EXTENSION_NOT_PRESENT:    return "the specified extension does not exist";
        case VK_ERROR_FEATURE_NOT_PRESENT:      return "the requested feature is not available on this device";
        case VK_ERROR_INCOMPATIBLE_DRIVER:      return "a Vulkan driver could not be found";
        case VK_ERROR_TOO_MANY_OBJECTS:         return "too many objects of the type have already been created";
        case VK_ERROR_FORMAT_NOT_SUPPORTED:     return "the requested format is not supported on this device";
        case VK_ERROR_SURFACE_LOST_KHR:         return "a surface is no longer available";
        case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "the requested window is already connected to another "
                                                       "VkSurfaceKHR object, or some other non-Vulkan surface object";
        case VK_SUBOPTIMAL_KHR:                 return "an image became available, and the swapchain no longer "
                                                       "matches the surface properties exactly, but can still be used to "
                                                       "present to the surface successfully.";
        case VK_ERROR_OUT_OF_DATE_KHR:          return "a surface has changed in such a way that it is no "
                                                       "longer compatible with the swapchain";
        case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "the display used by a swapchain does not use the same "
                                                       "presentable image layout, or is incompatible in a way that prevents "
                                                       "sharing an image";
        case VK_ERROR_VALIDATION_FAILED_EXT:    return "API validation has detected an invalid use of the API";
        case VK_ERROR_INVALID_SHADER_NV:        return "one or more shaders failed to compile or link";
        default:                                return "an error has occurred";
    };
    // clang-format on
}

/**
* Validate return code.
*
* Print a message describing the reason for failure when an error code is returned.
*
* @param report_data debug_report_data object for routing validation messages.
* @param apiName Name of API call being validated.
* @param ignore vector of VkResult return codes to be ignored
* @param value VkResult value to validate.
*/
static void validate_result(debug_report_data *report_data, const char *apiName, std::vector<VkResult> const &ignore,
                            VkResult result) {
    if (result < 0 && result != VK_ERROR_VALIDATION_FAILED_EXT) {
        if (std::find(ignore.begin(), ignore.end(), result) != ignore.end()) {
            return;
        }
        std::string resultName = string_VkResult(result);
        if (resultName == UnsupportedResultString) {
            // Unrecognized result code
            log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                    FAILURE_RETURN_CODE, LayerName, "%s: returned a result code indicating that an error has occurred", apiName);
        } else {
            std::string resultDesc = get_result_description(result);
            log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                    FAILURE_RETURN_CODE, LayerName, "%s: returned %s, indicating that %s", apiName, resultName.c_str(),
                    resultDesc.c_str());
        }
    }
}

}  // namespace parameter_validation

#endif  // PARAMETER_VALIDATION_UTILS_H
