#!/usr/bin/env vpython
#
# [VPYTHON:BEGIN]
# wheel: <
#   name: "infra/python/wheels/perfect-hash-py2_py3"
#   version: "version:0.2.1"
# >
# [VPYTHON:END]
#
# Copyright 2018 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_builtin_symbols.py:
#  Code generation for the built-in symbol tables.

from collections import OrderedDict
from datetime import date
from perfect_hash import generate_hash, Hash2
import argparse
import hashlib
import json
import re
import os
import sys
import random

template_immutablestring_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImmutableString_{source_label}autogen.cpp: Wrapper for static or pool allocated char arrays, that are guaranteed to be
// valid and unchanged for the duration of the compilation.
// Implements mangledNameHash using perfect hash function from gen_builtin_symbols.py

#include "compiler/translator/ImmutableString.h"

std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
{{
    return os.write(str.data(), str.length());
}}

#if defined(_MSC_VER)
#    pragma warning(disable : 4309)  // truncation of constant value
#endif


namespace
{{

constexpr int mangledkT1[] = {{{mangled_S1}}};
constexpr int mangledkT2[] = {{{mangled_S2}}};
constexpr int mangledkG[] = {{{mangled_G}}};

int MangledHashG(const char *key, const int *T)
{{
    int sum = 0;

    for (int i = 0; key[i] != '\\0'; i++)
    {{
        sum += T[i] * key[i];
        sum %= {mangled_NG};
    }}
    return mangledkG[sum];
}}

int MangledPerfectHash(const char *key)
{{
    if (strlen(key) > {mangled_NS})
        return 0;

    return (MangledHashG(key, mangledkT1) + MangledHashG(key, mangledkT2)) % {mangled_NG};
}}

constexpr int unmangledkT1[] = {{{unmangled_S1}}};
constexpr int unmangledkT2[] = {{{unmangled_S2}}};
constexpr int unmangledkG[] = {{{unmangled_G}}};

int UnmangledHashG(const char *key, const int *T)
{{
    int sum = 0;

    for (int i = 0; key[i] != '\\0'; i++)
    {{
        sum += T[i] * key[i];
        sum %= {unmangled_NG};
    }}
    return unmangledkG[sum];
}}

int UnmangledPerfectHash(const char *key)
{{
    if (strlen(key) > {unmangled_NS})
        return 0;

    return (UnmangledHashG(key, unmangledkT1) + UnmangledHashG(key, unmangledkT2)) % {unmangled_NG};
}}

}}

namespace sh
{{

template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;

template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;

template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
    static_cast<size_t>(1099511628211ull);

template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
    static_cast<size_t>(0xcbf29ce484222325ull);

uint32_t ImmutableString::mangledNameHash() const
{{
    return MangledPerfectHash(data());
}}

uint32_t ImmutableString::unmangledNameHash() const
{{
    return UnmangledPerfectHash(data());
}}

}}  // namespace sh
"""

template_immutablestringtest_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImmutableString_test_{source_label}autogen.cpp:
//   Tests for matching script-generated hashes with runtime computed hashes.

#include "compiler/translator/ImmutableString.h"
#include "gtest/gtest.h"

namespace sh
{{

TEST(ImmutableStringTest, ScriptGeneratedHashesMatch)
{{
{script_generated_hash_tests}
{unmangled_script_generated_hash_tests}
}}

}}  // namespace sh
"""

# The header file has a "get" function for each variable. They are used in traversers.
# It also declares id values of built-ins with human readable names, so they can be used to identify built-ins.
template_builtin_header = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// BuiltIn_{header_label}autogen.h:
//   Compile-time initialized built-ins.

#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_

#include "compiler/translator/SymbolUniqueId.h"

namespace sh
{{

class TVariable;

class BuiltInId
{{
public:

{builtin_id_declarations}

}};  // class BuiltInId

namespace BuiltInVariable
{{

{get_variable_declarations}

}}  // namespace BuiltInVariable

}}  // namespace sh

#endif  // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
"""

template_symboltable_header = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SymbolTable_autogen.h:
//   Autogenerated member variables of TSymbolTable.

#ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
#define COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_

namespace sh
{{

class TSymbolTableBase
{{
  public:
    TSymbolTableBase() = default;
{declare_member_variables}
}};

}}  // namespace sh

#endif  // COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
"""

# By having the variables defined in a cpp file we ensure that there's just one instance of each of the declared variables.
template_symboltable_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SymbolTable_{source_label}autogen.cpp:
//   Compile-time initialized built-ins.

#include "compiler/translator/SymbolTable.h"

#include "angle_gl.h"
#include "compiler/translator/tree_util/BuiltIn.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h"
#include "compiler/translator/SymbolTable.h"

namespace sh
{{
using Resources = ShBuiltInResources;
using TableBase = TSymbolTableBase;

// Since some of the BuiltInId declarations are used outside of constexpr expressions, we need to
// have these definitions without an initializer. C++17 should eventually remove the need for this.
{builtin_id_definitions}

const int TSymbolTable::kLastBuiltInId = {last_builtin_id};

namespace BuiltInName
{{

constexpr const ImmutableString _empty("");
{name_declarations}

}}  // namespace BuiltInName

// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
// this from TVariable. Now symbol constructors taking an id have to be public even though they're
// not supposed to be accessible from outside of here. http://anglebug.com/2390
namespace BuiltInVariable
{{

{type_array_sizes_declarations}

{variable_declarations}

{get_variable_definitions}

}}  // namespace BuiltInVariable

namespace BuiltInParameters
{{

{parameter_declarations}

}}  // namespace BuiltInParameters

// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
// this from TFunction. Now symbol constructors taking an id have to be public even though they're
// not supposed to be accessible from outside of here. http://anglebug.com/2390
namespace Func
{{

{function_declarations}

}}  // namespace Func

namespace BuiltInArray
{{
using namespace Func;
using Rule = SymbolRule;

// Rules used to initialize the mangled name array.
constexpr SymbolRule kRules[] = {{
{mangled_rules}
}};

// Flat array of all mangled names.
constexpr const char *kMangledNames[] = {{
{mangled_names_array}
}};

// Flat array of offsets from a symbol into the rules table.
constexpr uint16_t kMangledOffsets[] = {{
{mangled_offsets_array}
}};

using Ext = TExtension;

// Flat array of all unmangled name identifiers.
constexpr UnmangledEntry unmangled[] = {{
{unmangled_array}
}};

}}

void TSymbolTable::initializeBuiltInVariables(sh::GLenum shaderType,
                                              ShShaderSpec spec,
                                              const ShBuiltInResources &resources)
{{
    const TSourceLoc zeroSourceLoc = {{0, 0, 0, 0}};
{init_member_variables}
}}

namespace
{{
uint16_t GetNextRuleIndex(uint32_t nameHash)
{{
    if (nameHash == {num_mangled_names} - 1)
        return ArraySize(BuiltInArray::kRules);
    return BuiltInArray::kMangledOffsets[nameHash + 1];
}}
}}  // namespace

const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
                                         int shaderVersion) const
{{
    if (name.length() > {max_mangled_name_length})
        return nullptr;

    uint32_t nameHash = name.mangledNameHash();
    if (nameHash >= {num_mangled_names})
        return nullptr;

    const char *actualName = BuiltInArray::kMangledNames[nameHash];
    if (name != actualName)
        return nullptr;

    uint16_t startIndex = BuiltInArray::kMangledOffsets[nameHash];
    uint16_t nextIndex = GetNextRuleIndex(nameHash);

    return FindMangledBuiltIn(mShaderSpec, shaderVersion, mShaderType, mResources, *this, BuiltInArray::kRules, startIndex, nextIndex);
}}

bool TSymbolTable::isUnmangledBuiltInName(const ImmutableString &name,
                                          int shaderVersion,
                                          const TExtensionBehavior &extensions) const
{{
    if (name.length() > {max_unmangled_name_length})
        return false;

    uint32_t nameHash = name.unmangledNameHash();
    if (nameHash >= {num_unmangled_names})
        return false;

    return BuiltInArray::unmangled[nameHash].matches(name, mShaderSpec, shaderVersion, mShaderType, extensions);
}}

}}  // namespace sh
"""

template_parsecontext_header = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ParseContext_{header_label}autogen.h:
//   Helpers for built-in related checks.

#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_AUTOGEN_H_
#define COMPILER_TRANSLATOR_PARSECONTEXT_AUTOGEN_H_

namespace sh
{{

namespace BuiltInGroup
{{

{is_in_group_definitions}

}}  // namespace BuiltInGroup

}}  // namespace sh

#endif  // COMPILER_TRANSLATOR_PARSECONTEXT_AUTOGEN_H_

"""

