/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.
 */
#ifndef ART_CMDLINE_CMDLINE_TYPES_H_
#define ART_CMDLINE_CMDLINE_TYPES_H_

#define CMDLINE_NDEBUG 1  // Do not output any debugging information for parsing.

#include <list>
#include <ostream>

#include "android-base/parsebool.h"
#include "android-base/stringprintf.h"
#include "cmdline_type_parser.h"
#include "detail/cmdline_debug_detail.h"
#include "memory_representation.h"

#include "android-base/logging.h"
#include "android-base/strings.h"

// Includes for the types that are being specialized
#include <string>
#include "base/time_utils.h"
#include "base/logging.h"
#include "experimental_flags.h"
#include "gc/collector_type.h"
#include "gc/space/large_object_space.h"
#include "jdwp_provider.h"
#include "jit/profile_saver_options.h"
#include "plugin.h"
#include "read_barrier_config.h"
#include "ti/agent.h"
#include "unit.h"

namespace art {

// The default specialization will always fail parsing the type from a string.
// Provide your own specialization that inherits from CmdlineTypeParser<T>
// and implements either Parse or ParseAndAppend
// (only if the argument was defined with ::AppendValues()) but not both.
template <typename T>
struct CmdlineType : CmdlineTypeParser<T> {
};

// Specializations for CmdlineType<T> follow:

// Parse argument definitions for Unit-typed arguments.
template <>
struct CmdlineType<Unit> : CmdlineTypeParser<Unit> {
  Result Parse(const std::string& args) {
    if (args == "") {
      return Result::Success(Unit{});
    }
    return Result::Failure("Unexpected extra characters " + args);
  }
};

template <>
struct CmdlineType<bool> : CmdlineTypeParser<bool> {
  Result Parse(const std::string& args) {
    switch (::android::base::ParseBool(args)) {
      case ::android::base::ParseBoolResult::kError:
        return Result::Failure("Could not parse '" + args + "' as boolean");
      case ::android::base::ParseBoolResult::kTrue:
        return Result::Success(true);
      case ::android::base::ParseBoolResult::kFalse:
        return Result::Success(false);
    }
  }

  static const char* DescribeType() { return "true|false|1|0|y|n|yes|no|on|off"; }
};

template <>
struct CmdlineType<JdwpProvider> : CmdlineTypeParser<JdwpProvider> {
  /*
   * Handle a single JDWP provider name. Must be either 'internal', 'default', or the file name of
   * an agent. A plugin will make use of this and the jdwpOptions to set up jdwp when appropriate.
   */
  Result Parse(const std::string& option) {
    if (option == "help") {
      return Result::Usage(
          "Example: -XjdwpProvider:none to disable JDWP\n"
          "Example: -XjdwpProvider:adbconnection for adb connection mediated jdwp implementation\n"
          "Example: -XjdwpProvider:default for the default jdwp implementation\n");
    } else if (option == "default") {
      return Result::Success(JdwpProvider::kDefaultJdwpProvider);
    } else if (option == "adbconnection") {
      return Result::Success(JdwpProvider::kAdbConnection);
    } else if (option == "none") {
      return Result::Success(JdwpProvider::kNone);
    } else {
      return Result::Failure(std::string("not a valid jdwp provider: ") + option);
    }
  }
  static const char* Name() { return "JdwpProvider"; }
  static const char* DescribeType() { return "none|adbconnection|default"; }
};

template <size_t Divisor>
struct CmdlineType<Memory<Divisor>> : CmdlineTypeParser<Memory<Divisor>> {
  using typename CmdlineTypeParser<Memory<Divisor>>::Result;

  Result Parse(const std::string& arg) {
    CMDLINE_DEBUG_LOG << "Parsing memory: " << arg << std::endl;
    size_t val = ParseMemoryOption(arg.c_str(), Divisor);
    CMDLINE_DEBUG_LOG << "Memory parsed to size_t value: " << val << std::endl;

    if (val == 0) {
      return Result::Failure(std::string("not a valid memory value, or not divisible by ")
                             + std::to_string(Divisor));
    }

    return Result::Success(Memory<Divisor>(val));
  }

  // Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify
  // memory sizes.  [kK] indicates kilobytes, [mM] megabytes, and
  // [gG] gigabytes.
  //
  // "s" should point just past the "-Xm?" part of the string.
  // "div" specifies a divisor, e.g. 1024 if the value must be a multiple
  // of 1024.
  //
  // The spec says the -Xmx and -Xms options must be multiples of 1024.  It
  // doesn't say anything about -Xss.
  //
  // Returns 0 (a useless size) if "s" is malformed or specifies a low or
  // non-evenly-divisible value.
  //
  static size_t ParseMemoryOption(const char* s, size_t div) {
    // strtoul accepts a leading [+-], which we don't want,
    // so make sure our string starts with a decimal digit.
    if (isdigit(*s)) {
      char* s2;
      size_t val = strtoul(s, &s2, 10);
      if (s2 != s) {
        // s2 should be pointing just after the number.
        // If this is the end of the string, the user
        // has specified a number of bytes.  Otherwise,
        // there should be exactly one more character
        // that specifies a multiplier.
        if (*s2 != '\0') {
          // The remainder of the string is either a single multiplier
          // character, or nothing to indicate that the value is in
          // bytes.
          char c = *s2++;
          if (*s2 == '\0') {
            size_t mul;
            if (c == '\0') {
              mul = 1;
            } else if (c == 'k' || c == 'K') {
              mul = KB;
            } else if (c == 'm' || c == 'M') {
              mul = MB;
            } else if (c == 'g' || c == 'G') {
              mul = GB;
            } else {
              // Unknown multiplier character.
              return 0;
            }

            if (val <= std::numeric_limits<size_t>::max() / mul) {
              val *= mul;
            } else {
              // Clamp to a multiple of 1024.
              val = std::numeric_limits<size_t>::max() & ~(1024-1);
            }
          } else {
            // There's more than one character after the numeric part.
            return 0;
          }
        }
        // The man page says that a -Xm value must be a multiple of 1024.
        if (val % div == 0) {
          return val;
        }
      }
    }
    return 0;
  }

  static const char* Name() { return Memory<Divisor>::Name(); }
  static const char* DescribeType() {
    static std::string str;
    if (str.empty()) {
      str = "Memory with granularity of " + std::to_string(Divisor) + " bytes";
    }
    return str.c_str();
  }
};

template <>
struct CmdlineType<double> : CmdlineTypeParser<double> {
  Result Parse(const std::string& str) {
    char* end = nullptr;
    errno = 0;
    double value = strtod(str.c_str(), &end);

    if (*end != '\0') {
      return Result::Failure("Failed to parse double from " + str);
    }
    if (errno == ERANGE) {
      return Result::OutOfRange(
          "Failed to parse double from " + str + "; overflow/underflow occurred");
    }

    return Result::Success(value);
  }

  static const char* Name() { return "double"; }
  static const char* DescribeType() { return "double value"; }
};

template <typename T>
static inline CmdlineParseResult<T> ParseNumeric(const std::string& str) {
  static_assert(sizeof(T) < sizeof(long long int),  // NOLINT [runtime/int] [4]
                "Current support is restricted.");

  const char* begin = str.c_str();
  char* end;

  // Parse into a larger type (long long) because we can't use strtoul
  // since it silently converts negative values into unsigned long and doesn't set errno.
  errno = 0;
  long long int result = strtoll(begin, &end, 10);  // NOLINT [runtime/int] [4]
  if (begin == end || *end != '\0' || errno == EINVAL) {
    return CmdlineParseResult<T>::Failure("Failed to parse integer from " + str);
  } else if ((errno == ERANGE) ||  // NOLINT [runtime/int] [4]
      result < std::numeric_limits<T>::min() || result > std::numeric_limits<T>::max()) {
    return CmdlineParseResult<T>::OutOfRange(
        "Failed to parse integer from " + str + "; out of range");
  }

  return CmdlineParseResult<T>::Success(static_cast<T>(result));
}

template <>
struct CmdlineType<unsigned int> : CmdlineTypeParser<unsigned int> {
  Result Parse(const std::string& str) {
    return ParseNumeric<unsigned int>(str);
  }

  static const char* Name() { return "unsigned integer"; }
  static const char* DescribeType() { return "unsigned integer value"; }
};

template <>
struct CmdlineType<int> : CmdlineTypeParser<int> {
  Result Parse(const std::string& str) {
    return ParseNumeric<int>(str);
  }

