// Copyright 2015 The Shaderc Authors. All rights reserved.
//
// 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.

#include "shaderc/shaderc.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <memory>
#include <thread>
#include <unordered_map>

#include "common_shaders_for_test.h"
#include "spirv/unified1/spirv.hpp"

namespace {

using testing::Each;
using testing::HasSubstr;
using testing::Not;

TEST(Init, MultipleCalls) {
  shaderc_compiler_t compiler1, compiler2, compiler3;
  EXPECT_NE(nullptr, compiler1 = shaderc_compiler_initialize());
  EXPECT_NE(nullptr, compiler2 = shaderc_compiler_initialize());
  EXPECT_NE(nullptr, compiler3 = shaderc_compiler_initialize());
  shaderc_compiler_release(compiler1);
  shaderc_compiler_release(compiler2);
  shaderc_compiler_release(compiler3);
}

#ifndef SHADERC_DISABLE_THREADED_TESTS
TEST(Init, MultipleThreadsCalling) {
  shaderc_compiler_t compiler1, compiler2, compiler3;
  std::thread t1([&compiler1]() { compiler1 = shaderc_compiler_initialize(); });
  std::thread t2([&compiler2]() { compiler2 = shaderc_compiler_initialize(); });
  std::thread t3([&compiler3]() { compiler3 = shaderc_compiler_initialize(); });
  t1.join();
  t2.join();
  t3.join();
  EXPECT_NE(nullptr, compiler1);
  EXPECT_NE(nullptr, compiler2);
  EXPECT_NE(nullptr, compiler3);
  shaderc_compiler_release(compiler1);
  shaderc_compiler_release(compiler2);
  shaderc_compiler_release(compiler3);
}
#endif

TEST(Init, SPVVersion) {
  unsigned int version = 0;
  unsigned int revision = 0;
  shaderc_get_spv_version(&version, &revision);
  EXPECT_EQ(spv::Version, version);
  EXPECT_EQ(spv::Revision, revision);
}

// Determines the kind of output required from the compiler.
enum class OutputType {
  SpirvBinary,
  SpirvAssemblyText,
  PreprocessedText,
};

// Generate a compilation result object with the given compile,
// shader source, shader kind, input file name, entry point name, options,
// and for the specified output type.  The entry point name is only significant
// for HLSL compilation.
shaderc_compilation_result_t MakeCompilationResult(
    const shaderc_compiler_t compiler, const std::string& shader,
    shaderc_shader_kind kind, const char* input_file_name,
    const char* entry_point_name, const shaderc_compile_options_t options,
    OutputType output_type) {
  switch (output_type) {
    case OutputType::SpirvBinary:
      return shaderc_compile_into_spv(compiler, shader.c_str(), shader.size(),
                                      kind, input_file_name, entry_point_name,
                                      options);
      break;
    case OutputType::SpirvAssemblyText:
      return shaderc_compile_into_spv_assembly(
          compiler, shader.c_str(), shader.size(), kind, input_file_name,
          entry_point_name, options);
      break;
    case OutputType::PreprocessedText:
      return shaderc_compile_into_preprocessed_text(
          compiler, shader.c_str(), shader.size(), kind, input_file_name,
          entry_point_name, options);
      break;
  }
  // We shouldn't reach here.  But some compilers might not know that.
  // Be a little defensive and produce something.
  return shaderc_compile_into_spv(compiler, shader.c_str(), shader.size(), kind,
                                  input_file_name, entry_point_name, options);
}

// RAII class for shaderc_compilation_result. Used for shader compilation.
class Compilation {
 public:
  // Compiles shader and keeps the result.
  Compilation(const shaderc_compiler_t compiler, const std::string& shader,
              shaderc_shader_kind kind, const char* input_file_name,
              const char* entry_point_name,
              const shaderc_compile_options_t options = nullptr,
              OutputType output_type = OutputType::SpirvBinary)
      : compiled_result_(
            MakeCompilationResult(compiler, shader, kind, input_file_name,
                                  entry_point_name, options, output_type)) {}

  ~Compilation() { shaderc_result_release(compiled_result_); }

  shaderc_compilation_result_t result() const { return compiled_result_; }

 private:
  shaderc_compilation_result_t compiled_result_;
};

// RAII class for shaderc_compilation_result. Used for shader assembling.
class Assembling {
 public:
  // Assembles shader and keeps the result.
  Assembling(const shaderc_compiler_t compiler, const std::string& assembly,
             const shaderc_compile_options_t options = nullptr)
      : compiled_result_(shaderc_assemble_into_spv(compiler, assembly.data(),
                                                   assembly.size(), options)) {}

  ~Assembling() { shaderc_result_release(compiled_result_); }

  shaderc_compilation_result_t result() const { return compiled_result_; }

 private:
  shaderc_compilation_result_t compiled_result_;
};

struct CleanupOptions {
  void operator()(shaderc_compile_options_t options) const {
    shaderc_compile_options_release(options);
  }
};

typedef std::unique_ptr<shaderc_compile_options, CleanupOptions>
    compile_options_ptr;

// RAII class for shaderc_compiler_t
class Compiler {
 public:
  Compiler() { compiler = shaderc_compiler_initialize(); }
  ~Compiler() { shaderc_compiler_release(compiler); }
  shaderc_compiler_t get_compiler_handle() { return compiler; }

 private:
  shaderc_compiler_t compiler;
};

// RAII class for shader_compiler_options_t
class Options {
 public:
  Options() : options_(shaderc_compile_options_initialize()) {}
  ~Options() { shaderc_compile_options_release(options_); }
  shaderc_compile_options_t get() { return options_; }

 private:
  shaderc_compile_options_t options_;
};

// Helper function to check if the compilation result indicates a successful
// compilation.
bool CompilationResultIsSuccess(const shaderc_compilation_result_t result) {
  return shaderc_result_get_compilation_status(result) ==
         shaderc_compilation_status_success;
}

// Returns true if the given result contains a SPIR-V module that contains
// at least the number of bytes of the header and the correct magic number.
bool ResultContainsValidSpv(shaderc_compilation_result_t result) {
  if (!CompilationResultIsSuccess(result)) return false;
  size_t length = shaderc_result_get_length(result);
  if (length < 20) return false;
  const uint32_t* bytes = static_cast<const uint32_t*>(
      static_cast<const void*>(shaderc_result_get_bytes(result)));
  return bytes[0] == spv::MagicNumber;
}

// Compiles a shader and returns true if the result is valid SPIR-V.
bool CompilesToValidSpv(Compiler& compiler, const std::string& shader,
                        shaderc_shader_kind kind,
                        const shaderc_compile_options_t options = nullptr) {
  const Compilation comp(compiler.get_compiler_handle(), shader, kind, "shader",
                         "main", options, OutputType::SpirvBinary);
  return ResultContainsValidSpv(comp.result());
}

// A testing class to test the compilation of a string with or without options.
// This class wraps the initailization of compiler and compiler options and
// groups the result checking methods. Subclass tests can access the compiler
// object and compiler option object to set their properties. Input file names
// are set to "shader".
class CompileStringTest : public testing::Test {
 protected:
  // Compiles a shader and returns true on success, false on failure.
  bool CompilationSuccess(const std::string& shader, shaderc_shader_kind kind,
                          shaderc_compile_options_t options = nullptr,
                          OutputType output_type = OutputType::SpirvBinary) {
    return CompilationResultIsSuccess(
        Compilation(compiler_.get_compiler_handle(), shader, kind, "shader",
                    "main", options, output_type)
            .result());
  }

  // Compiles a shader, expects compilation success, and returns the warning
  // messages.
  const std::string CompilationWarnings(
      const std::string& shader, shaderc_shader_kind kind,
      const shaderc_compile_options_t options = nullptr,
      OutputType output_type = OutputType::SpirvBinary) {
    const Compilation comp(compiler_.get_compiler_handle(), shader, kind,
                           "shader", "main", options, output_type);
    EXPECT_TRUE(CompilationResultIsSuccess(comp.result())) << kind << '\n'
                                                           << shader;
    return shaderc_result_get_error_message(comp.result());
  }