template_rule = """Rule::Get<{spec}, {version}, {shaders}, {extension}>({symbol_or_var})"""

basic_types_enumeration = [
    'Void',
    'Float',
    'Double',
    'Int',
    'UInt',
    'Bool',
    'AtomicCounter',
    'YuvCscStandardEXT',
    'Sampler2D',
    'Sampler3D',
    'SamplerCube',
    'Sampler2DArray',
    'SamplerExternalOES',
    'SamplerExternal2DY2YEXT',
    'Sampler2DRect',
    'Sampler2DMS',
    'Sampler2DMSArray',
    'ISampler2D',
    'ISampler3D',
    'ISamplerCube',
    'ISampler2DArray',
    'ISampler2DMS',
    'ISampler2DMSArray',
    'USampler2D',
    'USampler3D',
    'USamplerCube',
    'USampler2DArray',
    'USampler2DMS',
    'USampler2DMSArray',
    'Sampler2DShadow',
    'SamplerCubeShadow',
    'Sampler2DArrayShadow',
    'Sampler1D',
    'Sampler1DArray',
    'Sampler1DArrayShadow',
    'SamplerBuffer',
    'SamplerCubeArray',
    'SamplerCubeArrayShadow',
    'Sampler1DShadow',
    'Sampler2DRectShadow',
    'ISampler1D',
    'ISampler1DArray',
    'ISampler2DRect',
    'ISamplerBuffer',
    'ISamplerCubeArray',
    'USampler1D',
    'USampler1DArray',
    'USampler2DRect',
    'USamplerBuffer',
    'USamplerCubeArray',
    'SamplerVideoWEBGL',
    'Image2D',
    'IImage2D',
    'UImage2D',
    'Image3D',
    'IImage3D',
    'UImage3D',
    'Image2DArray',
    'IImage2DArray',
    'UImage2DArray',
    'ImageCube',
    'IImageCube',
    'UImageCube',
    'Image1D',
    'IImage1D',
    'UImage1D',
    'Image1DArray',
    'IImage1DArray',
    'UImage1DArray',
    'Image2DMS',
    'IImage2DMS',
    'UImage2DMS',
    'Image2DMSArray',
    'IImage2DMSArray',
    'UImage2DMSArray',
    'Image2DRect',
    'IImage2DRect',
    'UImage2DRect',
    'ImageCubeArray',
    'IImageCubeArray',
    'UImageCubeArray',
    'ImageRect',
    'IImageRect',
    'UImageRect',
    'ImageBuffer',
    'IImageBuffer',
    'UImageBuffer',
    'SubpassInput',
    'ISubpassInput',
    'USubpassInput',
    'SubpassInputMS',
    'ISubpassInputMS',
    'USubpassInputMS',
]

id_counter = 0


def set_working_dir():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    os.chdir(script_dir)


def get_basic_mangled_name(basic):
    index = basic_types_enumeration.index(basic)
    if index < 26:
        return '0' + chr(ord('A') + index)
    if index < 52:
        return '0' + chr(ord('a') + index - 26)
    if index < 78:
        return '1' + chr(ord('A') + index - 52)
    return '1' + chr(ord('a') + index - 78)


essl_levels = [
    'ESSL3_2_BUILTINS', 'ESSL3_1_BUILTINS', 'ESSL3_BUILTINS', 'ESSL1_BUILTINS', 'COMMON_BUILTINS'
]

glsl_levels = [
    'GLSL4_6_BUILTINS', 'GLSL4_5_BUILTINS', 'GLSL4_4_BUILTINS', 'GLSL4_3_BUILTINS',
    'GLSL4_2_BUILTINS', 'GLSL4_1_BUILTINS', 'GLSL4_BUILTINS', 'GLSL3_3_BUILTINS',
    'GLSL1_5_BUILTINS', 'GLSL1_4_BUILTINS', 'GLSL1_3_BUILTINS', 'GLSL1_2_BUILTINS',
    'COMMON_BUILTINS'
]


def get_essl_shader_version_for_level(level):
    if level == None:
        return '-1'
    elif level == 'ESSL3_2_BUILTINS':
        return '320'
    elif level == 'ESSL3_1_BUILTINS':
        return '310'
    elif level == 'ESSL3_BUILTINS':
        return '300'
    elif level == 'ESSL1_BUILTINS':
        return '100'
    elif level == 'COMMON_BUILTINS':
        return '0'
    else:
        raise Exception('Unsupported symbol table level')


def get_glsl_shader_version_for_level(level):
    if level == None:
        return '-1'
    elif level == 'GLSL1_2_BUILTINS':
        return '120'
    elif level == 'GLSL1_3_BUILTINS':
        return '130'
    elif level == 'GLSL1_4_BUILTINS':
        return '140'
    elif level == 'GLSL1_5_BUILTINS':
        return '150'
    elif level == 'GLSL3_3_BUILTINS':
        return '330'
    elif level == 'GLSL4_BUILTINS':
        return '400'
    elif level == 'GLSL4_1_BUILTINS':
        return '410'
    elif level == 'GLSL4_2_BUILTINS':
        return '420'
    elif level == 'GLSL4_3_BUILTINS':
        return '430'
    elif level == 'GLSL4_4_BUILTINS':
        return '440'
    elif level == 'GLSL4_5_BUILTINS':
        return '450'
    elif level == 'GLSL4_6_BUILTINS':
        return '460'
    elif level == 'COMMON_BUILTINS':
        return '0'
    else:
        raise Exception('Unsupported symbol table level')


def get_shader_version_for_level(spec, level):
    if spec == "ESSL":
        return get_essl_shader_version_for_level(level)
    else:
        return get_glsl_shader_version_for_level(level)


class GroupedList:
    """"Class for storing a list of objects grouped by symbol table level and condition."""

    def __init__(self, hashfn, num_names):
        self.objs = OrderedDict()
        self.max_name_length = 0
        self.hashfn = hashfn
        self.num_names = num_names
        self.rule_offset = 0

    def add_entry(self, essl_level, glsl_level, shader_type, name, symbol, essl_extension,
                  glsl_extension, script_generated_hash_tests):
        if essl_level and essl_level not in essl_levels:
            raise Exception('Unexpected essl level: ' + str(essl_level))
        if glsl_level and glsl_level not in glsl_levels:
            raise Exception('Unexpected glsl level: ' + str(glsl_level))
        if len(name) > self.max_name_length:
            self.max_name_length = len(name)

        name_hash = mangledNameHash(name, self.hashfn, script_generated_hash_tests, False)
        if name_hash not in self.objs:
            self.objs[name_hash] = OrderedDict()

        self.objs[name_hash]['name'] = name

        if essl_extension == 'UNDEFINED' and glsl_extension == 'UNDEFINED':
            if essl_level:
                self.objs[name_hash]['essl_level'] = essl_level
            if glsl_level:
                self.objs[name_hash]['glsl_level'] = glsl_level
            self.objs[name_hash]['symbol'] = symbol
            self.objs[name_hash]['shader_type'] = shader_type

        if essl_extension != 'UNDEFINED':
            if ('essl_ext_symbol' in self.objs[name_hash] and
                    self.objs[name_hash]['essl_ext_symbol'] != symbol):
                # Adding a variable that is part of two ESSL extensions
                if essl_extension != 'UNDEFINED':
                    self.objs[name_hash]['essl_extension2'] = essl_extension
                    self.objs[name_hash]['essl_ext_level2'] = essl_level
                    self.objs[name_hash]['essl_ext_symbol2'] = symbol
                    self.objs[name_hash]['essl_ext_shader_type2'] = shader_type
            else:
                self.objs[name_hash]['essl_extension'] = essl_extension
                self.objs[name_hash]['essl_ext_level'] = essl_level
                self.objs[name_hash]['essl_ext_symbol'] = symbol
                self.objs[name_hash]['essl_ext_shader_type'] = shader_type

        if glsl_extension != 'UNDEFINED':
            self.objs[name_hash]['glsl_extension'] = glsl_extension
            self.objs[name_hash]['glsl_ext_level'] = glsl_level
            self.objs[name_hash]['glsl_ext_symbol'] = symbol
            self.objs[name_hash]['glsl_ext_shader_type'] = shader_type

    def get_max_name_length(self):
        return self.max_name_length

    def format_rule(self, rule):
        return template_rule.format(**rule)

    def format_rules(self, rules):
        return ", ".join([self.format_rule(rule) for rule in rules])

    def get_rules(self):
        return self.rules

    def get_names(self):
        return self.names

    def get_offsets(self):
        return self.offsets

    def update_arrays(self):

        def add_rule(rules, spec, level, shaders, extension, symbol):
            var = ("&TableBase::%s" % symbol) if symbol.startswith("m_gl") else None

            rules.append({
                "spec": "Spec::%s" % ("ESSL" if spec == "ESSL" else "GLSL"),
                "version": get_shader_version_for_level(spec, level),
                "shaders": "Shader::%s" % ("ALL" if shaders == "NONE" else shaders),
                "extension": "0" if extension == None else "EXT_INDEX(%s)" % extension,
                "symbol_or_var": symbol.replace("Func::", "") if var is None else var
            })

        self.names = []
        self.offsets = []
        self.rules = []
        for hash_val in range(0, self.num_names):
            if hash_val in self.objs:
                data = self.objs[hash_val]

                rules = []

                if "symbol" in data and "essl_level" in data:
                    add_rule(rules, "ESSL", data['essl_level'], data['shader_type'], None,
                             data["symbol"])

                if "symbol" in data and "glsl_level" in data:
                    add_rule(rules, "GLSL", data['glsl_level'], data['shader_type'], None,
                             data["symbol"])

                if "essl_ext_symbol" in data:
                    add_rule(rules, "ESSL", data["essl_ext_level"], data["essl_ext_shader_type"],
                             data["essl_extension"], data["essl_ext_symbol"])

                if "glsl_ext_symbol" in data:
                    add_rule(rules, "GLSL", data["glsl_ext_level"], data["glsl_ext_shader_type"],
                             data["glsl_extension"], data["glsl_ext_symbol"])

                if "essl_ext_symbol2" in data:
                    add_rule(rules, "ESSL", data["essl_ext_level2"], data["essl_ext_shader_type2"],
                             data["essl_extension2"], data["essl_ext_symbol2"])

                name = data['name']
                name_underscore = name.replace("(", "_")

                self.names.append('"%s"' % name)
                self.offsets.append("%d, // %s" % (self.rule_offset, name_underscore))
                self.rules.append("%s" % self.format_rules(rules))

                self.rule_offset += len(rules)

            else:
                self.names.append('""')
                self.offsets.append('%d, // Empty' % self.rule_offset)


