blob: cbd32f5ed6d78e21b83772278e32a8895debc886 [file] [log] [blame] [edit]
/*
* 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<std::string> 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<bool>&) -> FlagType { return FlagType::kBool; },
[](const CvdFlag<std::int32_t>&) -> FlagType { return FlagType::kInt32; },
[](const CvdFlag<std::string>&) -> FlagType { return FlagType::kString; },
[](auto) -> FlagType { return FlagType::kUnknown; },
};
return std::visit(decode_type, flag_);
}
Result<bool> 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<CvdFlagProxy> FlagCollection::Flags() const {
std::vector<CvdFlagProxy> flags;
flags.reserve(name_flag_map_.size());
for (const auto& [name, flag] : name_flag_map_) {
flags.push_back(flag);
}
return flags;
}
template <typename T>
static Result<std::optional<CvdFlagProxy::ValueVariant>> FilterKnownTypeFlag(
const CvdFlag<T>& flag, cvd_common::Args& args) {
std::optional<T> opt = CF_EXPECT(flag.FilterFlag(args));
if (!opt) {
return std::nullopt;
}
CvdFlagProxy::ValueVariant value_variant = *opt;
return value_variant;
}
Result<std::optional<CvdFlagProxy::ValueVariant>> CvdFlagProxy::FilterFlag(
cvd_common::Args& args) const {
CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type of typeid");
std::optional<CvdFlagProxy::ValueVariant> output;
auto filter_flag = Overload{
[&args](const CvdFlag<std::int32_t>& int32_t_flag)
-> Result<std::optional<ValueVariant>> {
return FilterKnownTypeFlag(int32_t_flag, args);
},
[&args](const CvdFlag<bool>& bool_flag)
-> Result<std::optional<ValueVariant>> {
return FilterKnownTypeFlag(bool_flag, args);
},
[&args](const CvdFlag<std::string>& string_flag)
-> Result<std::optional<ValueVariant>> {
return FilterKnownTypeFlag(string_flag, args);
},
[](auto) -> Result<std::optional<ValueVariant>> {
return CF_ERR("Invalid type is passed to FlagCollection::FilterFlags");
},
};
output = CF_EXPECT(std::visit(filter_flag, flag_));
return output;
}
Result<std::unordered_map<std::string, FlagCollection::FlagValuePair>>
FlagCollection::FilterFlags(cvd_common::Args& args) const {
std::unordered_map<std::string, FlagCollection::FlagValuePair> 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<std::unordered_map<std::string, FlagCollection::FlagValuePair>>
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<bool>())});
break;
case CvdFlagProxy::FlagType::kInt32:
output.emplace(
name, FlagValuePair{.flag = flag_proxy,
.value = CF_EXPECT(
flag_proxy.DefaultValue<std::int32_t>())});
break;
case CvdFlagProxy::FlagType::kString:
output.emplace(
name, FlagValuePair{.flag = flag_proxy,
.value = CF_EXPECT(
flag_proxy.DefaultValue<std::string>())});
break;
default:
return CF_ERR("Unsupported FlagType in "
<< "--" << name);
}
}
return output;
}
} // namespace cuttlefish