  // Compiles a shader, expects compilation failure, and returns the messages.
  const std::string CompilationErrors(
      const std::string& shader, shaderc_shader_kind kind,
      const shaderc_compile_options_t options = nullptr,
      OutputType output_type = OutputType::SpirvBinary,
      const char* source_name = "shader") {
    const Compilation comp(compiler_.get_compiler_handle(), shader, kind,
                           source_name, "main", options, output_type);
    EXPECT_FALSE(CompilationResultIsSuccess(comp.result())) << kind << '\n'
                                                            << shader;
    EXPECT_EQ(0u, shaderc_result_get_length(comp.result()));
    return shaderc_result_get_error_message(comp.result());
  }

  // Compiles a shader and returns the messages.
  const std::string CompilationMessages(
      const std::string& shader, shaderc_shader_kind kind,
      const shaderc_compile_options_t options = nullptr,
      OutputType output_type = OutputType::SpirvBinary) {
    const Compilation comp(compiler_.get_compiler_handle(), shader, kind,
                           "shader", "main", options, output_type);
    return shaderc_result_get_error_message(comp.result());
  }

  // Compiles a shader, expects compilation success, and returns the output
  // bytes.
  const std::string CompilationOutput(
      const std::string& shader, shaderc_shader_kind kind,
      const shaderc_compile_options_t options = nullptr,
      OutputType output_type = OutputType::SpirvBinary) {
    const Compilation comp(compiler_.get_compiler_handle(), shader, kind,
                           "shader", "main", options, output_type);
    EXPECT_TRUE(CompilationResultIsSuccess(comp.result()))
        << "shader kind: " << kind << "\nerror message: "
        << shaderc_result_get_error_message(comp.result())
        << "\nshader source code: \n"
        << shader;
    // Use string(const char* s, size_t n) constructor instead of
    // string(const char* s) to make sure the string has complete binary data.
    // string(const char* s) assumes a null-terminated C-string, which will cut
    // the binary data when it sees a '\0' byte.
    return std::string(shaderc_result_get_bytes(comp.result()),
                       shaderc_result_get_length(comp.result()));
  }

  Compiler compiler_;
  compile_options_ptr options_;

 public:
  CompileStringTest() : options_(shaderc_compile_options_initialize()) {}
};

// A testing class to test the assembling of a string.
// This class wraps the initailization of compiler and groups the result
// checking methods. Subclass tests can access the compiler object to set their
// properties.
class AssembleStringTest : public testing::Test {
 public:
  AssembleStringTest() : options_(shaderc_compile_options_initialize()) {}
  ~AssembleStringTest() { shaderc_compile_options_release(options_); }

 protected:
  // Assembles the given assembly and returns true on success.
  bool AssemblingSuccess(const std::string& assembly) {
    return CompilationResultIsSuccess(
        Assembling(compiler_.get_compiler_handle(), assembly, options_)
            .result());
  }

  bool AssemblingValid(const std::string& assembly) {
    const auto assembling =
        Assembling(compiler_.get_compiler_handle(), assembly);
    return ResultContainsValidSpv(assembling.result());
  }

  Compiler compiler_;
  shaderc_compile_options_t options_;
};

// Name holders so that we have test cases being grouped with only one real
// compilation class.
using CompileStringWithOptionsTest = CompileStringTest;
using CompileKindsTest = CompileStringTest;

TEST_F(CompileStringTest, EmptyString) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_FALSE(CompilationSuccess("", shaderc_glsl_vertex_shader));
  EXPECT_FALSE(CompilationSuccess("", shaderc_glsl_fragment_shader));
}

TEST_F(AssembleStringTest, EmptyString) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(AssemblingSuccess(""));
}

TEST_F(CompileStringTest, GarbageString) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_FALSE(CompilationSuccess("jfalkds", shaderc_glsl_vertex_shader));
  EXPECT_FALSE(CompilationSuccess("jfalkds", shaderc_glsl_fragment_shader));
}

TEST_F(AssembleStringTest, GarbageString) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  auto assembling = Assembling(compiler_.get_compiler_handle(), "jfalkds");
  EXPECT_FALSE(CompilationResultIsSuccess(assembling.result()));
  EXPECT_EQ(1u, shaderc_result_get_num_errors(assembling.result()));
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(assembling.result()));
}

// TODO(antiagainst): right now there is no assembling difference for all the
// target environments exposed by shaderc. So the following is just testing the
// target environment is accepted.
TEST_F(AssembleStringTest, AcceptTargetEnv) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_set_target_env(options_, shaderc_target_env_opengl,
                                         /* version = */ 0);
  EXPECT_TRUE(AssemblingSuccess("OpCapability Shader"));
}

TEST_F(CompileStringTest, ReallyLongShader) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  std::string minimal_shader = "";
  minimal_shader += "#version 140\n";
  minimal_shader += "void foo(){}";
  minimal_shader.append(1024 * 1024 * 8, ' ');  // 8MB of spaces.
  minimal_shader += "void main(){}";
  EXPECT_TRUE(CompilesToValidSpv(compiler_, minimal_shader,
                                 shaderc_glsl_vertex_shader));
  EXPECT_TRUE(CompilesToValidSpv(compiler_, minimal_shader,
                                 shaderc_glsl_fragment_shader));
}

TEST_F(CompileStringTest, MinimalShader) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
                                 shaderc_glsl_vertex_shader));
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
                                 shaderc_glsl_fragment_shader));
}

TEST_F(AssembleStringTest, MinimalShader) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(AssemblingValid(kMinimalShaderAssembly));
}

TEST_F(CompileStringTest, WorksWithCompileOptions) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringTest, GetNumErrors) {
  Compilation comp(compiler_.get_compiler_handle(), kTwoErrorsShader,
                   shaderc_glsl_vertex_shader, "shader", "main");
  // Expects compilation failure and two errors.
  EXPECT_FALSE(CompilationResultIsSuccess(comp.result()));
  EXPECT_EQ(2u, shaderc_result_get_num_errors(comp.result()));
  // Expects the number of warnings to be zero.
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp.result()));
}

TEST_F(CompileStringTest, GetNumWarnings) {
  Compilation comp(compiler_.get_compiler_handle(), kTwoWarningsShader,
                   shaderc_glsl_vertex_shader, "shader", "main");
  // Expects compilation success with two warnings.
  EXPECT_TRUE(CompilationResultIsSuccess(comp.result()));
  EXPECT_EQ(2u, shaderc_result_get_num_warnings(comp.result()));
  // Expects the number of errors to be zero.
  EXPECT_EQ(0u, shaderc_result_get_num_errors(comp.result()));
}

TEST_F(CompileStringTest, ZeroErrorsZeroWarnings) {
  Compilation comp(compiler_.get_compiler_handle(), kMinimalShader,
                   shaderc_glsl_vertex_shader, "shader", "main");
  // Expects compilation success with zero warnings.
  EXPECT_TRUE(CompilationResultIsSuccess(comp.result()));
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp.result()));
  // Expects the number of errors to be zero.
  EXPECT_EQ(0u, shaderc_result_get_num_errors(comp.result()));
}

TEST_F(CompileStringTest, ErrorTypeUnknownShaderStage) {
  // The shader kind/stage can not be determined, the error type field should
  // indicate the error type is shaderc_shader_kind_error.
  Compilation comp(compiler_.get_compiler_handle(), kMinimalShader,
                   shaderc_glsl_infer_from_source, "shader", "main");
  EXPECT_EQ(shaderc_compilation_status_invalid_stage,
            shaderc_result_get_compilation_status(comp.result()));
}
TEST_F(CompileStringTest, ErrorTypeCompilationError) {
  // The shader kind is valid, the result object's error type field should
  // indicate this compilaion fails due to compilation errors.
  Compilation comp(compiler_.get_compiler_handle(), kTwoErrorsShader,
                   shaderc_glsl_vertex_shader, "shader", "main");
  EXPECT_EQ(shaderc_compilation_status_compilation_error,
            shaderc_result_get_compilation_status(comp.result()));
}

