/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmCMakeLanguageCommand.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>

#include "cmsys/RegularExpression.hxx"

#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmDependencyProvider.h"
#include "cmExecutionStatus.h"
#include "cmExperimental.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h" // IWYU pragma: keep
#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"

namespace cm {
enum class TargetType;
}

namespace {

bool FatalError(cmExecutionStatus& status, std::string const& error)
{
  status.SetError(error);
  cmSystemTools::SetFatalErrorOccurred();
  return false;
}

std::array<cm::static_string_view, 14> InvalidCommands{
  { // clang-format off
  "function"_s, "endfunction"_s,
  "macro"_s, "endmacro"_s,
  "if"_s, "elseif"_s, "else"_s, "endif"_s,
  "while"_s, "endwhile"_s,
  "foreach"_s, "endforeach"_s,
  "block"_s, "endblock"_s
  } // clang-format on
};

std::array<cm::static_string_view, 1> InvalidDeferCommands{
  {
    // clang-format off
  "return"_s,
  } // clang-format on
};

struct Defer
{
  std::string Id;
  std::string IdVar;
  cmMakefile* Directory = nullptr;
};

bool cmCMakeLanguageCommandCALL(std::vector<cmListFileArgument> const& args,
                                std::string const& callCommand,
                                size_t startArg, cm::optional<Defer> defer,
                                cmExecutionStatus& status)
{
  // ensure specified command is valid
  // start/end flow control commands are not allowed
  auto cmd = cmSystemTools::LowerCase(callCommand);
  if (std::find(InvalidCommands.cbegin(), InvalidCommands.cend(), cmd) !=
      InvalidCommands.cend()) {
    return FatalError(status,
                      cmStrCat("invalid command specified: "_s, callCommand));
  }
  if (defer &&
      std::find(InvalidDeferCommands.cbegin(), InvalidDeferCommands.cend(),
                cmd) != InvalidDeferCommands.cend()) {
    return FatalError(status,
                      cmStrCat("invalid command specified: "_s, callCommand));
  }

  cmMakefile& makefile = status.GetMakefile();
  cmListFileContext context = makefile.GetBacktrace().Top();

  std::vector<cmListFileArgument> funcArgs;
  funcArgs.reserve(args.size() - startArg);

  // The rest of the arguments are passed to the function call above
  for (size_t i = startArg; i < args.size(); ++i) {
    funcArgs.emplace_back(args[i].Value, args[i].Delim, context.Line);
  }
  cmListFileFunction func{ callCommand, context.Line, context.Line,
                           std::move(funcArgs) };

  if (defer) {
    if (defer->Id.empty()) {
      defer->Id = makefile.NewDeferId();
    }
    if (!defer->IdVar.empty()) {
      makefile.AddDefinition(defer->IdVar, defer->Id);
    }
    cmMakefile* deferMakefile =
      defer->Directory ? defer->Directory : &makefile;
    if (!deferMakefile->DeferCall(defer->Id, context.FilePath, func)) {
      return FatalError(
        status,
        cmStrCat("DEFER CALL may not be scheduled in directory:\n  "_s,
                 deferMakefile->GetCurrentBinaryDirectory(),
                 "\nat this time."_s));
    }
    return true;
  }
  return makefile.ExecuteCommand(func, status);
}

bool cmCMakeLanguageCommandDEFER(Defer const& defer,
                                 std::vector<std::string> const& args,
                                 size_t arg, cmExecutionStatus& status)
{
  cmMakefile* deferMakefile =
    defer.Directory ? defer.Directory : &status.GetMakefile();
  if (args[arg] == "CANCEL_CALL"_s) {
    ++arg; // Consume CANCEL_CALL.
    auto ids = cmMakeRange(args).advance(arg);
    for (std::string const& id : ids) {
      if (id[0] >= 'A' && id[0] <= 'Z') {
        return FatalError(
          status, cmStrCat("DEFER CANCEL_CALL unknown argument:\n  "_s, id));
      }
      if (!deferMakefile->DeferCancelCall(id)) {
        return FatalError(
          status,
          cmStrCat("DEFER CANCEL_CALL may not update directory:\n  "_s,
                   deferMakefile->GetCurrentBinaryDirectory(),
                   "\nat this time."_s));
      }
    }
    return true;
  }
  if (args[arg] == "GET_CALL_IDS"_s) {
    ++arg; // Consume GET_CALL_IDS.
    if (arg == args.size()) {
      return FatalError(status, "DEFER GET_CALL_IDS missing output variable");
    }
    std::string const& var = args[arg++];
    if (arg != args.size()) {
      return FatalError(status, "DEFER GET_CALL_IDS given too many arguments");
    }
    cm::optional<std::string> ids = deferMakefile->DeferGetCallIds();
    if (!ids) {
      return FatalError(
        status,
        cmStrCat("DEFER GET_CALL_IDS may not access directory:\n  "_s,
                 deferMakefile->GetCurrentBinaryDirectory(),
                 "\nat this time."_s));
    }
    status.GetMakefile().AddDefinition(var, *ids);
    return true;
  }
  if (args[arg] == "GET_CALL"_s) {
    ++arg; // Consume GET_CALL.
    if (arg == args.size()) {
      return FatalError(status, "DEFER GET_CALL missing id");
    }
    std::string const& id = args[arg++];
    if (arg == args.size()) {
      return FatalError(status, "DEFER GET_CALL missing output variable");
    }
    std::string const& var = args[arg++];
    if (arg != args.size()) {
      return FatalError(status, "DEFER GET_CALL given too many arguments");
    }
    if (id.empty()) {
      return FatalError(status, "DEFER GET_CALL id may not be empty");
    }
    if (id[0] >= 'A' && id[0] <= 'Z') {
      return FatalError(status,
                        cmStrCat("DEFER GET_CALL unknown argument:\n "_s, id));
    }
    cm::optional<std::string> call = deferMakefile->DeferGetCall(id);
    if (!call) {
      return FatalError(
        status,
        cmStrCat("DEFER GET_CALL may not access directory:\n  "_s,
                 deferMakefile->GetCurrentBinaryDirectory(),
                 "\nat this time."_s));
    }
    status.GetMakefile().AddDefinition(var, *call);
    return true;
  }
  return FatalError(status,
                    cmStrCat("DEFER operation unknown: "_s, args[arg]));
}

bool cmCMakeLanguageCommandEVAL(std::vector<cmListFileArgument> const& args,
                                cmExecutionStatus& status)
{
  cmMakefile& makefile = status.GetMakefile();
  cmListFileContext context = makefile.GetBacktrace().Top();
  std::vector<std::string> expandedArgs;
  makefile.ExpandArguments(args, expandedArgs);

  if (expandedArgs.size() < 2) {
    return FatalError(status, "called with incorrect number of arguments");
  }

  if (expandedArgs[1] != "CODE") {
    auto code_iter =
      std::find(expandedArgs.begin() + 2, expandedArgs.end(), "CODE");
    if (code_iter == expandedArgs.end()) {
      return FatalError(status, "called without CODE argument");
    }
    return FatalError(
      status,
      "called with unsupported arguments between EVAL and CODE arguments");
  }

  std::string const code =
    cmJoin(cmMakeRange(expandedArgs.begin() + 2, expandedArgs.end()), " ");
  return makefile.ReadListFileAsString(
    code, cmStrCat(context.FilePath, ':', context.Line, ":EVAL"));
}

bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
  std::vector<std::string> const& args, cmExecutionStatus& status)
{
  cmState* state = status.GetMakefile().GetState();
  if (!state->InTopLevelIncludes()) {
    return FatalError(
      status,
      "Dependency providers can only be set as part of the first call to "
      "project(). More specifically, cmake_language(SET_DEPENDENCY_PROVIDER) "
      "can only be called while the first project() command processes files "
      "listed in CMAKE_PROJECT_TOP_LEVEL_INCLUDES.");
  }

  struct SetProviderArgs
  {
    std::string Command;
    ArgumentParser::NonEmpty<std::vector<std::string>> Methods;
  };

  auto const ArgsParser =
    cmArgumentParser<SetProviderArgs>()
      .Bind("SET_DEPENDENCY_PROVIDER"_s, &SetProviderArgs::Command)
      .Bind("SUPPORTED_METHODS"_s, &SetProviderArgs::Methods);

  std::vector<std::string> unparsed;
  auto parsedArgs = ArgsParser.Parse(args, &unparsed);

  if (!unparsed.empty()) {
    return FatalError(
      status, cmStrCat("Unrecognized keyword: \"", unparsed.front(), '"'));
  }

  // We store the command that FetchContent_MakeAvailable() can call in a
  // global (but considered internal) property. If the provider doesn't
  // support this method, we set this property to an empty string instead.
  // This simplifies the logic in FetchContent_MakeAvailable() and doesn't
  // require us to define a new internal command or sub-command.
  std::string fcmasProperty = "__FETCHCONTENT_MAKEAVAILABLE_SERIAL_PROVIDER";

  if (parsedArgs.Command.empty()) {
    if (!parsedArgs.Methods.empty()) {
      return FatalError(status,
                        "Must specify a non-empty command name when provider "
                        "methods are given");
    }
    state->ClearDependencyProvider();
    state->SetGlobalProperty(fcmasProperty, "");
    return true;
  }

  cmState::Command command = state->GetCommand(parsedArgs.Command);
  if (!command) {
    return FatalError(status,
                      cmStrCat("Command \"", parsedArgs.Command,
                               "\" is not a defined command"));
  }

  if (parsedArgs.Methods.empty()) {
    return FatalError(status, "Must specify at least one provider method");
  }

  bool supportsFetchContentMakeAvailableSerial = false;
  std::vector<cmDependencyProvider::Method> methods;
  for (auto const& method : parsedArgs.Methods) {
    if (method == "FIND_PACKAGE") {
      methods.emplace_back(cmDependencyProvider::Method::FindPackage);
    } else if (method == "FETCHCONTENT_MAKEAVAILABLE_SERIAL") {
      supportsFetchContentMakeAvailableSerial = true;
      methods.emplace_back(
        cmDependencyProvider::Method::FetchContentMakeAvailableSerial);
    } else {
      return FatalError(
        status,
        cmStrCat("Unknown dependency provider method \"", method, '"'));
    }
  }

  state->SetDependencyProvider({ parsedArgs.Command, methods });
  state->SetGlobalProperty(
    fcmasProperty,
    supportsFetchContentMakeAvailableSerial ? parsedArgs.Command : "");

  return true;
}