class UnmangledGroupedList:
    """"Class for storing a list of unmangled objects grouped by symbol table level and condition."""

    def __init__(self, hashfn, num_names):
        self.objs = OrderedDict()
        self.max_name_length = 0
        self.hashfn = hashfn
        self.num_names = num_names

    def add_entry(self, essl_level, glsl_level, shader_type, name, essl_ext, glsl_ext,
                  essl_extension, glsl_extension, unmangled_script_generated_hash_tests):
        if essl_level and essl_level not in essl_levels:
            raise Exception('Unexpected essl level: ' + str(essl_level))
        if glsl_level and glsl_level not in glsl_levels:
            raise Exception('Unexpected glsl level: ' + str(glsl_level))
        if len(name) > self.max_name_length:
            self.max_name_length = len(name)

        name_hash = mangledNameHash(name, self.hashfn, unmangled_script_generated_hash_tests, True)
        self.objs[name_hash] = OrderedDict()
        self.objs[name_hash]['name'] = name
        self.objs[name_hash]['essl_level'] = essl_level
        self.objs[name_hash]['glsl_level'] = glsl_level
        self.objs[name_hash]['shader_type'] = shader_type
        self.objs[name_hash]['essl_ext'] = essl_ext
        self.objs[name_hash]['glsl_ext'] = glsl_ext
        self.objs[name_hash]['essl_extension'] = essl_extension
        self.objs[name_hash]['glsl_extension'] = glsl_extension

    def has_key(self, essl_level, glsl_level, shader_type, name):
        name_hash = mangledNameHash(name, self.hashfn, None, True, False)
        if name_hash not in self.objs:
            return False
        entry = self.objs[name_hash]
        if entry['essl_level'] != essl_level:
            return False
        if entry['glsl_level'] != glsl_level:
            return False
        if entry['shader_type'] != shader_type:
            return False
        return True

    def get(self, essl_level, glsl_level, shader_type, name):
        if self.has_key(essl_level, glsl_level, shader_type, name):
            name_hash = mangledNameHash(name, self.hashfn, None, True, False)
            return self.objs[name_hash]
        return None

    def get_max_name_length(self):
        return self.max_name_length

    def get_array(self):
        code = []
        for hash_val in range(0, self.num_names):
            obj = self.objs[hash_val]
            essl_level = obj['essl_level']
            glsl_level = obj['glsl_level']
            shader_type = 'Shader::' + obj['shader_type'] if obj[
                'shader_type'] != 'NONE' else 'Shader::ALL'
            data = []
            data.append('"{name}"'.format(name=obj['name']))
            data.append("Ext::" + obj['essl_extension'])
            data.append("Ext::" + obj['glsl_extension'])
            data.append(get_essl_shader_version_for_level(essl_level))
            data.append(get_glsl_shader_version_for_level(glsl_level))
            data.append(shader_type)

            code.append('{%s}' % ', '.join(data))
        return code