  static const char* Name() { return "integer"; }
  static const char* DescribeType() { return "integer value"; }
};

// Lightweight nanosecond value type. Allows parser to convert user-input from milliseconds
// to nanoseconds automatically after parsing.
//
// All implicit conversion from uint64_t uses nanoseconds.
struct MillisecondsToNanoseconds {
  // Create from nanoseconds.
  MillisecondsToNanoseconds(uint64_t nanoseconds) : nanoseconds_(nanoseconds) {  // NOLINT [runtime/explicit] [5]
  }

  // Create from milliseconds.
  static MillisecondsToNanoseconds FromMilliseconds(unsigned int milliseconds) {
    return MillisecondsToNanoseconds(MsToNs(milliseconds));
  }

  // Get the underlying nanoseconds value.
  uint64_t GetNanoseconds() const {
    return nanoseconds_;
  }

  // Get the milliseconds value [via a conversion]. Loss of precision will occur.
  uint64_t GetMilliseconds() const {
    return NsToMs(nanoseconds_);
  }

  // Get the underlying nanoseconds value.
  operator uint64_t() const {
    return GetNanoseconds();
  }

  // Default constructors/copy-constructors.
  MillisecondsToNanoseconds() : nanoseconds_(0ul) {}
  MillisecondsToNanoseconds(const MillisecondsToNanoseconds&) = default;
  MillisecondsToNanoseconds(MillisecondsToNanoseconds&&) = default;

 private:
  uint64_t nanoseconds_;
};

template <>
struct CmdlineType<MillisecondsToNanoseconds> : CmdlineTypeParser<MillisecondsToNanoseconds> {
  Result Parse(const std::string& str) {
    CmdlineType<unsigned int> uint_parser;
    CmdlineParseResult<unsigned int> res = uint_parser.Parse(str);

    if (res.IsSuccess()) {
      return Result::Success(MillisecondsToNanoseconds::FromMilliseconds(res.GetValue()));
    } else {
      return Result::CastError(res);
    }
  }

  static const char* Name() { return "MillisecondsToNanoseconds"; }
  static const char* DescribeType() { return "millisecond value"; }
};

template <>
struct CmdlineType<std::string> : CmdlineTypeParser<std::string> {
  Result Parse(const std::string& args) {
    return Result::Success(args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::string& existing_value) {
    if (existing_value.empty()) {
      existing_value = args;
    } else {
      existing_value += ' ';
      existing_value += args;
    }
    return Result::SuccessNoValue();
  }
  static const char* DescribeType() { return "string value"; }
};

template <>
struct CmdlineType<std::vector<Plugin>> : CmdlineTypeParser<std::vector<Plugin>> {
  Result Parse(const std::string& args) {
    assert(false && "Use AppendValues() for a Plugin vector type");
    return Result::Failure("Unconditional failure: Plugin vector must be appended: " + args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::vector<Plugin>& existing_value) {
    existing_value.push_back(Plugin::Create(args));
    return Result::SuccessNoValue();
  }

  static const char* Name() { return "std::vector<Plugin>"; }
  static const char* DescribeType() { return "/path/to/libplugin.so"; }
};

template <>
struct CmdlineType<std::list<ti::AgentSpec>> : CmdlineTypeParser<std::list<ti::AgentSpec>> {
  Result Parse(const std::string& args) {
    assert(false && "Use AppendValues() for an Agent list type");
    return Result::Failure("Unconditional failure: Agent list must be appended: " + args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::list<ti::AgentSpec>& existing_value) {
    existing_value.emplace_back(args);
    return Result::SuccessNoValue();
  }

  static const char* Name() { return "std::list<ti::AgentSpec>"; }
  static const char* DescribeType() { return "/path/to/libagent.so=options"; }
};

template <>
struct CmdlineType<std::vector<std::string>> : CmdlineTypeParser<std::vector<std::string>> {
  Result Parse(const std::string& args) {
    assert(false && "Use AppendValues() for a string vector type");
    return Result::Failure("Unconditional failure: string vector must be appended: " + args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::vector<std::string>& existing_value) {
    existing_value.push_back(args);
    return Result::SuccessNoValue();
  }

  static const char* Name() { return "std::vector<std::string>"; }
  static const char* DescribeType() { return "string value"; }
};

template <>
struct CmdlineType<std::vector<int>> : CmdlineTypeParser<std::vector<int>> {
  Result Parse(const std::string& args) {
    assert(false && "Use AppendValues() for a int vector type");
    return Result::Failure("Unconditional failure: string vector must be appended: " + args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::vector<int>& existing_value) {
    auto result = ParseNumeric<int>(args);
    if (result.IsSuccess()) {
      existing_value.push_back(result.GetValue());
    } else {
      return Result::CastError(result);
    }
    return Result::SuccessNoValue();
  }

  static const char* Name() { return "std::vector<int>"; }
  static const char* DescribeType() { return "int values"; }
};

template <typename ArgType, char Separator>
struct ParseList {
  explicit ParseList(std::vector<ArgType>&& list) : list_(list) {}

