• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "host/commands/cvd/flag.h"
18 
19 #include "host/commands/cvd/common_utils.h"
20 
21 namespace cuttlefish {
22 
Name() const23 Result<std::string> CvdFlagProxy::Name() const {
24   CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type");
25   auto decode_name = Overload{
26       [](auto&& param) -> std::string { return param.Name(); },
27   };
28   return std::visit(decode_name, flag_);
29 }
30 
GetType() const31 CvdFlagProxy::FlagType CvdFlagProxy::GetType() const {
32   auto decode_type = Overload{
33       [](const CvdFlag<bool>&) -> FlagType { return FlagType::kBool; },
34       [](const CvdFlag<std::int32_t>&) -> FlagType { return FlagType::kInt32; },
35       [](const CvdFlag<std::string>&) -> FlagType { return FlagType::kString; },
36       [](auto) -> FlagType { return FlagType::kUnknown; },
37   };
38   return std::visit(decode_type, flag_);
39 }
40 
HasDefaultValue() const41 Result<bool> CvdFlagProxy::HasDefaultValue() const {
42   CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type of typeid");
43   auto decode_default_value = Overload{
44       [](auto&& flag) -> bool { return flag.HasDefaultValue(); },
45   };
46   return std::visit(decode_default_value, flag_);
47 }
48 
Flags() const49 std::vector<CvdFlagProxy> FlagCollection::Flags() const {
50   std::vector<CvdFlagProxy> flags;
51   flags.reserve(name_flag_map_.size());
52   for (const auto& [name, flag] : name_flag_map_) {
53     flags.push_back(flag);
54   }
55   return flags;
56 }
57 
58 template <typename T>
FilterKnownTypeFlag(const CvdFlag<T> & flag,cvd_common::Args & args)59 static Result<std::optional<CvdFlagProxy::ValueVariant>> FilterKnownTypeFlag(
60     const CvdFlag<T>& flag, cvd_common::Args& args) {
61   std::optional<T> opt = CF_EXPECT(flag.FilterFlag(args));
62   if (!opt) {
63     return std::nullopt;
64   }
65   CvdFlagProxy::ValueVariant value_variant = *opt;
66   return value_variant;
67 }
68 
FilterFlag(cvd_common::Args & args) const69 Result<std::optional<CvdFlagProxy::ValueVariant>> CvdFlagProxy::FilterFlag(
70     cvd_common::Args& args) const {
71   CF_EXPECT(GetType() != FlagType::kUnknown, "Unsupported flag type of typeid");
72   std::optional<CvdFlagProxy::ValueVariant> output;
73   auto filter_flag = Overload{
74       [&args](const CvdFlag<std::int32_t>& int32_t_flag)
75           -> Result<std::optional<ValueVariant>> {
76         return FilterKnownTypeFlag(int32_t_flag, args);
77       },
78       [&args](const CvdFlag<bool>& bool_flag)
79           -> Result<std::optional<ValueVariant>> {
80         return FilterKnownTypeFlag(bool_flag, args);
81       },
82       [&args](const CvdFlag<std::string>& string_flag)
83           -> Result<std::optional<ValueVariant>> {
84         return FilterKnownTypeFlag(string_flag, args);
85       },
86       [](auto) -> Result<std::optional<ValueVariant>> {
87         return CF_ERR("Invalid type is passed to FlagCollection::FilterFlags");
88       },
89   };
90   output = CF_EXPECT(std::visit(filter_flag, flag_));
91   return output;
92 }
93 
94 Result<std::unordered_map<std::string, FlagCollection::FlagValuePair>>
FilterFlags(cvd_common::Args & args) const95 FlagCollection::FilterFlags(cvd_common::Args& args) const {
96   std::unordered_map<std::string, FlagCollection::FlagValuePair> output;
97   for (const auto& [name, flag_proxy] : name_flag_map_) {
98     auto value_opt = CF_EXPECT(flag_proxy.FilterFlag(args));
99     if (!value_opt) {
100       continue;
101     }
102     output.emplace(name,
103                    FlagValuePair{.flag = flag_proxy, .value = *value_opt});
104   }
105   return output;
106 }
107 
108 Result<std::unordered_map<std::string, FlagCollection::FlagValuePair>>
CalculateFlags(cvd_common::Args & args) const109 FlagCollection::CalculateFlags(cvd_common::Args& args) const {
110   auto output = CF_EXPECT(FilterFlags(args));
111   for (const auto& [name, flag_proxy] : name_flag_map_) {
112     if (Contains(output, name)) {
113       // the flag was given with a value, there is no need for update it
114       continue;
115     }
116     if (!CF_EXPECT(flag_proxy.HasDefaultValue())) {
117       continue;
118     }
119     switch (flag_proxy.GetType()) {
120       case CvdFlagProxy::FlagType::kBool:
121         output.emplace(
122             name,
123             FlagValuePair{.flag = flag_proxy,
124                           .value = CF_EXPECT(flag_proxy.DefaultValue<bool>())});
125         break;
126       case CvdFlagProxy::FlagType::kInt32:
127         output.emplace(
128             name, FlagValuePair{.flag = flag_proxy,
129                                 .value = CF_EXPECT(
130                                     flag_proxy.DefaultValue<std::int32_t>())});
131         break;
132       case CvdFlagProxy::FlagType::kString:
133         output.emplace(
134             name, FlagValuePair{.flag = flag_proxy,
135                                 .value = CF_EXPECT(
136                                     flag_proxy.DefaultValue<std::string>())});
137         break;
138       default:
139         return CF_ERR("Unsupported FlagType in "
140                       << "--" << name);
141     }
142   }
143   return output;
144 }
145 
146 }  // namespace cuttlefish
147