#!/usr/bin/python3
#
# Copyright (c) 2019 Valve Corporation
# Copyright (c) 2019 LunarG, Inc.
# Copyright (c) 2019 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: Charles Giessen <charles@lunarg.com>

import os
import re
import sys
import string
import xml.etree.ElementTree as etree
import generator as gen
import operator
from collections import namedtuple
from collections import OrderedDict
from generator import *
from common_codegen import *

license_header = '''
/*
 * Copyright (c) 2019 The Khronos Group Inc.
 * Copyright (c) 2019 Valve Corporation
 * Copyright (c) 2019 LunarG, 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: Charles Giessen <charles@lunarg.com>
 *
 */

/*
 * This file is generated from the Khronos Vulkan XML API Registry.
 */
'''

custom_formaters = '''
std::ostream &operator<<(std::ostream &o, VkConformanceVersionKHR &c) {
    return o << std::to_string(c.major) << "." << std::to_string(c.minor) << "." << std::to_string(c.subminor) << "."
             << std::to_string(c.patch);
}

std::string VkExtent3DString(VkExtent3D e) {
    return std::string("(") + std::to_string(e.width) + ", " + std::to_string(e.height) + ", " + std::to_string(e.depth) + ")";
}

template <typename T>
std::string to_hex_str(T i) {
    std::stringstream stream;
    stream << "0x" << std::setfill('0') << std::setw(sizeof(T)) << std::hex << i;
    return stream.str();
}

template <typename T>
std::string to_hex_str(Printer &p, T i) {
    if (p.Type() == OutputType::json)
        return std::to_string(i);
    else
        return to_hex_str(i);
}
'''

# used in the .cpp code
structures_to_gen = ['VkExtent3D', 'VkExtent2D', 'VkPhysicalDeviceLimits', 'VkPhysicalDeviceFeatures',
                     'VkPhysicalDeviceSparseProperties', 'VkSurfaceCapabilitiesKHR', 'VkSurfaceFormatKHR', 'VkLayerProperties']
enums_to_gen = ['VkResult', 'VkFormat', 'VkPresentModeKHR',
                'VkPhysicalDeviceType', 'VkImageTiling']
flags_to_gen = ['VkSurfaceTransformFlagsKHR', 'VkCompositeAlphaFlagsKHR',
                'VkDeviceGroupPresentModeFlagsKHR', 'VkFormatFeatureFlags', 'VkMemoryPropertyFlags', 'VkMemoryHeapFlags']
flags_strings_to_gen = ['VkQueueFlags']

struct_comparisons_to_gen = ['VkSurfaceFormatKHR', 'VkSurfaceFormat2KHR', 'VkSurfaceCapabilitiesKHR',
                             'VkSurfaceCapabilities2KHR', 'VkSurfaceCapabilities2EXT']

# iostream or custom outputter handles these types
predefined_types = ['char', 'VkBool32', 'uint32_t', 'uint8_t', 'int32_t',
                    'float', 'uint64_t', 'size_t', 'VkDeviceSize', 'VkConformanceVersionKHR']
# need list of venders to blacklist vendor extensions
vendor_abbreviations = ['_IMG', '_AMD', '_AMDX', '_ARM', '_FSL', '_BRCM', '_NXP', '_NV', '_NVX', '_VIV', '_VSI', '_KDAB',
                        '_ANDROID', '_CHROMIUM', '_FUCHSIA', '_GGP', '_GOOGLE', '_QCOM', '_LUNARG', '_SAMSUNG', '_SEC', '_TIZEN',
                        '_RENDERDOC', '_NN', '_MVK', '_KHX', '_MESA', '_INTEL']

