We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Extension online docs are not reflecting CLI parameter metadata.
The docs for `az network firewall ip-config create` are mismatched.

Docs: `az network firewall ip-config create` list `--subnet` as a valid command.

CLI:

```
mike@Azure:~$ az network firewall ip-config create -h
This command is from the following extension: azure-firewall
The extension is in preview

Command
    az network firewall ip-config create : Create an Azure Firewall IP configuration.

Arguments
    --firewall-name -f  [Required] : Azure Firewall name.
    --name -n           [Required] : Name of the IP configuration.
    --public-ip-address [Required] : Name or ID of the public IP to use.
    --resource-group -g [Required] : Name of resource group. You can configure the default group
                                     using `az configure --defaults group=&lt;name&gt;`.
    --vnet-name         [Required] : The virtual network (VNet) name.
    --private-ip-address           : IP address used by the Firewall ILB as the next hop in User
                                     Defined Routes.

Global Arguments
    --debug                        : Increase logging verbosity to show all debug logs.
    --help -h                      : Show this help message and exit.
    --output -o                    : Output format.  Allowed values: json, jsonc, none, table, tsv,
                                     yaml.  Default: json.
    --query                        : JMESPath query string. See http://jmespath.org/ for more
                                     information and examples.
    --subscription                 : Name or ID of subscription. You can configure the default
                                     subscription using `az account set -s NAME_OR_ID`.
    --verbose                      : Increase logging verbosity. Use --debug for full debug logs
```

If you try and leverage the `--subnet` flag, you get this error:

```
mike@Azure:~$ az network firewall ip-config create -f &lt;fw&gt; --name &lt;name&gt; --vnet-name &lt;vnet&gt; --public-ip-address &lt;pip&gt; --private-ip-address 10.0.0.9 -g &lt;rg&gt; --subnet &lt;snet&gt;
Resource /subscriptions/.../resourceGroups/&lt;rg&gt;/providers/Microsoft.Network/virtualNetworks/&lt;vnet&gt;/subnets/&lt;snet&gt; referenced by resource /subscriptions/.../resourceGroups/&lt;rg&gt;/providers/Microsoft.Network/azureFirewalls/&lt;fw&gt; was not found. Please make sure that the referenced resource exists, and that both resources are in the same region.
```

Both resources are in the same resource group in the same region.

---
#### Document Details

⚠ *Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.*