class TType:

    def __init__(self, glsl_header_type):
        if isinstance(glsl_header_type, basestring):
            self.data = self.parse_type(glsl_header_type)
        else:
            self.data = glsl_header_type
        self.normalize()

    def normalize(self):
        # Note that this will set primarySize and secondarySize also on genTypes. In that case they
        # are overridden when the specific types are generated.
        if 'primarySize' not in self.data:
            if ('secondarySize' in self.data):
                raise Exception(
                    'Unexpected secondarySize on type that does not have primarySize set')
            self.data['primarySize'] = 1
        if 'secondarySize' not in self.data:
            self.data['secondarySize'] = 1
        if 'precision' not in self.data:
            self.data['precision'] = 'Undefined'
        if 'qualifier' not in self.data:
            self.data['qualifier'] = 'Global'

    def has_array_size(self):
        return 'arraySize' in self.data

    def get_statictype_string(self):
        template_type = 'StaticType::Get<Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize}>()'
        if self.has_array_size():
            template_type = 'StaticType::GetArray<Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize}, kArraySize{arraySize}, 1>()'
        return template_type.format(**self.data)

    def get_dynamic_type_string(self):
        template_type = 'new TType(Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize}'
        if self.has_array_size():
            template_type += ', TVector<unsigned int>{{{arraySize}}}'
        template_type += ')'
        return template_type.format(**self.data)

    def get_mangled_name(self):
        mangled_name = ''

        size_key = (self.data['secondarySize'] - 1) * 4 + self.data['primarySize'] - 1
        if size_key < 10:
            mangled_name += chr(ord('0') + size_key)
        else:
            mangled_name += chr(ord('A') + size_key - 10)
        mangled_name += get_basic_mangled_name(self.data['basic'])
        if self.has_array_size():
            mangled_name += 'x' + str(self.data['arraySize'])
        return mangled_name

    def get_human_readable_name(self):
        name = self.data['basic']
        if self.has_array_size():
            name = str(self.data['arraySize']) + 'x' + name
        name += str(self.data['primarySize'])
        if self.data['secondarySize'] > 1:
            name += 'x' + str(self.data['secondarySize'])
        return name

    def is_vector(self):
        return self.data['primarySize'] > 1 and self.data['secondarySize'] == 1

    def is_matrix(self):
        return self.data['secondarySize'] > 1

    def get_object_size(self):
        return self.data['primarySize'] * self.data['secondarySize']

    def specific_sampler_or_image_or_subpass_type(self, basic_type_prefix):
        if 'genType' in self.data and self.data['genType'] == 'sampler_or_image_or_subpass':
            type = {}
            if 'basic' not in self.data:
                type['basic'] = {'': 'Float', 'I': 'Int', 'U': 'UInt'}[basic_type_prefix]
                type['primarySize'] = self.data['primarySize']
            else:
                type['basic'] = basic_type_prefix + self.data['basic']
                type['primarySize'] = 1
            type['precision'] = 'Undefined'
            return TType(type)
        return self

    def specific_type(self, vec_size):
        type = {}
        if 'genType' in self.data:
            type['basic'] = self.data['basic']
            type['precision'] = self.data['precision']
            type['qualifier'] = self.data['qualifier']
            type['primarySize'] = vec_size
            type['secondarySize'] = 1
            return TType(type)
        return self

    def parse_type(self, glsl_header_type):
        # TODO(http://anglebug.com/3833): handle readonly, writeonly qualifiers
        if glsl_header_type.startswith('readonly writeonly '):
            type_obj = self.parse_type(glsl_header_type[19:])
            type_obj['qualifier'] = 'Readonly Writeonly'
            return type_obj
        if glsl_header_type.startswith('readonly '):
            type_obj = self.parse_type(glsl_header_type[9:])
            type_obj['qualifier'] = 'Readonly'
            return type_obj
        if glsl_header_type.startswith('writeonly '):
            type_obj = self.parse_type(glsl_header_type[10:])
            type_obj['qualifier'] = 'Writeonly'
            return type_obj
        if glsl_header_type.startswith('out '):
            type_obj = self.parse_type(glsl_header_type[4:])
            type_obj['qualifier'] = 'Out'
            return type_obj
        if glsl_header_type.startswith('inout '):
            type_obj = self.parse_type(glsl_header_type[6:])
            type_obj['qualifier'] = 'InOut'
            return type_obj

        basic_type_map = {
            'float': 'Float',
            'int': 'Int',
            'uint': 'UInt',
            'double': 'Double',
            'bool': 'Bool',
            'void': 'Void',
            'atomic_uint': 'AtomicCounter',
            'yuvCscStandardEXT': 'YuvCscStandardEXT'
        }

        if glsl_header_type in basic_type_map:
            return {'basic': basic_type_map[glsl_header_type]}

        type_obj = {}

        basic_type_prefix_map = {
            '': 'Float',
            'i': 'Int',
            'u': 'UInt',
            'd': 'Double',
            'b': 'Bool',
            'v': 'Void'
        }

        vec_re = re.compile(r'^([iudb]?)vec([234]?)((\[[234]\])?)$')
        vec_match = vec_re.match(glsl_header_type)
        if vec_match:
            type_obj['basic'] = basic_type_prefix_map[vec_match.group(1)]
            if vec_match.group(2) == '':
                # Type like "ivec" that represents either ivec2, ivec3 or ivec4
                type_obj['genType'] = 'vec'
            else:
                # vec with specific size
                if vec_match.group(3) != '':
                    # vec array
                    type_obj['primarySize'] = int(vec_match.group(2))
                    type_obj['arraySize'] = int(vec_match.group(3)[1])
                else:
                    type_obj['primarySize'] = int(vec_match.group(2))
            return type_obj

        mat_re = re.compile(r'^mat([234])(x([234]))?$')
        mat_match = mat_re.match(glsl_header_type)
        if mat_match:
            type_obj['basic'] = 'Float'
            if len(glsl_header_type) == 4:
                mat_size = int(mat_match.group(1))
                type_obj['primarySize'] = mat_size
                type_obj['secondarySize'] = mat_size
            else:
                type_obj['primarySize'] = int(mat_match.group(1))
                type_obj['secondarySize'] = int(mat_match.group(3))
            return type_obj

        gen_re = re.compile(r'^gen([IUDB]?)Type$')
        gen_match = gen_re.match(glsl_header_type)
        if gen_match:
            type_obj['basic'] = basic_type_prefix_map[gen_match.group(1).lower()]
            type_obj['genType'] = 'yes'
            return type_obj

        if glsl_header_type.startswith('sampler'):
            type_obj['basic'] = glsl_header_type[0].upper() + glsl_header_type[1:]
            return type_obj

        if glsl_header_type.startswith('gsampler') or glsl_header_type.startswith(
                'gimage') or glsl_header_type.startswith('gsubpassInput'):
            type_obj['basic'] = glsl_header_type[1].upper() + glsl_header_type[2:]
            type_obj['genType'] = 'sampler_or_image_or_subpass'
            return type_obj

        if glsl_header_type == 'gvec4':
            return {'primarySize': 4, 'genType': 'sampler_or_image_or_subpass'}
        if glsl_header_type == 'gvec3':
            return {'primarySize': 3, 'genType': 'sampler_or_image_or_subpass'}

        if glsl_header_type == 'IMAGE_PARAMS':
            return {'genType': 'image_params'}

        raise Exception('Unrecognized type: ' + str(glsl_header_type))


class HashFunction:

    def __init__(self, f1, f2, G):
        self.f1 = f1
        self.f2 = f2
        self.G = G

    def hash(self, key):
        return (self.G[self.f1(key)] + self.G[self.f2(key)]) % len(self.G)


def get_parsed_functions(functions_txt_filename, essl_only):

    def parse_function_parameters(parameters):
        if parameters == '':
            return []
        parametersOut = []
        parameters = parameters.split(', ')
        for parameter in parameters:
            parametersOut.append(TType(parameter.strip()))
        return parametersOut

    lines = []
    with open(functions_txt_filename) as f:
        lines = f.readlines()
    lines = [
        line.strip() for line in lines if line.strip() != '' and not line.strip().startswith('//')
    ]

    fun_re = re.compile(r'^(\w+) (\w+)\((.*)\);$')

    parsed_functions = OrderedDict()
    group_stack = []
    default_metadata = {}

    for line in lines:
        fun_match = fun_re.match(line)
        if line.startswith('GROUP BEGIN '):
            group_rest = line[12:].strip()
            group_parts = group_rest.split(' ', 1)
            current_group = {'functions': [], 'name': group_parts[0], 'subgroups': {}}
            if len(group_parts) > 1:
                group_metadata = json.loads(group_parts[1])
                current_group.update(group_metadata)
            group_stack.append(current_group)
        elif line.startswith('GROUP END '):
            group_end_name = line[10:].strip()
            current_group = group_stack[-1]
            if current_group['name'] != group_end_name:
                raise Exception('GROUP END: Unexpected function group name "' + group_end_name +
                                '" was expecting "' + current_group['name'] + '"')
            group_stack.pop()
            is_top_level_group = (len(group_stack) == 0)
            if is_top_level_group:
                parsed_functions[current_group['name']] = current_group
                default_metadata = {}
            else:
                super_group = group_stack[-1]
                super_group['subgroups'][current_group['name']] = current_group
        elif line.startswith('DEFAULT METADATA'):
            line_rest = line[16:].strip()
            default_metadata = json.loads(line_rest)
        elif fun_match:
            return_type = fun_match.group(1)
            name = fun_match.group(2)
            parameters = fun_match.group(3)
            function_props = {
                'name': name,
                'returnType': TType(return_type),
                'parameters': parse_function_parameters(parameters)
            }
            function_props.update(default_metadata)
            if essl_only:
                # Skip GLSL-only functions
                if 'essl_level' in function_props:
                    group_stack[-1]['functions'].append(function_props)
            else:
                group_stack[-1]['functions'].append(function_props)
        else:
            raise Exception('Unexpected function input line: ' + line)

    return parsed_functions


def mangledNameHash(str, hashfn, script_generated_hash_tests, unmangled, save_test=True):
    hash = hashfn.hash(str)
    if save_test:
        sanity_check = ''
        if unmangled:
            sanity_check = '    ASSERT_EQ(0x{hash}u, ImmutableString("{str}").unmangledNameHash());'.format(
                hash=('%08x' % hash), str=str)
        else:
            sanity_check = '    ASSERT_EQ(0x{hash}u, ImmutableString("{str}").mangledNameHash());'.format(
                hash=('%08x' % hash), str=str)
        script_generated_hash_tests.update({sanity_check: None})
    return hash


def get_function_names(group, mangled_names, unmangled_names):
    if 'functions' in group:
        for function_props in group['functions']:
            function_name = function_props['name']
            unmangled_names.append(function_name)
            function_variants = gen_function_variants(function_props)
            for function_props in function_variants:
                parameters = get_parameters(function_props)
                mangled_names.append(get_function_mangled_name(function_name, parameters))
    if 'subgroups' in group:
        for subgroup_name, subgroup in group['subgroups'].iteritems():
            get_function_names(subgroup, mangled_names, unmangled_names)


def get_variable_names(group, mangled_names):
    if 'variables' in group:
        for variable_name, props in group['variables'].iteritems():
            mangled_names.append(variable_name)
    if 'subgroups' in group:
        for subgroup_name, subgroup in group['subgroups'].iteritems():
            get_variable_names(subgroup, mangled_names)


def get_suffix(props):
    if 'suffix' in props:
        return props['suffix']
    return ''


def get_essl_extension(props):
    if 'essl_extension' in props:
        return props['essl_extension']
    return 'UNDEFINED'


def get_glsl_extension(props):
    if 'glsl_extension' in props:
        return props['glsl_extension']
    return 'UNDEFINED'


def get_op(name, function_props):
    if 'op' not in function_props:
        raise Exception('function op not defined')
    if function_props['op'] == 'auto':
        return name[0].upper() + name[1:]
    return function_props['op']


