command_line.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_COMMON_COMMAND_LINE_H_
  5. #define CARBON_COMMON_COMMAND_LINE_H_
  6. #include <memory>
  7. #include <utility>
  8. #include "common/check.h"
  9. #include "common/ostream.h"
  10. #include "llvm/ADT/ArrayRef.h"
  11. #include "llvm/ADT/DenseSet.h"
  12. #include "llvm/ADT/Sequence.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/ADT/StringExtras.h"
  15. #include "llvm/ADT/StringRef.h"
  16. // # Command-line argument parsing library.
  17. //
  18. // This is a collection of tools to describe both simple and reasonably complex
  19. // command line interfaces, and parse arguments based on those descriptions. It
  20. // optimizes for command line tools that will parse arguments exactly once per
  21. // execution, and specifically tools that make heavy use of subcommand-style
  22. // command line interfaces.
  23. //
  24. // ## Terminology used by this library
  25. //
  26. // _Argument_ or _arg_: One of the parsed components of the command line.
  27. //
  28. // _Option_: A _named_ argument starting with `--` to configure some aspect of
  29. // the tool. These often have both long spellings that start with `--` and
  30. // short, single character spellings that start with `-` and can be bundled with
  31. // other single character options.
  32. //
  33. // _Flag_: A boolean or binary option. These can only be enabled or disabled.
  34. //
  35. // _Positional argument_: An argument that is not named but is identified based
  36. // on the order in which it is encountered in the command line, with options
  37. // removed. Only a leaf command can contain positional arguments.
  38. //
  39. // _Value_: The value parameter provided to an argument. For options, this is
  40. // provided after an `=` and the option name. For positional arguments, the
  41. // value is the only thing provided. The string of the value is parsed according
  42. // to the kind of argument with fairly simple rules. See the argument builders
  43. // for more details.
  44. //
  45. // _Command_: The container of options, subcommands, and positional arguments to
  46. // parse and an action to take when successful.
  47. //
  48. // _Leaf command_: A command that doesn't contain subcommands. This is the only
  49. // kind of command that can contain positional arguments.
  50. //
  51. // _Subcommand_: A command nested within another command and identified by a
  52. // specific name that ends the parsing of arguments based on the parent and
  53. // switches to parse based on the specific subcommand's options and positional
  54. // arguments. A command with subcommands cannot parse positional arguments.
  55. //
  56. // _Action_: An open-ended callback, typically reflecting a specific subcommand
  57. // being parsed. Can either directly perform the operation or simply mark which
  58. // operation was selected.
  59. //
  60. // _Meta action_: An action fully handled by argument parsing such as displaying
  61. // help, version information, or completion.
  62. //
  63. // Example command to illustrate the different components:
  64. //
  65. // git --no-pager clone --shared --filter=blob:none my-repo my-directory
  66. //
  67. // This command breaks down as:
  68. // - `git`: The top-level command.
  69. // - `--no-pager`: A negated flag on the top-level command (`git`).
  70. // - `clone`: A subcommand.
  71. // - `--shared`: A positive flag for the subcommand (`clone`).
  72. // - `--filter=blob:none`: An option named `filter` with a value `blob:none`.
  73. // - `my-repo`: The first positional argument to the subcommand.
  74. // - `my-directory`: the second positional argument to the subcommand.
  75. //
  76. // **Note:** while the example uses a `git` command to be relatively familiar
  77. // and well documented, this library does not support the same flag syntaxes as
  78. // `git` or use anything similar for its subcommand dispatch. This example is
  79. // just to help clarify the terminology used, and carefully chosen to only use a
  80. // syntax that overlaps with this library's parsed syntax.
  81. //
  82. // ## Options and flags
  83. //
  84. // The option syntax and behavior supported by this library is designed to be
  85. // strict and relatively simple while still supporting a wide range of expected
  86. // use cases:
  87. //
  88. // - All options must have a unique long name that is accessed with a `--`
  89. // prefix. The name must consist of characters in the set [-a-zA-Z0-9], and it
  90. // must not start with a `-` or `no-`.
  91. //
  92. // - Values are always attached using an `=` after the name. Only a few simple
  93. // value formats are supported:
  94. // - Arbitrary strings
  95. // - Integers as parsed by `llvm::StringRef` and whose value fits in an
  96. // `int`.
  97. // - One of a fixed set of strings
  98. //
  99. // - Options may be parsed multiple times, and the behavior can be configured:
  100. // - Each time, they can set a new value, overwriting any previous.
  101. // - They can append the value to a container.
  102. // - TODO: They can increment a count.
  103. //
  104. // - Options may have a default value that will be synthesized even if they do
  105. // not occur in the parsed command line.
  106. //
  107. // - Flags (boolean options) have some special rules.
  108. // - They may be spelled normally, and default to setting that flag to `true`.
  109. // - They may also accept a value of either exactly `true` or `false` and that
  110. // is the value.
  111. // - They may be spelled with a `no-` prefix, such as `--no-verbose`, and that
  112. // is exactly equivalent to `--verbose=false`.
  113. // - For flags with a default `true` value, they are rendered in help using
  114. // the `no-` prefix.
  115. //
  116. // - Options may additionally have a short name of a single character [a-zA-Z].
  117. // - There is no distinction between the behavior of long and short names.
  118. // - The short name can only specify the positive or `true` value for flags.
  119. // There is no negative form of short names.
  120. // - Short names are parsed after a single `-`, such as `-v`.
  121. // - Any number of short names for boolean flags or options with default
  122. // values may be grouped after `-`, such as `-xyz`: this is three options,
  123. // `x`, `y`, and `z`.
  124. // - Short options may include a value after an `=`, but not when grouped with
  125. // other short options.
  126. //
  127. // - Options are parsed from any argument until either a subcommand switches to
  128. // that subcommand's options or a `--` argument ends all option parsing to
  129. // allow arguments that would be ambiguous with the option syntax.
  130. //
  131. // ## Subcommands
  132. //
  133. // Subcommands can be nested to any depth, and each subcommand gets its own
  134. // option space.
  135. //
  136. // ## Positional arguments
  137. //
  138. // Leaf commands (and subcommands) can accept positional arguments. These work
  139. // similar to options but consist *only* of the value. They have names, but the
  140. // name is only used in documentation and error messages. Except for the special
  141. // case of the exact argument `-`, positional argument values cannot start with
  142. // a `-` character until after option parsing is ended with a `--` argument.
  143. //
  144. // Singular positional arguments store the single value in that position.
  145. // Appending positional arguments append all of the values in sequence.
  146. //
  147. // Multiple positional arguments to a single command are parsed in sequence. For
  148. // appending positional arguments, the sequence of values appended is ended with
  149. // a `--` argument. For example, a command that takes two sequences of
  150. // positional arguments might look like:
  151. //
  152. // my-diff-tool a.txt b.txt c.txt -- new-a.txt new-b.txt new-c.txt
  153. //
  154. // The `--` used in this way *both* ends option parsing and the positional
  155. // argument sequence. Note that if there are no positional arguments prior to
  156. // the first `--`, then it will just end option parsing. To pass an empty
  157. // sequence of positional arguments two `--` arguments would be required. Once
  158. // option parsing is ended, even a single positional argument can be skipped
  159. // using a `--` argument without a positional argument.
  160. //
  161. // ## Help text blocks and rendering
  162. //
  163. // At many points in this library, a block of text is specified as a string.
  164. // These should be written using multi-line raw string literals that start on
  165. // their own line such as:
  166. //
  167. // ```cpp
  168. // ...
  169. // .help = R"""(
  170. // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
  171. // tempor incididunt ut labore et dolore magna aliqua.
  172. // )""",
  173. // ```
  174. //
  175. // The code using these blocks will remove leading and trailing newlines. TODO:
  176. // It should also reflow all of the text in a way that tries to be roughly
  177. // similar to how Markdown would be reflowed when rendered:
  178. //
  179. // - Blank lines will be preserved.
  180. // - (TODO) A best effort to detect lists and other common Markdown constructs
  181. // and preserve the newlines between those.
  182. // - (TODO) Fenced regions will be preserved exactly.
  183. //
  184. // The remaining blocks will have all newlines removed when there is no column
  185. // width information on the output stream, or will be re-flowed to the output
  186. // stream's column width when available.
  187. //
  188. // ## The `Args` class
  189. //
  190. // The `Args` class is not a meaningful type, it serves two purposes: to give a
  191. // structured name prefix to the inner types, and to allow marking many
  192. // components `private` and using `friend` to grant access to implementation
  193. // details.
  194. //
  195. // ## Roadmap / TODOs / planned future work
  196. //
  197. // - Detect column width when the stream is a terminal and re-flow text.
  198. // - Implement short help display mode (and enable that by default).
  199. // - Add help text to one-of values and render it when present.
  200. // - Add formatting when the stream supports it (colors, bold, etc).
  201. // - Improve error messages when parsing fails.
  202. // - Reliably display the most appropriate usage string.
  203. // - Suggest typo corrections?
  204. // - Print snippet or otherwise render the failure better?
  205. // - Add support for responding to shell autocomplete queries.
  206. // - Finish adding support for setting and printing version information.
  207. // - Add short option counting support (`-vvv` -> `--verbose=3`).
  208. //
  209. namespace Carbon::CommandLine {
  210. // Forward declare some implementation detail classes and classes that are
  211. // friended.
  212. struct Arg;
  213. struct Command;
  214. class MetaPrinter;
  215. class Parser;
  216. class CommandBuilder;
  217. // The result of parsing arguments can be a parse error, a successfully parsed
  218. // command line, or a meta-success due to triggering a meta-action during the
  219. // parse such as rendering help text.
  220. enum class ParseResult : int8_t {
  221. // Signifies an error parsing arguments. It will have been diagnosed using
  222. // the streams provided to the parser, and no useful parsed arguments are
  223. // available.
  224. Error,
  225. // Signifies that program arguments were successfully parsed and can be
  226. // used.
  227. Success,
  228. // Signifies a successful meta operation such as displaying help text
  229. // was performed. No parsed arguments are available, and the side-effects
  230. // have been directly provided via the streams provided to the parser.
  231. MetaSuccess,
  232. };
  233. auto operator<<(llvm::raw_ostream& output, ParseResult result)
  234. -> llvm::raw_ostream&;
  235. // Actions are stored in data structures so we use an owning closure to model
  236. // them.
  237. using ActionT = std::function<void()>;
  238. // The core argument info used to render help and other descriptive
  239. // information. This is used for both options and positional arguments.
  240. // Commands use an extended version below.
  241. struct ArgInfo {
  242. // The name of the argument. For options, this is the long name parsed after
  243. // `--`. Option names must also be unique. Conventionally, these are spelled
  244. // in lower case with a single dash separating words as that tends to be
  245. // especially easy to type and reasonably easy to read.
  246. //
  247. // For positional arguments this is only used for help text, and is often
  248. // spelled with `ALL-CAPS` to make it clear that it is a placeholder name
  249. // and does not appear in the actual command line.
  250. llvm::StringRef name;
  251. // Optional short name for options. This must consist of a single character
  252. // in the set [a-zA-Z].
  253. llvm::StringRef short_name = "";
  254. // For options, it is sometimes useful to render a distinct value
  255. // placeholder name to help clarify what the value should contain. These are
  256. // often in `ALL-CAPS` to make it clear they are placeholders. For example,
  257. // an `output` option might set this to `FILE` so it renders as
  258. // `--output=FILE`.
  259. llvm::StringRef value_name = "";
  260. // A long-form help string that will be rendered for this argument in
  261. // command help strings. It supports multiple lines and is rendered as a
  262. // text block described in the `Args` top-level comment.
  263. llvm::StringRef help = "";
  264. // A short help string for the argument. This should be as short as
  265. // possible, and always fit easily on a single line. Ideally, it can fit in
  266. // a narrow column of a single line and is in the range of 40 columns wide.
  267. //
  268. // If not provided, the first paragraph (up to a blank line) from `help`
  269. // will be used.
  270. llvm::StringRef help_short = "";
  271. };
  272. // The kinds of arguments that can be parsed.
  273. enum class ArgKind : int8_t {
  274. Invalid,
  275. Flag,
  276. Integer,
  277. String,
  278. OneOf,
  279. MetaActionOnly,
  280. };
  281. auto operator<<(llvm::raw_ostream& output, ArgKind kind) -> llvm::raw_ostream&;
  282. // A builder used to configure an argument for parsing.
  283. class ArgBuilder {
  284. public:
  285. // When marked as required, if an argument is not provided explicitly in the
  286. // command line the parse will produce an error.
  287. void Required(bool is_required);
  288. // An argument can be hidden from the help output.
  289. void HelpHidden(bool is_help_hidden);
  290. // Sets a meta-action to run when this argument is parsed. This is used to
  291. // set up arguments like `--help` or `--version` that can be entirely
  292. // handled during parsing and rather than produce parsed information about
  293. // the command line, override that for some custom behavior.
  294. template <typename T>
  295. void MetaAction(T action);
  296. protected:
  297. friend CommandBuilder;
  298. explicit ArgBuilder(Arg& arg);
  299. Arg& arg_;
  300. };
  301. // Customized argument builder when the value is a boolean flag.
  302. class FlagBuilder : public ArgBuilder {
  303. public:
  304. // Flags can be defaulted to true. However, flags always have *some*
  305. // default, this merely customizes which value is default. If uncustomized,
  306. // the default of a flag is false.
  307. void Default(bool flag_value);
  308. // Configures the argument to store a parsed value in the provided storage.
  309. //
  310. // This must be called on the builder.
  311. void Set(bool* flag);
  312. private:
  313. using ArgBuilder::ArgBuilder;
  314. };
  315. // Customized argument builder when the value is an integer.
  316. class IntegerArgBuilder : public ArgBuilder {
  317. public:
  318. // Sets a default for the argument with the provided value. There is no
  319. // default for integer arguments unless this is called.
  320. //
  321. // For arguments that are `Set` below, this value will be stored even if the
  322. // argument is never explicitly provided. For arguments that are `Append`ed
  323. // below, this value will be used whenever the argument occurs without an
  324. // explicit value, but unless the argument is parsed nothing will be
  325. // appended.
  326. void Default(int integer_value);
  327. // Configures the argument to store a parsed value in the provided storage.
  328. // Each time the argument is parsed, it will write a new value to this
  329. // storage.
  330. //
  331. // Exactly one of this method or `Append` below must be configured for the
  332. // argument.
  333. void Set(int* integer);
  334. // Configures the argument to append a parsed value to the provided
  335. // container. Each time the argument is parsed, a new value will be
  336. // appended.
  337. //
  338. // Exactly one of this method or `Set` above must be configured for the
  339. // argument.
  340. void Append(llvm::SmallVectorImpl<int>* sequence);
  341. private:
  342. using ArgBuilder::ArgBuilder;
  343. };
  344. // Customized argument builder when the value is a string.
  345. class StringArgBuilder : public ArgBuilder {
  346. public:
  347. // Sets a default for the argument with the provided value. There is no
  348. // default for string arguments unless this is called.
  349. //
  350. // For arguments that are `Set` below, this value will be stored even if the
  351. // argument is never explicitly provided. For arguments that are `Append`ed
  352. // below, this value will be used whenever the argument occurs without an
  353. // explicit value, but unless the argument is parsed nothing will be
  354. // appended.
  355. void Default(llvm::StringRef string_value);
  356. // Configures the argument to store a parsed value in the provided storage.
  357. // Each time the argument is parsed, it will write a new value to this
  358. // storage.
  359. //
  360. // Exactly one of this method or `Append` below must be configured for the
  361. // argument.
  362. void Set(llvm::StringRef* string);
  363. // Configures the argument to append a parsed value to the provided
  364. // container. Each time the argument is parsed, a new value will be
  365. // appended.
  366. //
  367. // Exactly one of this method or `Set` above must be configured for the
  368. // argument.
  369. void Append(llvm::SmallVectorImpl<llvm::StringRef>* sequence);
  370. private:
  371. using ArgBuilder::ArgBuilder;
  372. };
  373. // Customized argument builder when the value is required to be one of a fixed
  374. // set of possible strings, and each one maps to a specific value of some
  375. // type, often an enumerator.
  376. class OneOfArgBuilder : public ArgBuilder {
  377. public:
  378. // A tiny helper / builder type for describing one of the possible values
  379. // that a particular argument accepts.
  380. //
  381. // Beyond carrying the string, type, and value for this candidate, it also
  382. // allows marking the candidate as the default.
  383. template <typename T>
  384. class OneOfValueT {
  385. public:
  386. // Configure whether a candidate is the default. If not called, it is not
  387. // the default. This can only be used when setting, not when appending.
  388. auto Default(bool is_default) && -> OneOfValueT;
  389. private:
  390. friend OneOfArgBuilder;
  391. explicit OneOfValueT(llvm::StringRef str, T value);
  392. llvm::StringRef str;
  393. T value;
  394. bool is_default = false;
  395. };
  396. // A helper function to create an object that models one of the candidate
  397. // values for this argument. It takes the string used to select this value
  398. // on the command line, deduces the type of the value, and accepts the value
  399. // itself that should be used when this candidate is parsed.
  400. template <typename T>
  401. static auto OneOfValue(llvm::StringRef string, T value) -> OneOfValueT<T>;
  402. // Configures the argument to store a parsed value in the provided storage.
  403. // Each time the argument is parsed, it will write a new value to this
  404. // storage.
  405. //
  406. // Exactly one of this method or `AppendOneOf` below must be configured for
  407. // the argument.
  408. //
  409. // For one-of arguments, this method also provides an array of possible
  410. // values that may be used:
  411. //
  412. // ```cpp
  413. // arg_b.SetOneOf(
  414. // {
  415. // arg_b.OneOfValue("x", 1),
  416. // arg_b.OneOfValue("y", 2),
  417. // arg_b.OneOfValue("z", 3).Default(true),
  418. // },
  419. // &value);
  420. // ```
  421. //
  422. // The only value strings that will be parsed are those described in the
  423. // array, and the value stored in the storage for a particular parsed value
  424. // string is the one associated with it. There must be a single homogeneous
  425. // type for the all of the candidate values and that type must be storable
  426. // into the result storage pointee type. At most one of the array can also
  427. // be marked as a default value, which will make specifying a value
  428. // optional, and also will cause that value to be stored into the result
  429. // even if the argument is not parsed explicitly.
  430. template <typename T, typename U, size_t N>
  431. void SetOneOf(const OneOfValueT<U> (&values)[N], T* result);
  432. // Configures the argument to append a parsed value to the provided
  433. // container. Each time the argument is parsed, a new value will be
  434. // appended.
  435. //
  436. // Exactly one of this method or `SetOneOf` above must be configured for the
  437. // argument.
  438. //
  439. // Similar to `SetOneOf`, this must also describe the candidate value
  440. // strings that can be parsed and the consequent values that are used for
  441. // those strings:
  442. //
  443. // ```cpp
  444. // arg_b.AppendOneOf(
  445. // {
  446. // arg_b.OneOfValue("x", 1),
  447. // arg_b.OneOfValue("y", 2),
  448. // arg_b.OneOfValue("z", 3),
  449. // },
  450. // &values);
  451. // ```
  452. //
  453. // Instead of storing, these values are appended.
  454. //
  455. // However, appending one-of arguments cannot use a default. The values must
  456. // always be explicitly parsed.
  457. template <typename T, typename U, size_t N>
  458. void AppendOneOf(const OneOfValueT<U> (&values)[N],
  459. llvm::SmallVectorImpl<T>* sequence);
  460. private:
  461. using ArgBuilder::ArgBuilder;
  462. template <typename U, size_t N, typename MatchT, size_t... Indices>
  463. void OneOfImpl(const OneOfValueT<U> (&input_values)[N], MatchT match,
  464. std::index_sequence<Indices...> /*indices*/);
  465. };
  466. // The extended info for a command, including for a subcommand.
  467. //
  468. // This provides the primary descriptive information for commands used by help
  469. // and other diagnostic messages. For subcommands, it also provides the name
  470. // used to access the subcommand.
  471. struct CommandInfo {
  472. // The name of the command. For subcommands, this is also the argument
  473. // spelling that accesses this subcommand. It must consist of characters in
  474. // the set [-a-zA-Z0-9], and must not start with a `-`.
  475. llvm::StringRef name;
  476. // An optional version string that will be rendered as part of version meta
  477. // action by the library. While this library does not impose a machine
  478. // parsable structure, users will expect this to be extractable and parsable
  479. // in practice.
  480. //
  481. // Subcommands with an empty version will inherit the first non-empty parent
  482. // version.
  483. //
  484. // Whether a (possibly inherited) version string is non-empty determines
  485. // whether this library provides the version-printing meta actions via a
  486. // `--version` flag or, if there are subcommands, a `version` subcommand.
  487. llvm::StringRef version = "";
  488. // Optional build information to include when printing the version.
  489. llvm::StringRef build_info = "";
  490. // An optional long-form help string for the command.
  491. //
  492. // When accessing a command's dedicated help output, this will form the main
  493. // prose output at the beginning of the help message. When listing
  494. // subcommands, the subcommand's `help` string will be used to describe it
  495. // in the list.
  496. //
  497. // The help meta actions are available regardless of whether this is
  498. // provided in order to mechanically describe other aspects of the command.
  499. //
  500. // This field supports multiple lines and uses the text block handling
  501. // described in the top-level `Args` comment.
  502. llvm::StringRef help = "";
  503. // An optional short help string for the command.
  504. //
  505. // This should be very short, at most one line and ideally fitting within a
  506. // narrow column of a line. If left blank, the first paragraph of text (up
  507. // to the first blank line) in the `help` string will be used.
  508. llvm::StringRef help_short = "";
  509. // An optional custom block of text to describe the usage of the command.
  510. //
  511. // The usage should just be a series of lines with possible invocations of
  512. // the command summarized as briefly as possible. Ideally, each variation on
  513. // a single line. The goal is to show the *structure* of different command
  514. // invocations, not to be comprehensive.
  515. //
  516. // When omitted, the library will generate these based on the parsing logic.
  517. // The generated usage is expected to be suitable for the vast majority of
  518. // users, but can be customized in cases where necessary.
  519. llvm::StringRef usage = "";
  520. // An optional epilogue multi-line block of text appended to the help display
  521. // for this command. It is only used for this command's dedicated help, but
  522. // can contain extra, custom guidance that is especially useful to have at
  523. // the very end of the output.
  524. llvm::StringRef help_epilogue = "";
  525. };
  526. // Commands are classified based on the action they result in when run.
  527. //
  528. // Commands that require a subcommand have no action and are just a means to
  529. // reach the subcommand actions.
  530. //
  531. // Commands with _meta_ actions are also a separate kind from those with
  532. // normal actions.
  533. enum class CommandKind : int8_t {
  534. Invalid,
  535. RequiresSubcommand,
  536. Action,
  537. MetaAction,
  538. };
  539. auto operator<<(llvm::raw_ostream& output, CommandKind kind)
  540. -> llvm::raw_ostream&;
  541. // Builder used to configure a command to parse.
  542. //
  543. // An instance of this is used to configure the top-level command, and a fresh
  544. // instance is provided for configuring each subcommand as well.
  545. class CommandBuilder {
  546. public:
  547. using Kind = CommandKind;
  548. void AddFlag(const ArgInfo& info,
  549. llvm::function_ref<void(FlagBuilder&)> build);
  550. void AddIntegerOption(const ArgInfo& info,
  551. llvm::function_ref<void(IntegerArgBuilder&)> build);
  552. void AddStringOption(const ArgInfo& info,
  553. llvm::function_ref<void(StringArgBuilder&)> build);
  554. void AddOneOfOption(const ArgInfo& info,
  555. llvm::function_ref<void(OneOfArgBuilder&)> build);
  556. void AddMetaActionOption(const ArgInfo& info,
  557. llvm::function_ref<void(ArgBuilder&)> build);
  558. void AddIntegerPositionalArg(
  559. const ArgInfo& info, llvm::function_ref<void(IntegerArgBuilder&)> build);
  560. void AddStringPositionalArg(
  561. const ArgInfo& info, llvm::function_ref<void(StringArgBuilder&)> build);
  562. void AddOneOfPositionalArg(const ArgInfo& info,
  563. llvm::function_ref<void(OneOfArgBuilder&)> build);
  564. void AddSubcommand(const CommandInfo& info,
  565. llvm::function_ref<void(CommandBuilder&)> build);
  566. // Subcommands can be hidden from the help listing of their parents with
  567. // this setting. Hiding a subcommand doesn't disable its own help, it just
  568. // removes it from the listing.
  569. void HelpHidden(bool is_help_hidden);
  570. // Exactly one of these three should be called to select and configure the
  571. // kind of the built command.
  572. void RequiresSubcommand();
  573. void Do(ActionT action);
  574. void Meta(ActionT meta_action);
  575. private:
  576. friend Parser;
  577. explicit CommandBuilder(Command& command, MetaPrinter& meta_printer);
  578. auto AddArgImpl(const ArgInfo& info, ArgKind kind) -> Arg&;
  579. void AddPositionalArgImpl(const ArgInfo& info, ArgKind kind,
  580. llvm::function_ref<void(Arg&)> build);
  581. void Finalize();
  582. Command& command_;
  583. MetaPrinter& meta_printer_;
  584. llvm::SmallDenseSet<llvm::StringRef> arg_names_;
  585. llvm::SmallDenseSet<llvm::StringRef> subcommand_names_;
  586. };
  587. // Builds a description of a command and then parses the provided arguments
  588. // for that command.
  589. //
  590. // This is the main entry point to both build up the description of the
  591. // command whose arguments are being parsed and to do the parsing. Everything
  592. // is done in a single invocation as the common case is to build a command
  593. // description, parse the arguments once, and then run with that
  594. // configuration.
  595. //
  596. // The `out` stream is treated like `stdout` would be for a Unix-style command
  597. // line tool, and `errors` like `stderr`: any errors or diagnostic information
  598. // are printed to `errors`, but meta-actions like printing a command's help go
  599. // to `out`.
  600. auto Parse(llvm::ArrayRef<llvm::StringRef> unparsed_args,
  601. llvm::raw_ostream& out, llvm::raw_ostream& errors,
  602. const CommandInfo& command_info,
  603. llvm::function_ref<void(CommandBuilder&)> build) -> ParseResult;
  604. // Implementation details only below.
  605. // The internal representation of a parsable argument description.
  606. struct Arg {
  607. using Kind = ArgKind;
  608. using ValueActionT =
  609. std::function<bool(const Arg& arg, llvm::StringRef value_string)>;
  610. using DefaultActionT = std::function<void(const Arg& arg)>;
  611. explicit Arg(const ArgInfo& info);
  612. ~Arg();
  613. ArgInfo info;
  614. Kind kind = Kind::Invalid;
  615. bool has_default = false;
  616. bool is_required = false;
  617. bool is_append = false;
  618. bool is_help_hidden = false;
  619. // Meta action storage, only populated if this argument causes a meta action.
  620. ActionT meta_action;
  621. // Storage options depending on the kind.
  622. union {
  623. // Singular argument storage pointers.
  624. bool* flag_storage;
  625. int* integer_storage;
  626. llvm::StringRef* string_storage;
  627. // Appending argument storage pointers.
  628. llvm::SmallVectorImpl<int>* integer_sequence;
  629. llvm::SmallVectorImpl<llvm::StringRef>* string_sequence;
  630. // One-of information.
  631. struct {
  632. llvm::OwningArrayRef<llvm::StringRef> value_strings;
  633. ValueActionT value_action;
  634. };
  635. };
  636. // Default values depending on the kind.
  637. union {
  638. bool default_flag;
  639. int default_integer;
  640. llvm::StringRef default_string;
  641. struct {
  642. DefaultActionT default_action;
  643. int default_value_index;
  644. };
  645. };
  646. };
  647. // The internal representation of a parsable command description, including its
  648. // options, positional arguments, and subcommands.
  649. struct Command {
  650. using Kind = CommandBuilder::Kind;
  651. explicit Command(const CommandInfo& info, Command* parent = nullptr);
  652. CommandInfo info;
  653. Command* parent;
  654. ActionT action;
  655. Kind kind = Kind::Invalid;
  656. bool is_help_hidden = false;
  657. llvm::SmallVector<std::unique_ptr<Arg>> options;
  658. llvm::SmallVector<std::unique_ptr<Arg>> positional_args;
  659. llvm::SmallVector<std::unique_ptr<Command>> subcommands;
  660. };
  661. template <typename T>
  662. void ArgBuilder::MetaAction(T action) {
  663. CARBON_CHECK(!arg_.meta_action, "Cannot set a meta action twice!");
  664. arg_.meta_action = std::move(action);
  665. }
  666. template <typename T>
  667. auto OneOfArgBuilder::OneOfValueT<T>::Default(
  668. bool is_default) && -> OneOfValueT {
  669. OneOfValueT result = std::move(*this);
  670. result.is_default = is_default;
  671. return result;
  672. }
  673. template <typename T>
  674. OneOfArgBuilder::OneOfValueT<T>::OneOfValueT(llvm::StringRef str, T value)
  675. : str(str), value(std::move(value)) {}
  676. template <typename T>
  677. auto OneOfArgBuilder::OneOfValue(llvm::StringRef str, T value)
  678. -> OneOfValueT<T> {
  679. return OneOfValueT<T>(str, value);
  680. }
  681. template <typename T, typename U, size_t N>
  682. void OneOfArgBuilder::SetOneOf(const OneOfValueT<U> (&values)[N], T* result) {
  683. static_assert(N > 0, "Must include at least one value.");
  684. arg_.is_append = false;
  685. OneOfImpl(
  686. values, [result](T value) { *result = value; },
  687. std::make_index_sequence<N>{});
  688. }
  689. template <typename T, typename U, size_t N>
  690. void OneOfArgBuilder::AppendOneOf(const OneOfValueT<U> (&values)[N],
  691. llvm::SmallVectorImpl<T>* sequence) {
  692. static_assert(N > 0, "Must include at least one value.");
  693. arg_.is_append = true;
  694. OneOfImpl(
  695. values, [sequence](T value) { sequence->push_back(value); },
  696. std::make_index_sequence<N>{});
  697. }
  698. // An implementation tool for the one-of value candidate handling. Delegating to
  699. // this allows us to deduce a pack of indices from the array of candidates, and
  700. // then use that variadic pack to operate on the array in the variadic space.
  701. // This includes packaging the components up separately into our storage
  702. // representation, as well as processing the array to find and register any
  703. // default.
  704. //
  705. // The representation is especially tricky because we want all of the actual
  706. // values and even the *type* of values to be erased. We do that by building
  707. // lambdas that do the type-aware operations and storing those into type-erased
  708. // function objects.
  709. template <typename U, size_t N, typename MatchT, size_t... Indices>
  710. void OneOfArgBuilder::OneOfImpl(const OneOfValueT<U> (&input_values)[N],
  711. MatchT match,
  712. std::index_sequence<Indices...> /*indices*/) {
  713. std::array<llvm::StringRef, N> value_strings = {input_values[Indices].str...};
  714. std::array<U, N> values = {input_values[Indices].value...};
  715. // Directly copy the value strings into a heap-allocated array in the
  716. // argument.
  717. new (&arg_.value_strings)
  718. llvm::OwningArrayRef<llvm::StringRef>(value_strings);
  719. // And build a type-erased action that maps a specific value string to a value
  720. // by index.
  721. new (&arg_.value_action) Arg::ValueActionT(
  722. [values, match](const Arg& arg, llvm::StringRef value_string) -> bool {
  723. for (int i : llvm::seq<int>(0, N)) {
  724. if (value_string == arg.value_strings[i]) {
  725. match(values[i]);
  726. return true;
  727. }
  728. }
  729. return false;
  730. });
  731. // Fold over all the input values to see if there is a default.
  732. if ((input_values[Indices].is_default || ...)) {
  733. CARBON_CHECK(!arg_.is_append, "Can't append default.");
  734. CARBON_CHECK((input_values[Indices].is_default + ... + 0) == 1,
  735. "Cannot default more than one value.");
  736. arg_.has_default = true;
  737. // First build a lambda that configures the default using an index. We'll
  738. // call this below, this lambda isn't the one that is stored.
  739. auto set_default = [&](size_t index, const auto& default_value) {
  740. // Now that we have the desired default index, build a lambda and store it
  741. // as the default action. This lambda is stored and so it captures the
  742. // necessary information explicitly and by value.
  743. new (&arg_.default_action)
  744. Arg::DefaultActionT([value = default_value.value,
  745. match](const Arg& /*arg*/) { match(value); });
  746. // Also store the index itself for use when printing help.
  747. arg_.default_value_index = index;
  748. };
  749. // Now we fold across the inputs and in the one case that is the default, we
  750. // call the lambda. This is just a somewhat awkward way to write a loop with
  751. // a condition in it over a pack.
  752. ((input_values[Indices].is_default
  753. ? set_default(Indices, input_values[Indices])
  754. : static_cast<void>(0)),
  755. ...);
  756. }
  757. }
  758. } // namespace Carbon::CommandLine
  759. #endif // CARBON_COMMON_COMMAND_LINE_H_