1 /* 2 * Copyright (C) 2015, The Android Open Source Project * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #pragma once 17 18 #include <set> 19 #include <string> 20 #include <vector> 21 22 #include <android-base/result.h> 23 #include <android-base/strings.h> 24 25 #include "diagnostics.h" 26 #include "logging.h" 27 28 namespace android { 29 namespace aidl { 30 31 using std::set; 32 using std::string; 33 using std::vector; 34 35 // The oldest SDK version that is supported for each backend. For non-Java backends, these are the 36 // platform SDK version where the support for the backend was added. For Java backend, this is 1. 37 // TODO(b/205065703) switch back to DEFAULT_SDK_VERSION_JAVA = 23 38 constexpr uint32_t DEFAULT_SDK_VERSION_JAVA = 1; 39 constexpr uint32_t DEFAULT_SDK_VERSION_CPP = 23; 40 constexpr uint32_t DEFAULT_SDK_VERSION_NDK = 29; 41 constexpr uint32_t DEFAULT_SDK_VERSION_RUST = 31; 42 43 constexpr uint32_t SDK_VERSION_current = 10000; 44 constexpr uint32_t SDK_VERSION_Tiramisu = 33; 45 constexpr uint32_t SDK_VERSION_UpsideDownCake = 34; 46 constexpr uint32_t SDK_VERSION_VanillaIceCream = 35; 47 48 constexpr uint32_t JAVA_PROPAGATE_VERSION = SDK_VERSION_Tiramisu; 49 50 // A simple wrapper around ostringstream. This is just to make Options class 51 // copiable by the implicit copy constructor. If ostingstream is not wrapped, 52 // the implcit copy constructor is not generated because ostringstream isn't 53 // copiable. This class makes the field copiable by having a copy constructor 54 // that does not copy the underlying stream. 55 class ErrorMessage { 56 public: 57 ErrorMessage() = default; ErrorMessage(const ErrorMessage &)58 ErrorMessage(const ErrorMessage&) {} 59 std::ostringstream stream_; 60 61 template <typename T> 62 ErrorMessage& operator<<(T& t) { 63 stream_ << t; 64 return *this; 65 } 66 67 template <typename T> 68 ErrorMessage& operator<<(const T& t) { 69 stream_ << t; 70 return *this; 71 } 72 73 // for "<< endl" 74 ErrorMessage& operator<<(std::ostream& (*f)(std::ostream&)) { 75 f(stream_); 76 return *this; 77 } 78 }; 79 80 // Handles warning-related options (e.g. -W, -w, ...) 81 class WarningOptions { 82 public: 83 std::vector<const char*> Parse(int argc, const char* const argv[], ErrorMessage& error_message); 84 DiagnosticMapping GetDiagnosticMapping() const; 85 86 private: 87 bool as_errors_ = false; // -Werror 88 bool enable_all_ = false; // -Weverything 89 bool disable_all_ = false; // -w 90 std::set<std::string> enabled_; // -Wfoo 91 std::set<std::string> disabled_; // -Wno-foo 92 std::set<std::string> no_errors_; // -Wno-error=foo 93 }; 94 95 // Options for AIDL 96 // 97 // These are passed all throughout the compiler, but they should not affect the 98 // code which is generated. In order to avoid ODR issues, and also in order to 99 // make sure the language is orthogonal and portable, we should only generate 100 // different things based on the file contents themselves. 101 class Options final { 102 public: 103 enum class Language { UNSPECIFIED, JAVA, CPP, NDK, RUST, CPP_ANALYZER }; 104 105 enum class Task { HELP, COMPILE, PREPROCESS, DUMP_API, CHECK_API, DUMP_MAPPINGS }; 106 107 enum class CheckApiLevel { COMPATIBLE, EQUAL }; 108 109 enum class Stability { UNSPECIFIED, VINTF }; 110 bool StabilityFromString(const std::string& stability, Stability* out_stability); 111 112 Options(int argc, const char* const argv[], Language default_lang = Language::UNSPECIFIED); 113 114 Options PlusImportDir(const std::string& import_dir) const; 115 AsPreviousVersion()116 Options AsPreviousVersion() const { 117 Options copy(*this); 118 copy.as_previous_version_ = true; 119 return copy; 120 } 121 WithoutVersion()122 Options WithoutVersion() const { 123 Options copy(*this); 124 copy.version_ = 0; 125 copy.hash_ = ""; 126 return copy; 127 } 128 WithNoWarnings()129 Options WithNoWarnings() const { 130 Options copy(*this); 131 copy.warning_options_ = WarningOptions(); 132 return copy; 133 } 134 135 static Options From(const string& cmdline); 136 137 static Options From(const vector<string>& args); 138 139 // to print in output files RawArgs()140 std::string RawArgs() const { return raw_args_; } 141 142 // Contain no references to unstructured data types (such as a parcelable that is 143 // implemented in Java). These interfaces aren't inherently stable but they have the 144 // capacity to be stabilized. IsStructured()145 bool IsStructured() const { return structured_; } 146 GetStability()147 Stability GetStability() const { return stability_; } 148 GetMinSdkVersion()149 uint32_t GetMinSdkVersion() const { return min_sdk_version_; } 150 TargetLanguage()151 Language TargetLanguage() const { return language_; } IsCppOutput()152 bool IsCppOutput() const { 153 return language_ == Language::CPP || language_ == Language::NDK || 154 language_ == Language::CPP_ANALYZER; 155 } 156 GetTask()157 Task GetTask() const { return task_; } 158 GetCheckApiLevel()159 CheckApiLevel GetCheckApiLevel() const { return check_api_level_; } 160 ImportDirs()161 const set<string>& ImportDirs() const { 162 if (as_previous_version_) { 163 return previous_import_dirs_; 164 } else { 165 return import_dirs_; 166 } 167 } 168 PreprocessedFiles()169 const vector<string>& PreprocessedFiles() const { return preprocessed_files_; } 170 DependencyFile()171 string DependencyFile() const { 172 return dependency_file_; 173 } 174 AutoDepFile()175 bool AutoDepFile() const { return auto_dep_file_; } 176 GenRpc()177 bool GenRpc() const { return gen_rpc_; } 178 GenTraces()179 bool GenTraces() const { return gen_traces_; } 180 GenTransactionNames()181 bool GenTransactionNames() const { return gen_transaction_names_; } 182 GenMockall()183 bool GenMockall() const { return gen_mockall_; } 184 DependencyFileNinja()185 bool DependencyFileNinja() const { return dependency_file_ninja_; } 186 PreviousApiDir()187 const string& PreviousApiDir() const { return previous_api_dir_; } 188 InputFiles()189 const vector<string>& InputFiles() const { return input_files_; } 190 191 // Path to the output file. This is used only when there is only one 192 // output file for the invocation. When there are multiple outputs 193 // (e.g. compile multiple AIDL files), output files are created under 194 // OutputDir(). OutputFile()195 const string& OutputFile() const { return output_file_; } 196 197 // Path to the directory where output file(s) will be generated under. OutputDir()198 const string& OutputDir() const { return output_dir_; } 199 200 // Path to the directory where header file(s) will be generated under. 201 // Only used when TargetLanguage() == Language::CPP OutputHeaderDir()202 const string& OutputHeaderDir() const { return output_header_dir_; } 203 FailOnParcelable()204 bool FailOnParcelable() const { return fail_on_parcelable_; } 205 Version()206 int Version() const { return version_; } 207 PreviousVersion()208 int PreviousVersion() const { 209 AIDL_FATAL_IF(version_ <= 1, "This should only be called on versions greater than 1"); 210 return version_ - 1; 211 } 212 IsLatestUnfrozenVersion()213 bool IsLatestUnfrozenVersion() const { return !PreviousApiDir().empty(); } 214 Hash()215 string Hash() const { return hash_; } 216 PreviousHash()217 string PreviousHash() const { return previous_hash_; } 218 GenLog()219 bool GenLog() const { return gen_log_; } 220 DumpNoLicense()221 bool DumpNoLicense() const { return dump_no_license_; } 222 Ok()223 bool Ok() const { return error_message_.stream_.str().empty(); } 224 GetErrorMessage()225 string GetErrorMessage() const { return error_message_.stream_.str(); } 226 227 string GetUsage() const; 228 GenApiMapping()229 bool GenApiMapping() const { return task_ == Task::DUMP_MAPPINGS; } 230 GetDiagnosticMapping()231 DiagnosticMapping GetDiagnosticMapping() const { return warning_options_.GetDiagnosticMapping(); } 232 233 // The following are for testability, but cannot be influenced on the command line. 234 // Threshold of interface methods to enable outlining of onTransact cases. 235 size_t onTransact_outline_threshold_{275u}; 236 // Number of cases to _not_ outline, if outlining is enabled. 237 size_t onTransact_non_outline_count_{275u}; 238 239 private: 240 Options() = default; 241 242 const string myname_; 243 std::string raw_args_; 244 Language language_ = Language::UNSPECIFIED; 245 Task task_ = Task::COMPILE; 246 CheckApiLevel check_api_level_ = CheckApiLevel::COMPATIBLE; 247 set<string> import_dirs_; 248 set<string> previous_import_dirs_; 249 bool as_previous_version_ = false; 250 vector<string> preprocessed_files_; 251 string dependency_file_; 252 bool gen_rpc_ = false; 253 bool gen_traces_ = false; 254 bool gen_transaction_names_ = false; 255 bool gen_mockall_ = false; 256 bool dependency_file_ninja_ = false; 257 string previous_api_dir_; 258 bool structured_ = false; 259 Stability stability_ = Stability::UNSPECIFIED; 260 uint32_t min_sdk_version_ = 0; // invalid version 261 string output_dir_; 262 string output_header_dir_; 263 bool fail_on_parcelable_ = false; 264 bool auto_dep_file_ = false; 265 vector<string> input_files_; 266 string output_file_; 267 int version_ = 0; 268 string hash_ = ""; 269 string previous_hash_ = ""; 270 bool gen_log_ = false; 271 bool dump_no_license_ = false; 272 ErrorMessage error_message_; 273 WarningOptions warning_options_; 274 }; 275 276 std::string to_string(Options::Language language); 277 android::base::Result<uint32_t> MinSdkVersionFromString(const std::string& str); 278 279 } // namespace aidl 280 } // namespace android 281