def get_known_to_not_have_side_effects(function_props):
    if 'op' in function_props and function_props['op'] != 'CallBuiltInFunction':
        if 'hasSideEffects' in function_props:
            return 'false'
        else:
            for param in get_parameters(function_props):
                if 'qualifier' in param.data and (param.data['qualifier'] == 'Out' or
                                                  param.data['qualifier'] == 'InOut'):
                    return 'false'
            return 'true'
    return 'false'


def get_parameters(function_props):
    if 'parameters' in function_props:
        return function_props['parameters']
    return []


def get_function_mangled_name(function_name, parameters):
    mangled_name = function_name + '('
    for param in parameters:
        mangled_name += param.get_mangled_name()
    return mangled_name


def get_function_human_readable_name(function_name, parameters):
    name = function_name
    for param in parameters:
        name += '_' + param.get_human_readable_name()
    return name


def get_unique_identifier_name(function_name, parameters):
    unique_name = function_name + '_'
    for param in parameters:
        unique_name += param.get_mangled_name()
    return unique_name


def get_variable_name_to_store_parameter(param):
    unique_name = 'pt'
    if 'qualifier' in param.data:
        if param.data['qualifier'] == 'Out':
            unique_name += '_o_'
        if param.data['qualifier'] == 'InOut':
            unique_name += '_io_'
    unique_name += param.get_mangled_name()
    return unique_name


def get_variable_name_to_store_parameters(parameters):
    if len(parameters) == 0:
        return 'empty'
    unique_name = 'p'
    for param in parameters:
        if 'qualifier' in param.data:
            if param.data['qualifier'] == 'Out':
                unique_name += '_o_'
            if param.data['qualifier'] == 'InOut':
                unique_name += '_io_'
        unique_name += param.get_mangled_name()
    return unique_name


def define_constexpr_type_array_sizes(template_args, type_array_sizes_declarations):
    template_array_sizes_declaration = 'constexpr const unsigned int kArraySize{arraySize}[1] = {{{arraySize}}};'
    type_array_sizes_declarations.add(template_array_sizes_declaration.format(**template_args))


def define_constexpr_variable(template_args, variable_declarations):
    template_variable_declaration = 'constexpr const TVariable k{name_with_suffix}(BuiltInId::{name_with_suffix}, BuiltInName::{name}, SymbolType::BuiltIn, TExtension::{extension}, {type});'
    variable_declarations.append(template_variable_declaration.format(**template_args))


def gen_function_variants(function_props):
    function_variants = []
    parameters = get_parameters(function_props)
    function_is_gen_type = False
    gen_type = set()
    image_params_index = 0
    for param in parameters + [function_props['returnType']]:
        if 'genType' in param.data:
            if param.data['genType'] not in [
                    'sampler_or_image_or_subpass', 'vec', 'yes', 'image_params'
            ]:
                raise Exception(
                    'Unexpected value of genType "' + str(param.data['genType']) +
                    '" should be "sampler_or_image_or_subpass", "vec", "yes", or "image_params"')
            gen_type.add(param.data['genType'])
            if param.data['genType'] == 'image_params':
                image_params_index = parameters.index(param)

    if len(gen_type) == 0:
        function_variants.append(function_props)
        return function_variants

    # If we have image_params then we're generating variants for 33 separate functions,
    # each for a different type of image variable
    if 'image_params' in gen_type:
        variants = [['gimage2D', 'ivec2'], ['gimage3D', 'ivec3'], ['gimageCube', 'ivec3'],
                    ['gimageBuffer', 'int'], ['gimage2DArray', 'ivec3'],
                    ['gimageCubeArray', 'ivec3'], ['gimage1D', 'int'], ['gimage1DArray', 'ivec2'],
                    ['gimage2DRect', 'ivec2'], ['gimage2DMS', 'ivec2', 'int'],
                    ['gimage2DMSArray', 'ivec3', 'int']]
        for variant in variants:
            image_variant_parameters = []
            for param in parameters:
                if parameters.index(param) == image_params_index:
                    for variant_param in variant:
                        image_variant_parameters.append(TType(variant_param))
                else:
                    image_variant_parameters.append(param)
            types = ['', 'I', 'U']
            for type in types:
                variant_props = function_props.copy()
                variant_parameters = []
                for param in image_variant_parameters:
                    variant_parameters.append(
                        param.specific_sampler_or_image_or_subpass_type(type))
                variant_props['parameters'] = variant_parameters
                variant_props['returnType'] = function_props[
                    'returnType'].specific_sampler_or_image_or_subpass_type(type)
                function_variants.append(variant_props)
        return function_variants

    # If we have a gsampler_or_image_or_subpass then we're generating variants for float, int and uint
    # samplers.
    if 'sampler_or_image_or_subpass' in gen_type:
        types = ['', 'I', 'U']
        for type in types:
            variant_props = function_props.copy()
            variant_parameters = []
            for param in parameters:
                variant_parameters.append(param.specific_sampler_or_image_or_subpass_type(type))
            variant_props['parameters'] = variant_parameters
            variant_props['returnType'] = function_props[
                'returnType'].specific_sampler_or_image_or_subpass_type(type)
            function_variants.append(variant_props)
        return function_variants

    # If we have a normal gentype then we're generating variants for different sizes of vectors.
    sizes = range(1, 5)
    if 'vec' in gen_type:
        sizes = range(2, 5)
    for size in sizes:
        variant_props = function_props.copy()
        variant_parameters = []
        for param in parameters:
            variant_parameters.append(param.specific_type(size))
        variant_props['parameters'] = variant_parameters
        variant_props['returnType'] = function_props['returnType'].specific_type(size)
        function_variants.append(variant_props)
    return function_variants


