147 lines
5.1 KiB
C++
147 lines
5.1 KiB
C++
/*
|
|
* 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
|