TEST_F(CompileStringWithOptionsTest, CloneCompilerOptions) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  compile_options_ptr options_(shaderc_compile_options_initialize());
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
                                 shaderc_glsl_vertex_shader,
                                 cloned_options.get()));
}

TEST_F(CompileStringWithOptionsTest, MacroCompileOptions) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_add_macro_definition(options_.get(), "E", 1u, "main",
                                               4u);
  const std::string kMinimalExpandedShader = "#version 140\nvoid E(){}";
  const std::string kMinimalDoubleExpandedShader = "#version 140\nF E(){}";
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalExpandedShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  // The simplest should still compile with the cloned options.
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalExpandedShader,
                                 shaderc_glsl_vertex_shader,
                                 cloned_options.get()));
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kMinimalDoubleExpandedShader,
                                  shaderc_glsl_vertex_shader,
                                  cloned_options.get()));

  shaderc_compile_options_add_macro_definition(cloned_options.get(), "F", 1u,
                                               "void", 4u);
  // This should still not work with the original options.
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kMinimalDoubleExpandedShader,
                                  shaderc_glsl_vertex_shader, options_.get()));
  // This should work with the cloned options that have the additional
  // parameter.
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalDoubleExpandedShader,
                                 shaderc_glsl_vertex_shader,
                                 cloned_options.get()));
}

TEST_F(CompileStringWithOptionsTest, MacroCompileOptionsNotNullTerminated) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_add_macro_definition(options_.get(), "EFGH", 1u,
                                               "mainnnnnn", 4u);
  const std::string kMinimalExpandedShader = "#version 140\nvoid E(){}";
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalExpandedShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest, ValuelessMacroCompileOptionsZeroLength) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_add_macro_definition(options_.get(), "E", 1u,
                                               "somthing", 0u);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kValuelessPredefinitionShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest, ValuelessMacroCompileOptionsNullPointer) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_add_macro_definition(options_.get(), "E", 1u, nullptr,
                                               100u);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kValuelessPredefinitionShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest, DisassemblyOption) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  // This should work with both the glslang assembly format and the
  // SPIR-V tools assembly format.
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("Capability Shader"));
  EXPECT_THAT(disassembly_text, HasSubstr("MemoryModel"));
}

TEST_F(CompileStringWithOptionsTest, DisassembleMinimalShader) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
    EXPECT_THAT(disassembly_text, HasSubstr(substring));
  }
}

TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileCorrectStd) {
  // Forces the version and profile to 450core, which fixes the missing
  // #version.
  shaderc_compile_options_set_forced_version_profile(options_.get(), 450,
                                                     shaderc_profile_core);
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kCoreVertShaderWithoutVersion,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       ForcedVersionProfileCorrectStdClonedOptions) {
  // Forces the version and profile to 450core, which fixes the missing
  // #version.
  shaderc_compile_options_set_forced_version_profile(options_.get(), 450,
                                                     shaderc_profile_core);
  // This mode should be carried to any clone of the original options object.
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kCoreVertShaderWithoutVersion,
                                 shaderc_glsl_vertex_shader,
                                 cloned_options.get()));
}

TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileInvalidModule) {
  // Forces the version and profile to 310es, while the source module is invalid
  // for this version of GLSL. Compilation should fail.
  shaderc_compile_options_set_forced_version_profile(options_.get(), 310,
                                                     shaderc_profile_es);
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_THAT(CompilationErrors(kCoreVertShaderWithoutVersion,
                                shaderc_glsl_vertex_shader, options_.get()),
              HasSubstr("error: 'gl_ClipDistance' : undeclared identifier\n"));
}

TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileConflictingStd) {
  // Forces the version and profile to 450core, which is in conflict with the
  // #version in shader.
  shaderc_compile_options_set_forced_version_profile(options_.get(), 450,
                                                     shaderc_profile_core);
  const std::string kVertexShader =
      std::string("#version 310 es\n") + kCoreVertShaderWithoutVersion;
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_THAT(CompilationWarnings(kVertexShader, shaderc_glsl_vertex_shader,
                                  options_.get()),
              HasSubstr("warning: (version, profile) forced to be (450, core), "
                        "while in source code it is (310, es)\n"));
}

TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileUnknownVersionStd) {
  // Forces the version and profile to 4242core, which is an unknown version.
  shaderc_compile_options_set_forced_version_profile(
      options_.get(), 4242 /*unknown version*/, shaderc_profile_core);
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  // Warning message should complain about the unknown version.
  //
  // Also, Glslang errors out on unkown versions, due to commit:
  // https://github.com/KhronosGroup/glslang/commit/9353f1afab8d1c2b1811c6acd807675128eaabc5
  const auto errs = CompilationErrors(
      kMinimalShader, shaderc_glsl_vertex_shader, options_.get());
  EXPECT_THAT(
      errs, HasSubstr("warning: (version, profile) forced to be (4242, core), "
                      "while in source code it is (140, none)\n"));
  EXPECT_THAT(errs, HasSubstr("error: version not supported\n"));
}

TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileVersionsBefore150) {
  // Versions before 150 do not allow a profile token, shaderc_profile_none
  // should be passed down as the profile parameter.
  shaderc_compile_options_set_forced_version_profile(options_.get(), 140,
                                                     shaderc_profile_none);
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_TRUE(CompilationSuccess(kMinimalShaderWithoutVersion,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest, ForcedVersionProfileRedundantProfileStd) {
  // Forces the version and profile to 100core. But versions before 150 do not
  // allow a profile token, compilation should fail.
  shaderc_compile_options_set_forced_version_profile(options_.get(), 100,
                                                     shaderc_profile_core);
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_THAT(CompilationErrors(kMinimalShader, shaderc_glsl_vertex_shader,
                                options_.get()),
              HasSubstr("error: #version: versions before 150 do not allow a "
                        "profile token\n"));
}

TEST_F(CompileStringWithOptionsTest, GenerateDebugInfoBinary) {
  shaderc_compile_options_set_generate_debug_info(options_.get());
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string binary_output =
      CompilationOutput(kMinimalDebugInfoShader,
                        shaderc_glsl_vertex_shader, options_.get());
  // The binary output should contain the name of the vector (debug_info_sample)
  // null-terminated, as well as the whole original source.
  std::string vector_name("debug_info_sample");
  vector_name.resize(vector_name.size() + 1);
  EXPECT_THAT(binary_output, HasSubstr(vector_name));
  EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
}

TEST_F(CompileStringWithOptionsTest, GenerateDebugInfoBinaryClonedOptions) {
  shaderc_compile_options_set_generate_debug_info(options_.get());
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string binary_output =
      CompilationOutput(kMinimalDebugInfoShader,
                        shaderc_glsl_vertex_shader, cloned_options.get());
  // The binary output should contain the name of the vector (debug_info_sample)
  // null-terminated, as well as the whole original source.
  std::string vector_name("debug_info_sample");
  vector_name.resize(vector_name.size() + 1);
  EXPECT_THAT(binary_output, HasSubstr(vector_name));
  EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
}

TEST_F(CompileStringWithOptionsTest, GenerateDebugInfoDisassembly) {
  shaderc_compile_options_set_generate_debug_info(options_.get());
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  // Generate assembly text we can compare its output as a string.
  // The disassembly output should contain the name of the vector:
  // debug_info_sample.
  EXPECT_THAT(
      CompilationOutput(kMinimalDebugInfoShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText),
      HasSubstr("debug_info_sample"));
}

TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeWithLevelZero) {
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_zero);
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
    EXPECT_THAT(disassembly_text, HasSubstr(substring));
  }
  // Check that we still have debug instructions.
  EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
}

TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeWithLevelPerformance) {
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_performance);
  const std::string disassembly_text =
      CompilationOutput(kGlslMultipleFnShader, shaderc_glsl_fragment_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  // Check that we do not have function calls anymore.
  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpFunctionCall")));
}

TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeWithLevelSize) {
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_size);
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
    EXPECT_THAT(disassembly_text, HasSubstr(substring));
  }
  // Check that we do not have debug instructions.
  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpName")));
  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpSource")));
}

TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeForVulkan10Failure) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_performance);

  EXPECT_FALSE(CompilesToValidSpv(compiler_, kHlslWaveActiveSumeComputeShader,
                                  shaderc_compute_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest, CompileAndOptimizeForVulkan11Success) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_performance);

  const std::string disassembly_text = CompilationOutput(
      kHlslWaveActiveSumeComputeShader, shaderc_compute_shader, options_.get(),
      OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpGroupNonUniformIAdd"));
}

TEST_F(CompileStringWithOptionsTest, FollowingOptLevelOverridesPreviousOne) {
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_size);
  // Optimization level settings overridden by
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_zero);
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
    EXPECT_THAT(disassembly_text, HasSubstr(substring));
  }
  // Check that we still have debug instructions.
  EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
}

TEST_F(CompileStringWithOptionsTest,
       GenerateDebugInfoOverridesOptimizationLevel) {
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_size);
  // Optimization level settings overridden by
  shaderc_compile_options_set_generate_debug_info(options_.get());
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
    EXPECT_THAT(disassembly_text, HasSubstr(substring));
  }
  // Check that we still have debug instructions.
  EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
}

TEST_F(CompileStringWithOptionsTest,
       GenerateDebugInfoProhibitsOptimizationLevel) {
  // Setting generate debug info first also works.
  shaderc_compile_options_set_generate_debug_info(options_.get());
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_size);
  const std::string disassembly_text =
      CompilationOutput(kMinimalShader, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
    EXPECT_THAT(disassembly_text, HasSubstr(substring));
  }
  // Check that we still have debug instructions.
  EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
}

TEST_F(CompileStringWithOptionsTest, PreprocessingOnlyOption) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kMinimalShaderWithMacro =
      "#version 150\n"
      "#define E main\n"
      "void E(){}\n";
  const std::string preprocessed_text =
      CompilationOutput(kMinimalShaderWithMacro, shaderc_glsl_vertex_shader,
                        options_.get(), OutputType::PreprocessedText);
  EXPECT_THAT(preprocessed_text, HasSubstr("void main() { }"));

  const std::string kMinimalShaderWithMacroCloneOption =
      "#version 150\n"
      "#define E_CLONE_OPTION main\n"
      "void E_CLONE_OPTION(){}\n";
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  const std::string preprocessed_text_cloned_options = CompilationOutput(
      kMinimalShaderWithMacroCloneOption, shaderc_glsl_vertex_shader,
      options_.get(), OutputType::PreprocessedText);
  EXPECT_THAT(preprocessed_text_cloned_options, HasSubstr("void main() { }"));
}

// A shader kind test cases needs: 1) A shader text with or without #pragma
// annotation, 2) shader_kind.
struct ShaderKindTestCase {
  const char* shader_;
  shaderc_shader_kind shader_kind_;
};

// Test the shader kind deduction process. If the shader kind is one of the
// forced ones, the compiler will just try to compile the source code in that
// specified shader kind. If the shader kind is shaderc_glsl_deduce_from_pragma,
// the compiler will determine the shader kind from #pragma annotation in the
// source code and emit error if none such annotation is found. When the shader
// kind is one of the default ones, the compiler will fall back to use the
// specified shader kind if and only if #pragma annoation is not found.

// Valid shader kind settings should generate valid SPIR-V code.
using ValidShaderKind = testing::TestWithParam<ShaderKindTestCase>;