# Types that need pNext Chains built. 'extends' is the xml tag used in the structextends member. 'type' can be device, instance, or both
EXTENSION_CATEGORIES = {'phys_device_props2': {'extends': 'VkPhysicalDeviceProperties2', 'type': 'device'},
                        'phys_device_mem_props2': {'extends': 'VkPhysicalDeviceMemoryProperties2', 'type': 'device'},
                        'phys_device_features2': {'extends': 'VkPhysicalDeviceFeatures2,VkDeviceCreateInfo', 'type': 'device'},
                        'surface_capabilities2': {'extends': 'VkSurfaceCapabilities2KHR', 'type': 'both'},
                        'format_properties2': {'extends': 'VkFormatProperties2', 'type': 'device'}
                        }


class VulkanInfoGeneratorOptions(GeneratorOptions):
    def __init__(self,
                 conventions=None,
                 input=None,
                 filename=None,
                 directory='.',
                 apiname=None,
                 profile=None,
                 versions='.*',
                 emitversions='.*',
                 defaultExtensions=None,
                 addExtensions=None,
                 removeExtensions=None,
                 emitExtensions=None,
                 sortProcedure=None,
                 prefixText="",
                 genFuncPointers=True,
                 protectFile=True,
                 protectFeature=True,
                 protectProto=None,
                 protectProtoStr=None,
                 apicall='',
                 apientry='',
                 apientryp='',
                 indentFuncProto=True,
                 indentFuncPointer=False,
                 alignFuncParam=0,
                 expandEnumerants=True,
                 ):
        GeneratorOptions.__init__(self, conventions, filename, directory, apiname, profile,
                                  versions, emitversions, defaultExtensions,
                                  addExtensions, removeExtensions, emitExtensions, sortProcedure)
        self.input = input
        self.prefixText = prefixText
        self.genFuncPointers = genFuncPointers
        self.protectFile = protectFile
        self.protectFeature = protectFeature
        self.protectProto = protectProto
        self.protectProtoStr = protectProtoStr
        self.apicall = apicall
        self.apientry = apientry
        self.apientryp = apientryp
        self.indentFuncProto = indentFuncProto
        self.indentFuncPointer = indentFuncPointer
        self.alignFuncParam = alignFuncParam

# VulkanInfoGenerator - subclass of OutputGenerator.
# Generates a vulkan info output helper function