  operator std::vector<ArgType>() const {
    return list_;
  }

  operator std::vector<ArgType>&&() && {
    return std::move(list_);
  }

  size_t Size() const {
    return list_.size();
  }

  std::string Join() const {
    return android::base::Join(list_, Separator);
  }

  ParseList() = default;
  ParseList(const ParseList&) = default;
  ParseList(ParseList&&) noexcept = default;

 private:
  std::vector<ArgType> list_;
};

template <char Separator>
using ParseIntList = ParseList<int, Separator>;

template <char Separator>
struct ParseStringList : public ParseList<std::string, Separator> {
  explicit ParseStringList(std::vector<std::string>&& list) : ParseList<std::string, Separator>(std::move(list)) {}

  static ParseStringList<Separator> Split(const std::string& str) {
    std::vector<std::string> list;
    art::Split(str, Separator, &list);
    return ParseStringList<Separator>(std::move(list));
  }

  ParseStringList() = default;
  ParseStringList(const ParseStringList&) = default;
  ParseStringList(ParseStringList&&) noexcept = default;
};

template <char Separator>
struct CmdlineType<ParseStringList<Separator>> : CmdlineTypeParser<ParseStringList<Separator>> {
  using Result = CmdlineParseResult<ParseStringList<Separator>>;

  Result Parse(const std::string& args) {
    return Result::Success(ParseStringList<Separator>::Split(args));
  }

  static const char* Name() { return "ParseStringList<Separator>"; }
  static const char* DescribeType() {
    static std::string str;
    if (str.empty()) {
      str = android::base::StringPrintf("list separated by '%c'", Separator);
    }
    return str.c_str();
  }
};

template <char Separator>
struct CmdlineType<ParseIntList<Separator>> : CmdlineTypeParser<ParseIntList<Separator>> {
  using Result = CmdlineParseResult<ParseIntList<Separator>>;

  Result Parse(const std::string& args) {
    std::vector<int> list;
    const char* pos = args.c_str();
    errno = 0;

    while (true) {
      char* end = nullptr;
      int64_t value = strtol(pos, &end, 10);
      if (pos == end ||  errno == EINVAL) {
        return Result::Failure("Failed to parse integer from " + args);
      } else if ((errno == ERANGE) ||  // NOLINT [runtime/int] [4]
                 value < std::numeric_limits<int>::min() ||
                 value > std::numeric_limits<int>::max()) {
        return Result::OutOfRange("Failed to parse integer from " + args + "; out of range");
      }
      list.push_back(static_cast<int>(value));
      if (*end == '\0') {
        break;
      } else if (*end != Separator) {
        return Result::Failure(std::string("Unexpected character: ") + *end);
      }
      pos = end + 1;
    }
    return Result::Success(ParseIntList<Separator>(std::move(list)));
  }