TEST_P(ValidShaderKind, ValidSpvCode) {
  const ShaderKindTestCase& test_case = GetParam();
  Compiler compiler;
  EXPECT_TRUE(
      CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
}

INSTANTIATE_TEST_SUITE_P(
    CompileStringTest, ValidShaderKind,
    testing::ValuesIn(std::vector<ShaderKindTestCase>{
        // Valid default shader kinds.
        {kEmpty310ESShader, shaderc_glsl_default_vertex_shader},
        {kEmpty310ESShader, shaderc_glsl_default_fragment_shader},
        {kEmpty310ESShader, shaderc_glsl_default_compute_shader},
        {kGeometryOnlyShader, shaderc_glsl_default_geometry_shader},
        {kTessControlOnlyShader, shaderc_glsl_default_tess_control_shader},
        {kTessEvaluationOnlyShader,
         shaderc_glsl_default_tess_evaluation_shader},
        {kNVMeshShader, shaderc_glsl_default_mesh_shader},
        {kNVTaskShader, shaderc_glsl_default_task_shader},

        // #pragma annotation overrides default shader kinds.
        {kVertexOnlyShaderWithPragma, shaderc_glsl_default_compute_shader},
        {kFragmentOnlyShaderWithPragma, shaderc_glsl_default_vertex_shader},
        {kTessControlOnlyShaderWithPragma,
         shaderc_glsl_default_fragment_shader},
        {kTessEvaluationOnlyShaderWithPragma,
         shaderc_glsl_default_tess_control_shader},
        {kGeometryOnlyShaderWithPragma,
         shaderc_glsl_default_tess_evaluation_shader},
        {kComputeOnlyShaderWithPragma, shaderc_glsl_default_geometry_shader},
        {kNVMeshShaderWithPragma, shaderc_glsl_default_geometry_shader},
        {kNVTaskShaderWithPragma, shaderc_glsl_default_geometry_shader},

        // Infer from source
        {kVertexOnlyShaderWithPragma, shaderc_glsl_infer_from_source},
        {kNVMeshShaderWithPragma, shaderc_glsl_infer_from_source},
        {kNVTaskShaderWithPragma, shaderc_glsl_infer_from_source},

        // Specified non-default shader kind overrides #pragma annotation.
        {kVertexOnlyShaderWithInvalidPragma, shaderc_glsl_vertex_shader},
    }));

using InvalidShaderKind = testing::TestWithParam<ShaderKindTestCase>;

// Invalid shader kind settings should generate errors.
TEST_P(InvalidShaderKind, CompilationShouldFail) {
  const ShaderKindTestCase& test_case = GetParam();
  Compiler compiler;
  EXPECT_FALSE(
      CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
}

INSTANTIATE_TEST_SUITE_P(
    CompileStringTest, InvalidShaderKind,
    testing::ValuesIn(std::vector<ShaderKindTestCase>{
        // Invalid default shader kind.
        {kVertexOnlyShader, shaderc_glsl_default_fragment_shader},
        // Sets to deduce shader kind from #pragma, but #pragma is defined in
        // the source code.
        {kVertexOnlyShader, shaderc_glsl_infer_from_source},
        // Invalid #pragma cause errors, even though default shader kind is set
        // to valid shader kind.
        {kVertexOnlyShaderWithInvalidPragma,
         shaderc_glsl_default_vertex_shader},
    }));

// To test file inclusion, use an unordered_map as a fake file system to store
// fake files to be included. The unordered_map represents a filesystem by
// mapping filename (or path) string to the contents of that file as a string.
using FakeFS = std::unordered_map<std::string, std::string>;

// An includer test case needs: 1) A fake file system which is actually an
// unordered_map, so that we can resolve the content given a string. A valid
// fake file system must have one entry with key:'root' to specify the start
// shader file for compilation. 2) An string that we expect to see in the
// compilation output.
class IncluderTestCase {
 public:
  IncluderTestCase(FakeFS fake_fs, std::string expected_substring)
      : fake_fs_(fake_fs), expected_substring_(expected_substring) {
    assert(fake_fs_.find("root") != fake_fs_.end() &&
           "Valid fake file system needs a 'root' file\n");
  }

  const FakeFS& fake_fs() const { return fake_fs_; }
  const std::string& expected_substring() const { return expected_substring_; }

 private:
  FakeFS fake_fs_;
  std::string expected_substring_;
};

// A mock class that simulate an includer. C API needs two function pointers
// each for get including data and release the data. This class defined two
// static functions, which wrap their matching member functions, to be passed to
// libshaderc C API.
class TestIncluder {
 public:
  explicit TestIncluder(const FakeFS& fake_fs)
      : fake_fs_(fake_fs), responses_({}) {}

  // Get path and content from the fake file system.
  shaderc_include_result* GetInclude(const char* filename) {
    responses_.emplace_back(shaderc_include_result{
        filename, strlen(filename), fake_fs_.at(std::string(filename)).c_str(),
        fake_fs_.at(std::string(filename)).size()});
    return &responses_.back();
  }

  // Response data is owned as private property, no need to release explicitly.
  void ReleaseInclude(shaderc_include_result*) {}

  // Wrapper for the corresponding member function.
  static shaderc_include_result* GetIncluderResponseWrapper(
      void* user_data, const char* filename, int, const char* includer,
      size_t include_depth) {
    return static_cast<TestIncluder*>(user_data)->GetInclude(filename);
  }

  // Wrapper for the corresponding member function.
  static void ReleaseIncluderResponseWrapper(void* user_data,
                                             shaderc_include_result* data) {
    return static_cast<TestIncluder*>(user_data)->ReleaseInclude(data);
  }

 private:
  // Includer response data is stored as private property.
  const FakeFS& fake_fs_;
  std::vector<shaderc_include_result> responses_;
};

using IncluderTests = testing::TestWithParam<IncluderTestCase>;

// Parameterized tests for includer.
TEST_P(IncluderTests, SetIncluderCallbacks) {
  const IncluderTestCase& test_case = GetParam();
  const FakeFS& fs = test_case.fake_fs();
  const std::string& shader = fs.at("root");
  TestIncluder includer(fs);
  Compiler compiler;
  compile_options_ptr options(shaderc_compile_options_initialize());
  shaderc_compile_options_set_include_callbacks(
      options.get(), TestIncluder::GetIncluderResponseWrapper,
      TestIncluder::ReleaseIncluderResponseWrapper, &includer);

  const Compilation comp(compiler.get_compiler_handle(), shader,
                         shaderc_glsl_vertex_shader, "shader", "main",
                         options.get(), OutputType::PreprocessedText);
  // Checks the existence of the expected string.
  EXPECT_THAT(shaderc_result_get_bytes(comp.result()),
              HasSubstr(test_case.expected_substring()));
}

TEST_P(IncluderTests, SetIncluderCallbacksClonedOptions) {
  const IncluderTestCase& test_case = GetParam();
  const FakeFS& fs = test_case.fake_fs();
  const std::string& shader = fs.at("root");
  TestIncluder includer(fs);
  Compiler compiler;
  compile_options_ptr options(shaderc_compile_options_initialize());
  shaderc_compile_options_set_include_callbacks(
      options.get(), TestIncluder::GetIncluderResponseWrapper,
      TestIncluder::ReleaseIncluderResponseWrapper, &includer);

  // Cloned options should have all the settings.
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options.get()));

  const Compilation comp(compiler.get_compiler_handle(), shader,
                         shaderc_glsl_vertex_shader, "shader", "main",
                         cloned_options.get(), OutputType::PreprocessedText);
  // Checks the existence of the expected string.
  EXPECT_THAT(shaderc_result_get_bytes(comp.result()),
              HasSubstr(test_case.expected_substring()));
}

INSTANTIATE_TEST_SUITE_P(CompileStringTest, IncluderTests,
                        testing::ValuesIn(std::vector<IncluderTestCase>{
                            IncluderTestCase(
                                // Fake file system.
                                {
                                    {"root",
                                     "#version 150\n"
                                     "void foo() {}\n"
                                     "#include \"path/to/file_1\"\n"},
                                    {"path/to/file_1", "content of file_1\n"},
                                },
                                // Expected output.
                                "#line 0 \"path/to/file_1\"\n"
                                " content of file_1\n"
                                "#line 3"),
                            IncluderTestCase(
                                // Fake file system.
                                {{"root",
                                  "#version 150\n"
                                  "void foo() {}\n"
                                  "#include \"path/to/file_1\"\n"},
                                 {"path/to/file_1",
                                  "#include \"path/to/file_2\"\n"
                                  "content of file_1\n"},
                                 {"path/to/file_2", "content of file_2\n"}},
                                // Expected output.
                                "#line 0 \"path/to/file_1\"\n"
                                "#line 0 \"path/to/file_2\"\n"
                                " content of file_2\n"
                                "#line 1 \"path/to/file_1\"\n"
                                " content of file_1\n"
                                "#line 3"),

                        }));

TEST_F(CompileStringWithOptionsTest, WarningsOnLine) {
  // Some versions of Glslang will return an error, some will return just
  // warnings.
  EXPECT_THAT(
      CompilationMessages(kDeprecatedAttributeShader,
                          shaderc_glsl_vertex_shader, options_.get()),
      HasSubstr(":2: warning: attribute deprecated in version 130; may be "
                "removed in future release\n"));
}

TEST_F(CompileStringWithOptionsTest, WarningsOnLineAsErrors) {
  shaderc_compile_options_set_warnings_as_errors(options_.get());
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_THAT(
      CompilationErrors(kDeprecatedAttributeShader, shaderc_glsl_vertex_shader,
                        options_.get()),
      HasSubstr(":2: error: attribute deprecated in version 130; may be "
                "removed in future release\n"));
}

TEST_F(CompileStringWithOptionsTest, SuppressWarningsOnLine) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_set_suppress_warnings(options_.get());
  EXPECT_THAT(
      CompilationMessages(kDeprecatedAttributeShader,
                          shaderc_glsl_vertex_shader, options_.get()),
      Not(HasSubstr(":2: warning: attribute deprecated in version 130; may be "
                    "removed in future release\n")));
}

TEST_F(CompileStringWithOptionsTest, GlobalWarnings) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_set_forced_version_profile(options_.get(), 400,
                                                     shaderc_profile_core);
  EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
                                  shaderc_glsl_vertex_shader, options_.get()),
              HasSubstr("(version, profile) forced to be (400, core),"
                        " while in source code it is (550, none)\n"));
}

TEST_F(CompileStringWithOptionsTest, GlobalWarningsAsErrors) {
  shaderc_compile_options_set_warnings_as_errors(options_.get());
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_set_forced_version_profile(options_.get(), 400,
                                                     shaderc_profile_core);
  EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
                                shaderc_glsl_vertex_shader, options_.get()),
              HasSubstr("(version, profile) forced to be (400, core),"
                        " while in source code it is (550, none)\n"));
}

TEST_F(CompileStringWithOptionsTest, SuppressGlobalWarnings) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_set_suppress_warnings(options_.get());
  shaderc_compile_options_set_forced_version_profile(options_.get(), 400,
                                                     shaderc_profile_core);
  EXPECT_EQ("",
            CompilationWarnings(kMinimalUnknownVersionShader,
                                shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       SuppressWarningsModeFirstOverridesWarningsAsErrorsMode) {
  // Sets suppress-warnings mode first, then sets warnings-as-errors mode.
  // suppress-warnings mode should override warnings-as-errors mode.
  shaderc_compile_options_set_suppress_warnings(options_.get());
  shaderc_compile_options_set_warnings_as_errors(options_.get());
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());

  // Warnings on particular lines should be inhibited.
  Compilation comp_line(compiler_.get_compiler_handle(),
                        kDeprecatedAttributeShader, shaderc_glsl_vertex_shader,
                        "shader", "main", options_.get());
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_line.result()));

  // Global warnings should be inhibited.
  Compilation comp_global(
      compiler_.get_compiler_handle(), kMinimalUnknownVersionShader,
      shaderc_glsl_vertex_shader, "shader", "main", options_.get());
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_global.result()));
}

