// 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.
///|
fn metadata_scope_def_from_directive(
directive : WgslPreprocessorDirective,
) -> (Bool, String?) {
let tail = wgsl_effective_directive_tail(directive)
let has_required_separator = directive.has_required_tail_separator()
match wgsl_effective_directive_kind(directive) {
Ifdef =>
if has_required_separator {
match parse_wgsl_directive_identifier(tail) {
Some(name) => (true, Some(name))
None => (false, None)
}
} else {
(false, None)
}
Ifndef =>
if has_required_separator {
match parse_wgsl_directive_identifier(tail) {
Some(name) => (true, Some(name))
None => (false, None)
}
} else {
(false, None)
}
If =>
if has_required_separator {
match metadata_shader_def_comparison_def(tail) {
Some(def) => (true, Some(def))
None => (false, None)
}
} else {
(false, None)
}
Else => {
let else_tail_has_space = wgsl_text_starts_with_tokenized_space(tail)
if else_tail_has_space &&
wgsl_required_space_word_tail(tail, "ifdef") is Some(rest) &&
parse_wgsl_directive_identifier(rest) is Some(name) {
return (true, Some(name))
}
if else_tail_has_space &&
wgsl_required_space_word_tail(tail, "ifndef") is Some(rest) &&
parse_wgsl_directive_identifier(rest) is Some(name) {
return (true, Some(name))
}
if else_tail_has_space &&
wgsl_required_space_word_tail(tail, "if") is Some(expr) &&
metadata_shader_def_comparison_def(expr) is Some(def) {
return (true, Some(def))
}
(true, None)
}
Endif => (true, None)
_ => (false, None)
}
}
///|
fn metadata_shader_def_comparison_def(expression : String) -> String? {
match parse_wgsl_shader_def_comparison(expression) {
Some(comparison) => Some(comparison.def_name())
None => None
}
}
///|
fn metadata_source_line_text_end(text : String, line_start : Int) -> Int {
wgsl_line_text_end(text, line_start)
}
///|
fn metadata_collect_source_item(
item : WgslDirectiveScanItem,
effective_defs : @set.Set[String],
) -> Unit {
let mut line_start = 0
let cleaned_text = item.source().cleaned_text()
while line_start < cleaned_text.length() {
let line_text_end = metadata_source_line_text_end(cleaned_text, line_start)
let line_end = line_text_end +
wgsl_line_break_width(cleaned_text, line_text_end)
let line = cleaned_text[line_start:line_text_end].to_owned()
collect_effective_def_names(line, effective_defs)
line_start = line_end
}
}
///|
fn metadata_collect_import_uses(
source : String,
import_state : WgslImportSubstitutionState,
used_imports : Array[ImportDefWithOffset],
) -> Unit raise MetadataError {
ignore(
import_state.rewrite_source(source, 0, used_imports, true) catch {
AmbiguousImport(position) =>
raise ImportParseError("Ambiguous import path for item", position)
InvalidWgslSyntax(message, position) =>
raise ImportParseError(message, position)
},
)
}