  static const char* Name() { return "ParseIntList<Separator>"; }
  static const char* DescribeType() {
    static std::string str;
    if (str.empty()) {
      str = android::base::StringPrintf("integer list separated by '%c'", Separator);
    }
    return str.c_str();
  }
};

static gc::CollectorType ParseCollectorType(const std::string& option) {
  if (option == "MS" || option == "nonconcurrent") {
    return gc::kCollectorTypeMS;
  } else if (option == "CMS" || option == "concurrent") {
    return gc::kCollectorTypeCMS;
  } else if (option == "SS") {
    return gc::kCollectorTypeSS;
  } else if (option == "CC") {
    return gc::kCollectorTypeCC;
  } else {
    return gc::kCollectorTypeNone;
  }
}

struct XGcOption {
  // These defaults are used when the command line arguments for -Xgc:
  // are either omitted completely or partially.
  gc::CollectorType collector_type_ = gc::kCollectorTypeDefault;
  bool verify_pre_gc_heap_ = false;
  bool verify_pre_sweeping_heap_ = kIsDebugBuild;
  bool generational_cc = kEnableGenerationalCCByDefault;
  bool verify_post_gc_heap_ = false;
  bool verify_pre_gc_rosalloc_ = kIsDebugBuild;
  bool verify_pre_sweeping_rosalloc_ = false;
  bool verify_post_gc_rosalloc_ = false;
  // Do no measurements for kUseTableLookupReadBarrier to avoid test timeouts. b/31679493
  bool measure_ = kIsDebugBuild && !kUseTableLookupReadBarrier;
  bool gcstress_ = false;
};

template <>
struct CmdlineType<XGcOption> : CmdlineTypeParser<XGcOption> {
  Result Parse(const std::string& option) {  // -Xgc: already stripped
    XGcOption xgc{};

    std::vector<std::string> gc_options;
    Split(option, ',', &gc_options);
    for (const std::string& gc_option : gc_options) {
      gc::CollectorType collector_type = ParseCollectorType(gc_option);
      if (collector_type != gc::kCollectorTypeNone) {
        xgc.collector_type_ = collector_type;
      } else if (gc_option == "preverify") {
        xgc.verify_pre_gc_heap_ = true;
      } else if (gc_option == "nopreverify") {
        xgc.verify_pre_gc_heap_ = false;
      }  else if (gc_option == "presweepingverify") {
        xgc.verify_pre_sweeping_heap_ = true;
      } else if (gc_option == "nopresweepingverify") {
        xgc.verify_pre_sweeping_heap_ = false;
      } else if (gc_option == "generational_cc") {
        // Note: Option "-Xgc:generational_cc" can be passed directly by
        // app_process/zygote (see `android::AndroidRuntime::startVm`). If this
        // option is ever deprecated, it should still be accepted (but ignored)
        // for compatibility reasons (this should not prevent the runtime from
        // starting up).
        xgc.generational_cc = true;
      } else if (gc_option == "nogenerational_cc") {
        // Note: Option "-Xgc:nogenerational_cc" can be passed directly by
        // app_process/zygote (see `android::AndroidRuntime::startVm`). If this
        // option is ever deprecated, it should still be accepted (but ignored)
        // for compatibility reasons (this should not prevent the runtime from
        // starting up).
        xgc.generational_cc = false;
      } else if (gc_option == "postverify") {
        xgc.verify_post_gc_heap_ = true;
      } else if (gc_option == "nopostverify") {
        xgc.verify_post_gc_heap_ = false;
      } else if (gc_option == "preverify_rosalloc") {
        xgc.verify_pre_gc_rosalloc_ = true;
      } else if (gc_option == "nopreverify_rosalloc") {
        xgc.verify_pre_gc_rosalloc_ = false;
      } else if (gc_option == "presweepingverify_rosalloc") {
        xgc.verify_pre_sweeping_rosalloc_ = true;
      } else if (gc_option == "nopresweepingverify_rosalloc") {
        xgc.verify_pre_sweeping_rosalloc_ = false;
      } else if (gc_option == "postverify_rosalloc") {
        xgc.verify_post_gc_rosalloc_ = true;
      } else if (gc_option == "nopostverify_rosalloc") {
        xgc.verify_post_gc_rosalloc_ = false;
      } else if (gc_option == "gcstress") {
        xgc.gcstress_ = true;
      } else if (gc_option == "nogcstress") {
        xgc.gcstress_ = false;
      } else if (gc_option == "measure") {
        xgc.measure_ = true;
      } else if ((gc_option == "precise") ||
                 (gc_option == "noprecise") ||
                 (gc_option == "verifycardtable") ||
                 (gc_option == "noverifycardtable")) {
        // Ignored for backwards compatibility.
      } else {
        return Result::Usage(std::string("Unknown -Xgc option ") + gc_option);
      }
    }

    return Result::Success(std::move(xgc));
  }