TEST_F(CompileStringWithOptionsTest,
       SuppressWarningsModeSecondOverridesWarningsAsErrorsMode) {
  // Sets suppress-warnings mode first, then sets warnings-as-errors mode.
  // suppress-warnings mode should override warnings-as-errors mode.
  shaderc_compile_options_set_warnings_as_errors(options_.get());
  shaderc_compile_options_set_suppress_warnings(options_.get());
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());

  // Warnings on particular lines should be inhibited.
  Compilation comp_line(compiler_.get_compiler_handle(),
                        kDeprecatedAttributeShader, shaderc_glsl_vertex_shader,
                        "shader", "main", options_.get());
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_line.result()));

  // Global warnings should be inhibited.
  Compilation comp_global(
      compiler_.get_compiler_handle(), kMinimalUnknownVersionShader,
      shaderc_glsl_vertex_shader, "shader", "main", options_.get());
  EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_global.result()));
}

TEST_F(CompileStringWithOptionsTest, IfDefCompileOption) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  shaderc_compile_options_add_macro_definition(options_.get(), "E", 1u, nullptr,
                                               0u);
  const std::string kMinimalExpandedShader =
      "#version 140\n"
      "#ifdef E\n"
      "void main(){}\n"
      "#else\n"
      "#error\n"
      "#endif";
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalExpandedShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(
    CompileStringWithOptionsTest,
    TargetEnvRespectedWhenCompilingOpenGLCompatibilityShaderToBinaryAndAlwaysFails) {
  // Glslang does not support generating SPIR-V for compatibility profile
  // shaders.

  EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_opengl_compat, 0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_opengl, 0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan, 0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLCompatibilityFragmentShader,
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));
}

TEST_F(CompileStringWithOptionsTest, CompilingFailsWhenTargetingOpenGLCompat) {
  // Confirm that kOpenGLVertexShader fails when targeting OpenGL
  // compatibility profile.

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_opengl_compat, 0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kOpenGLVertexShader,
                                  shaderc_glsl_vertex_shader, options_.get()));
  const std::string errors = CompilationErrors(
      kOpenGLVertexShader, shaderc_glsl_vertex_shader, options_.get());
  EXPECT_EQ(errors, "error: OpenGL compatibility profile is not supported");
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingOpenGLCoreShaderToBinary) {
  // Confirm that kOpenGLVertexShader compiles when targeting OpenGL core
  // profile.

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_opengl, 0);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kOpenGLVertexShader,
                                 shaderc_glsl_vertex_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_0ShaderToVulkan1_0Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderComputeBarrier,
                                 shaderc_glsl_compute_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_0ShaderToVulkan1_1Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderComputeBarrier,
                                 shaderc_glsl_compute_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_1ShaderToVulkan1_0Fails) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kGlslShaderComputeSubgroupBarrier,
                                  shaderc_glsl_compute_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_1ShaderToVulkan1_1Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderComputeSubgroupBarrier,
                                 shaderc_glsl_compute_shader, options_.get()));
}

// task shader
TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_0TaskShaderToVulkan1_0Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderTaskBarrier,
                                 shaderc_glsl_task_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_0TaskShaderToVulkan1_1Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderTaskBarrier,
                                 shaderc_glsl_task_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_1TaskShaderToVulkan1_0Fails) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kGlslShaderTaskSubgroupBarrier,
                                  shaderc_glsl_task_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_1TaskShaderToVulkan1_1Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderTaskSubgroupBarrier,
                                 shaderc_glsl_task_shader, options_.get()));
}

// mesh shader
TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_0MeshShaderToVulkan1_0Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderMeshBarrier,
                                 shaderc_glsl_mesh_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_0MeshShaderToVulkan1_1Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderMeshBarrier,
                                 shaderc_glsl_mesh_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_1MeshShaderToVulkan1_0Fails) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_0);
  EXPECT_FALSE(CompilesToValidSpv(compiler_, kGlslShaderMeshSubgroupBarrier,
                                  shaderc_glsl_mesh_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       TargetEnvRespectedWhenCompilingVulkan1_1MeshShaderToVulkan1_1Succeeds) {
  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan,
                                         shaderc_env_version_vulkan_1_1);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kGlslShaderMeshSubgroupBarrier,
                                 shaderc_glsl_mesh_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest,
       DISABLED_TargetEnvIgnoredWhenPreprocessing) {
  // This test is disabled since some versions of glslang may refuse to compile
  // very old shaders to SPIR-V with OpenGL target. Re-enable and rewrite this
  // test once we have a differential set of environments to test.
  const auto output_type = OutputType::PreprocessedText;

  EXPECT_TRUE(CompilationSuccess(kOpenGLCompatibilityFragmentShader,
                                 shaderc_glsl_fragment_shader, options_.get(),
                                 output_type));

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_opengl_compat, 0);
  EXPECT_TRUE(CompilationSuccess(kOpenGLCompatibilityFragmentShader,
                                 shaderc_glsl_fragment_shader, options_.get(),
                                 output_type));

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_opengl, 0);
  EXPECT_TRUE(CompilationSuccess(kOpenGLCompatibilityFragmentShader,
                                 shaderc_glsl_fragment_shader, options_.get(),
                                 output_type));

  shaderc_compile_options_set_target_env(options_.get(),
                                         shaderc_target_env_vulkan, 0);
  EXPECT_TRUE(CompilationSuccess(kOpenGLCompatibilityFragmentShader,
                                 shaderc_glsl_fragment_shader, options_.get(),
                                 output_type));
}

TEST_F(CompileStringTest, ShaderKindRespected) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kVertexShader =
      "#version 140\nvoid main(){ gl_Position = vec4(0);}";
  EXPECT_TRUE(CompilationSuccess(kVertexShader, shaderc_glsl_vertex_shader));
  EXPECT_FALSE(CompilationSuccess(kVertexShader, shaderc_glsl_fragment_shader));
}

TEST_F(CompileStringTest, ErrorsReported) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  EXPECT_THAT(CompilationErrors("int f(){return wrongname;}",
                                shaderc_glsl_vertex_shader),
              HasSubstr("wrongname"));
}

#ifndef SHADERC_DISABLE_THREADED_TESTS
TEST_F(CompileStringTest, MultipleThreadsCalling) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  bool results[10];
  std::vector<std::thread> threads;
  for (auto& r : results) {
    threads.emplace_back([&r, this]() {
      r = CompilationSuccess("#version 140\nvoid main(){}",
                             shaderc_glsl_vertex_shader);
    });
  }
  for (auto& t : threads) {
    t.join();
  }
  EXPECT_THAT(results, Each(true));
}
#endif

TEST_F(CompileKindsTest, Vertex) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kVertexShader =
      "#version 140\nvoid main(){ gl_Position = vec4(0);}";
  EXPECT_TRUE(CompilationSuccess(kVertexShader, shaderc_glsl_vertex_shader));
}

TEST_F(CompileKindsTest, Fragment) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kFragShader =
      "#version 140\nvoid main(){ gl_FragColor = vec4(0);}";
  EXPECT_TRUE(CompilationSuccess(kFragShader, shaderc_glsl_fragment_shader));
}

TEST_F(CompileKindsTest, Compute) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kCompShader =
      R"(#version 310 es
       void main() {}
  )";
  EXPECT_TRUE(CompilationSuccess(kCompShader, shaderc_glsl_compute_shader));
}

