ArgParser::initOptionTable()
{
    std::map<std::string, OptionEntry>* t = &this->help_option_table;
    (*t)["help"] = oe_bare(&ArgParser::argHelp);
    (*t)["version"] = oe_bare(&ArgParser::argVersion);
    (*t)["copyright"] = oe_bare(&ArgParser::argCopyright);
    (*t)["completion-bash"] = oe_bare(&ArgParser::argCompletionBash);
    (*t)["completion-zsh"] = oe_bare(&ArgParser::argCompletionZsh);
    (*t)["json-help"] = oe_bare(&ArgParser::argJsonHelp);

    t = &this->main_option_table;
    char const* yn[] = {"y", "n", 0};
    (*t)[""] = oe_positional(&ArgParser::argPositional);
    (*t)["password"] = oe_requiredParameter(
        &ArgParser::argPassword, "password");
    (*t)["empty"] = oe_bare(&ArgParser::argEmpty);
    (*t)["linearize"] = oe_bare(&ArgParser::argLinearize);
    (*t)["encrypt"] = oe_bare(&ArgParser::argEncrypt);
    (*t)["decrypt"] = oe_bare(&ArgParser::argDecrypt);
    (*t)["password-is-hex-key"] = oe_bare(&ArgParser::argPasswordIsHexKey);
    (*t)["suppress-password-recovery"] =
        oe_bare(&ArgParser::argSuppressPasswordRecovery);
    char const* password_mode_choices[] =
        {"bytes", "hex-bytes", "unicode", "auto", 0};
    (*t)["password-mode"] = oe_requiredChoices(
        &ArgParser::argPasswordMode, password_mode_choices);
    (*t)["copy-encryption"] = oe_requiredParameter(
        &ArgParser::argCopyEncryption, "file");
    (*t)["encryption-file-password"] = oe_requiredParameter(
        &ArgParser::argEncryptionFilePassword, "password");
    (*t)["pages"] = oe_bare(&ArgParser::argPages);
    (*t)["rotate"] = oe_requiredParameter(
        &ArgParser::argRotate, "[+|-]angle:page-range");
    char const* stream_data_choices[] =
        {"compress", "preserve", "uncompress", 0};
    (*t)["collate"] = oe_bare(&ArgParser::argCollate);
    (*t)["stream-data"] = oe_requiredChoices(
        &ArgParser::argStreamData, stream_data_choices);
    (*t)["compress-streams"] = oe_requiredChoices(
        &ArgParser::argCompressStreams, yn);
    char const* decode_level_choices[] =
        {"none", "generalized", "specialized", "all", 0};
    (*t)["decode-level"] = oe_requiredChoices(
        &ArgParser::argDecodeLevel, decode_level_choices);
    (*t)["normalize-content"] = oe_requiredChoices(
        &ArgParser::argNormalizeContent, yn);
    (*t)["suppress-recovery"] = oe_bare(&ArgParser::argSuppressRecovery);
    char const* object_streams_choices[] = {
        "disable", "preserve", "generate", 0};
    (*t)["object-streams"] = oe_requiredChoices(
        &ArgParser::argObjectStreams, object_streams_choices);
    (*t)["ignore-xref-streams"] = oe_bare(&ArgParser::argIgnoreXrefStreams);
    (*t)["qdf"] = oe_bare(&ArgParser::argQdf);
    (*t)["preserve-unreferenced"] = oe_bare(
        &ArgParser::argPreserveUnreferenced);
    (*t)["preserve-unreferenced-resources"] = oe_bare(
        &ArgParser::argPreserveUnreferencedResources);
    (*t)["keep-files-open"] = oe_requiredChoices(
        &ArgParser::argKeepFilesOpen, yn);
    (*t)["keep-files-open-threshold"] = oe_requiredParameter(
        &ArgParser::argKeepFilesOpenThreshold, "count");
    (*t)["newline-before-endstream"] = oe_bare(
        &ArgParser::argNewlineBeforeEndstream);
    (*t)["linearize-pass1"] = oe_requiredParameter(
        &ArgParser::argLinearizePass1, "filename");
    (*t)["coalesce-contents"] = oe_bare(&ArgParser::argCoalesceContents);
    char const* flatten_choices[] = {"all", "print", "screen", 0};
    (*t)["flatten-annotations"] = oe_requiredChoices(
        &ArgParser::argFlattenAnnotations, flatten_choices);
    (*t)["generate-appearances"] =
        oe_bare(&ArgParser::argGenerateAppearances);
    (*t)["min-version"] = oe_requiredParameter(
        &ArgParser::argMinVersion, "version");
    (*t)["force-version"] = oe_requiredParameter(
        &ArgParser::argForceVersion, "version");
    (*t)["split-pages"] = oe_optionalParameter(&ArgParser::argSplitPages);
    (*t)["verbose"] = oe_bare(&ArgParser::argVerbose);
    (*t)["progress"] = oe_bare(&ArgParser::argProgress);
    (*t)["no-warn"] = oe_bare(&ArgParser::argNoWarn);
    (*t)["deterministic-id"] = oe_bare(&ArgParser::argDeterministicId);
    (*t)["static-id"] = oe_bare(&ArgParser::argStaticId);
    (*t)["static-aes-iv"] = oe_bare(&ArgParser::argStaticAesIv);
    (*t)["no-original-object-ids"] = oe_bare(
        &ArgParser::argNoOriginalObjectIds);
    (*t)["show-encryption"] = oe_bare(&ArgParser::argShowEncryption);
    (*t)["show-encryption-key"] = oe_bare(&ArgParser::argShowEncryptionKey);
    (*t)["check-linearization"] = oe_bare(&ArgParser::argCheckLinearization);
    (*t)["show-linearization"] = oe_bare(&ArgParser::argShowLinearization);
    (*t)["show-xref"] = oe_bare(&ArgParser::argShowXref);
    (*t)["show-object"] = oe_requiredParameter(
        &ArgParser::argShowObject, "trailer|obj[,gen]");
    (*t)["raw-stream-data"] = oe_bare(&ArgParser::argRawStreamData);
    (*t)["filtered-stream-data"] = oe_bare(&ArgParser::argFilteredStreamData);
    (*t)["show-npages"] = oe_bare(&ArgParser::argShowNpages);
    (*t)["show-pages"] = oe_bare(&ArgParser::argShowPages);
    (*t)["with-images"] = oe_bare(&ArgParser::argWithImages);
    (*t)["json"] = oe_bare(&ArgParser::argJson);
    // The list of selectable top-level keys id duplicated in three
    // places: json_schema, do_json, and initOptionTable.
    char const* json_key_choices[] = {
        "objects", "pages", "pagelabels", "outlines", "acroform", 0};
    (*t)["json-key"] = oe_requiredChoices(
        &ArgParser::argJsonKey, json_key_choices);
    (*t)["json-object"] = oe_requiredParameter(
        &ArgParser::argJsonObject, "trailer|obj[,gen]");
    (*t)["check"] = oe_bare(&ArgParser::argCheck);
    (*t)["optimize-images"] = oe_bare(&ArgParser::argOptimizeImages);
    (*t)["externalize-inline-images"] =
        oe_bare(&ArgParser::argExternalizeInlineImages);
    (*t)["keep-inline-images"] = oe_bare(&ArgParser::argKeepInlineImages);
    (*t)["remove-page-labels"] = oe_bare(&ArgParser::argRemovePageLabels);
    (*t)["oi-min-width"] = oe_requiredParameter(
        &ArgParser::argOiMinWidth, "minimum-width");
    (*t)["oi-min-height"] = oe_requiredParameter(
        &ArgParser::argOiMinHeight, "minimum-height");
    (*t)["oi-min-area"] = oe_requiredParameter(
        &ArgParser::argOiMinArea, "minimum-area");
    (*t)["ii-min-bytes"] = oe_requiredParameter(
        &ArgParser::argIiMinBytes, "minimum-bytes");
    (*t)["overlay"] = oe_bare(&ArgParser::argOverlay);
    (*t)["underlay"] = oe_bare(&ArgParser::argUnderlay);

    t = &this->encrypt40_option_table;
    (*t)["--"] = oe_bare(&ArgParser::argEndEncrypt);
    (*t)["print"] = oe_requiredChoices(&ArgParser::arg40Print, yn);
    (*t)["modify"] = oe_requiredChoices(&ArgParser::arg40Modify, yn);
    (*t)["extract"] = oe_requiredChoices(&ArgParser::arg40Extract, yn);
    (*t)["annotate"] = oe_requiredChoices(&ArgParser::arg40Annotate, yn);

    t = &this->encrypt128_option_table;
    (*t)["--"] = oe_bare(&ArgParser::argEndEncrypt);
    (*t)["accessibility"] = oe_requiredChoices(
        &ArgParser::arg128Accessibility, yn);
    (*t)["extract"] = oe_requiredChoices(&ArgParser::arg128Extract, yn);
    char const* print128_choices[] = {"full", "low", "none", 0};
    (*t)["print"] = oe_requiredChoices(
        &ArgParser::arg128Print, print128_choices);
    (*t)["assemble"] = oe_requiredChoices(&ArgParser::arg128Assemble, yn);
    (*t)["annotate"] = oe_requiredChoices(&ArgParser::arg128Annotate, yn);
    (*t)["form"] = oe_requiredChoices(&ArgParser::arg128Form, yn);
    (*t)["modify-other"] = oe_requiredChoices(&ArgParser::arg128ModOther, yn);
    char const* modify128_choices[] =
        {"all", "annotate", "form", "assembly", "none", 0};
    (*t)["modify"] = oe_requiredChoices(
        &ArgParser::arg128Modify, modify128_choices);
    (*t)["cleartext-metadata"] = oe_bare(&ArgParser::arg128ClearTextMetadata);

    // The above 128-bit options are also 256-bit options, so copy
    // what we have so far. Then continue separately with 128 and 256.
    this->encrypt256_option_table = this->encrypt128_option_table;
    (*t)["use-aes"] = oe_requiredChoices(&ArgParser::arg128UseAes, yn);
    (*t)["force-V4"] = oe_bare(&ArgParser::arg128ForceV4);

    t = &this->encrypt256_option_table;
    (*t)["force-R5"] = oe_bare(&ArgParser::arg256ForceR5);

    t = &this->under_overlay_option_table;
    (*t)[""] = oe_positional(&ArgParser::argUOpositional);
    (*t)["to"] = oe_requiredParameter(
        &ArgParser::argUOto, "page-range");
    (*t)["from"] = oe_requiredParameter(
        &ArgParser::argUOfrom, "page-range");
    (*t)["repeat"] = oe_requiredParameter(
        &ArgParser::argUOrepeat, "page-range");
    (*t)["password"] = oe_requiredParameter(
        &ArgParser::argUOpassword, "password");
    (*t)["--"] = oe_bare(&ArgParser::argEndUnderOverlay);
}