class VulkanInfoGenerator(OutputGenerator):

    def __init__(self,
                 errFile=sys.stderr,
                 warnFile=sys.stderr,
                 diagFile=sys.stdout):
        OutputGenerator.__init__(self, errFile, warnFile, diagFile)

        self.constants = OrderedDict()

        self.extension_sets = OrderedDict()
        for ext_cat in EXTENSION_CATEGORIES.keys():
            self.extension_sets[ext_cat] = set()

        self.enums = set()
        self.flags = set()
        self.bitmasks = set()
        self.structures = set()
        self.structs_to_comp = set()
        self.all_structures = set()

        self.types_to_gen = set()

        self.extFuncs = OrderedDict()
        self.extTypes = OrderedDict()

    def beginFile(self, genOpts):
        gen.OutputGenerator.beginFile(self, genOpts)

        root = self.registry.reg

        for node in self.registry.reg.findall('enums'):
            if node.get('name') == 'API Constants':
                for item in node.findall('enum'):
                    self.constants[item.get('name')] = item.get('value')

        for node in root.find('extensions').findall('extension'):
            ext = VulkanExtension(node)
            for item in ext.vktypes:
                self.extTypes[item] = ext
            for item in ext.vkfuncs:
                self.extFuncs[item] = ext

    def endFile(self):
        types_to_gen = set()
        for s in enums_to_gen:
            types_to_gen.add(s)

        for f in flags_to_gen:
            types_to_gen.add(f)

        types_to_gen = types_to_gen.union(GatherTypesToGen(self.structures))
        for key, value in EXTENSION_CATEGORIES.items():
            types_to_gen = types_to_gen.union(
                GatherTypesToGen(self.extension_sets[key]))

        structs_to_comp = set()
        for s in struct_comparisons_to_gen:
            structs_to_comp.add(s)
        structs_to_comp = structs_to_comp.union(
            GatherTypesToGen(self.structs_to_comp))

        self.enums = sorted(self.enums, key=operator.attrgetter('name'))
        self.flags = sorted(self.flags, key=operator.attrgetter('name'))
        self.bitmasks = sorted(self.bitmasks, key=operator.attrgetter('name'))
        self.structures = sorted(
            self.structures, key=operator.attrgetter('name'))
        self.all_structures = sorted(
            self.all_structures, key=operator.attrgetter('name'))

        for key, value in self.extension_sets.items():
            self.extension_sets[key] = sorted(
                value, key=operator.attrgetter('name'))

        out = ''
        out += license_header + "\n"
        out += "#include \"vulkaninfo.h\"\n"
        out += "#include \"outputprinter.h\"\n"
        out += custom_formaters

        for e in self.enums:
            if e.name in types_to_gen:
                out += PrintEnumToString(e, self)
                out += PrintEnum(e, self)

        for f in self.flags:
            if f.name in types_to_gen:
                for b in self.bitmasks:
                    if b.name == f.enum:
                        out += PrintFlags(f, b, self)
                        out += PrintBitMask(b, f.name, self)

            if f.name in flags_strings_to_gen:
                for b in self.bitmasks:
                    if b.name == f.enum:
                        out += PrintBitMaskToString(b, f.name, self)

        # find all structures needed to dump the requested structures
        structure_names = set()
        for s in self.all_structures:
            if s.name in types_to_gen:
                structure_names.add(s.name)

        for s in self.all_structures:
            if s.name in types_to_gen:
                out += PrintForwardDeclaration(s, self)

        for s in self.all_structures:
            if s.name in types_to_gen:
                out += PrintStructure(s, structure_names, self)

        out += "pNextChainInfos get_chain_infos() {\n"
        out += "    pNextChainInfos infos;\n"
        for key, value in EXTENSION_CATEGORIES.items():
            out += PrintChainBuilders(key, self.extension_sets[key])
        out += "    return infos;\n}\n"

        for key, value in EXTENSION_CATEGORIES.items():
            out += PrintChainIterator(key,
                                      self.extension_sets[key], value.get('type'))

        for s in self.all_structures:
            if s.name in structs_to_comp:
                out += PrintStructComparisonForwardDef(s)

        for s in self.all_structures:
            if s.name in structs_to_comp:
                out += PrintStructComparison(s)

        gen.write(out, file=self.outFile)

        gen.OutputGenerator.endFile(self)

    def genCmd(self, cmd, name, alias):
        gen.OutputGenerator.genCmd(self, cmd, name, alias)

    # These are actually constants
    def genEnum(self, enuminfo, name, alias):
        gen.OutputGenerator.genEnum(self, enuminfo, name, alias)

    # These are actually enums
    def genGroup(self, groupinfo, groupName, alias):
        gen.OutputGenerator.genGroup(self, groupinfo, groupName, alias)

        if alias is not None:
            return

        if groupinfo.elem.get('type') == 'bitmask':
            self.bitmasks.add(VulkanBitmask(groupinfo.elem))
        elif groupinfo.elem.get('type') == 'enum':
            self.enums.add(VulkanEnum(groupinfo.elem))

    def genType(self, typeinfo, name, alias):
        gen.OutputGenerator.genType(self, typeinfo, name, alias)

        if alias is not None:
            return

        if typeinfo.elem.get('category') == 'bitmask':
            self.flags.add(VulkanFlags(typeinfo.elem))

        if typeinfo.elem.get('category') == 'struct' and name in structures_to_gen:
            self.structures.add(VulkanStructure(
                name, typeinfo.elem, self.constants, self.extTypes))

        if typeinfo.elem.get('category') == 'struct' and name in struct_comparisons_to_gen:
            self.structs_to_comp.add(VulkanStructure(
                name, typeinfo.elem, self.constants, self.extTypes))

        if typeinfo.elem.get('category') == 'struct':
            self.all_structures.add(VulkanStructure(
                name, typeinfo.elem, self.constants, self.extTypes))

        for vendor in vendor_abbreviations:
            for node in typeinfo.elem.findall('member'):
                if(node.get('values') is not None):
                    if(node.get('values').find(vendor)) != -1:
                        return

        for key, value in EXTENSION_CATEGORIES.items():
            if typeinfo.elem.get('structextends') == value.get('extends'):
                self.extension_sets[key].add(VulkanStructure(
                    name, typeinfo.elem, self.constants, self.extTypes))