def process_single_function_group(
        shader_type, group_name, group, parameter_declarations, name_declarations,
        unmangled_function_if_statements, defined_function_variants, builtin_id_declarations,
        builtin_id_definitions, defined_parameter_names, type_array_sizes_declarations,
        variable_declarations, function_declarations, script_generated_hash_tests,
        unmangled_script_generated_hash_tests, mangled_builtins):
    global id_counter

    if 'functions' not in group:
        return

    for function_props in group['functions']:
        function_name = function_props['name']
        essl_level = function_props['essl_level'] if 'essl_level' in function_props else None
        glsl_level = function_props['glsl_level'] if 'glsl_level' in function_props else None
        essl_extension = get_essl_extension(function_props)
        glsl_extension = get_glsl_extension(function_props)
        extension = essl_extension if essl_extension != 'UNDEFINED' else glsl_extension
        template_args = {
            'name': function_name,
            'name_with_suffix': function_name + get_suffix(function_props),
            'essl_level': essl_level,
            'glsl_level': glsl_level,
            'essl_extension': essl_extension,
            'glsl_extension': glsl_extension,
            # This assumes that functions cannot be part of an ESSL and GLSL extension
            # Will need to update after adding GLSL extension functions if this is not the case
            'extension': essl_extension if essl_extension != 'UNDEFINED' else glsl_extension,
            'op': get_op(function_name, function_props),
            'known_to_not_have_side_effects': get_known_to_not_have_side_effects(function_props)
        }

        function_variants = gen_function_variants(function_props)

        template_name_declaration = 'constexpr const ImmutableString {name_with_suffix}("{name}");'
        name_declaration = template_name_declaration.format(**template_args)
        if not name_declaration in name_declarations:
            name_declarations.add(name_declaration)

        essl_ext = '{essl_extension}'.format(**template_args)
        glsl_ext = '{glsl_extension}'.format(**template_args)
        unmangled_builtin_no_shader_type = unmangled_function_if_statements.get(
            essl_level, glsl_level, 'NONE', function_name)
        if unmangled_builtin_no_shader_type != None and unmangled_builtin_no_shader_type[
                'essl_extension'] == 'UNDEFINED' and unmangled_builtin_no_shader_type[
                    'glsl_extension'] == 'UNDEFINED':
            # We already have this unmangled name without a shader type nor extension on the same level.
            # No need to add a duplicate with a type.
            pass
        elif (not unmangled_function_if_statements.has_key(
                essl_level, glsl_level, shader_type, function_name)) or (
                    unmangled_builtin_no_shader_type and
                    ((essl_extension == 'UNDEFINED' and
                      unmangled_builtin_no_shader_type['essl_extension'] != 'UNDEFINED') or
                     (glsl_extension == 'UNDEFINED' and
                      unmangled_builtin_no_shader_type['glsl_extension'] != 'UNDEFINED'))):
            unmangled_function_if_statements.add_entry(
                essl_level, glsl_level, shader_type, function_name, essl_ext, glsl_ext,
                essl_extension, glsl_extension, unmangled_script_generated_hash_tests)

        for function_props in function_variants:
            template_args['id'] = id_counter

            parameters = get_parameters(function_props)

            template_args['unique_name'] = get_unique_identifier_name(
                template_args['name_with_suffix'], parameters)
            template_args['param_count'] = len(parameters)
            template_args['return_type'] = function_props['returnType'].get_statictype_string()
            template_args['mangled_name'] = get_function_mangled_name(function_name, parameters)
            template_args['human_readable_name'] = get_function_human_readable_name(
                template_args['name_with_suffix'], parameters)
            template_args['mangled_name_length'] = len(template_args['mangled_name'])

            symbol = '&Func::{unique_name}'.format(**template_args)
            mangled_builtins.add_entry(
                essl_level, glsl_level, shader_type, template_args['mangled_name'], symbol,
                template_args['essl_extension'], template_args['glsl_extension'],
                script_generated_hash_tests)

            if template_args['unique_name'] in defined_function_variants:
                continue
            defined_function_variants.add(template_args['unique_name'])

            template_builtin_id_declaration = '    static constexpr const TSymbolUniqueId {human_readable_name} = TSymbolUniqueId({id});'
            builtin_id_declarations.append(template_builtin_id_declaration.format(**template_args))
            template_builtin_id_definition = 'constexpr const TSymbolUniqueId BuiltInId::{human_readable_name};'
            builtin_id_definitions.append(template_builtin_id_definition.format(**template_args))

            parameters_list = []
            for param in parameters:
                unique_param_name = get_variable_name_to_store_parameter(param)
                param_template_args = {
                    'name': '_empty',
                    'name_with_suffix': unique_param_name,
                    'type': param.get_statictype_string(),
                    'extension': 'UNDEFINED'
                }
                if unique_param_name not in defined_parameter_names:
                    id_counter += 1
                    param_template_args['id'] = id_counter
                    template_builtin_id_declaration = '    static constexpr const TSymbolUniqueId {name_with_suffix} = TSymbolUniqueId({id});'
                    builtin_id_declarations.append(
                        template_builtin_id_declaration.format(**param_template_args))
                    define_constexpr_variable(param_template_args, variable_declarations)
                    defined_parameter_names.add(unique_param_name)
                    if param.has_array_size():
                        array_size_template_args = {'arraySize': param.data['arraySize']}
                        define_constexpr_type_array_sizes(array_size_template_args,
                                                          type_array_sizes_declarations)
                parameters_list.append(
                    '&BuiltInVariable::k{name_with_suffix}'.format(**param_template_args))

            template_args['parameters_var_name'] = get_variable_name_to_store_parameters(
                parameters)
            if len(parameters) > 0:
                template_args['parameters_list'] = ', '.join(parameters_list)
                template_parameter_list_declaration = 'constexpr const TVariable *{parameters_var_name}[{param_count}] = {{ {parameters_list} }};'
                parameter_declarations[template_args[
                    'parameters_var_name']] = template_parameter_list_declaration.format(
                        **template_args)
            else:
                template_parameter_list_declaration = 'constexpr const TVariable **{parameters_var_name} = nullptr;'
                parameter_declarations[template_args[
                    'parameters_var_name']] = template_parameter_list_declaration.format(
                        **template_args)

            template_function_declaration = 'constexpr const TFunction {unique_name}(BuiltInId::{human_readable_name}, BuiltInName::{name_with_suffix}, TExtension::{extension}, BuiltInParameters::{parameters_var_name}, {param_count}, {return_type}, EOp{op}, {known_to_not_have_side_effects});'
            function_declarations.append(template_function_declaration.format(**template_args))

            id_counter += 1


def process_function_group(
        group_name, group, parameter_declarations, name_declarations,
        unmangled_function_if_statements, defined_function_variants, builtin_id_declarations,
        builtin_id_definitions, defined_parameter_names, type_array_sizes_declarations,
        variable_declarations, function_declarations, script_generated_hash_tests,
        unmangled_script_generated_hash_tests, mangled_builtins, is_in_group_definitions):
    global id_counter
    first_id = id_counter

    shader_type = 'NONE'
    if 'shader_type' in group:
        shader_type = group['shader_type']

    process_single_function_group(
        shader_type, group_name, group, parameter_declarations, name_declarations,
        unmangled_function_if_statements, defined_function_variants, builtin_id_declarations,
        builtin_id_definitions, defined_parameter_names, type_array_sizes_declarations,
        variable_declarations, function_declarations, script_generated_hash_tests,
        unmangled_script_generated_hash_tests, mangled_builtins)

    if 'subgroups' in group:
        for subgroup_name, subgroup in group['subgroups'].iteritems():
            process_function_group(
                group_name + subgroup_name, subgroup, parameter_declarations, name_declarations,
                unmangled_function_if_statements, defined_function_variants,
                builtin_id_declarations, builtin_id_definitions, defined_parameter_names,
                type_array_sizes_declarations, variable_declarations, function_declarations,
                script_generated_hash_tests, unmangled_script_generated_hash_tests,
                mangled_builtins, is_in_group_definitions)

    if 'queryFunction' in group:
        template_args = {'first_id': first_id, 'last_id': id_counter - 1, 'group_name': group_name}
        template_is_in_group_definition = """bool is{group_name}(const TFunction *func)
{{
    int id = func->uniqueId().get();
    return id >= {first_id} && id <= {last_id};
}}"""
        is_in_group_definitions.append(template_is_in_group_definition.format(**template_args))


def prune_parameters_arrays(parameter_declarations, function_declarations):
    # We can share parameters arrays between functions in case one array is a subarray of another.
    parameter_variable_name_replacements = {}
    used_param_variable_names = set()
    for param_variable_name, param_declaration in sorted(
            parameter_declarations.iteritems(), key=lambda item: -len(item[0])):
        replaced = False
        for used in used_param_variable_names:
            if used.startswith(param_variable_name):
                parameter_variable_name_replacements[param_variable_name] = used
                replaced = True
                break
        if not replaced:
            used_param_variable_names.add(param_variable_name)

    for i in xrange(len(function_declarations)):
        for replaced, replacement in parameter_variable_name_replacements.iteritems():
            function_declarations[i] = function_declarations[i].replace(
                'BuiltInParameters::' + replaced + ',', 'BuiltInParameters::' + replacement + ',')

    return [
        value for key, value in parameter_declarations.iteritems()
        if key in used_param_variable_names
    ]