bool cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(
  std::vector<cmListFileArgument> const& args, cmExecutionStatus& status)
{
  cmMakefile& makefile = status.GetMakefile();
  std::vector<std::string> expandedArgs;
  makefile.ExpandArguments(args, expandedArgs);

  if (args.size() < 2 || expandedArgs.size() > 2) {
    return FatalError(
      status,
      "sub-command GET_MESSAGE_LOG_LEVEL expects exactly one argument");
  }

  Message::LogLevel logLevel = makefile.GetCurrentLogLevel();
  std::string outputValue = cmake::LogLevelToString(logLevel);

  std::string const& outputVariable = expandedArgs[1];
  makefile.AddDefinition(outputVariable, outputValue);
  return true;
}

bool cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED(
  std::vector<cmListFileArgument> const& args, cmExecutionStatus& status)
{
  cmMakefile& makefile = status.GetMakefile();
  std::vector<std::string> expandedArgs;
  makefile.ExpandArguments(args, expandedArgs);

  if (expandedArgs.size() != 3) {
    return FatalError(status,
                      "sub-command GET_EXPERIMENTAL_FEATURE_ENABLED expects "
                      "exactly two arguments");
  }

  auto const& featureName = expandedArgs[1];
  auto const& variableName = expandedArgs[2];

  if (auto feature = cmExperimental::FeatureByName(featureName)) {
    if (cmExperimental::HasSupportEnabled(makefile, *feature)) {
      makefile.AddDefinition(variableName, "TRUE");
    } else {
      makefile.AddDefinition(variableName, "FALSE");
    }
  } else {
    return FatalError(status,
                      cmStrCat("Experimental feature name \"", featureName,
                               "\" does not exist."));
  }

  return true;
}