def GatherTypesToGen(structures):
    types = set()
    added_stuff = True  # repeat until no new types are added
    while added_stuff == True:
        added_stuff = False
        for s in structures:
            size = len(types)
            types.add(s.name)
            if len(types) != size:
                added_stuff = True
            for m in s.members:
                if m.typeID not in predefined_types and m.name not in ['sType', 'pNext']:
                    types.add(m.typeID)
    return types


def GetExtension(name, generator):
    if name in generator.extFuncs:
        return generator.extFuncs[name]
    elif name in generator.extTypes:
        return generator.extTypes[name]
    else:
        return None


def AddGuardHeader(obj):
    if obj is not None and obj.guard is not None:
        return "#ifdef {}\n".format(obj.guard)
    else:
        return ""


def AddGuardFooter(obj):
    if obj is not None and obj.guard is not None:
        return "#endif  // {}\n".format(obj.guard)
    else:
        return ""


def PrintEnumToString(e, gen):
    out = ''
    out += AddGuardHeader(GetExtension(e.name, gen))

    out += "static const char *" + e.name + "String(" + e.name + " value) {\n"
    out += "    switch (value) {\n"
    for v in e.options:
        out += "        case (" + str(v.value) + \
            "): return \"" + v.name[3:] + "\";\n"
    out += "        default: return \"UNKNOWN_" + e.name + "\";\n"
    out += "    }\n}\n"
    out += AddGuardFooter(GetExtension(e.name, gen))
    return out


def PrintEnum(e, gen):
    out = ''
    out += AddGuardHeader(GetExtension(e.name, gen))
    out += "void Dump" + e.name + \
        "(Printer &p, std::string name, " + \
        e.name + " value, int width = 0) {\n"
    out += "    if (p.Type() == OutputType::json) {\n"
    out += "        p.PrintKeyValue(name, value, width);\n"
    out += "        return;\n"
    out += "    } else {\n"
    out += "        p.PrintKeyValue(name, " + \
        e.name + "String(value), width);\n    }\n"
    out += "}\n"
    out += AddGuardFooter(GetExtension(e.name, gen))
    return out


def PrintFlags(f, b, gen):
    out = ''
    out += AddGuardHeader(GetExtension(f.name, gen))

    out += "void Dump" + f.name + \
        "(Printer &p, std::string name, " + \
        f.enum + " value, int width = 0) {\n"
    out += "    if (value == 0) p.PrintElement(\"None\");\n"
    for v in b.options:
        out += "    if (" + str(v.value) + \
            " & value) p.SetAsType().PrintElement(\"" + \
            str(v.name[3:]) + "\");\n"
    out += "}\n"

    out += AddGuardFooter(GetExtension(f.name, gen))
    return out


def PrintBitMask(b, name, gen):
    out = ''
    out += AddGuardHeader(GetExtension(b.name, gen))
    out += "void Dump" + name + \
        "(Printer &p, std::string name, " + name + " value, int width = 0) {\n"
    out += "    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }\n"
    out += "    p.ObjectStart(name);\n"
    out += "    Dump" + name + \
        "(p, name, static_cast<" + b.name + ">(value), width);\n"
    out += "    p.ObjectEnd();\n"
    out += "}\n"
    out += "void Dump" + b.name + \
        "(Printer &p, std::string name, " + \
        b.name + " value, int width = 0) {\n"
    out += "    if (p.Type() == OutputType::json) { p.PrintKeyValue(name, value); return; }\n"
    out += "    p.ObjectStart(name);\n"
    out += "    Dump" + name + "(p, name, value, width);\n"
    out += "    p.ObjectEnd();\n"
    out += "}\n"
    out += AddGuardFooter(GetExtension(b.name, gen))
    return out