def process_single_variable_group(shader_type, group_name, group, builtin_id_declarations,
                                  builtin_id_definitions, name_declarations, init_member_variables,
                                  get_variable_declarations, mangled_builtins,
                                  declare_member_variables, variable_declarations,
                                  get_variable_definitions, script_generated_hash_tests):
    global id_counter
    if 'variables' not in group:
        return
    for variable_name, props in group['variables'].iteritems():
        essl_level = props['essl_level'] if 'essl_level' in props else None
        glsl_level = props['glsl_level'] if 'glsl_level' in props else None
        template_args = {
            'id':
                id_counter,
            'name':
                variable_name,
            'name_with_suffix':
                variable_name + get_suffix(props),
            'essl_level':
                essl_level,
            'glsl_level':
                glsl_level,
            'essl_extension':
                get_essl_extension(props),
            'glsl_extension':
                get_glsl_extension(props),
            # This assumes that variables cannot be part of an ESSL and GLSL extension
            # Will need to update after adding GLSL extension variables if this is not the case
            'extension':
                get_essl_extension(props)
                if get_essl_extension(props) != 'UNDEFINED' else get_glsl_extension(props),
            'class':
                'TVariable'
        }

        template_builtin_id_declaration = '    static constexpr const TSymbolUniqueId {name_with_suffix} = TSymbolUniqueId({id});'
        builtin_id_declarations.append(template_builtin_id_declaration.format(**template_args))
        template_builtin_id_definition = 'constexpr const TSymbolUniqueId BuiltInId::{name_with_suffix};'
        builtin_id_definitions.append(template_builtin_id_definition.format(**template_args))

        template_name_declaration = 'constexpr const ImmutableString {name}("{name}");'
        name_declarations.add(template_name_declaration.format(**template_args))

        is_member = True
        template_init_variable = ''

        if 'type' in props:
            if props['type']['basic'] != 'Bool' and 'precision' not in props['type']:
                raise Exception('Missing precision for variable ' + variable_name)
            template_args['type'] = TType(props['type']).get_statictype_string()

        if 'fields' in props:
            # Handle struct and interface block definitions.
            template_args['class'] = props['class']
            template_args['fields'] = 'fields_{name_with_suffix}'.format(**template_args)
            init_member_variables.append(
                '    TFieldList *{fields} = new TFieldList();'.format(**template_args))
            for field_name, field_type in props['fields'].iteritems():
                template_args['field_name'] = field_name
                template_args['field_type'] = TType(field_type).get_dynamic_type_string()
                template_name_declaration = 'constexpr const ImmutableString {field_name}("{field_name}");'
                name_declarations.add(template_name_declaration.format(**template_args))
                template_add_field = '    {fields}->push_back(new TField({field_type}, BuiltInName::{field_name}, zeroSourceLoc, SymbolType::BuiltIn));'
                init_member_variables.append(template_add_field.format(**template_args))
            template_init_temp_variable = '    {class} *{name_with_suffix} = new {class}(BuiltInId::{name_with_suffix}, BuiltInName::{name}, TExtension::{extension}, {fields});'
            init_member_variables.append(template_init_temp_variable.format(**template_args))
            if 'private' in props and props['private']:
                is_member = False
            else:
                template_init_variable = '    m_{name_with_suffix} = {name_with_suffix};'

        elif 'initDynamicType' in props:
            # Handle variables whose type can't be expressed as TStaticType
            # (type is a struct or has variable array size for example).
            template_args['type_name'] = 'type_{name_with_suffix}'.format(**template_args)
            template_args['type'] = template_args['type_name']
            template_args['initDynamicType'] = props['initDynamicType'].format(**template_args)
            template_init_variable = """    {initDynamicType}
    {type_name}->realize();
    m_{name_with_suffix} = new TVariable(BuiltInId::{name_with_suffix}, BuiltInName::{name}, SymbolType::BuiltIn, TExtension::{extension}, {type});"""

        elif 'value' in props:
            # Handle variables with constant value, such as gl_MaxDrawBuffers.
            if props['value'] != 'resources':
                raise Exception('Unrecognized value source in variable properties: ' +
                                str(props['value']))
            resources_key = variable_name[3:]
            if 'valueKey' in props:
                resources_key = props['valueKey']
            template_args['value'] = 'resources.' + resources_key
            template_args['object_size'] = TType(props['type']).get_object_size()
            template_init_variable = """    m_{name_with_suffix} = new TVariable(BuiltInId::{name_with_suffix}, BuiltInName::{name}, SymbolType::BuiltIn, TExtension::{extension}, {type});
    {{
        TConstantUnion *unionArray = new TConstantUnion[{object_size}];
        unionArray[0].setIConst({value});
        static_cast<TVariable *>(m_{name_with_suffix})->shareConstPointer(unionArray);
    }}"""
            if template_args['object_size'] > 1:
                template_init_variable = """    m_{name_with_suffix} = new TVariable(BuiltInId::{name_with_suffix}, BuiltInName::{name}, SymbolType::BuiltIn, TExtension::{extension}, {type});
    {{
        TConstantUnion *unionArray = new TConstantUnion[{object_size}];
        for (size_t index = 0u; index < {object_size}; ++index)
        {{
            unionArray[index].setIConst({value}[index]);
        }}
        static_cast<TVariable *>(m_{name_with_suffix})->shareConstPointer(unionArray);
    }}"""

        else:
            # Handle variables that can be stored as constexpr TVariable like
            # gl_Position, gl_FragColor etc.
            define_constexpr_variable(template_args, variable_declarations)
            is_member = False

            template_get_variable_declaration = 'const TVariable *{name_with_suffix}();'
            get_variable_declarations.append(
                template_get_variable_declaration.format(**template_args))

            template_get_variable_definition = """const TVariable *{name_with_suffix}()
{{
    return &k{name_with_suffix};
}}
"""
            get_variable_definitions.append(
                template_get_variable_definition.format(**template_args))

            if essl_level != 'GLSL_BUILTINS':
                obj = '&BuiltInVariable::k{name_with_suffix}'.format(**template_args)
                # TODO(http://anglebug.com/3835): Add GLSL level once GLSL built-in vars are added
                mangled_builtins.add_entry(
                    essl_level, 'COMMON_BUILTINS', shader_type, template_args['name'], obj,
                    template_args['essl_extension'], template_args['glsl_extension'],
                    script_generated_hash_tests)

        if is_member:
            init_member_variables.append(template_init_variable.format(**template_args))

            template_declare_member_variable = 'TSymbol *m_{name_with_suffix} = nullptr;'
            declare_member_variables.append(
                template_declare_member_variable.format(**template_args))

            obj = 'm_{name_with_suffix}'.format(**template_args)

            # TODO(http://anglebug.com/3835): Add GLSL level once GLSL built-in vars are added
            mangled_builtins.add_entry(essl_level, 'COMMON_BUILTINS', shader_type,
                                       template_args['name'], obj, template_args['essl_extension'],
                                       template_args['glsl_extension'],
                                       script_generated_hash_tests)

        id_counter += 1


def process_variable_group(shader_type, group_name, group, builtin_id_declarations,
                           builtin_id_definitions, name_declarations, init_member_variables,
                           get_variable_declarations, mangled_builtins, declare_member_variables,
                           variable_declarations, get_variable_definitions,
                           script_generated_hash_tests):
    global id_counter

    if 'shader_type' in group:
        shader_type = group['shader_type']

    process_single_variable_group(shader_type, group_name, group, builtin_id_declarations,
                                  builtin_id_definitions, name_declarations, init_member_variables,
                                  get_variable_declarations, mangled_builtins,
                                  declare_member_variables, variable_declarations,
                                  get_variable_definitions, script_generated_hash_tests)

    if 'subgroups' in group:
        for subgroup_name, subgroup in group['subgroups'].iteritems():
            process_variable_group(
                shader_type, subgroup_name, subgroup, builtin_id_declarations,
                builtin_id_definitions, name_declarations, init_member_variables,
                get_variable_declarations, mangled_builtins, declare_member_variables,
                variable_declarations, get_variable_definitions, script_generated_hash_tests)


