// Copyright 2026 International Digital Economy Academy
//
// 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.
///|
pub fn wgsl_ir_identifier_is_predeclared_type(ident : String) -> Bool {
ident == "array" ||
ident == "atomic" ||
ident == "bool" ||
ident == "f32" ||
ident == "f16" ||
ident == "i32" ||
ident == "i64" ||
ident == "mat2x2" ||
ident == "mat2x3" ||
ident == "mat2x4" ||
ident == "mat3x2" ||
ident == "mat3x3" ||
ident == "mat3x4" ||
ident == "mat4x2" ||
ident == "mat4x3" ||
ident == "mat4x4" ||
ident == "ptr" ||
ident == "sampler" ||
ident == "sampler_comparison" ||
ident == "texture_1d" ||
ident == "texture_2d" ||
ident == "texture_2d_array" ||
ident == "texture_3d" ||
ident == "texture_cube" ||
ident == "texture_cube_array" ||
ident == "texture_external" ||
ident == "texture_multisampled_2d" ||
ident == "texture_storage_1d" ||
ident == "texture_storage_2d" ||
ident == "texture_storage_2d_array" ||
ident == "texture_storage_3d" ||
ident == "texture_depth_2d" ||
ident == "texture_depth_2d_array" ||
ident == "texture_depth_cube" ||
ident == "texture_depth_cube_array" ||
ident == "texture_depth_multisampled_2d" ||
ident == "u32" ||
ident == "u64" ||
ident == "vec2" ||
ident == "vec3" ||
ident == "vec4"
}
///|
pub fn wgsl_ir_identifier_is_reserved(ident : String) -> Bool {
if ident == "" {
return false
}
wgsl_ir_identifier_is_predeclared_type(ident) ||
ident == "alias" ||
ident == "bitcast" ||
ident == "break" ||
ident == "case" ||
ident == "const" ||
ident == "const_assert" ||
ident == "continue" ||
ident == "continuing" ||
ident == "default" ||
ident == "diagnostic" ||
ident == "discard" ||
ident == "else" ||
ident == "enable" ||
ident == "false" ||
ident == "fn" ||
ident == "for" ||
ident == "if" ||
ident == "let" ||
ident == "loop" ||
ident == "override" ||
ident == "return" ||
ident == "static_assert" ||
ident == "struct" ||
ident == "switch" ||
ident == "true" ||
ident == "type" ||
ident == "var" ||
ident == "while" ||
ident == "CompileShader" ||
ident == "ComputeShader" ||
ident == "DomainShader" ||
ident == "GeometryShader" ||
ident == "Hullshader" ||
ident == "NULL" ||
ident == "Self" ||
ident == "abstract" ||
ident == "active" ||
ident == "alignas" ||
ident == "alignof" ||
ident == "as" ||
ident == "asm" ||
ident == "asm_fragment" ||
ident == "async" ||
ident == "attribute" ||
ident == "auto" ||
ident == "await" ||
ident == "become" ||
ident == "binding_array" ||
ident == "cast" ||
ident == "catch" ||
ident == "class" ||
ident == "co_await" ||
ident == "co_return" ||
ident == "co_yield" ||
ident == "coherent" ||
ident == "column_major" ||
ident == "common" ||
ident == "compile" ||
ident == "compile_fragment" ||
ident == "concept" ||
ident == "const_cast" ||
ident == "consteval" ||
ident == "constexpr" ||
ident == "constinit" ||
ident == "crate" ||
ident == "debugger" ||
ident == "decltype" ||
ident == "delete" ||
ident == "demote" ||
ident == "demote_to_helper" ||
ident == "do" ||
ident == "dynamic_cast" ||
ident == "enum" ||
ident == "explicit" ||
ident == "export" ||
ident == "extends" ||
ident == "extern" ||
ident == "external" ||
ident == "fallthrough" ||
ident == "filter" ||
ident == "final" ||
ident == "finally" ||
ident == "friend" ||
ident == "from" ||
ident == "fxgroup" ||
ident == "get" ||
ident == "goto" ||
ident == "groupshared" ||
ident == "handle" ||
ident == "highp" ||
ident == "impl" ||
ident == "implements" ||
ident == "import" ||
ident == "inline" ||
ident == "inout" ||
ident == "instanceof" ||
ident == "interface" ||
ident == "layout" ||
ident == "lowp" ||
ident == "macro" ||
ident == "macro_rules" ||
ident == "match" ||
ident == "mediump" ||
ident == "meta" ||
ident == "mod" ||
ident == "module" ||
ident == "move" ||
ident == "mut" ||
ident == "mutable" ||
ident == "namespace" ||
ident == "new" ||
ident == "nil" ||
ident == "noexcept" ||
ident == "noinline" ||
ident == "nointerpolation" ||
ident == "noperspective" ||
ident == "null" ||
ident == "nullptr" ||
ident == "of" ||
ident == "operator" ||
ident == "package" ||
ident == "packoffset" ||
ident == "partition" ||
ident == "pass" ||
ident == "patch" ||
ident == "pixelfragment" ||
ident == "precise" ||
ident == "precision" ||
ident == "premerge" ||
ident == "priv" ||
ident == "protected" ||
ident == "pub" ||
ident == "public" ||
ident == "readonly" ||
ident == "ref" ||
ident == "regardless" ||
ident == "register" ||
ident == "reinterpret_cast" ||
ident == "requires" ||
ident == "resource" ||
ident == "restrict" ||
ident == "self" ||
ident == "set" ||
ident == "shared" ||
ident == "signed" ||
ident == "sizeof" ||
ident == "smooth" ||
ident == "snorm" ||
ident == "static" ||
ident == "static_cast" ||
ident == "std" ||
ident == "subroutine" ||
ident == "super" ||
ident == "target" ||
ident == "template" ||
ident == "this" ||
ident == "thread_local" ||
ident == "throw" ||
ident == "trait" ||
ident == "try" ||
ident == "typedef" ||
ident == "typeid" ||
ident == "typename" ||
ident == "typeof" ||
ident == "union" ||
ident == "unless" ||
ident == "unorm" ||
ident == "unsafe" ||
ident == "unsized" ||
ident == "use" ||
ident == "using" ||
ident == "varying" ||
ident == "virtual" ||
ident == "volatile" ||
ident == "wgsl" ||
ident == "where" ||
ident == "with" ||
ident == "writeonly" ||
ident == "yield"
}
///|
pub fn wgsl_ir_identifier_is_builtin_function(ident : String) -> Bool {
ident == "abs" ||
ident == "acos" ||
ident == "acosh" ||
ident == "all" ||
ident == "any" ||
ident == "arrayLength" ||
ident == "asin" ||
ident == "asinh" ||
ident == "atan" ||
ident == "atan2" ||
ident == "atanh" ||
ident == "atomicAdd" ||
ident == "atomicAnd" ||
ident == "atomicCompareExchangeWeak" ||
ident == "atomicExchange" ||
ident == "atomicLoad" ||
ident == "atomicMax" ||
ident == "atomicMin" ||
ident == "atomicOr" ||
ident == "atomicStore" ||
ident == "atomicSub" ||
ident == "atomicXor" ||
ident == "ceil" ||
ident == "clamp" ||
ident == "cos" ||
ident == "cosh" ||
ident == "countLeadingZeros" ||
ident == "countOneBits" ||
ident == "countTrailingZeros" ||
ident == "cross" ||
ident == "degrees" ||
ident == "determinant" ||
ident == "distance" ||
ident == "dot" ||
ident == "dot4I8Packed" ||
ident == "dot4U8Packed" ||
ident == "dpdx" ||
ident == "dpdxCoarse" ||
ident == "dpdxFine" ||
ident == "dpdy" ||
ident == "dpdyCoarse" ||
ident == "dpdyFine" ||
ident == "exp" ||
ident == "exp2" ||
ident == "extractBits" ||
ident == "faceForward" ||
ident == "firstLeadingBit" ||
ident == "firstTrailingBit" ||
ident == "floor" ||
ident == "fma" ||
ident == "fract" ||
ident == "frexp" ||
ident == "fwidth" ||
ident == "fwidthCoarse" ||
ident == "fwidthFine" ||
ident == "insertBits" ||
ident == "inverse" ||
ident == "inverseSqrt" ||
ident == "isInf" ||
ident == "isNan" ||
ident == "ldexp" ||
ident == "length" ||
ident == "log" ||
ident == "log2" ||
ident == "max" ||
ident == "min" ||
ident == "mix" ||
ident == "modf" ||
ident == "normalize" ||
ident == "pack2x16float" ||
ident == "pack2x16snorm" ||
ident == "pack2x16unorm" ||
ident == "pack4x8snorm" ||
ident == "pack4x8unorm" ||
ident == "pack4xI8" ||
ident == "pack4xI8Clamp" ||
ident == "pack4xU8" ||
ident == "pack4xU8Clamp" ||
ident == "pow" ||
ident == "quantizeToF16" ||
ident == "radians" ||
ident == "reflect" ||
ident == "refract" ||
ident == "reverseBits" ||
ident == "round" ||
ident == "saturate" ||
ident == "sign" ||
ident == "sin" ||
ident == "sinh" ||
ident == "smoothstep" ||
ident == "sqrt" ||
ident == "step" ||
ident == "subgroupBallot" ||
ident == "subgroupBroadcast" ||
ident == "subgroupElect" ||
ident == "subgroupShuffle" ||
ident == "subgroupShuffleDown" ||
ident == "subgroupShuffleUp" ||
ident == "subgroupShuffleXor" ||
ident == "tan" ||
ident == "tanh" ||
ident == "textureDimensions" ||
ident == "textureGather" ||
ident == "textureGatherCompare" ||
ident == "textureLoad" ||
ident == "textureNumLayers" ||
ident == "textureNumLevels" ||
ident == "textureNumSamples" ||
ident == "textureSample" ||
ident == "textureSampleBaseClampToEdge" ||
ident == "textureSampleBias" ||
ident == "textureSampleCompare" ||
ident == "textureSampleCompareLevel" ||
ident == "textureSampleGrad" ||
ident == "textureSampleLevel" ||
ident == "textureStore" ||
ident == "transpose" ||
ident == "trunc" ||
ident == "unpack2x16float" ||
ident == "unpack2x16snorm" ||
ident == "unpack2x16unorm" ||
ident == "unpack4x8snorm" ||
ident == "unpack4x8unorm" ||
ident == "unpack4xI8" ||
ident == "unpack4xU8" ||
ident == "workgroupBarrier" ||
ident == "workgroupUniformLoad"
}
///|
pub fn wgsl_ir_identifier_ends_with_digit(ident : String) -> Bool {
if ident == "" {
return false
}
ident.has_suffix("0") ||
ident.has_suffix("1") ||
ident.has_suffix("2") ||
ident.has_suffix("3") ||
ident.has_suffix("4") ||
ident.has_suffix("5") ||
ident.has_suffix("6") ||
ident.has_suffix("7") ||
ident.has_suffix("8") ||
ident.has_suffix("9")
}
///|
pub fn sanitize_wgsl_ir_identifier(ident : String) -> String {
let had_trailing_separator = ident.has_suffix("_")
let mut out = ident
while out.has_suffix("_") {
out = out[:out.length() - 1].to_owned()
}
while out.has_prefix("__") {
out = out[1:out.length()].to_owned()
}
if out == "" {
out = "unnamed"
}
if out.has_prefix("_naga") {
out = "gen_\{out}"
}
if wgsl_ir_identifier_is_reserved(out) {
out = "\{out}_wgsl"
} else if had_trailing_separator && wgsl_ir_identifier_ends_with_digit(out) {
out = "\{out}_"
}
out
}