def PrintBitMaskToString(b, name, gen):
    out = ''
    out += AddGuardHeader(GetExtension(b.name, gen))
    out += "std::string " + name + \
        "String(" + name + " value, int width = 0) {\n"
    out += "    std::string out;\n"
    out += "    bool is_first = true;\n"
    for v in b.options:
        out += "    if (" + str(v.value) + " & value) {\n"
        out += "        if (is_first) { is_first = false; } else { out += \" | \"; }\n"
        out += "        out += \"" + \
            str(v.name).strip("VK_").strip("_BIT") + "\";\n"
        out += "    }\n"
    out += "    return out;\n"
    out += "}\n"
    out += AddGuardFooter(GetExtension(b.name, gen))
    return out


def PrintForwardDeclaration(struct, gen):
    out = ''
    out += AddGuardHeader(struct)
    out += "void Dump" + struct.name + \
        "(Printer &p, std::string name, " + struct.name + " &obj);\n"
    out += AddGuardFooter(struct)

    return out


def PrintStructure(struct, structure_names, gen):
    out = ''
    out += AddGuardHeader(struct)
    max_key_len = len(struct.members[0].name)
    for v in struct.members:
        if v.arrayLength is not None:
            if len(v.name) + len(v.arrayLength) + 2 > max_key_len:
                max_key_len = len(v.name) + len(v.arrayLength) + 2
        elif v.typeID in predefined_types:
            if len(v.name) > max_key_len:
                max_key_len = len(v.name)

    out += "void Dump" + struct.name + \
        "(Printer &p, std::string name, " + struct.name + " &obj) {\n"
    if struct.name == "VkPhysicalDeviceLimits":
        out += "    if (p.Type() == OutputType::json)\n"
        out += "        p.ObjectStart(\"limits\");\n"
        out += "    else\n"
        out += "        p.SetSubHeader().ObjectStart(name);\n"
    elif struct.name == "VkPhysicalDeviceSparseProperties":
        out += "    if (p.Type() == OutputType::json)\n"
        out += "        p.ObjectStart(\"sparseProperties\");\n"
        out += "    else\n"
        out += "        p.SetSubHeader().ObjectStart(name);\n"
    else:
        out += "    p.ObjectStart(name);\n"

    for v in struct.members:
        # arrays
        if v.arrayLength is not None:
            # strings
            if v.typeID == "char":
                out += "    p.PrintKeyString(\"" + v.name + "\", obj." + \
                    v.name + ", " + str(max_key_len) + ");\n"
            # uuid's
            elif (v.arrayLength == str(16) and v.typeID == "uint8_t"):  # VK_UUID_SIZE
                out += "    p.PrintKeyString(\"" + v.name + "\", to_string_16(obj." + \
                    v.name + "), " + str(max_key_len) + ");\n"
            elif (v.arrayLength == str(8) and v.typeID == "uint8_t"):  # VK_LUID_SIZE
                out += "    if (obj.deviceLUIDValid)"  # special case
                out += " p.PrintKeyString(\"" + v.name + "\", to_string_8(obj." + \
                    v.name + "), " + str(max_key_len) + ");\n"
            elif v.arrayLength.isdigit():
                out += "    p.ArrayStart(\"" + v.name + \
                    "\", "+v.arrayLength+");\n"
                for i in range(0, int(v.arrayLength)):
                    out += "    p.PrintElement(obj." + \
                        v.name + "[" + str(i) + "]);\n"
                out += "    p.ArrayEnd();\n"
            else:  # dynamic array length based on other member
                out += "    p.ArrayStart(\"" + v.name + \
                    "\", obj."+v.arrayLength+");\n"
                out += "    for (uint32_t i = 0; i < obj." + \
                    v.arrayLength+"; i++) {\n"
                if v.typeID in structure_names:
                    out += "        if (obj." + v.name + " != nullptr) {\n"
                    out += "            p.SetElementIndex(i);\n"
                    out += "            Dump" + v.typeID + \
                        "(p, \"" + v.name + "\", obj." + v.name + "[i]);\n"
                    out += "        }\n"
                else:
                    out += "        p.PrintElement(obj." + v.name + "[i]);\n"
                out += "    }\n    p.ArrayEnd();\n"
        elif v.typeID == "VkBool32":
            out += "    p.PrintKeyBool(\"" + v.name + "\", static_cast<bool>(obj." + \
                v.name + "), " + str(max_key_len) + ");\n"
        elif v.typeID == "VkDeviceSize":
            out += "    p.PrintKeyValue(\"" + v.name + "\", to_hex_str(p, obj." + \
                v.name + "), " + str(max_key_len) + ");\n"
        elif v.typeID in predefined_types:
            out += "    p.PrintKeyValue(\"" + v.name + "\", obj." + \
                v.name + ", " + str(max_key_len) + ");\n"
        elif v.name not in ['sType', 'pNext']:
            if v.typeID in structure_names:
                out += "    Dump" + v.typeID + \
                    "(p, \"" + v.name + "\", obj." + v.name + ");\n"
            else:
                out += "    Dump" + v.typeID + \
                    "(p, \"" + v.name + "\", obj." + \
                    v.name + ", " + str(max_key_len) + ");\n"

    out += "    p.ObjectEnd();\n"
    out += "}\n"

    out += AddGuardFooter(struct)
    return out


