/* * Copyright (C) 2023 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. */ #include "host/commands/cvd/flag.h" #include "host/commands/cvd/common_utils.h" namespace cuttlefish { Result CvdFlagProxy::Name() const { CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type"); auto decode_name = Overload{ [](auto&& param) -> std::string { return param.Name(); }, }; return std::visit(decode_name, flag_); } CvdFlagProxy::FlagType CvdFlagProxy::GetType() const { auto decode_type = Overload{ [](const CvdFlag&) -> FlagType { return FlagType::kBool; }, [](const CvdFlag&) -> FlagType { return FlagType::kInt32; }, [](const CvdFlag&) -> FlagType { return FlagType::kString; }, [](auto) -> FlagType { return FlagType::kUnknown; }, }; return std::visit(decode_type, flag_); } Result CvdFlagProxy::HasDefaultValue() const { CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type of typeid"); auto decode_default_value = Overload{ [](auto&& flag) -> bool { return flag.HasDefaultValue(); }, }; return std::visit(decode_default_value, flag_); } std::vector FlagCollection::Flags() const { std::vector flags; flags.reserve(name_flag_map_.size()); for (const auto& [name, flag] : name_flag_map_) { flags.push_back(flag); } return flags; } template static Result> FilterKnownTypeFlag( const CvdFlag& flag, cvd_common::Args& args) { std::optional opt = CF_EXPECT(flag.FilterFlag(args)); if (!opt) { return std::nullopt; } CvdFlagProxy::ValueVariant value_variant = *opt; return value_variant; } Result> CvdFlagProxy::FilterFlag( cvd_common::Args& args) const { CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type of typeid"); std::optional output; auto filter_flag = Overload{ [&args](const CvdFlag& int32_t_flag) -> Result> { return FilterKnownTypeFlag(int32_t_flag, args); }, [&args](const CvdFlag& bool_flag) -> Result> { return FilterKnownTypeFlag(bool_flag, args); }, [&args](const CvdFlag& string_flag) -> Result> { return FilterKnownTypeFlag(string_flag, args); }, [](auto) -> Result> { return CF_ERR("Invalid type is passed to FlagCollection::FilterFlags"); }, }; output = CF_EXPECT(std::visit(filter_flag, flag_)); return output; } Result> FlagCollection::FilterFlags(cvd_common::Args& args) const { std::unordered_map output; for (const auto& [name, flag_proxy] : name_flag_map_) { auto value_opt = CF_EXPECT(flag_proxy.FilterFlag(args)); if (!value_opt) { continue; } output.emplace(name, FlagValuePair{.flag = flag_proxy, .value = *value_opt}); } return output; } Result> FlagCollection::CalculateFlags(cvd_common::Args& args) const { auto output = CF_EXPECT(FilterFlags(args)); for (const auto& [name, flag_proxy] : name_flag_map_) { if (Contains(output, name)) { // the flag was given with a value, there is no need for update it continue; } if (!CF_EXPECT(flag_proxy.HasDefaultValue())) { continue; } switch (flag_proxy.GetType()) { case CvdFlagProxy::FlagType::kBool: output.emplace( name, FlagValuePair{.flag = flag_proxy, .value = CF_EXPECT(flag_proxy.DefaultValue())}); break; case CvdFlagProxy::FlagType::kInt32: output.emplace( name, FlagValuePair{.flag = flag_proxy, .value = CF_EXPECT( flag_proxy.DefaultValue())}); break; case CvdFlagProxy::FlagType::kString: output.emplace( name, FlagValuePair{.flag = flag_proxy, .value = CF_EXPECT( flag_proxy.DefaultValue())}); break; default: return CF_ERR("Unsupported FlagType in " << "--" << name); } } return output; } } // namespace cuttlefish