/* * Copyright (C) 2022 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/frontline_parser.h" #include #include #include #include #include #include "common/libs/utils/flag_parser.h" #include "host/commands/cvd/selector/selector_constants.h" namespace cuttlefish { Result> FrontlineParser::Parse( ParserParam param) { CF_EXPECT(!param.all_args.empty()); FrontlineParser* frontline_parser = new FrontlineParser(param); CF_EXPECT(frontline_parser != nullptr, "Memory allocation for FrontlineParser failed."); CF_EXPECT(frontline_parser->Separate()); return std::unique_ptr(frontline_parser); } FrontlineParser::FrontlineParser(const ParserParam& param) : server_supported_subcmds_{param.server_supported_subcmds}, all_args_(param.all_args), internal_cmds_(param.internal_cmds), cvd_flags_(param.cvd_flags) {} Result FrontlineParser::Separate() { arguments_separator_ = CF_EXPECT(CallSeparator()); return {}; } Result FrontlineParser::ValidSubcmdsList() { cvd_common::Args valid_subcmds(server_supported_subcmds_); std::copy(internal_cmds_.cbegin(), internal_cmds_.cend(), std::back_inserter(valid_subcmds)); return valid_subcmds; } static Result> BoolFlagNames( const std::vector& flags) { std::unordered_set output; for (const auto& flag : flags) { if (flag.GetType() == CvdFlagProxy::FlagType::kBool) { output.insert(CF_EXPECT(flag.Name())); } } return output; } static Result> ValueFlagNames( const std::vector& flags) { std::unordered_set output; for (const auto& flag : flags) { if (flag.GetType() == CvdFlagProxy::FlagType::kInt32 || flag.GetType() == CvdFlagProxy::FlagType::kString) { output.insert(CF_EXPECT(flag.Name())); } } return output; } Result> FrontlineParser::CallSeparator() { auto valid_subcmds_vector = CF_EXPECT(ValidSubcmdsList()); std::unordered_set valid_subcmds{valid_subcmds_vector.begin(), valid_subcmds_vector.end()}; auto cvd_flags = cvd_flags_.Flags(); auto known_bool_flags = CF_EXPECT(BoolFlagNames(cvd_flags)); auto known_value_flags = CF_EXPECT(ValueFlagNames(cvd_flags)); ArgumentsSeparator::FlagsRegistration flag_registration{ .known_boolean_flags = known_bool_flags, .known_value_flags = known_value_flags, .valid_subcommands = valid_subcmds}; auto arguments_separator = CF_EXPECT(ArgumentsSeparator::Parse(flag_registration, all_args_)); CF_EXPECT(arguments_separator != nullptr); return arguments_separator; } const std::string& FrontlineParser::ProgPath() const { return arguments_separator_->ProgPath(); } std::optional FrontlineParser::SubCmd() const { return arguments_separator_->SubCmd(); } const cvd_common::Args& FrontlineParser::SubCmdArgs() const { return arguments_separator_->SubCmdArgs(); } const cvd_common::Args& FrontlineParser::CvdArgs() const { return arguments_separator_->CvdArgs(); } } // namespace cuttlefish