def PrintChainBuilders(listName, structures):
    out = ''
    out += "    infos." + listName + " = {\n"
    for s in structures:
        out += AddGuardHeader(s)
        if s.sTypeName is not None:
            out += "        {" + s.sTypeName + ", sizeof(" + s.name + ")},\n"
        out += AddGuardFooter(s)
    out += "    };\n"
    return out


def PrintChainIterator(listName, structures, checkExtLoc):
    sorted_structures = sorted(structures, key=operator.attrgetter("name"))

    out = ''
    out += "void chain_iterator_" + listName + "(Printer &p, "
    if checkExtLoc == "device":
        out += "AppGpu &gpu"
    elif checkExtLoc == "instance":
        out += "AppInstance &inst"
    elif checkExtLoc == "both":
        out += "AppInstance &inst, AppGpu &gpu"
    out += ", void * place) {\n"

    out += "    while (place) {\n"
    out += "        struct VkStructureHeader *structure = (struct VkStructureHeader *)place;\n"
    out += "        p.SetSubHeader();\n"
    for s in sorted_structures:
        out += AddGuardHeader(s)
        if s.sTypeName is not None:
            if s.extNameStr is not None:
                out += "        if (structure->sType == " + \
                    s.sTypeName + " &&\n"
                if s.extType == "device":
                    out += "            gpu.CheckPhysicalDeviceExtensionIncluded(" + \
                        s.extNameStr + ")) {\n"
                elif s.extType == "instance":
                    out += "            inst.CheckExtensionEnabled(" + \
                        s.extNameStr + ")) {\n"

            else:
                out += "        if (structure->sType == " + \
                    s.sTypeName + ") {\n"

            out += "            " + s.name + "* props = " + \
                "("+s.name+"*)structure;\n"
            out += "            Dump" + s.name + \
                "(p, \"" + s.name + "\", *props);\n"
            out += "            p.AddNewline();\n"
            out += "        }\n"
        out += AddGuardFooter(s)
    out += "        place = structure->pNext;\n"
    out += "    }\n"
    out += "}\n"
    return out