TEST_F(CompileKindsTest, Geometry) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kGeoShader =

      R"(#version 310 es
       #extension GL_OES_geometry_shader : enable
       layout(points) in;
       layout(points, max_vertices=1) out;
       void main() {
         gl_Position = vec4(1.0);
         EmitVertex();
         EndPrimitive();
       }
  )";
  EXPECT_TRUE(CompilationSuccess(kGeoShader, shaderc_glsl_geometry_shader));
}

TEST_F(CompileKindsTest, TessControl) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kTessControlShader =
      R"(#version 310 es
       #extension GL_OES_tessellation_shader : enable
       layout(vertices=1) out;
       void main() {}
  )";
  EXPECT_TRUE(
      CompilationSuccess(kTessControlShader, shaderc_glsl_tess_control_shader));
}

TEST_F(CompileKindsTest, TessEvaluation) {
  ASSERT_NE(nullptr, compiler_.get_compiler_handle());
  const std::string kTessEvaluationShader =
      R"(#version 310 es
       #extension GL_OES_tessellation_shader : enable
       layout(triangles, equal_spacing, ccw) in;
       void main() {
         gl_Position = vec4(gl_TessCoord, 1.0);
       }
  )";
  EXPECT_TRUE(CompilationSuccess(kTessEvaluationShader,
                                 shaderc_glsl_tess_evaluation_shader));
}

// A test case for ParseVersionProfileTest needs: 1) the input string, 2)
// expected parsing results, including 'succeed' flag, version value, and
// profile enum.
struct ParseVersionProfileTestCase {
  ParseVersionProfileTestCase(
      const std::string& input_string, bool expected_succeed,
      int expected_version = 0,
      shaderc_profile expected_profile = shaderc_profile_none)
      : input_string_(input_string),
        expected_succeed_(expected_succeed),
        expected_version_(expected_version),
        expected_profile_(expected_profile) {}
  std::string input_string_;
  bool expected_succeed_;
  int expected_version_;
  shaderc_profile expected_profile_;
};

// Test for a helper function to parse version and profile from string.
using ParseVersionProfileTest =
    testing::TestWithParam<ParseVersionProfileTestCase>;

TEST_P(ParseVersionProfileTest, FromNullTerminatedString) {
  const ParseVersionProfileTestCase& test_case = GetParam();
  int version;
  shaderc_profile profile;
  bool succeed = shaderc_parse_version_profile(test_case.input_string_.c_str(),
                                               &version, &profile);
  EXPECT_EQ(test_case.expected_succeed_, succeed);
  // check the return version and profile only when the parsing succeeds.
  if (succeed) {
    EXPECT_EQ(test_case.expected_version_, version);
    EXPECT_EQ(test_case.expected_profile_, profile);
  }
}

INSTANTIATE_TEST_SUITE_P(
    HelperMethods, ParseVersionProfileTest,
    testing::ValuesIn(std::vector<ParseVersionProfileTestCase>{
        // Valid version profiles
        ParseVersionProfileTestCase("450core", true, 450, shaderc_profile_core),
        ParseVersionProfileTestCase("450compatibility", true, 450,
                                    shaderc_profile_compatibility),
        ParseVersionProfileTestCase("310es", true, 310, shaderc_profile_es),
        ParseVersionProfileTestCase("100", true, 100, shaderc_profile_none),

        // Invalid version profiles, the expected_version and expected_profile
        // doesn't matter as they won't be checked if the tests pass correctly.
        ParseVersionProfileTestCase("totally_wrong", false),
        ParseVersionProfileTestCase("111core", false),
        ParseVersionProfileTestCase("450wrongprofile", false),
        ParseVersionProfileTestCase("", false),
    }));

TEST_F(CompileStringTest, NullSourceNameFailsCompilingToBinary) {
  EXPECT_THAT(CompilationErrors(kEmpty310ESShader, shaderc_glsl_vertex_shader,
                                nullptr, OutputType::SpirvBinary, nullptr),
              HasSubstr("Input file name string was null."));
}

TEST_F(CompileStringTest, NullSourceNameFailsCompilingToAssemblyText) {
  EXPECT_THAT(
      CompilationErrors(kEmpty310ESShader, shaderc_glsl_vertex_shader, nullptr,
                        OutputType::SpirvAssemblyText, nullptr),
      HasSubstr("Input file name string was null."));
}

TEST_F(CompileStringTest, NullSourceNameFailsCompilingToPreprocessedText) {
  EXPECT_THAT(CompilationErrors(kEmpty310ESShader, shaderc_glsl_vertex_shader,
                                nullptr, OutputType::PreprocessedText, nullptr),
              HasSubstr("Input file name string was null."));
}

const char kGlslVertexShader[] =
    "#version 140\nvoid main(){ gl_Position = vec4(0);}";

const char kHlslVertexShader[] =
    "float4 EntryPoint(uint index : SV_VERTEXID) : SV_POSITION\n"
    "{ return float4(1.0, 2.0, 3.0, 4.0); }";

TEST_F(CompileStringTest, LangGlslOnGlslVertexSucceeds) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_glsl);
  EXPECT_TRUE(CompilationSuccess(kGlslVertexShader, shaderc_glsl_vertex_shader,
                                 options_.get()));
}

TEST_F(CompileStringTest, LangGlslOnHlslVertexFails) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_glsl);
  EXPECT_FALSE(CompilationSuccess(kHlslVertexShader, shaderc_glsl_vertex_shader,
                                  options_.get()));
}

TEST_F(CompileStringTest, LangHlslOnGlslVertexFails) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  EXPECT_FALSE(CompilationSuccess(kGlslVertexShader, shaderc_glsl_vertex_shader,
                                  options_.get()));
}

TEST_F(CompileStringTest, LangHlslOnHlslVertexSucceeds) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  EXPECT_TRUE(CompilationSuccess(kHlslVertexShader, shaderc_glsl_vertex_shader,
                                 options_.get()));
}

TEST(EntryPointTest,
     LangGlslOnHlslVertexSucceedsButAssumesEntryPointNameIsMain) {
  Compiler compiler;
  Options options;
  auto compilation =
      Compilation(compiler.get_compiler_handle(), kGlslVertexShader,
                  shaderc_glsl_vertex_shader, "shader", "blah blah blah",
                  options.get(), OutputType::SpirvAssemblyText);

  EXPECT_THAT(shaderc_result_get_bytes(compilation.result()),
              HasSubstr("OpEntryPoint Vertex %main \"main\""))
      << std::string(shaderc_result_get_bytes(compilation.result()));
}

TEST(EntryPointTest, LangHlslOnHlslVertexSucceedsWithGivenEntryPointName) {
  Compiler compiler;
  Options options;
  shaderc_compile_options_set_source_language(options.get(),
                                              shaderc_source_language_hlsl);
  auto compilation =
      Compilation(compiler.get_compiler_handle(), kHlslVertexShader,
                  shaderc_glsl_vertex_shader, "shader", "EntryPoint",
                  options.get(), OutputType::SpirvAssemblyText);

  EXPECT_THAT(shaderc_result_get_bytes(compilation.result()),
              HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\""))
      << std::string(shaderc_result_get_bytes(compilation.result()));
}

// Returns a fragment shader accessing a texture with the given
// offset.
std::string ShaderWithTexOffset(int offset) {
  std::ostringstream oss;
  oss << "#version 450\n"
         "layout (binding=0) uniform sampler1D tex;\n"
         "void main() { vec4 x = textureOffset(tex, 1.0, "
      << offset << "); }\n";
  return oss.str();
}

// Ensure compilation is sensitive to limit setting.  Sample just
// two particular limits.
TEST_F(CompileStringTest, LimitsTexelOffsetDefault) {
  EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-9).c_str(),
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));
  EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-8).c_str(),
                                 shaderc_glsl_fragment_shader, options_.get()));
  EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(7).c_str(),
                                 shaderc_glsl_fragment_shader, options_.get()));
  EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(8).c_str(),
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));
}