  static const char* Name() { return "XgcOption"; }
  static const char* DescribeType() {
    return "MS|nonconccurent|concurrent|CMS|SS|CC|[no]preverify[_rosalloc]|"
           "[no]presweepingverify[_rosalloc]|[no]generation_cc|[no]postverify[_rosalloc]|"
           "[no]gcstress|measure|[no]precisce|[no]verifycardtable";
  }
};

struct BackgroundGcOption {
  // If background_collector_type_ is kCollectorTypeNone, it defaults to the
  // XGcOption::collector_type_ after parsing options. If you set this to
  // kCollectorTypeHSpaceCompact then we will do an hspace compaction when
  // we transition to background instead of a normal collector transition.
  gc::CollectorType background_collector_type_;

  BackgroundGcOption(gc::CollectorType background_collector_type)  // NOLINT [runtime/explicit] [5]
    : background_collector_type_(background_collector_type) {}
  BackgroundGcOption()
    : background_collector_type_(gc::kCollectorTypeNone) {
  }

  operator gc::CollectorType() const { return background_collector_type_; }
};

template<>
struct CmdlineType<BackgroundGcOption>
  : CmdlineTypeParser<BackgroundGcOption>, private BackgroundGcOption {
  Result Parse(const std::string& substring) {
    // Special handling for HSpaceCompact since this is only valid as a background GC type.
    if (substring == "HSpaceCompact") {
      background_collector_type_ = gc::kCollectorTypeHomogeneousSpaceCompact;
    } else {
      gc::CollectorType collector_type = ParseCollectorType(substring);
      if (collector_type != gc::kCollectorTypeNone) {
        background_collector_type_ = collector_type;
      } else {
        return Result::Failure();
      }
    }

    BackgroundGcOption res = *this;
    return Result::Success(res);
  }

  static const char* Name() { return "BackgroundGcOption"; }
  static const char* DescribeType() {
    return "HSpaceCompact|MS|nonconccurent|CMS|concurrent|SS|CC";
  }
};

template <>
struct CmdlineType<LogVerbosity> : CmdlineTypeParser<LogVerbosity> {
  Result Parse(const std::string& options) {
    LogVerbosity log_verbosity = LogVerbosity();

    std::vector<std::string> verbose_options;
    Split(options, ',', &verbose_options);
    for (size_t j = 0; j < verbose_options.size(); ++j) {
      if (verbose_options[j] == "class") {
        log_verbosity.class_linker = true;
      } else if (verbose_options[j] == "collector") {
        log_verbosity.collector = true;
      } else if (verbose_options[j] == "compiler") {
        log_verbosity.compiler = true;
      } else if (verbose_options[j] == "deopt") {
        log_verbosity.deopt = true;
      } else if (verbose_options[j] == "gc") {
        log_verbosity.gc = true;
      } else if (verbose_options[j] == "heap") {
        log_verbosity.heap = true;
      } else if (verbose_options[j] == "interpreter") {
        log_verbosity.interpreter = true;
      } else if (verbose_options[j] == "jdwp") {
        log_verbosity.jdwp = true;
      } else if (verbose_options[j] == "jit") {
        log_verbosity.jit = true;
      } else if (verbose_options[j] == "jni") {
        log_verbosity.jni = true;
      } else if (verbose_options[j] == "monitor") {
        log_verbosity.monitor = true;
      } else if (verbose_options[j] == "oat") {
        log_verbosity.oat = true;
      } else if (verbose_options[j] == "profiler") {
        log_verbosity.profiler = true;
      } else if (verbose_options[j] == "signals") {
        log_verbosity.signals = true;
      } else if (verbose_options[j] == "simulator") {
        log_verbosity.simulator = true;
      } else if (verbose_options[j] == "startup") {
        log_verbosity.startup = true;
      } else if (verbose_options[j] == "third-party-jni") {
        log_verbosity.third_party_jni = true;
      } else if (verbose_options[j] == "threads") {
        log_verbosity.threads = true;
      } else if (verbose_options[j] == "verifier") {
        log_verbosity.verifier = true;
      } else if (verbose_options[j] == "verifier-debug") {
        log_verbosity.verifier_debug = true;
      } else if (verbose_options[j] == "image") {
        log_verbosity.image = true;
      } else if (verbose_options[j] == "systrace-locks") {
        log_verbosity.systrace_lock_logging = true;
      } else if (verbose_options[j] == "plugin") {
        log_verbosity.plugin = true;
      } else if (verbose_options[j] == "agents") {
        log_verbosity.agents = true;
      } else if (verbose_options[j] == "dex") {
        log_verbosity.dex = true;
      } else {
        return Result::Usage(std::string("Unknown -verbose option ") + verbose_options[j]);
      }
    }

    return Result::Success(log_verbosity);
  }