def PrintStructComparisonForwardDef(structure):
    out = ''
    out += "bool operator==(const " + structure.name + \
        " & a, const " + structure.name + " b);\n"
    return out


def PrintStructComparison(structure):
    out = ''
    out += "bool operator==(const " + structure.name + \
        " & a, const " + structure.name + " b) {\n"
    out += "    return "
    is_first = True
    for m in structure.members:
        if m.name not in ['sType', 'pNext']:
            if not is_first:
                out += "\n        && "
            else:
                is_first = False
            out += "a." + m.name + " == b." + m.name
    out += ";\n"
    out += "}\n"
    return out


def isPow2(num):
    return num != 0 and ((num & (num - 1)) == 0)


def StrToInt(s):
    try:
        return int(s)
    except ValueError:
        return int(s, 16)


class VulkanEnum:
    class Option:

        def __init__(self, name, value, bitpos, comment):
            self.name = name
            self.comment = comment
            self.multiValue = None

            if value is not None:

                self.multiValue = not isPow2(StrToInt(value))

            if value == 0 or value is None:
                value = 1 << int(bitpos)

            self.value = value

        def values(self):
            return {
                'optName': self.name,
                'optValue': self.value,
                'optComment': self.comment,
                'optMultiValue': self.multiValue,
            }

    def __init__(self, rootNode):
        self.name = rootNode.get('name')
        self.type = rootNode.get('type')
        self.options = []

        for child in rootNode:
            childName = child.get('name')
            childValue = child.get('value')
            childBitpos = child.get('bitpos')
            childComment = child.get('comment')
            childExtends = child.get('extends')
            childOffset = child.get('offset')
            childExtNum = child.get('extnumber')
            support = child.get('supported')
            if(support == "disabled"):
                continue

            if childName is None:
                continue
            if (childValue is None and childBitpos is None and childOffset is None):
                continue

            if childExtends is not None and childExtNum is not None and childOffset is not None:
                enumNegative = False
                extNum = int(childExtNum)
                extOffset = int(childOffset)
                extBase = 1000000000
                extBlockSize = 1000
                childValue = extBase + (extNum - 1) * extBlockSize + extOffset
                if ('dir' in child.keys()):
                    childValue = -childValue
            duplicate = False
            for o in self.options:
                if o.values()['optName'] == childName:
                    duplicate = True
            if duplicate:
                continue

            self.options.append(VulkanEnum.Option(
                childName, childValue, childBitpos, childComment))


class VulkanBitmask:

    def __init__(self, rootNode):
        self.name = rootNode.get('name')
        self.type = rootNode.get('type')

        # Read each value that the enum contains
        self.options = []
        for child in rootNode:
            childName = child.get('name')
            childValue = child.get('value')
            childBitpos = child.get('bitpos')
            childComment = child.get('comment')
            support = child.get('supported')
            if childName is None or (childValue is None and childBitpos is None):
                continue
            if(support == "disabled"):
                continue

            self.options.append(VulkanEnum.Option(
                childName, childValue, childBitpos, childComment))


class VulkanFlags:

    def __init__(self, rootNode):
        self.name = rootNode.get('name')
        self.type = rootNode.get('type')
        self.enum = rootNode.get('requires')