struct PrintTargetsArgs : public ArgumentParser::ParseResult
{
  cm::optional<std::string> Regex;
  bool ImportedOnly = false;
  bool NoImported = false;
  bool IgnoreCase = false;
  cm::optional<std::string> MessagePrefix;
};

// Lists every target that currently exists, optionally filtered by a
// name REGEX and by imported state.  "Currently exists" means anything
// CMake has defined up to this call: targets in the current directory,
// its ancestors, and any already-processed subdirectories.  Walking the
// global generator's makefiles captures exactly that set; a name-keyed
// map sorts the output and dedupes imported targets, which are inherited
// into child makefiles and would otherwise be seen many times.
bool cmCMakeLanguageCommandPRINT_TARGETS(
  std::vector<cmListFileArgument> const& args, cmExecutionStatus& status)
{
  cmMakefile& makefile = status.GetMakefile();
  std::vector<std::string> expandedArgs;
  makefile.ExpandArguments(args, expandedArgs);

  // Drop the leading "PRINT_TARGETS" subcommand keyword.
  std::vector<std::string> body(expandedArgs.begin() + 1, expandedArgs.end());

  auto const ArgsParser =
    cmArgumentParser<PrintTargetsArgs>()
      .Bind("REGEX"_s, &PrintTargetsArgs::Regex)
      .Bind("IMPORTED_ONLY"_s, &PrintTargetsArgs::ImportedOnly)
      .Bind("NO_IMPORTED"_s, &PrintTargetsArgs::NoImported)
      .Bind("IGNORE_CASE"_s, &PrintTargetsArgs::IgnoreCase)
      .Bind("__MESSAGE_PREFIX"_s, &PrintTargetsArgs::MessagePrefix);

  std::vector<std::string> unparsed;
  auto parsedArgs = ArgsParser.Parse(body, &unparsed);

  if (!unparsed.empty()) {
    return FatalError(
      status,
      cmStrCat(
        "Unknown argument(s) given to cmake_language(PRINT_TARGETS) call: \"",
        cmJoin(unparsed, "\" \""), "\"."));
  }
  if (parsedArgs.MaybeReportError(makefile)) {
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  if (parsedArgs.ImportedOnly && parsedArgs.NoImported) {
    return FatalError(status,
                      "IMPORTED_ONLY and NO_IMPORTED keywords are mutually "
                      "exclusive in cmake_language(PRINT_TARGETS) call.");
  }

  if (parsedArgs.IgnoreCase && !parsedArgs.Regex) {
    return FatalError(status,
                      "IGNORE_CASE keyword in cmake_language(PRINT_TARGETS) "
                      "call is only valid with REGEX.");
  }

  // Compile the optional REGEX up front so a bad pattern fails fast.  With
  // IGNORE_CASE the pattern and the candidate names are both lower-cased.
  cm::optional<cmsys::RegularExpression> regex;
  if (parsedArgs.Regex) {
    cmsys::RegularExpression re;
    std::string const pat = parsedArgs.IgnoreCase
      ? cmSystemTools::LowerCase(*parsedArgs.Regex)
      : *parsedArgs.Regex;
    if (!re.compile(pat)) {
      return FatalError(status,
                        cmStrCat("REGEX regular expression \"",
                                 *parsedArgs.Regex, "\" cannot compile."));
    }
    regex = std::move(re);
  }

  bool const includeNormal = !parsedArgs.ImportedOnly;
  bool const includeImported = !parsedArgs.NoImported;

  struct TargetInfo
  {
    cm::TargetType Type;
    bool Imported;
  };
  std::map<std::string, TargetInfo> targets;
  for (auto const& mf : makefile.GetGlobalGenerator()->GetMakefiles()) {
    if (includeNormal) {
      for (auto const& ti : mf->GetTargets()) {
        cmTarget const& t = ti.second;
        targets.insert({ t.GetName(), { t.GetType(), false } });
      }
    }
    if (includeImported) {
      for (cmTarget const* t : mf->GetImportedTargets()) {
        targets.insert({ t->GetName(), { t->GetType(), true } });
      }
    }
  }

  // Build the body first so the header is suppressed when a REGEX filters
  // everything out (matches cmake_language(PRINT_VARIABLES) behavior).
  std::string lines;
  bool anyMatched = false;
  for (auto const& t : targets) {
    if (regex) {
      std::string const subj =
        parsedArgs.IgnoreCase ? cmSystemTools::LowerCase(t.first) : t.first;
      if (!regex->find(subj)) {
        continue;
      }
    }
    lines +=
      cmStrCat("   ", t.first, " (", cmState::GetTargetTypeName(t.second.Type),
               t.second.Imported ? ", IMPORTED" : "", ")\n");
    anyMatched = true;
  }

  if (anyMatched) {
    // The message opens with a banner line.  The internal __MESSAGE_PREFIX
    // keyword overrides it (used by wrappers to reproduce legacy output); it
    // is not part of the public interface.
    std::string const messagePrefix =
      parsedArgs.MessagePrefix.value_or("Printing targets...\n");
    // The header reflects the imported-filter mode and any REGEX in effect.
    char const* label = "All targets";
    if (parsedArgs.ImportedOnly) {
      label = "Imported targets";
    } else if (parsedArgs.NoImported) {
      label = "Non-imported targets";
    }
    std::string out = cmStrCat(messagePrefix, " ", label);
    if (parsedArgs.Regex) {
      out += cmStrCat(
        " matching REGEX '", *parsedArgs.Regex, "' (",
        parsedArgs.IgnoreCase ? "case insensitive" : "case sensitive", ")");
    }
    out += cmStrCat(":\n", lines);
    makefile.DisplayStatus(out, -1);
  }

  if (!anyMatched && parsedArgs.Regex) {
    makefile.IssueMessage(
      MessageType::WARNING,
      cmStrCat("No targets matching REGEX '", *parsedArgs.Regex, "' (",
               parsedArgs.IgnoreCase ? "case insensitive" : "case sensitive",
               ") in cmake_language(PRINT_TARGETS ...)."));
  }
  return true;
}
}

bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
                            cmExecutionStatus& status)
{
  std::vector<std::string> expArgs;
  size_t rawArg = 0;
  size_t expArg = 0;

  // Helper to consume and expand one raw argument at a time.
  auto moreArgs = [&]() -> bool {
    while (expArg >= expArgs.size()) {
      if (rawArg >= args.size()) {
        return false;
      }
      std::vector<cmListFileArgument> tmpArg;
      tmpArg.emplace_back(args[rawArg++]);
      status.GetMakefile().ExpandArguments(tmpArg, expArgs);
    }
    return true;
  };
  auto finishArgs = [&]() {
    std::vector<cmListFileArgument> tmpArgs(args.begin() + rawArg, args.end());
    status.GetMakefile().ExpandArguments(tmpArgs, expArgs);
    rawArg = args.size();
  };

  if (!moreArgs()) {
    return FatalError(status, "called with incorrect number of arguments");
  }
  if (expArgs[expArg] == "EXIT"_s) {
    ++expArg; // consume "EXIT".

    if (!moreArgs()) {
      return FatalError(status, "EXIT requires one argument");
    }

    if (!status.GetMakefile().GetCMakeInstance()->RoleSupportsExitCode()) {
      return FatalError(status, "EXIT can be used only in SCRIPT mode");
    }

    long retCode = 0;

    if (!cmStrToLong(expArgs[expArg], &retCode)) {
      return FatalError(status,
                        cmStrCat("EXIT requires one integral argument, got \"",
                                 expArgs[expArg], '\"'));
    }

    status.SetExitCode(static_cast<int>(retCode));
    return true;
  }

  if (expArgs[expArg] == "SET_DEPENDENCY_PROVIDER"_s) {
    finishArgs();
    return cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(expArgs, status);
  }

  cm::optional<Defer> maybeDefer;
  if (expArgs[expArg] == "DEFER"_s) {
    ++expArg; // Consume "DEFER".

    if (!moreArgs()) {
      return FatalError(status, "DEFER requires at least one argument");
    }

    Defer defer;

    // Process optional arguments.
    while (moreArgs()) {
      if (expArgs[expArg] == "CALL"_s) {
        break;
      }
      if (expArgs[expArg] == "CANCEL_CALL"_s ||
          expArgs[expArg] == "GET_CALL_IDS"_s ||
          expArgs[expArg] == "GET_CALL"_s) {
        if (!defer.Id.empty() || !defer.IdVar.empty()) {
          return FatalError(status,
                            cmStrCat("DEFER "_s, expArgs[expArg],
                                     " does not accept ID or ID_VAR."_s));
        }
        finishArgs();
        return cmCMakeLanguageCommandDEFER(defer, expArgs, expArg, status);
      }
      if (expArgs[expArg] == "DIRECTORY"_s) {
        ++expArg; // Consume "DIRECTORY".
        if (defer.Directory) {
          return FatalError(status,
                            "DEFER given multiple DIRECTORY arguments");
        }
        if (!moreArgs()) {
          return FatalError(status, "DEFER DIRECTORY missing value");
        }
        std::string dir = expArgs[expArg++];
        if (dir.empty()) {
          return FatalError(status, "DEFER DIRECTORY may not be empty");
        }
        dir = cmSystemTools::CollapseFullPath(
          dir, status.GetMakefile().GetCurrentSourceDirectory());
        defer.Directory =
          status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
        if (!defer.Directory) {
          return FatalError(status,
                            cmStrCat("DEFER DIRECTORY:\n  "_s, dir,
                                     "\nis not known.  "
                                     "It may not have been processed yet."_s));
        }
      } else if (expArgs[expArg] == "ID"_s) {
        ++expArg; // Consume "ID".
        if (!defer.Id.empty()) {
          return FatalError(status, "DEFER given multiple ID arguments");
        }
        if (!moreArgs()) {
          return FatalError(status, "DEFER ID missing value");
        }
        defer.Id = expArgs[expArg++];
        if (defer.Id.empty()) {
          return FatalError(status, "DEFER ID may not be empty");
        }
        if (defer.Id[0] >= 'A' && defer.Id[0] <= 'Z') {
          return FatalError(status, "DEFER ID may not start in A-Z.");
        }
      } else if (expArgs[expArg] == "ID_VAR"_s) {
        ++expArg; // Consume "ID_VAR".
        if (!defer.IdVar.empty()) {
          return FatalError(status, "DEFER given multiple ID_VAR arguments");
        }
        if (!moreArgs()) {
          return FatalError(status, "DEFER ID_VAR missing variable name");
        }
        defer.IdVar = expArgs[expArg++];
        if (defer.IdVar.empty()) {
          return FatalError(status, "DEFER ID_VAR may not be empty");
        }
      } else {
        return FatalError(
          status, cmStrCat("DEFER unknown option:\n  "_s, expArgs[expArg]));
      }
    }

    if (!(moreArgs() && expArgs[expArg] == "CALL"_s)) {
      return FatalError(status, "DEFER must be followed by a CALL argument");
    }

    maybeDefer = std::move(defer);
  }

  if (expArgs[expArg] == "CALL") {
    ++expArg; // Consume "CALL".

    // CALL requires a command name.
    if (!moreArgs()) {
      return FatalError(status, "CALL missing command name");
    }
    std::string const& callCommand = expArgs[expArg++];

    // CALL accepts no further expanded arguments.
    if (expArg != expArgs.size()) {
      return FatalError(status, "CALL command's arguments must be literal");
    }

    // Run the CALL.
    return cmCMakeLanguageCommandCALL(args, callCommand, rawArg,
                                      std::move(maybeDefer), status);
  }

  if (expArgs[expArg] == "EVAL") {
    return cmCMakeLanguageCommandEVAL(args, status);
  }

  if (expArgs[expArg] == "GET_MESSAGE_LOG_LEVEL") {
    return cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(args, status);
  }

  if (expArgs[expArg] == "GET_EXPERIMENTAL_FEATURE_ENABLED") {
    return cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED(args,
                                                                  status);
  }

  if (expArgs[expArg] == "PRINT_TARGETS") {
    return cmCMakeLanguageCommandPRINT_TARGETS(args, status);
  }

  if (expArgs[expArg] == "TRACE") {
    ++expArg; // Consume "TRACE".

    if (!moreArgs()) {
      return FatalError(status, "TRACE missing a boolean value");
    }

    bool const value = cmValue::IsOn(expArgs[expArg++]);
    bool expand = false;

    if (value && moreArgs()) {
      expand = (expArgs[expArg] == "EXPAND");
      if (!expand) {
        return FatalError(
          status,
          cmStrCat("TRACE ON given an invalid argument ", expArgs[expArg]));
      }
      ++expArg;
    }

    if (moreArgs()) {
      return FatalError(
        status,
        cmStrCat("TRACE O", value ? "N" : "FF", " given too many arguments"));
    }

    cmMakefile& makefile = status.GetMakefile();
    if (value) {
      makefile.GetCMakeInstance()->PushTraceCmd(expand);
      return true;
    }
    return makefile.GetCMakeInstance()->PopTraceCmd() ||
      FatalError(status, "TRACE OFF request without a corresponding TRACE ON");
  }

  return FatalError(status, "called with unknown meta-operation");
}
