1 /*
2 * Copyright (C) 2022 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/frontline_parser.h"
18
19 #include <sstream>
20 #include <type_traits>
21 #include <vector>
22
23 #include <android-base/file.h>
24 #include <android-base/strings.h>
25
26 #include "common/libs/utils/flag_parser.h"
27 #include "host/commands/cvd/selector/selector_constants.h"
28
29 namespace cuttlefish {
30
Parse(ParserParam param)31 Result<std::unique_ptr<FrontlineParser>> FrontlineParser::Parse(
32 ParserParam param) {
33 CF_EXPECT(!param.all_args.empty());
34 FrontlineParser* frontline_parser = new FrontlineParser(param);
35 CF_EXPECT(frontline_parser != nullptr,
36 "Memory allocation for FrontlineParser failed.");
37 CF_EXPECT(frontline_parser->Separate());
38 return std::unique_ptr<FrontlineParser>(frontline_parser);
39 }
40
FrontlineParser(const ParserParam & param)41 FrontlineParser::FrontlineParser(const ParserParam& param)
42 : server_supported_subcmds_{param.server_supported_subcmds},
43 all_args_(param.all_args),
44 internal_cmds_(param.internal_cmds),
45 cvd_flags_(param.cvd_flags) {}
46
Separate()47 Result<void> FrontlineParser::Separate() {
48 arguments_separator_ = CF_EXPECT(CallSeparator());
49 return {};
50 }
51
ValidSubcmdsList()52 Result<cvd_common::Args> FrontlineParser::ValidSubcmdsList() {
53 cvd_common::Args valid_subcmds(server_supported_subcmds_);
54 std::copy(internal_cmds_.cbegin(), internal_cmds_.cend(),
55 std::back_inserter(valid_subcmds));
56 return valid_subcmds;
57 }
58
BoolFlagNames(const std::vector<CvdFlagProxy> & flags)59 static Result<std::unordered_set<std::string>> BoolFlagNames(
60 const std::vector<CvdFlagProxy>& flags) {
61 std::unordered_set<std::string> output;
62 for (const auto& flag : flags) {
63 if (flag.GetType() == CvdFlagProxy::FlagType::kBool) {
64 output.insert(CF_EXPECT(flag.Name()));
65 }
66 }
67 return output;
68 }
69
ValueFlagNames(const std::vector<CvdFlagProxy> & flags)70 static Result<std::unordered_set<std::string>> ValueFlagNames(
71 const std::vector<CvdFlagProxy>& flags) {
72 std::unordered_set<std::string> output;
73 for (const auto& flag : flags) {
74 if (flag.GetType() == CvdFlagProxy::FlagType::kInt32 ||
75 flag.GetType() == CvdFlagProxy::FlagType::kString) {
76 output.insert(CF_EXPECT(flag.Name()));
77 }
78 }
79 return output;
80 }
81
82 Result<std::unique_ptr<selector::ArgumentsSeparator>>
CallSeparator()83 FrontlineParser::CallSeparator() {
84 auto valid_subcmds_vector = CF_EXPECT(ValidSubcmdsList());
85 std::unordered_set<std::string> valid_subcmds{valid_subcmds_vector.begin(),
86 valid_subcmds_vector.end()};
87 auto cvd_flags = cvd_flags_.Flags();
88
89 auto known_bool_flags = CF_EXPECT(BoolFlagNames(cvd_flags));
90 auto known_value_flags = CF_EXPECT(ValueFlagNames(cvd_flags));
91
92 ArgumentsSeparator::FlagsRegistration flag_registration{
93 .known_boolean_flags = known_bool_flags,
94 .known_value_flags = known_value_flags,
95 .valid_subcommands = valid_subcmds};
96 auto arguments_separator =
97 CF_EXPECT(ArgumentsSeparator::Parse(flag_registration, all_args_));
98 CF_EXPECT(arguments_separator != nullptr);
99 return arguments_separator;
100 }
101
ProgPath() const102 const std::string& FrontlineParser::ProgPath() const {
103 return arguments_separator_->ProgPath();
104 }
105
SubCmd() const106 std::optional<std::string> FrontlineParser::SubCmd() const {
107 return arguments_separator_->SubCmd();
108 }
109
SubCmdArgs() const110 const cvd_common::Args& FrontlineParser::SubCmdArgs() const {
111 return arguments_separator_->SubCmdArgs();
112 }
113
CvdArgs() const114 const cvd_common::Args& FrontlineParser::CvdArgs() const {
115 return arguments_separator_->CvdArgs();
116 }
117
118 } // namespace cuttlefish
119