* ID: 4a309da7-b5b4-3aa1-e546-174af6270e4d
* Version Independent ID: f62e6045-1dd9-677f-f4df-5b29338f29dc
* Content: [az network firewall ip-config](https://docs.microsoft.com/en-us/cli/azure/ext/azure-firewall/network/firewall/ip-config?view=azure-cli-latest#ext-azure-firewall-az-network-firewall-ip-config-create)
* Content Source: [latest/docs-ref-autogen/ext/azure-firewall/network/firewall/ip-config.yml](https://github.com/MicrosoftDocs/azure-docs-cli/blob/live/latest/docs-ref-autogen/ext/azure-firewall/network/firewall/ip-config.yml)
* GitHub Login: @rloutlaw
* Microsoft Alias: **routlaw**

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scripts/refdoc/azhelpgen/azhelpgen.py`
Content:
```
1 # --------------------------------------------------------------------------------------------
2 # Copyright (c) Microsoft Corporation. All rights reserved.
3 # Licensed under the MIT License. See License.txt in the project root for license information.
4 # --------------------------------------------------------------------------------------------
5 
6 import argparse
7 import json
8 from os.path import expanduser
9 from docutils import nodes
10 from docutils.statemachine import ViewList
11 from docutils.parsers.rst import Directive
12 from sphinx.util.nodes import nested_parse_with_titles
13 
14 from knack.help_files import helps
15 
16 from knack.help import GroupHelpFile
17 from azure.cli.core import MainCommandsLoader, AzCli
18 from azure.cli.core.commands import AzCliCommandInvoker, ExtensionCommandSource
19 from azure.cli.core.parser import AzCliCommandParser
20 from azure.cli.core._help import AzCliHelp, CliCommandHelpFile, ArgumentGroupRegistry
21 
22 USER_HOME = expanduser('~')
23 
24 
25 def get_extension_help_files(cli_ctx):
26     invoker = cli_ctx.invocation_cls(cli_ctx=cli_ctx, commands_loader_cls=cli_ctx.commands_loader_cls,
27                                      parser_cls=cli_ctx.parser_cls, help_cls=cli_ctx.help_cls)
28     cli_ctx.invocation = invoker
29     cmd_table = invoker.commands_loader.load_command_table(None)
30     # Filter the command table to only get commands from extensions
31     cmd_table = {k: v for k, v in cmd_table.items() if isinstance(v.command_source, ExtensionCommandSource)}
32     invoker.commands_loader.command_table = cmd_table
33     print('FOUND {} command(s) from the extension.'.format(len(cmd_table)))
34     for cmd_name in cmd_table:
35             invoker.commands_loader.load_arguments(cmd_name)
36     invoker.parser.load_command_table(invoker.commands_loader)
37 
38     parser_keys = []
39     parser_values = []
40     sub_parser_keys = []
41     sub_parser_values = []
42     _store_parsers(invoker.parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values)
43     for cmd, parser in zip(parser_keys, parser_values):
44         if cmd not in sub_parser_keys:
45             sub_parser_keys.append(cmd)
46             sub_parser_values.append(parser)
47     help_ctx = cli_ctx.help_cls(cli_ctx=cli_ctx)
48     help_files = []
49     for cmd, parser in zip(sub_parser_keys, sub_parser_values):
50         try:
51             help_file = GroupHelpFile(help_ctx, cmd, parser) if _is_group(parser) \
52                 else CliCommandHelpFile(help_ctx, cmd, parser)
53             help_file.load(parser)
54             help_files.append(help_file)
55         except Exception as ex:
56             print("Skipped '{}' due to '{}'".format(cmd, ex))
57     help_files = sorted(help_files, key=lambda x: x.command)
58     return help_files
59 
60 class AzHelpGenDirective(Directive):
61     def make_rst(self):
62         INDENT = '   '
63         DOUBLEINDENT = INDENT * 2
64 
65         az_cli = AzCli(cli_name='az',
66                commands_loader_cls=MainCommandsLoader,
67                invocation_cls=AzCliCommandInvoker,
68                parser_cls=AzCliCommandParser,
69                help_cls=AzCliHelp)
70         help_files = get_extension_help_files(az_cli)
71 
72         for help_file in help_files:
73             is_command = isinstance(help_file, CliCommandHelpFile)
74             yield '.. cli{}:: {}'.format('command' if is_command else 'group', help_file.command if help_file.command else 'az') #it is top level group az if command is empty
75             yield ''
76             yield '{}:summary: {}'.format(INDENT, help_file.short_summary)
77             yield '{}:description: {}'.format(INDENT, help_file.long_summary)
78             if help_file.deprecate_info:
79                 yield '{}:deprecated: {}'.format(INDENT, help_file.deprecate_info._get_message(help_file.deprecate_info))
80             yield ''
81 
82             if is_command and help_file.parameters:
83                group_registry = ArgumentGroupRegistry([p.group_name for p in help_file.parameters if p.group_name]) 
84 
85                for arg in sorted(help_file.parameters,
86                                 key=lambda p: group_registry.get_group_priority(p.group_name)
87                                 + str(not p.required) + p.name):
88                     yield '{}.. cliarg:: {}'.format(INDENT, arg.name)
89                     yield ''
90                     yield '{}:required: {}'.format(DOUBLEINDENT, arg.required)
91                     if arg.deprecate_info:
92                         yield '{}:deprecated: {}'.format(DOUBLEINDENT, arg.deprecate_info._get_message(arg.deprecate_info))
93                     short_summary = arg.short_summary or ''
94                     possible_values_index = short_summary.find(' Possible values include')
95                     short_summary = short_summary[0:possible_values_index
96                                                 if possible_values_index >= 0 else len(short_summary)]
97                     short_summary = short_summary.strip()
98                     yield '{}:summary: {}'.format(DOUBLEINDENT, short_summary)
99                     yield '{}:description: {}'.format(DOUBLEINDENT, arg.long_summary)
100                     if arg.choices:
101                         yield '{}:values: {}'.format(DOUBLEINDENT, ', '.join(sorted([str(x) for x in arg.choices])))
102                     if arg.default and arg.default != argparse.SUPPRESS:
103                         try:
104                             if arg.default.startswith(USER_HOME):
105                                 arg.default = arg.default.replace(USER_HOME, '~').replace('\\', '/')
106                         except Exception:
107                             pass
108                         try:
109                             arg.default = arg.default.replace("\\", "\\\\")
110                         except Exception:
111                             pass
112                         yield '{}:default: {}'.format(DOUBLEINDENT, arg.default)
113                     if arg.value_sources:
114                         yield '{}:source: {}'.format(DOUBLEINDENT, ', '.join(arg.value_sources))
115                     yield ''
116             yield ''
117             if len(help_file.examples) > 0:
118                for e in help_file.examples:
119                   yield '{}.. cliexample:: {}'.format(INDENT, e.name)
120                   yield ''
121                   yield DOUBLEINDENT + e.text.replace("\\", "\\\\")
122                   yield ''
123 
124     def run(self):
125         node = nodes.section()
126         node.document = self.state.document
127         result = ViewList()
128         for line in self.make_rst():
129             result.append(line, '<azhelpgen>')
130 
131         nested_parse_with_titles(self.state, result, node)
132         return node.children
133 
134 def setup(app):
135     app.add_directive('azhelpgen', AzHelpGenDirective)
136 
137 
138 def _store_parsers(parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values):
139     for s in parser.subparsers.values():
140         parser_keys.append(_get_parser_name(s))
141         parser_values.append(s)
142         if _is_group(s):
143             for c in s.choices.values():
144                 sub_parser_keys.append(_get_parser_name(c))
145                 sub_parser_values.append(c)
146                 _store_parsers(c, parser_keys, parser_values, sub_parser_keys, sub_parser_values)
147 
148 def _is_group(parser):
149     return getattr(parser, '_subparsers', None) is not None \
150         or getattr(parser, 'choices', None) is not None
151 
152 def _get_parser_name(s):
153     return (s._prog_prefix if hasattr(s, '_prog_prefix') else s.prog)[3:]
154
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scripts/refdoc/azhelpgen/azhelpgen.py b/scripts/refdoc/azhelpgen/azhelpgen.py
--- a/scripts/refdoc/azhelpgen/azhelpgen.py
+++ b/scripts/refdoc/azhelpgen/azhelpgen.py
@@ -23,18 +23,31 @@
 
 
 def get_extension_help_files(cli_ctx):
+
+    # 1. Create invoker and load command table and arguments. Remember to turn off applicability check.
     invoker = cli_ctx.invocation_cls(cli_ctx=cli_ctx, commands_loader_cls=cli_ctx.commands_loader_cls,
                                      parser_cls=cli_ctx.parser_cls, help_cls=cli_ctx.help_cls)
     cli_ctx.invocation = invoker
+
+    invoker.commands_loader.skip_applicability = True
     cmd_table = invoker.commands_loader.load_command_table(None)
-    # Filter the command table to only get commands from extensions
+
+    #   turn off applicability check for all loaders
+    for loaders in invoker.commands_loader.cmd_to_loader_map.values():
+        for loader in loaders:
+            loader.skip_applicability = True
+
+    #   filter the command table to only get commands from extensions
     cmd_table = {k: v for k, v in cmd_table.items() if isinstance(v.command_source, ExtensionCommandSource)}
     invoker.commands_loader.command_table = cmd_table
     print('FOUND {} command(s) from the extension.'.format(len(cmd_table)))
+
     for cmd_name in cmd_table:
-            invoker.commands_loader.load_arguments(cmd_name)
+        invoker.commands_loader.load_arguments(cmd_name)
+
     invoker.parser.load_command_table(invoker.commands_loader)
 
+    # 2. Now load applicable help files
     parser_keys = []
     parser_values = []
     sub_parser_keys = []

{"golden_diff": "diff --git a/scripts/refdoc/azhelpgen/azhelpgen.py b/scripts/refdoc/azhelpgen/azhelpgen.py\n--- a/scripts/refdoc/azhelpgen/azhelpgen.py\n+++ b/scripts/refdoc/azhelpgen/azhelpgen.py\n@@ -23,18 +23,31 @@\n \n \n def get_extension_help_files(cli_ctx):\n+\n+    # 1. Create invoker and load command table and arguments. Remember to turn off applicability check.\n     invoker = cli_ctx.invocation_cls(cli_ctx=cli_ctx, commands_loader_cls=cli_ctx.commands_loader_cls,\n                                      parser_cls=cli_ctx.parser_cls, help_cls=cli_ctx.help_cls)\n     cli_ctx.invocation = invoker\n+\n+    invoker.commands_loader.skip_applicability = True\n     cmd_table = invoker.commands_loader.load_command_table(None)\n-    # Filter the command table to only get commands from extensions\n+\n+    #   turn off applicability check for all loaders\n+    for loaders in invoker.commands_loader.cmd_to_loader_map.values():\n+        for loader in loaders:\n+            loader.skip_applicability = True\n+\n+    #   filter the command table to only get commands from extensions\n     cmd_table = {k: v for k, v in cmd_table.items() if isinstance(v.command_source, ExtensionCommandSource)}\n     invoker.commands_loader.command_table = cmd_table\n     print('FOUND {} command(s) from the extension.'.format(len(cmd_table)))\n+\n     for cmd_name in cmd_table:\n-            invoker.commands_loader.load_arguments(cmd_name)\n+        invoker.commands_loader.load_arguments(cmd_name)\n+\n     invoker.parser.load_command_table(invoker.commands_loader)\n \n+    # 2. Now load applicable help files\n     parser_keys = []\n     parser_values = []\n     sub_parser_keys = []\n", "issue": "Extension online docs are not reflecting CLI parameter metadata.\nThe docs for `az network firewall ip-config create` are mismatched.\n\nDocs: `az network firewall ip-config create` list `--subnet` as a valid command.\n\nCLI:\n\n```\nmike@Azure:~$ az network firewall ip-config create -h\nThis command is from the following extension: azure-firewall\nThe extension is in preview\n\nCommand\n    az network firewall ip-config create : Create an Azure Firewall IP configuration.\n\nArguments\n    --firewall-name -f  [Required] : Azure Firewall name.\n    --name -n           [Required] : Name of the IP configuration.\n    --public-ip-address [Required] : Name or ID of the public IP to use.\n    --resource-group -g [Required] : Name of resource group. You can configure the default group\n                                     using `az configure --defaults group=&lt;name&gt;`.\n    --vnet-name         [Required] : The virtual network (VNet) name.\n    --private-ip-address           : IP address used by the Firewall ILB as the next hop in User\n                                     Defined Routes.\n\nGlobal Arguments\n    --debug                        : Increase logging verbosity to show all debug logs.\n    --help -h                      : Show this help message and exit.\n    --output -o                    : Output format.  Allowed values: json, jsonc, none, table, tsv,\n                                     yaml.  Default: json.\n    --query                        : JMESPath query string. See http://jmespath.org/ for more\n                                     information and examples.\n    --subscription                 : Name or ID of subscription. You can configure the default\n                                     subscription using `az account set -s NAME_OR_ID`.\n    --verbose                      : Increase logging verbosity. Use --debug for full debug logs\n```\n\nIf you try and leverage the `--subnet` flag, you get this error:\n\n```\nmike@Azure:~$ az network firewall ip-config create -f &lt;fw&gt; --name &lt;name&gt; --vnet-name &lt;vnet&gt; --public-ip-address &lt;pip&gt; --private-ip-address 10.0.0.9 -g &lt;rg&gt; --subnet &lt;snet&gt;\nResource /subscriptions/.../resourceGroups/&lt;rg&gt;/providers/Microsoft.Network/virtualNetworks/&lt;vnet&gt;/subnets/&lt;snet&gt; referenced by resource /subscriptions/.../resourceGroups/&lt;rg&gt;/providers/Microsoft.Network/azureFirewalls/&lt;fw&gt; was not found. Please make sure that the referenced resource exists, and that both resources are in the same region.\n```\n\nBoth resources are in the same resource group in the same region.\n\n---\n#### Document Details\n\n\u26a0 *Do not edit this section. It is required for docs.microsoft.com \u279f GitHub issue linking.*\n\n* ID: 4a309da7-b5b4-3aa1-e546-174af6270e4d\n* Version Independent ID: f62e6045-1dd9-677f-f4df-5b29338f29dc\n* Content: [az network firewall ip-config](https://docs.microsoft.com/en-us/cli/azure/ext/azure-firewall/network/firewall/ip-config?view=azure-cli-latest#ext-azure-firewall-az-network-firewall-ip-config-create)\n* Content Source: [latest/docs-ref-autogen/ext/azure-firewall/network/firewall/ip-config.yml](https://github.com/MicrosoftDocs/azure-docs-cli/blob/live/latest/docs-ref-autogen/ext/azure-firewall/network/firewall/ip-config.yml)\n* GitHub Login: @rloutlaw\n* Microsoft Alias: **routlaw**\n", "before_files": [{"content": "# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nimport argparse\nimport json\nfrom os.path import expanduser\nfrom docutils import nodes\nfrom docutils.statemachine import ViewList\nfrom docutils.parsers.rst import Directive\nfrom sphinx.util.nodes import nested_parse_with_titles\n\nfrom knack.help_files import helps\n\nfrom knack.help import GroupHelpFile\nfrom azure.cli.core import MainCommandsLoader, AzCli\nfrom azure.cli.core.commands import AzCliCommandInvoker, ExtensionCommandSource\nfrom azure.cli.core.parser import AzCliCommandParser\nfrom azure.cli.core._help import AzCliHelp, CliCommandHelpFile, ArgumentGroupRegistry\n\nUSER_HOME = expanduser('~')\n\n\ndef get_extension_help_files(cli_ctx):\n    invoker = cli_ctx.invocation_cls(cli_ctx=cli_ctx, commands_loader_cls=cli_ctx.commands_loader_cls,\n                                     parser_cls=cli_ctx.parser_cls, help_cls=cli_ctx.help_cls)\n    cli_ctx.invocation = invoker\n    cmd_table = invoker.commands_loader.load_command_table(None)\n    # Filter the command table to only get commands from extensions\n    cmd_table = {k: v for k, v in cmd_table.items() if isinstance(v.command_source, ExtensionCommandSource)}\n    invoker.commands_loader.command_table = cmd_table\n    print('FOUND {} command(s) from the extension.'.format(len(cmd_table)))\n    for cmd_name in cmd_table:\n            invoker.commands_loader.load_arguments(cmd_name)\n    invoker.parser.load_command_table(invoker.commands_loader)\n\n    parser_keys = []\n    parser_values = []\n    sub_parser_keys = []\n    sub_parser_values = []\n    _store_parsers(invoker.parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values)\n    for cmd, parser in zip(parser_keys, parser_values):\n        if cmd not in sub_parser_keys:\n            sub_parser_keys.append(cmd)\n            sub_parser_values.append(parser)\n    help_ctx = cli_ctx.help_cls(cli_ctx=cli_ctx)\n    help_files = []\n    for cmd, parser in zip(sub_parser_keys, sub_parser_values):\n        try:\n            help_file = GroupHelpFile(help_ctx, cmd, parser) if _is_group(parser) \\\n                else CliCommandHelpFile(help_ctx, cmd, parser)\n            help_file.load(parser)\n            help_files.append(help_file)\n        except Exception as ex:\n            print(\"Skipped '{}' due to '{}'\".format(cmd, ex))\n    help_files = sorted(help_files, key=lambda x: x.command)\n    return help_files\n\nclass AzHelpGenDirective(Directive):\n    def make_rst(self):\n        INDENT = '   '\n        DOUBLEINDENT = INDENT * 2\n\n        az_cli = AzCli(cli_name='az',\n               commands_loader_cls=MainCommandsLoader,\n               invocation_cls=AzCliCommandInvoker,\n               parser_cls=AzCliCommandParser,\n               help_cls=AzCliHelp)\n        help_files = get_extension_help_files(az_cli)\n\n        for help_file in help_files:\n            is_command = isinstance(help_file, CliCommandHelpFile)\n            yield '.. cli{}:: {}'.format('command' if is_command else 'group', help_file.command if help_file.command else 'az') #it is top level group az if command is empty\n            yield ''\n            yield '{}:summary: {}'.format(INDENT, help_file.short_summary)\n            yield '{}:description: {}'.format(INDENT, help_file.long_summary)\n            if help_file.deprecate_info:\n                yield '{}:deprecated: {}'.format(INDENT, help_file.deprecate_info._get_message(help_file.deprecate_info))\n            yield ''\n\n            if is_command and help_file.parameters:\n               group_registry = ArgumentGroupRegistry([p.group_name for p in help_file.parameters if p.group_name]) \n\n               for arg in sorted(help_file.parameters,\n                                key=lambda p: group_registry.get_group_priority(p.group_name)\n                                + str(not p.required) + p.name):\n                    yield '{}.. cliarg:: {}'.format(INDENT, arg.name)\n                    yield ''\n                    yield '{}:required: {}'.format(DOUBLEINDENT, arg.required)\n                    if arg.deprecate_info:\n                        yield '{}:deprecated: {}'.format(DOUBLEINDENT, arg.deprecate_info._get_message(arg.deprecate_info))\n                    short_summary = arg.short_summary or ''\n                    possible_values_index = short_summary.find(' Possible values include')\n                    short_summary = short_summary[0:possible_values_index\n                                                if possible_values_index >= 0 else len(short_summary)]\n                    short_summary = short_summary.strip()\n                    yield '{}:summary: {}'.format(DOUBLEINDENT, short_summary)\n                    yield '{}:description: {}'.format(DOUBLEINDENT, arg.long_summary)\n                    if arg.choices:\n                        yield '{}:values: {}'.format(DOUBLEINDENT, ', '.join(sorted([str(x) for x in arg.choices])))\n                    if arg.default and arg.default != argparse.SUPPRESS:\n                        try:\n                            if arg.default.startswith(USER_HOME):\n                                arg.default = arg.default.replace(USER_HOME, '~').replace('\\\\', '/')\n                        except Exception:\n                            pass\n                        try:\n                            arg.default = arg.default.replace(\"\\\\\", \"\\\\\\\\\")\n                        except Exception:\n                            pass\n                        yield '{}:default: {}'.format(DOUBLEINDENT, arg.default)\n                    if arg.value_sources:\n                        yield '{}:source: {}'.format(DOUBLEINDENT, ', '.join(arg.value_sources))\n                    yield ''\n            yield ''\n            if len(help_file.examples) > 0:\n               for e in help_file.examples:\n                  yield '{}.. cliexample:: {}'.format(INDENT, e.name)\n                  yield ''\n                  yield DOUBLEINDENT + e.text.replace(\"\\\\\", \"\\\\\\\\\")\n                  yield ''\n\n    def run(self):\n        node = nodes.section()\n        node.document = self.state.document\n        result = ViewList()\n        for line in self.make_rst():\n            result.append(line, '<azhelpgen>')\n\n        nested_parse_with_titles(self.state, result, node)\n        return node.children\n\ndef setup(app):\n    app.add_directive('azhelpgen', AzHelpGenDirective)\n\n\ndef _store_parsers(parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values):\n    for s in parser.subparsers.values():\n        parser_keys.append(_get_parser_name(s))\n        parser_values.append(s)\n        if _is_group(s):\n            for c in s.choices.values():\n                sub_parser_keys.append(_get_parser_name(c))\n                sub_parser_values.append(c)\n                _store_parsers(c, parser_keys, parser_values, sub_parser_keys, sub_parser_values)\n\ndef _is_group(parser):\n    return getattr(parser, '_subparsers', None) is not None \\\n        or getattr(parser, 'choices', None) is not None\n\ndef _get_parser_name(s):\n    return (s._prog_prefix if hasattr(s, '_prog_prefix') else s.prog)[3:]\n", "path": "scripts/refdoc/azhelpgen/azhelpgen.py"}], "after_files": [{"content": "# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nimport argparse\nimport json\nfrom os.path import expanduser\nfrom docutils import nodes\nfrom docutils.statemachine import ViewList\nfrom docutils.parsers.rst import Directive\nfrom sphinx.util.nodes import nested_parse_with_titles\n\nfrom knack.help_files import helps\n\nfrom knack.help import GroupHelpFile\nfrom azure.cli.core import MainCommandsLoader, AzCli\nfrom azure.cli.core.commands import AzCliCommandInvoker, ExtensionCommandSource\nfrom azure.cli.core.parser import AzCliCommandParser\nfrom azure.cli.core._help import AzCliHelp, CliCommandHelpFile, ArgumentGroupRegistry\n\nUSER_HOME = expanduser('~')\n\n\ndef get_extension_help_files(cli_ctx):\n\n    # 1. Create invoker and load command table and arguments. Remember to turn off applicability check.\n    invoker = cli_ctx.invocation_cls(cli_ctx=cli_ctx, commands_loader_cls=cli_ctx.commands_loader_cls,\n                                     parser_cls=cli_ctx.parser_cls, help_cls=cli_ctx.help_cls)\n    cli_ctx.invocation = invoker\n\n    invoker.commands_loader.skip_applicability = True\n    cmd_table = invoker.commands_loader.load_command_table(None)\n\n    #   turn off applicability check for all loaders\n    for loaders in invoker.commands_loader.cmd_to_loader_map.values():\n        for loader in loaders:\n            loader.skip_applicability = True\n\n    #   filter the command table to only get commands from extensions\n    cmd_table = {k: v for k, v in cmd_table.items() if isinstance(v.command_source, ExtensionCommandSource)}\n    invoker.commands_loader.command_table = cmd_table\n    print('FOUND {} command(s) from the extension.'.format(len(cmd_table)))\n\n    for cmd_name in cmd_table:\n        invoker.commands_loader.load_arguments(cmd_name)\n\n    invoker.parser.load_command_table(invoker.commands_loader)\n\n    # 2. Now load applicable help files\n    parser_keys = []\n    parser_values = []\n    sub_parser_keys = []\n    sub_parser_values = []\n    _store_parsers(invoker.parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values)\n    for cmd, parser in zip(parser_keys, parser_values):\n        if cmd not in sub_parser_keys:\n            sub_parser_keys.append(cmd)\n            sub_parser_values.append(parser)\n    help_ctx = cli_ctx.help_cls(cli_ctx=cli_ctx)\n    help_files = []\n    for cmd, parser in zip(sub_parser_keys, sub_parser_values):\n        try:\n            help_file = GroupHelpFile(help_ctx, cmd, parser) if _is_group(parser) \\\n                else CliCommandHelpFile(help_ctx, cmd, parser)\n            help_file.load(parser)\n            help_files.append(help_file)\n        except Exception as ex:\n            print(\"Skipped '{}' due to '{}'\".format(cmd, ex))\n    help_files = sorted(help_files, key=lambda x: x.command)\n    return help_files\n\nclass AzHelpGenDirective(Directive):\n    def make_rst(self):\n        INDENT = '   '\n        DOUBLEINDENT = INDENT * 2\n\n        az_cli = AzCli(cli_name='az',\n               commands_loader_cls=MainCommandsLoader,\n               invocation_cls=AzCliCommandInvoker,\n               parser_cls=AzCliCommandParser,\n               help_cls=AzCliHelp)\n        help_files = get_extension_help_files(az_cli)\n\n        for help_file in help_files:\n            is_command = isinstance(help_file, CliCommandHelpFile)\n            yield '.. cli{}:: {}'.format('command' if is_command else 'group', help_file.command if help_file.command else 'az') #it is top level group az if command is empty\n            yield ''\n            yield '{}:summary: {}'.format(INDENT, help_file.short_summary)\n            yield '{}:description: {}'.format(INDENT, help_file.long_summary)\n            if help_file.deprecate_info:\n                yield '{}:deprecated: {}'.format(INDENT, help_file.deprecate_info._get_message(help_file.deprecate_info))\n            yield ''\n\n            if is_command and help_file.parameters:\n               group_registry = ArgumentGroupRegistry([p.group_name for p in help_file.parameters if p.group_name]) \n\n               for arg in sorted(help_file.parameters,\n                                key=lambda p: group_registry.get_group_priority(p.group_name)\n                                + str(not p.required) + p.name):\n                    yield '{}.. cliarg:: {}'.format(INDENT, arg.name)\n                    yield ''\n                    yield '{}:required: {}'.format(DOUBLEINDENT, arg.required)\n                    if arg.deprecate_info:\n                        yield '{}:deprecated: {}'.format(DOUBLEINDENT, arg.deprecate_info._get_message(arg.deprecate_info))\n                    short_summary = arg.short_summary or ''\n                    possible_values_index = short_summary.find(' Possible values include')\n                    short_summary = short_summary[0:possible_values_index\n                                                if possible_values_index >= 0 else len(short_summary)]\n                    short_summary = short_summary.strip()\n                    yield '{}:summary: {}'.format(DOUBLEINDENT, short_summary)\n                    yield '{}:description: {}'.format(DOUBLEINDENT, arg.long_summary)\n                    if arg.choices:\n                        yield '{}:values: {}'.format(DOUBLEINDENT, ', '.join(sorted([str(x) for x in arg.choices])))\n                    if arg.default and arg.default != argparse.SUPPRESS:\n                        try:\n                            if arg.default.startswith(USER_HOME):\n                                arg.default = arg.default.replace(USER_HOME, '~').replace('\\\\', '/')\n                        except Exception:\n                            pass\n                        try:\n                            arg.default = arg.default.replace(\"\\\\\", \"\\\\\\\\\")\n                        except Exception:\n                            pass\n                        yield '{}:default: {}'.format(DOUBLEINDENT, arg.default)\n                    if arg.value_sources:\n                        yield '{}:source: {}'.format(DOUBLEINDENT, ', '.join(arg.value_sources))\n                    yield ''\n            yield ''\n            if len(help_file.examples) > 0:\n               for e in help_file.examples:\n                  yield '{}.. cliexample:: {}'.format(INDENT, e.name)\n                  yield ''\n                  yield DOUBLEINDENT + e.text.replace(\"\\\\\", \"\\\\\\\\\")\n                  yield ''\n\n    def run(self):\n        node = nodes.section()\n        node.document = self.state.document\n        result = ViewList()\n        for line in self.make_rst():\n            result.append(line, '<azhelpgen>')\n\n        nested_parse_with_titles(self.state, result, node)\n        return node.children\n\ndef setup(app):\n    app.add_directive('azhelpgen', AzHelpGenDirective)\n\n\ndef _store_parsers(parser, parser_keys, parser_values, sub_parser_keys, sub_parser_values):\n    for s in parser.subparsers.values():\n        parser_keys.append(_get_parser_name(s))\n        parser_values.append(s)\n        if _is_group(s):\n            for c in s.choices.values():\n                sub_parser_keys.append(_get_parser_name(c))\n                sub_parser_values.append(c)\n                _store_parsers(c, parser_keys, parser_values, sub_parser_keys, sub_parser_values)\n\ndef _is_group(parser):\n    return getattr(parser, '_subparsers', None) is not None \\\n        or getattr(parser, 'choices', None) is not None\n\ndef _get_parser_name(s):\n    return (s._prog_prefix if hasattr(s, '_prog_prefix') else s.prog)[3:]\n", "path": "scripts/refdoc/azhelpgen/azhelpgen.py"}]}