  static const char* Name() { return "LogVerbosity"; }
  static const char* DescribeType() {
    return "class|collector|compiler|deopt|gc|heap|interpreter|jdwp|jit|jni|monitor|oat|profiler|"
           "signals|simulator|startup|third-party-jni|threads|verifier|verifier-debug|image|"
           "systrace-locks|plugin|agents|dex";
  }
};

template <>
struct CmdlineType<ProfileSaverOptions> : CmdlineTypeParser<ProfileSaverOptions> {
  using Result = CmdlineParseResult<ProfileSaverOptions>;

 private:
  using StringResult = CmdlineParseResult<std::string>;
  using DoubleResult = CmdlineParseResult<double>;

  template <typename T>
  static Result ParseInto(ProfileSaverOptions& options,
                          T ProfileSaverOptions::*pField,
                          CmdlineParseResult<T>&& result) {
    assert(pField != nullptr);

    if (result.IsSuccess()) {
      options.*pField = result.ReleaseValue();
      return Result::SuccessNoValue();
    }

    return Result::CastError(result);
  }

  static std::string RemovePrefix(const std::string& source) {
    size_t prefix_idx = source.find(':');

    if (prefix_idx == std::string::npos) {
      return "";
    }

    return source.substr(prefix_idx + 1);
  }

 public:
  Result ParseAndAppend(const std::string& option, ProfileSaverOptions& existing) {
    // Special case which doesn't include a wildcard argument definition.
    // We pass-it through as-is.
    if (option == "-Xjitsaveprofilinginfo") {
      existing.enabled_ = true;
      return Result::SuccessNoValue();
    }

    if (option == "profile-boot-class-path") {
      existing.profile_boot_class_path_ = true;
      return Result::SuccessNoValue();
    }

    if (option == "profile-aot-code") {
      existing.profile_aot_code_ = true;
      return Result::SuccessNoValue();
    }

    if (option == "save-without-jit-notifications") {
      existing.wait_for_jit_notifications_to_save_ = false;
      return Result::SuccessNoValue();
    }

    // The rest of these options are always the wildcard from '-Xps-*'
    std::string suffix = RemovePrefix(option);

    if (android::base::StartsWith(option, "min-save-period-ms:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::min_save_period_ms_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "min-first-save-ms:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::min_first_save_ms_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "save-resolved-classes-delay-ms:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::save_resolved_classes_delay_ms_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "hot-startup-method-samples:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::hot_startup_method_samples_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "min-methods-to-save:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::min_methods_to_save_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "min-classes-to-save:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::min_classes_to_save_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "min-notification-before-wake:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::min_notification_before_wake_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "max-notification-before-wake:")) {
      CmdlineType<unsigned int> type_parser;
      return ParseInto(existing,
             &ProfileSaverOptions::max_notification_before_wake_,
             type_parser.Parse(suffix));
    }
    if (android::base::StartsWith(option, "profile-path:")) {
      existing.profile_path_ = suffix;
      return Result::SuccessNoValue();
    }

    return Result::Failure(std::string("Invalid suboption '") + option + "'");
  }

  static const char* Name() { return "ProfileSaverOptions"; }
  static const char* DescribeType() { return "string|unsigned integer"; }
  static constexpr bool kCanParseBlankless = true;
};

template<>
struct CmdlineType<ExperimentalFlags> : CmdlineTypeParser<ExperimentalFlags> {
  Result ParseAndAppend(const std::string& option, ExperimentalFlags& existing) {
    if (option == "none") {
      existing = ExperimentalFlags::kNone;
    } else {
      return Result::Failure(std::string("Unknown option '") + option + "'");
    }
    return Result::SuccessNoValue();
  }

  static const char* Name() { return "ExperimentalFlags"; }
  static const char* DescribeType() { return "none"; }
};
}  // namespace art
#endif  // ART_CMDLINE_CMDLINE_TYPES_H_