TEST_F(CompileStringTest, LimitsTexelOffsetLowerMinimum) {
  shaderc_compile_options_set_limit(
      options_.get(), shaderc_limit_min_program_texel_offset, -99);
  EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-100).c_str(),
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));
  EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-99).c_str(),
                                 shaderc_glsl_fragment_shader, options_.get()));
}

TEST_F(CompileStringTest, LimitsTexelOffsetHigherMaximum) {
  shaderc_compile_options_set_limit(options_.get(),
                                    shaderc_limit_max_program_texel_offset, 10);
  EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(10).c_str(),
                                 shaderc_glsl_fragment_shader, options_.get()));
  EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(11).c_str(),
                                  shaderc_glsl_fragment_shader,
                                  options_.get()));
}

TEST_F(CompileStringWithOptionsTest, UniformsWithoutBindingsFailCompilation) {
  const std::string errors =
      CompilationErrors(kShaderWithUniformsWithoutBindings,
                        shaderc_glsl_vertex_shader, options_.get());
  EXPECT_THAT(errors,
              HasSubstr("sampler/texture/image requires layout(binding=X)"));
}

TEST_F(CompileStringWithOptionsTest,
       UniformsWithoutBindingsOptionSetAutoBindingsAssignsBindings) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
}

TEST_F(CompileStringWithOptionsTest, AutoBindUniformsOptionsSurvivesCloning) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      cloned_options.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
}

TEST_F(CompileStringWithOptionsTest,
       SetBindingBaseForTextureAdjustsTextureBindingsOnly) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_texture, 44);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 44"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
}

TEST_F(CompileStringWithOptionsTest,
       SetBindingBaseForSamplerAdjustsSamplerBindingsOnly) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_sampler, 44);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 44"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
}

TEST_F(CompileStringWithOptionsTest,
       SetBindingBaseForImageAdjustsImageBindingsOnly) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_image, 44);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 44"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 45"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 2"));
}

TEST_F(CompileStringWithOptionsTest,
       SetBindingBaseForBufferAdjustsBufferBindingsOnly) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_buffer, 44);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 44"));
}

TEST_F(CompileStringWithOptionsTest, SetBindingBaseSurvivesCloning) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_texture, 40);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_sampler, 50);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_image, 60);
  shaderc_compile_options_set_binding_base(options_.get(),
                                           shaderc_uniform_kind_buffer, 70);
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader,
      cloned_options.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 40"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 50"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 60"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 61"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 70"));
}

TEST(Compiler, IncludeWithoutOptionsReturnsValidError) {
  auto compiler = shaderc_compiler_initialize();
  const char source[] = "#version 450\n#include \"no where\"";
  auto result = shaderc_compile_into_spv(compiler, source, strlen(source),
                                         shaderc_glsl_vertex_shader, "file",
                                         "main", nullptr);
  EXPECT_EQ(shaderc_compilation_status_compilation_error,
            shaderc_result_get_compilation_status(result));
  EXPECT_THAT(shaderc_result_get_error_message(result),
              HasSubstr("error: '#include' : #error unexpected include "
                        "directive for header name: no where"));

  shaderc_result_release(result);
  shaderc_compiler_release(compiler);
}

TEST_F(
    CompileStringWithOptionsTest,
    SetBindingBaseForTextureForVertexAdjustsTextureBindingsOnlyCompilingAsVertex) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  shaderc_compile_options_set_binding_base_for_stage(
      options_.get(), shaderc_vertex_shader, shaderc_uniform_kind_texture, 100);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_vertex_shader, options_.get(),
      OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 100"))
      << disassembly_text;
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
}

TEST_F(CompileStringWithOptionsTest,
       SetBindingBaseForTextureForVertexIgnoredWhenCompilingAsFragment) {
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  // This is ignored since we're compiling as a different stage.
  shaderc_compile_options_set_binding_base_for_stage(
      options_.get(), shaderc_vertex_shader, shaderc_uniform_kind_texture, 100);
  const std::string disassembly_text = CompilationOutput(
      kShaderWithUniformsWithoutBindings, shaderc_fragment_shader,
      options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
}

TEST_F(CompileStringWithOptionsTest, GlslDefaultPackingUsed) {
  const std::string disassembly_text =
      CompilationOutput(kGlslShaderWeirdPacking, shaderc_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
}

TEST_F(CompileStringWithOptionsTest, HlslOffsetsOptionDisableRespected) {
  shaderc_compile_options_set_hlsl_offsets(options_.get(), false);
  const std::string disassembly_text =
      CompilationOutput(kGlslShaderWeirdPacking, shaderc_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
}

TEST_F(CompileStringWithOptionsTest, HlslOffsetsOptionEnableRespected) {
  shaderc_compile_options_set_hlsl_offsets(options_.get(), true);
  const std::string disassembly_text =
      CompilationOutput(kGlslShaderWeirdPacking, shaderc_vertex_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 4"));
}

TEST_F(CompileStringWithOptionsTest, HlslFunctionality1OffByDefault) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  // The counter should automatically get a binding.
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  const std::string disassembly_text =
      CompilationOutput(kHlslShaderWithCounterBuffer, shaderc_fragment_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, Not(HasSubstr("OpDecorateString")))
      << disassembly_text;
}

TEST_F(CompileStringWithOptionsTest, HlslFunctionality1Respected) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  shaderc_compile_options_set_hlsl_functionality1(options_.get(), true);
  // The counter should automatically get a binding.
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  const std::string disassembly_text =
      CompilationOutput(kHlslShaderWithCounterBuffer, shaderc_fragment_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
}

TEST_F(CompileStringWithOptionsTest, HlslFunctionality1SurvivesCloning) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  shaderc_compile_options_set_hlsl_functionality1(options_.get(), true);
  // The counter should automatically get a binding.
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  const std::string disassembly_text =
      CompilationOutput(kHlslShaderWithCounterBuffer, shaderc_fragment_shader,
                        cloned_options.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
}

TEST_F(CompileStringWithOptionsTest, HlslFlexibleMemoryLayoutAllowed) {
  shaderc_compile_options_set_source_language(options_.get(),
                                              shaderc_source_language_hlsl);
  shaderc_compile_options_set_optimization_level(
      options_.get(), shaderc_optimization_level_performance);
  // There is no way to set the counter's binding, so set it automatically.
  // See https://github.com/KhronosGroup/glslang/issues/1616
  shaderc_compile_options_set_auto_bind_uniforms(options_.get(), true);
  EXPECT_TRUE(CompilesToValidSpv(compiler_, kHlslMemLayoutResourceSelect,
                                 shaderc_fragment_shader, options_.get()));
}

TEST_F(CompileStringWithOptionsTest, ClampMapsToFClampByDefault) {
  const std::string disassembly_text =
      CompilationOutput(kGlslShaderWithClamp, shaderc_fragment_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 FClamp"));
}

TEST_F(CompileStringWithOptionsTest, ClampMapsToNClampWithNanClamp) {
  shaderc_compile_options_set_nan_clamp(options_.get(), true);
  const std::string disassembly_text =
      CompilationOutput(kGlslShaderWithClamp, shaderc_fragment_shader,
                        options_.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
}

TEST_F(CompileStringWithOptionsTest, NanClampSurvivesCloning) {
  shaderc_compile_options_set_nan_clamp(options_.get(), true);
  compile_options_ptr cloned_options(
      shaderc_compile_options_clone(options_.get()));
  const std::string disassembly_text =
      CompilationOutput(kGlslShaderWithClamp, shaderc_fragment_shader,
                        cloned_options.get(), OutputType::SpirvAssemblyText);
  EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
}

}  // anonymous namespace