class VulkanVariable:
    def __init__(self, rootNode, constants, parentName):
        self.name = rootNode.find('name').text
        # Typename, dereferenced and converted to a useable C++ token
        self.typeID = rootNode.find('type').text
        self.baseType = self.typeID
        self.childType = None
        self.arrayLength = None

        self.text = ''
        for node in rootNode.itertext():
            comment = rootNode.find('comment')
            if comment is not None and comment.text == node:
                continue
            self.text += node

        typeMatch = re.search('.+?(?=' + self.name + ')', self.text)
        self.type = typeMatch.string[typeMatch.start():typeMatch.end()]
        self.type = ' '.join(self.type.split())
        bracketMatch = re.search('(?<=\\[)[a-zA-Z0-9_]+(?=\\])', self.text)
        if bracketMatch is not None:
            matchText = bracketMatch.string[bracketMatch.start(
            ):bracketMatch.end()]
            self.childType = self.type
            self.type += '[' + matchText + ']'
            if matchText in constants:
                self.arrayLength = constants[matchText]
            else:
                self.arrayLength = matchText

        self.lengthMember = False
        lengthString = rootNode.get('len')
        lengths = []
        if lengthString is not None:
            lengths = re.split(',', lengthString)
            lengths = list(filter(('null-terminated').__ne__, lengths))
        assert(len(lengths) <= 1)
        if self.arrayLength is None and len(lengths) > 0:
            self.childType = '*'.join(self.type.split('*')[0:-1])
            self.arrayLength = lengths[0]
            self.lengthMember = True
        if self.arrayLength is not None and self.arrayLength.startswith('latexmath'):
            code = self.arrayLength[10:len(self.arrayLength)]
            code = re.sub('\\[', '', code)
            code = re.sub('\\]', '', code)
            code = re.sub('\\\\(lceil|rceil)', '', code)
            code = re.sub('{|}', '', code)
            code = re.sub('\\\\mathit', '', code)
            code = re.sub('\\\\over', '/', code)
            code = re.sub('\\\\textrm', '', code)
            self.arrayLength = code

        # Dereference if necessary and handle members of variables
        if self.arrayLength is not None:
            self.arrayLength = re.sub('::', '->', self.arrayLength)
            sections = self.arrayLength.split('->')
            if sections[-1][0] == 'p' and sections[0][1].isupper():
                self.arrayLength = '*' + self.arrayLength


class VulkanStructure:
    def __init__(self, name, rootNode, constants, extTypes):
        self.name = name
        self.members = []
        self.guard = None
        self.sTypeName = None
        self.extNameStr = None
        self.extType = None
        for node in rootNode.findall('member'):
            if(node.get('values') is not None):
                self.sTypeName = node.get('values')
            self.members.append(VulkanVariable(
                node, constants, self.name))

        for k, e in extTypes.items():
            if k == self.name:
                if e.guard is not None:
                    self.guard = e.guard
                if e.extNameStr is not None:
                    self.extNameStr = e.extNameStr
                if e.type is not None:
                    self.extType = e.type


class VulkanExtension:
    def __init__(self, rootNode):
        self.name = rootNode.get('name')
        self.number = int(rootNode.get('number'))
        self.type = rootNode.get('type')
        self.dependency = rootNode.get('requires')
        self.guard = GetFeatureProtect(rootNode)
        self.supported = rootNode.get('supported')
        self.extNameStr = None
        self.vktypes = []
        self.vkfuncs = []
        self.constants = {}
        self.enumValues = {}

        for req in rootNode.findall('require'):
            for ty in req.findall('type'):
                self.vktypes.append(ty.get('name'))

            for func in req.findall('command'):
                self.vkfuncs.append(func.get('name'))

            for enum in req.findall('enum'):
                base = enum.get('extends')
                name = enum.get('name')
                value = enum.get('value')
                bitpos = enum.get('bitpos')
                offset = enum.get('offset')
                # gets the VK_XXX_EXTENSION_NAME string
                if value == "\"" + self.name + "\"":
                    self.extNameStr = name

                if value is None and bitpos is not None:
                    value = 1 << int(bitpos)

                if offset is not None:
                    offset = int(offset)
                if base is not None and offset is not None:
                    enumValue = 1000000000 + 1000*(self.number - 1) + offset
                    if enum.get('dir') == '-':
                        enumValue = -enumValue
                    self.enumValues[base] = (name, enumValue)
                else:
                    self.constants[name] = value