def generate_files(essl_only, args, functions_txt_filename, variables_json_filename,
                   immutablestring_cpp_filename, immutablestringtest_cpp_filename,
                   builtin_header_filename, symboltable_cpp_filename, parsecontext_header_filename,
                   symboltable_header_filename):
    # Declarations of symbol unique ids
    builtin_id_declarations = []

    # Definitions of symbol unique ids needed for those ids used outside of constexpr expressions.
    builtin_id_definitions = []

    # Declarations of name string variables
    name_declarations = set()

    # Declarations of static array sizes if any builtin TVariable is array.
    type_array_sizes_declarations = set()

    # Declarations of builtin TVariables
    variable_declarations = []

    # Declarations of builtin TFunctions
    function_declarations = []

    # Functions for querying the pointer to a specific TVariable.
    get_variable_declarations = []
    get_variable_definitions = []

    # Code for defining TVariables stored as members of TSymbolTable.
    declare_member_variables = []
    init_member_variables = []

    # Code for testing that script-generated hashes match with runtime computed hashes.
    script_generated_hash_tests = OrderedDict()
    unmangled_script_generated_hash_tests = OrderedDict()

    # Functions for testing whether a builtin belongs in group.
    is_in_group_definitions = []

    # Declarations of parameter arrays for builtin TFunctions. Map from C++ variable name to the full
    # declaration.
    parameter_declarations = {}

    defined_function_variants = set()
    defined_parameter_names = set()

    parsed_functions = get_parsed_functions(functions_txt_filename, essl_only)

    if args.dump_intermediate_json:
        with open('builtin_functions_ESSL.json' if essl_only else 'builtin_functions.json',
                  'w') as outfile:

            def serialize_obj(obj):
                if isinstance(obj, TType):
                    return obj.data
                else:
                    raise "Cannot serialize to JSON: " + str(obj)

            json.dump(
                parsed_functions, outfile, indent=4, separators=(',', ': '), default=serialize_obj)

    parsed_variables = None
    with open(variables_json_filename) as f:
        # TODO(http://anglebug.com/3835): skip loading GLSL-only vars when they are added if essl_only
        parsed_variables = json.load(f, object_pairs_hook=OrderedDict)

    # This script uses a perfect hash function to avoid dealing with collisions
    mangled_names = []
    unmangled_names = []
    for group_name, group in parsed_functions.iteritems():
        get_function_names(group, mangled_names, unmangled_names)
    for group_name, group in parsed_variables.iteritems():
        get_variable_names(group, mangled_names)

    # Hashing mangled names
    mangled_names = list(dict.fromkeys(mangled_names))
    num_mangled_names = len(mangled_names)
    mangled_names_dict = dict(zip(mangled_names, range(0, len(mangled_names))))
    # Generate the perfect hash function
    f1, f2, mangled_G = generate_hash(mangled_names_dict, Hash2)
    mangled_hashfn = HashFunction(f1, f2, mangled_G)
    mangled_S1 = f1.salt
    mangled_S2 = f2.salt
    # Array for querying mangled builtins
    mangled_builtins = GroupedList(mangled_hashfn, num_mangled_names)

    # Hashing unmangled names
    unmangled_names = list(dict.fromkeys(unmangled_names))
    num_unmangled_names = len(unmangled_names)
    unmangled_names_dict = dict(zip(unmangled_names, range(0, len(unmangled_names))))
    # Generate the perfect hash function
    f1, f2, unmangled_G = generate_hash(unmangled_names_dict, Hash2)
    unmangled_hashfn = HashFunction(f1, f2, unmangled_G)
    unmangled_S1 = f1.salt
    unmangled_S2 = f2.salt
    # Array for querying unmangled builtins
    unmangled_function_if_statements = UnmangledGroupedList(unmangled_hashfn, num_unmangled_names)

    for group_name, group in parsed_functions.iteritems():
        process_function_group(
            group_name, group, parameter_declarations, name_declarations,
            unmangled_function_if_statements, defined_function_variants, builtin_id_declarations,
            builtin_id_definitions, defined_parameter_names, type_array_sizes_declarations,
            variable_declarations, function_declarations, script_generated_hash_tests,
            unmangled_script_generated_hash_tests, mangled_builtins, is_in_group_definitions)

    parameter_declarations = prune_parameters_arrays(parameter_declarations, function_declarations)

    for group_name, group in parsed_variables.iteritems():
        process_variable_group('NONE', group_name, group, builtin_id_declarations,
                               builtin_id_definitions, name_declarations, init_member_variables,
                               get_variable_declarations, mangled_builtins,
                               declare_member_variables, variable_declarations,
                               get_variable_definitions, script_generated_hash_tests)

    mangled_builtins.update_arrays()

    output_strings = {
        'script_name':
            os.path.basename(__file__),
        'copyright_year':
            date.today().year,
        'builtin_id_declarations':
            '\n'.join(builtin_id_declarations),
        'builtin_id_definitions':
            '\n'.join(builtin_id_definitions),
        'last_builtin_id':
            id_counter - 1,
        'name_declarations':
            '\n'.join(sorted(list(name_declarations))),
        'function_data_source_name':
            functions_txt_filename,
        'function_declarations':
            '\n'.join(function_declarations),
        'parameter_declarations':
            '\n'.join(sorted(parameter_declarations)),
        'is_in_group_definitions':
            '\n'.join(is_in_group_definitions),
        'variable_data_source_name':
            variables_json_filename,
        'type_array_sizes_declarations':
            '\n'.join(sorted(type_array_sizes_declarations)),
        'variable_declarations':
            '\n'.join(sorted(variable_declarations)),
        'get_variable_declarations':
            '\n'.join(sorted(get_variable_declarations)),
        'get_variable_definitions':
            '\n'.join(sorted(get_variable_definitions)),
        'declare_member_variables':
            '\n'.join(declare_member_variables),
        'init_member_variables':
            '\n'.join(init_member_variables),
        'mangled_names_array':
            ',\n'.join(mangled_builtins.get_names()),
        'mangled_offsets_array':
            '\n'.join(mangled_builtins.get_offsets()),
        'mangled_rules':
            ',\n'.join(mangled_builtins.get_rules()),
        'unmangled_array':
            ', '.join(unmangled_function_if_statements.get_array()),
        'max_unmangled_name_length':
            unmangled_function_if_statements.get_max_name_length(),
        'max_mangled_name_length':
            mangled_builtins.get_max_name_length(),
        'num_unmangled_names':
            num_unmangled_names,
        'num_mangled_names':
            num_mangled_names,
        'script_generated_hash_tests':
            '\n'.join(script_generated_hash_tests.iterkeys()),
        'unmangled_script_generated_hash_tests':
            '\n'.join(unmangled_script_generated_hash_tests.iterkeys()),
        'mangled_S1':
            str(mangled_S1).replace('[', ' ').replace(']', ' '),
        'mangled_S2':
            str(mangled_S2).replace('[', ' ').replace(']', ' '),
        'mangled_G':
            str(mangled_G).replace('[', ' ').replace(']', ' '),
        'mangled_NG':
            len(mangled_G),
        'mangled_NS':
            len(mangled_S1),
        'unmangled_S1':
            str(unmangled_S1).replace('[', ' ').replace(']', ' '),
        'unmangled_S2':
            str(unmangled_S2).replace('[', ' ').replace(']', ' '),
        'unmangled_G':
            str(unmangled_G).replace('[', ' ').replace(']', ' '),
        'unmangled_NG':
            len(unmangled_G),
        'unmangled_NS':
            len(unmangled_S1),
        'header_label':
            'ESSL_' if essl_only else 'complete_',
        'source_label':
            'ESSL_' if essl_only else ''
    }

    with open(immutablestring_cpp_filename, 'wt') as outfile_cpp:
        output_cpp = template_immutablestring_cpp.format(**output_strings)
        outfile_cpp.write(output_cpp)

    with open(immutablestringtest_cpp_filename, 'wt') as outfile_cpp:
        output_cpp = template_immutablestringtest_cpp.format(**output_strings)
        outfile_cpp.write(output_cpp)

    with open(builtin_header_filename, 'wt') as outfile_header:
        output_header = template_builtin_header.format(**output_strings)
        outfile_header.write(output_header)

    with open(symboltable_cpp_filename, 'wt') as outfile_cpp:
        output_cpp = template_symboltable_cpp.format(**output_strings)
        outfile_cpp.write(output_cpp)

    with open(parsecontext_header_filename, 'wt') as outfile_header:
        output_header = template_parsecontext_header.format(**output_strings)
        outfile_header.write(output_header)

    if not essl_only:
        with open(symboltable_header_filename, 'wt') as outfile_h:
            output_h = template_symboltable_header.format(**output_strings)
            outfile_h.write(output_h)


def main():
    random.seed(0)
    set_working_dir()

    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--dump-intermediate-json',
        help='Dump parsed function data as a JSON file builtin_functions.json',
        action="store_true")
    parser.add_argument('auto_script_command', nargs='?', default='')
    args = parser.parse_args()

    test_filename = '../../tests/compiler_tests/ImmutableString_test_autogen.cpp'
    essl_test_filename = '../../tests/compiler_tests/ImmutableString_test_ESSL_autogen.cpp'
    variables_json_filename = 'builtin_variables.json'
    functions_txt_filename = 'builtin_function_declarations.txt'

    # auto_script parameters.
    if args.auto_script_command != '':
        inputs = [
            functions_txt_filename,
            variables_json_filename,
        ]
        outputs = [
            'ImmutableString_autogen.cpp',
            'ParseContext_complete_autogen.h',
            'SymbolTable_autogen.cpp',
            'SymbolTable_autogen.h',
            'tree_util/BuiltIn_complete_autogen.h',
            test_filename,
            'ImmutableString_ESSL_autogen.cpp',
            'ParseContext_ESSL_autogen.h',
            'SymbolTable_ESSL_autogen.cpp',
            'tree_util/BuiltIn_ESSL_autogen.h',
            essl_test_filename,
        ]

        if args.auto_script_command == 'inputs':
            print ','.join(inputs)
        elif args.auto_script_command == 'outputs':
            print ','.join(outputs)
        else:
            print('Invalid script parameters')
            return 1
        return 0

    # Generate files based on GLSL + ESSL symbols
    generate_files(False, args, functions_txt_filename, variables_json_filename,
                   'ImmutableString_autogen.cpp', test_filename,
                   'tree_util/BuiltIn_complete_autogen.h', 'SymbolTable_autogen.cpp',
                   'ParseContext_complete_autogen.h', 'SymbolTable_autogen.h')

    # Generate files based on only ESSL symbols
    # Symbol table with GLSL + ESSL symbols is too large for Android
    generate_files(True, args, functions_txt_filename, variables_json_filename,
                   'ImmutableString_ESSL_autogen.cpp', essl_test_filename,
                   'tree_util/BuiltIn_ESSL_autogen.h', 'SymbolTable_ESSL_autogen.cpp',
                   'ParseContext_ESSL_autogen.h', 'SymbolTable_autogen.h')

    return 0


if __name__ == '__main__':
    sys.exit(main())
