We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Guidelines not displayed when check fails 
I am crafting some custom rules and am unable to get the guidelines section to print out when the rule fails. 
When I run the out-of-the box rules, guidelines prints.  How do I get my custom rules to generate the guideline so that my users can access url? 

```
metadata:
  name: "Ensure instance profile is configured - https://test.example.com/EC2/MK_AWS_EC2_2.md?at=refs%2Fheads%2Fdevelop"
  guidelines: "https://test.example.com/EC2/MK_AWS_EC2_2.md?at=refs%2Fheads%2Fdevelop"
  id: "CKV_AWS_TF_EC2_2"
  category: "IAM"
  severity: "TBD"
scope:
provider: "aws"
definition:
            cond_type: "attribute"
            resource_types:
              - "aws_instance"
            attribute: "iam_instance_profile"
            operator: "exists"
```

**Version (please complete the following information):**
 - Checkov Version [2.0.1065]




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `checkov/common/checks_infra/checks_parser.py`
Content:
```
1 from __future__ import annotations
2 
3 from typing import Dict, Any, List, Optional, Type, TYPE_CHECKING
4 
5 from checkov.common.checks_infra.solvers import (
6     EqualsAttributeSolver,
7     NotEqualsAttributeSolver,
8     RegexMatchAttributeSolver,
9     NotRegexMatchAttributeSolver,
10     ExistsAttributeSolver,
11     AnyResourceSolver,
12     ContainsAttributeSolver,
13     NotExistsAttributeSolver,
14     WithinAttributeSolver,
15     NotContainsAttributeSolver,
16     StartingWithAttributeSolver,
17     NotStartingWithAttributeSolver,
18     EndingWithAttributeSolver,
19     NotEndingWithAttributeSolver,
20     AndSolver,
21     OrSolver,
22     NotSolver,
23     ConnectionExistsSolver,
24     ConnectionNotExistsSolver,
25     AndConnectionSolver,
26     OrConnectionSolver,
27     WithinFilterSolver,
28     GreaterThanAttributeSolver,
29     GreaterThanOrEqualAttributeSolver,
30     LessThanAttributeSolver,
31     LessThanOrEqualAttributeSolver,
32     SubsetAttributeSolver,
33     NotSubsetAttributeSolver,
34     IsEmptyAttributeSolver,
35     IsNotEmptyAttributeSolver,
36     LengthEqualsAttributeSolver,
37     LengthNotEqualsAttributeSolver,
38     LengthGreaterThanAttributeSolver,
39     LengthLessThanAttributeSolver,
40     LengthLessThanOrEqualAttributeSolver,
41     LengthGreaterThanOrEqualAttributeSolver,
42     IsTrueAttributeSolver,
43     IsFalseAttributeSolver,
44     IntersectsAttributeSolver,
45     NotIntersectsAttributeSolver
46 )
47 from checkov.common.checks_infra.solvers.connections_solvers.connection_one_exists_solver import \
48     ConnectionOneExistsSolver
49 from checkov.common.graph.checks_infra.base_check import BaseGraphCheck
50 from checkov.common.graph.checks_infra.base_parser import BaseGraphCheckParser
51 from checkov.common.graph.checks_infra.enums import SolverType
52 from checkov.common.graph.checks_infra.solvers.base_solver import BaseSolver
53 from checkov.common.util.type_forcers import force_list
54 
55 if TYPE_CHECKING:
56     from checkov.common.checks_infra.solvers.attribute_solvers.base_attribute_solver import BaseAttributeSolver
57     from checkov.common.checks_infra.solvers.complex_solvers.base_complex_solver import BaseComplexSolver
58     from checkov.common.checks_infra.solvers.connections_solvers.base_connection_solver import BaseConnectionSolver
59     from checkov.common.checks_infra.solvers.connections_solvers.complex_connection_solver import ComplexConnectionSolver
60     from checkov.common.checks_infra.solvers.filter_solvers.base_filter_solver import BaseFilterSolver
61 
62 
63 operators_to_attributes_solver_classes: dict[str, Type[BaseAttributeSolver]] = {
64     "equals": EqualsAttributeSolver,
65     "not_equals": NotEqualsAttributeSolver,
66     "regex_match": RegexMatchAttributeSolver,
67     "not_regex_match": NotRegexMatchAttributeSolver,
68     "exists": ExistsAttributeSolver,
69     "any": AnyResourceSolver,
70     "contains": ContainsAttributeSolver,
71     "not_exists": NotExistsAttributeSolver,
72     "within": WithinAttributeSolver,
73     "not_contains": NotContainsAttributeSolver,
74     "starting_with": StartingWithAttributeSolver,
75     "not_starting_with": NotStartingWithAttributeSolver,
76     "ending_with": EndingWithAttributeSolver,
77     "not_ending_with": NotEndingWithAttributeSolver,
78     "greater_than": GreaterThanAttributeSolver,
79     "greater_than_or_equal": GreaterThanOrEqualAttributeSolver,
80     "less_than": LessThanAttributeSolver,
81     "less_than_or_equal": LessThanOrEqualAttributeSolver,
82     "subset": SubsetAttributeSolver,
83     "not_subset": NotSubsetAttributeSolver,
84     "is_empty": IsEmptyAttributeSolver,
85     "is_not_empty": IsNotEmptyAttributeSolver,
86     "length_equals": LengthEqualsAttributeSolver,
87     "length_not_equals": LengthNotEqualsAttributeSolver,
88     "length_greater_than": LengthGreaterThanAttributeSolver,
89     "length_greater_than_or_equal": LengthGreaterThanOrEqualAttributeSolver,
90     "length_less_than": LengthLessThanAttributeSolver,
91     "length_less_than_or_equal": LengthLessThanOrEqualAttributeSolver,
92     "is_true": IsTrueAttributeSolver,
93     "is_false": IsFalseAttributeSolver,
94     "intersects": IntersectsAttributeSolver,
95     "not_intersects": NotIntersectsAttributeSolver
96 }
97 
98 operators_to_complex_solver_classes: dict[str, Type[BaseComplexSolver]] = {
99     "and": AndSolver,
100     "or": OrSolver,
101     "not": NotSolver,
102 }
103 
104 operator_to_connection_solver_classes: dict[str, Type[BaseConnectionSolver]] = {
105     "exists": ConnectionExistsSolver,
106     "one_exists": ConnectionOneExistsSolver,
107     "not_exists": ConnectionNotExistsSolver
108 }
109 
110 operator_to_complex_connection_solver_classes: dict[str, Type[ComplexConnectionSolver]] = {
111     "and": AndConnectionSolver,
112     "or": OrConnectionSolver,
113 }
114 
115 operator_to_filter_solver_classes: dict[str, Type[BaseFilterSolver]] = {
116     "within": WithinFilterSolver,
117 }
118 
119 condition_type_to_solver_type = {
120     "": SolverType.ATTRIBUTE,
121     "attribute": SolverType.ATTRIBUTE,
122     "connection": SolverType.CONNECTION,
123     "filter": SolverType.FILTER,
124 }
125 
126 JSONPATH_PREFIX = "jsonpath_"
127 
128 
129 class NXGraphCheckParser(BaseGraphCheckParser):
130     def parse_raw_check(self, raw_check: Dict[str, Dict[str, Any]], **kwargs: Any) -> BaseGraphCheck:
131         policy_definition = raw_check.get("definition", {})
132         check = self._parse_raw_check(policy_definition, kwargs.get("resources_types"))
133         check.id = raw_check.get("metadata", {}).get("id", "")
134         check.name = raw_check.get("metadata", {}).get("name", "")
135         check.category = raw_check.get("metadata", {}).get("category", "")
136         check.frameworks = raw_check.get("metadata", {}).get("frameworks", [])
137         solver = self.get_check_solver(check)
138         check.set_solver(solver)
139 
140         return check
141 
142     def _parse_raw_check(self, raw_check: Dict[str, Any], resources_types: Optional[List[str]]) -> BaseGraphCheck:
143         check = BaseGraphCheck()
144         complex_operator = get_complex_operator(raw_check)
145         if complex_operator:
146             check.type = SolverType.COMPLEX
147             check.operator = complex_operator
148             sub_solvers = raw_check.get(complex_operator, [])
149 
150             # this allows flexibility for specifying the child conditions, and makes "not" more intuitive by
151             # not requiring an actual list
152             if isinstance(sub_solvers, dict):
153                 sub_solvers = [sub_solvers]
154 
155             for sub_solver in sub_solvers:
156                 check.sub_checks.append(self._parse_raw_check(sub_solver, resources_types))
157             resources_types_of_sub_solvers = [
158                 force_list(q.resource_types) for q in check.sub_checks if q is not None and q.resource_types is not None
159             ]
160             check.resource_types = list(set(sum(resources_types_of_sub_solvers, [])))
161             if any(q.type in [SolverType.CONNECTION, SolverType.COMPLEX_CONNECTION] for q in check.sub_checks):
162                 check.type = SolverType.COMPLEX_CONNECTION
163 
164         else:
165             resource_type = raw_check.get("resource_types", [])
166             if (
167                     not resource_type
168                     or (isinstance(resource_type, str) and resource_type.lower() == "all")
169                     or (isinstance(resource_type, list) and resource_type[0].lower() == "all")
170             ):
171                 check.resource_types = resources_types or []
172             else:
173                 check.resource_types = resource_type
174 
175             connected_resources_type = raw_check.get("connected_resource_types", [])
176             if connected_resources_type == ["All"] or connected_resources_type == "all":
177                 check.connected_resources_types = resources_types or []
178             else:
179                 check.connected_resources_types = connected_resources_type
180 
181             condition_type = raw_check.get("cond_type", "")
182             check.type = condition_type_to_solver_type.get(condition_type)
183             if condition_type == "":
184                 check.operator = "any"
185             else:
186                 check.operator = raw_check.get("operator", "")
187             check.attribute = raw_check.get("attribute")
188             check.attribute_value = raw_check.get("value")
189 
190         return check
191 
192     @staticmethod
193     def get_solver_type_method(check: BaseGraphCheck) -> Optional[BaseAttributeSolver]:
194         check.is_jsonpath_check = check.operator.startswith(JSONPATH_PREFIX)
195         if check.is_jsonpath_check:
196             solver = check.operator.replace(JSONPATH_PREFIX, '')
197         else:
198             solver = check.operator
199 
200         return operators_to_attributes_solver_classes.get(solver, lambda *args: None)(
201             check.resource_types, check.attribute, check.attribute_value, check.is_jsonpath_check
202         )
203 
204     def get_check_solver(self, check: BaseGraphCheck) -> BaseSolver:
205         sub_solvers: List[BaseSolver] = []
206         if check.sub_checks:
207             sub_solvers = []
208             for sub_solver in check.sub_checks:
209                 sub_solvers.append(self.get_check_solver(sub_solver))
210 
211         type_to_solver = {
212             SolverType.COMPLEX_CONNECTION: operator_to_complex_connection_solver_classes.get(
213                 check.operator, lambda *args: None
214             )(sub_solvers, check.operator),
215             SolverType.COMPLEX: operators_to_complex_solver_classes.get(check.operator, lambda *args: None)(
216                 sub_solvers, check.resource_types
217             ),
218             SolverType.ATTRIBUTE: self.get_solver_type_method(check),
219             SolverType.CONNECTION: operator_to_connection_solver_classes.get(check.operator, lambda *args: None)(
220                 check.resource_types, check.connected_resources_types
221             ),
222             SolverType.FILTER: operator_to_filter_solver_classes.get(check.operator, lambda *args: None)(
223                 check.resource_types, check.attribute, check.attribute_value
224             ),
225         }
226 
227         solver = type_to_solver.get(check.type)  # type:ignore[arg-type]  # if not str will return None
228         if not solver:
229             raise NotImplementedError(f"solver type {check.type} with operator {check.operator} is not supported")
230         return solver
231 
232 
233 def get_complex_operator(raw_check: Dict[str, Any]) -> Optional[str]:
234     for operator in operators_to_complex_solver_classes.keys():
235         if raw_check.get(operator):
236             return operator
237     return None
238
```
--- 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/checkov/common/checks_infra/checks_parser.py b/checkov/common/checks_infra/checks_parser.py
--- a/checkov/common/checks_infra/checks_parser.py
+++ b/checkov/common/checks_infra/checks_parser.py
@@ -134,6 +134,7 @@
         check.name = raw_check.get("metadata", {}).get("name", "")
         check.category = raw_check.get("metadata", {}).get("category", "")
         check.frameworks = raw_check.get("metadata", {}).get("frameworks", [])
+        check.guideline = raw_check.get("metadata", {}).get("guideline")
         solver = self.get_check_solver(check)
         check.set_solver(solver)

{"golden_diff": "diff --git a/checkov/common/checks_infra/checks_parser.py b/checkov/common/checks_infra/checks_parser.py\n--- a/checkov/common/checks_infra/checks_parser.py\n+++ b/checkov/common/checks_infra/checks_parser.py\n@@ -134,6 +134,7 @@\n         check.name = raw_check.get(\"metadata\", {}).get(\"name\", \"\")\n         check.category = raw_check.get(\"metadata\", {}).get(\"category\", \"\")\n         check.frameworks = raw_check.get(\"metadata\", {}).get(\"frameworks\", [])\n+        check.guideline = raw_check.get(\"metadata\", {}).get(\"guideline\")\n         solver = self.get_check_solver(check)\n         check.set_solver(solver)\n", "issue": "Guidelines not displayed when check fails \nI am crafting some custom rules and am unable to get the guidelines section to print out when the rule fails. \r\nWhen I run the out-of-the box rules, guidelines prints.  How do I get my custom rules to generate the guideline so that my users can access url? \r\n\r\n```\r\nmetadata:\r\n  name: \"Ensure instance profile is configured - https://test.example.com/EC2/MK_AWS_EC2_2.md?at=refs%2Fheads%2Fdevelop\"\r\n  guidelines: \"https://test.example.com/EC2/MK_AWS_EC2_2.md?at=refs%2Fheads%2Fdevelop\"\r\n  id: \"CKV_AWS_TF_EC2_2\"\r\n  category: \"IAM\"\r\n  severity: \"TBD\"\r\nscope:\r\nprovider: \"aws\"\r\ndefinition:\r\n            cond_type: \"attribute\"\r\n            resource_types:\r\n              - \"aws_instance\"\r\n            attribute: \"iam_instance_profile\"\r\n            operator: \"exists\"\r\n```\r\n\r\n**Version (please complete the following information):**\r\n - Checkov Version [2.0.1065]\r\n\r\n\r\n\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom typing import Dict, Any, List, Optional, Type, TYPE_CHECKING\n\nfrom checkov.common.checks_infra.solvers import (\n    EqualsAttributeSolver,\n    NotEqualsAttributeSolver,\n    RegexMatchAttributeSolver,\n    NotRegexMatchAttributeSolver,\n    ExistsAttributeSolver,\n    AnyResourceSolver,\n    ContainsAttributeSolver,\n    NotExistsAttributeSolver,\n    WithinAttributeSolver,\n    NotContainsAttributeSolver,\n    StartingWithAttributeSolver,\n    NotStartingWithAttributeSolver,\n    EndingWithAttributeSolver,\n    NotEndingWithAttributeSolver,\n    AndSolver,\n    OrSolver,\n    NotSolver,\n    ConnectionExistsSolver,\n    ConnectionNotExistsSolver,\n    AndConnectionSolver,\n    OrConnectionSolver,\n    WithinFilterSolver,\n    GreaterThanAttributeSolver,\n    GreaterThanOrEqualAttributeSolver,\n    LessThanAttributeSolver,\n    LessThanOrEqualAttributeSolver,\n    SubsetAttributeSolver,\n    NotSubsetAttributeSolver,\n    IsEmptyAttributeSolver,\n    IsNotEmptyAttributeSolver,\n    LengthEqualsAttributeSolver,\n    LengthNotEqualsAttributeSolver,\n    LengthGreaterThanAttributeSolver,\n    LengthLessThanAttributeSolver,\n    LengthLessThanOrEqualAttributeSolver,\n    LengthGreaterThanOrEqualAttributeSolver,\n    IsTrueAttributeSolver,\n    IsFalseAttributeSolver,\n    IntersectsAttributeSolver,\n    NotIntersectsAttributeSolver\n)\nfrom checkov.common.checks_infra.solvers.connections_solvers.connection_one_exists_solver import \\\n    ConnectionOneExistsSolver\nfrom checkov.common.graph.checks_infra.base_check import BaseGraphCheck\nfrom checkov.common.graph.checks_infra.base_parser import BaseGraphCheckParser\nfrom checkov.common.graph.checks_infra.enums import SolverType\nfrom checkov.common.graph.checks_infra.solvers.base_solver import BaseSolver\nfrom checkov.common.util.type_forcers import force_list\n\nif TYPE_CHECKING:\n    from checkov.common.checks_infra.solvers.attribute_solvers.base_attribute_solver import BaseAttributeSolver\n    from checkov.common.checks_infra.solvers.complex_solvers.base_complex_solver import BaseComplexSolver\n    from checkov.common.checks_infra.solvers.connections_solvers.base_connection_solver import BaseConnectionSolver\n    from checkov.common.checks_infra.solvers.connections_solvers.complex_connection_solver import ComplexConnectionSolver\n    from checkov.common.checks_infra.solvers.filter_solvers.base_filter_solver import BaseFilterSolver\n\n\noperators_to_attributes_solver_classes: dict[str, Type[BaseAttributeSolver]] = {\n    \"equals\": EqualsAttributeSolver,\n    \"not_equals\": NotEqualsAttributeSolver,\n    \"regex_match\": RegexMatchAttributeSolver,\n    \"not_regex_match\": NotRegexMatchAttributeSolver,\n    \"exists\": ExistsAttributeSolver,\n    \"any\": AnyResourceSolver,\n    \"contains\": ContainsAttributeSolver,\n    \"not_exists\": NotExistsAttributeSolver,\n    \"within\": WithinAttributeSolver,\n    \"not_contains\": NotContainsAttributeSolver,\n    \"starting_with\": StartingWithAttributeSolver,\n    \"not_starting_with\": NotStartingWithAttributeSolver,\n    \"ending_with\": EndingWithAttributeSolver,\n    \"not_ending_with\": NotEndingWithAttributeSolver,\n    \"greater_than\": GreaterThanAttributeSolver,\n    \"greater_than_or_equal\": GreaterThanOrEqualAttributeSolver,\n    \"less_than\": LessThanAttributeSolver,\n    \"less_than_or_equal\": LessThanOrEqualAttributeSolver,\n    \"subset\": SubsetAttributeSolver,\n    \"not_subset\": NotSubsetAttributeSolver,\n    \"is_empty\": IsEmptyAttributeSolver,\n    \"is_not_empty\": IsNotEmptyAttributeSolver,\n    \"length_equals\": LengthEqualsAttributeSolver,\n    \"length_not_equals\": LengthNotEqualsAttributeSolver,\n    \"length_greater_than\": LengthGreaterThanAttributeSolver,\n    \"length_greater_than_or_equal\": LengthGreaterThanOrEqualAttributeSolver,\n    \"length_less_than\": LengthLessThanAttributeSolver,\n    \"length_less_than_or_equal\": LengthLessThanOrEqualAttributeSolver,\n    \"is_true\": IsTrueAttributeSolver,\n    \"is_false\": IsFalseAttributeSolver,\n    \"intersects\": IntersectsAttributeSolver,\n    \"not_intersects\": NotIntersectsAttributeSolver\n}\n\noperators_to_complex_solver_classes: dict[str, Type[BaseComplexSolver]] = {\n    \"and\": AndSolver,\n    \"or\": OrSolver,\n    \"not\": NotSolver,\n}\n\noperator_to_connection_solver_classes: dict[str, Type[BaseConnectionSolver]] = {\n    \"exists\": ConnectionExistsSolver,\n    \"one_exists\": ConnectionOneExistsSolver,\n    \"not_exists\": ConnectionNotExistsSolver\n}\n\noperator_to_complex_connection_solver_classes: dict[str, Type[ComplexConnectionSolver]] = {\n    \"and\": AndConnectionSolver,\n    \"or\": OrConnectionSolver,\n}\n\noperator_to_filter_solver_classes: dict[str, Type[BaseFilterSolver]] = {\n    \"within\": WithinFilterSolver,\n}\n\ncondition_type_to_solver_type = {\n    \"\": SolverType.ATTRIBUTE,\n    \"attribute\": SolverType.ATTRIBUTE,\n    \"connection\": SolverType.CONNECTION,\n    \"filter\": SolverType.FILTER,\n}\n\nJSONPATH_PREFIX = \"jsonpath_\"\n\n\nclass NXGraphCheckParser(BaseGraphCheckParser):\n    def parse_raw_check(self, raw_check: Dict[str, Dict[str, Any]], **kwargs: Any) -> BaseGraphCheck:\n        policy_definition = raw_check.get(\"definition\", {})\n        check = self._parse_raw_check(policy_definition, kwargs.get(\"resources_types\"))\n        check.id = raw_check.get(\"metadata\", {}).get(\"id\", \"\")\n        check.name = raw_check.get(\"metadata\", {}).get(\"name\", \"\")\n        check.category = raw_check.get(\"metadata\", {}).get(\"category\", \"\")\n        check.frameworks = raw_check.get(\"metadata\", {}).get(\"frameworks\", [])\n        solver = self.get_check_solver(check)\n        check.set_solver(solver)\n\n        return check\n\n    def _parse_raw_check(self, raw_check: Dict[str, Any], resources_types: Optional[List[str]]) -> BaseGraphCheck:\n        check = BaseGraphCheck()\n        complex_operator = get_complex_operator(raw_check)\n        if complex_operator:\n            check.type = SolverType.COMPLEX\n            check.operator = complex_operator\n            sub_solvers = raw_check.get(complex_operator, [])\n\n            # this allows flexibility for specifying the child conditions, and makes \"not\" more intuitive by\n            # not requiring an actual list\n            if isinstance(sub_solvers, dict):\n                sub_solvers = [sub_solvers]\n\n            for sub_solver in sub_solvers:\n                check.sub_checks.append(self._parse_raw_check(sub_solver, resources_types))\n            resources_types_of_sub_solvers = [\n                force_list(q.resource_types) for q in check.sub_checks if q is not None and q.resource_types is not None\n            ]\n            check.resource_types = list(set(sum(resources_types_of_sub_solvers, [])))\n            if any(q.type in [SolverType.CONNECTION, SolverType.COMPLEX_CONNECTION] for q in check.sub_checks):\n                check.type = SolverType.COMPLEX_CONNECTION\n\n        else:\n            resource_type = raw_check.get(\"resource_types\", [])\n            if (\n                    not resource_type\n                    or (isinstance(resource_type, str) and resource_type.lower() == \"all\")\n                    or (isinstance(resource_type, list) and resource_type[0].lower() == \"all\")\n            ):\n                check.resource_types = resources_types or []\n            else:\n                check.resource_types = resource_type\n\n            connected_resources_type = raw_check.get(\"connected_resource_types\", [])\n            if connected_resources_type == [\"All\"] or connected_resources_type == \"all\":\n                check.connected_resources_types = resources_types or []\n            else:\n                check.connected_resources_types = connected_resources_type\n\n            condition_type = raw_check.get(\"cond_type\", \"\")\n            check.type = condition_type_to_solver_type.get(condition_type)\n            if condition_type == \"\":\n                check.operator = \"any\"\n            else:\n                check.operator = raw_check.get(\"operator\", \"\")\n            check.attribute = raw_check.get(\"attribute\")\n            check.attribute_value = raw_check.get(\"value\")\n\n        return check\n\n    @staticmethod\n    def get_solver_type_method(check: BaseGraphCheck) -> Optional[BaseAttributeSolver]:\n        check.is_jsonpath_check = check.operator.startswith(JSONPATH_PREFIX)\n        if check.is_jsonpath_check:\n            solver = check.operator.replace(JSONPATH_PREFIX, '')\n        else:\n            solver = check.operator\n\n        return operators_to_attributes_solver_classes.get(solver, lambda *args: None)(\n            check.resource_types, check.attribute, check.attribute_value, check.is_jsonpath_check\n        )\n\n    def get_check_solver(self, check: BaseGraphCheck) -> BaseSolver:\n        sub_solvers: List[BaseSolver] = []\n        if check.sub_checks:\n            sub_solvers = []\n            for sub_solver in check.sub_checks:\n                sub_solvers.append(self.get_check_solver(sub_solver))\n\n        type_to_solver = {\n            SolverType.COMPLEX_CONNECTION: operator_to_complex_connection_solver_classes.get(\n                check.operator, lambda *args: None\n            )(sub_solvers, check.operator),\n            SolverType.COMPLEX: operators_to_complex_solver_classes.get(check.operator, lambda *args: None)(\n                sub_solvers, check.resource_types\n            ),\n            SolverType.ATTRIBUTE: self.get_solver_type_method(check),\n            SolverType.CONNECTION: operator_to_connection_solver_classes.get(check.operator, lambda *args: None)(\n                check.resource_types, check.connected_resources_types\n            ),\n            SolverType.FILTER: operator_to_filter_solver_classes.get(check.operator, lambda *args: None)(\n                check.resource_types, check.attribute, check.attribute_value\n            ),\n        }\n\n        solver = type_to_solver.get(check.type)  # type:ignore[arg-type]  # if not str will return None\n        if not solver:\n            raise NotImplementedError(f\"solver type {check.type} with operator {check.operator} is not supported\")\n        return solver\n\n\ndef get_complex_operator(raw_check: Dict[str, Any]) -> Optional[str]:\n    for operator in operators_to_complex_solver_classes.keys():\n        if raw_check.get(operator):\n            return operator\n    return None\n", "path": "checkov/common/checks_infra/checks_parser.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom typing import Dict, Any, List, Optional, Type, TYPE_CHECKING\n\nfrom checkov.common.checks_infra.solvers import (\n    EqualsAttributeSolver,\n    NotEqualsAttributeSolver,\n    RegexMatchAttributeSolver,\n    NotRegexMatchAttributeSolver,\n    ExistsAttributeSolver,\n    AnyResourceSolver,\n    ContainsAttributeSolver,\n    NotExistsAttributeSolver,\n    WithinAttributeSolver,\n    NotContainsAttributeSolver,\n    StartingWithAttributeSolver,\n    NotStartingWithAttributeSolver,\n    EndingWithAttributeSolver,\n    NotEndingWithAttributeSolver,\n    AndSolver,\n    OrSolver,\n    NotSolver,\n    ConnectionExistsSolver,\n    ConnectionNotExistsSolver,\n    AndConnectionSolver,\n    OrConnectionSolver,\n    WithinFilterSolver,\n    GreaterThanAttributeSolver,\n    GreaterThanOrEqualAttributeSolver,\n    LessThanAttributeSolver,\n    LessThanOrEqualAttributeSolver,\n    SubsetAttributeSolver,\n    NotSubsetAttributeSolver,\n    IsEmptyAttributeSolver,\n    IsNotEmptyAttributeSolver,\n    LengthEqualsAttributeSolver,\n    LengthNotEqualsAttributeSolver,\n    LengthGreaterThanAttributeSolver,\n    LengthLessThanAttributeSolver,\n    LengthLessThanOrEqualAttributeSolver,\n    LengthGreaterThanOrEqualAttributeSolver,\n    IsTrueAttributeSolver,\n    IsFalseAttributeSolver,\n    IntersectsAttributeSolver,\n    NotIntersectsAttributeSolver\n)\nfrom checkov.common.checks_infra.solvers.connections_solvers.connection_one_exists_solver import \\\n    ConnectionOneExistsSolver\nfrom checkov.common.graph.checks_infra.base_check import BaseGraphCheck\nfrom checkov.common.graph.checks_infra.base_parser import BaseGraphCheckParser\nfrom checkov.common.graph.checks_infra.enums import SolverType\nfrom checkov.common.graph.checks_infra.solvers.base_solver import BaseSolver\nfrom checkov.common.util.type_forcers import force_list\n\nif TYPE_CHECKING:\n    from checkov.common.checks_infra.solvers.attribute_solvers.base_attribute_solver import BaseAttributeSolver\n    from checkov.common.checks_infra.solvers.complex_solvers.base_complex_solver import BaseComplexSolver\n    from checkov.common.checks_infra.solvers.connections_solvers.base_connection_solver import BaseConnectionSolver\n    from checkov.common.checks_infra.solvers.connections_solvers.complex_connection_solver import ComplexConnectionSolver\n    from checkov.common.checks_infra.solvers.filter_solvers.base_filter_solver import BaseFilterSolver\n\n\noperators_to_attributes_solver_classes: dict[str, Type[BaseAttributeSolver]] = {\n    \"equals\": EqualsAttributeSolver,\n    \"not_equals\": NotEqualsAttributeSolver,\n    \"regex_match\": RegexMatchAttributeSolver,\n    \"not_regex_match\": NotRegexMatchAttributeSolver,\n    \"exists\": ExistsAttributeSolver,\n    \"any\": AnyResourceSolver,\n    \"contains\": ContainsAttributeSolver,\n    \"not_exists\": NotExistsAttributeSolver,\n    \"within\": WithinAttributeSolver,\n    \"not_contains\": NotContainsAttributeSolver,\n    \"starting_with\": StartingWithAttributeSolver,\n    \"not_starting_with\": NotStartingWithAttributeSolver,\n    \"ending_with\": EndingWithAttributeSolver,\n    \"not_ending_with\": NotEndingWithAttributeSolver,\n    \"greater_than\": GreaterThanAttributeSolver,\n    \"greater_than_or_equal\": GreaterThanOrEqualAttributeSolver,\n    \"less_than\": LessThanAttributeSolver,\n    \"less_than_or_equal\": LessThanOrEqualAttributeSolver,\n    \"subset\": SubsetAttributeSolver,\n    \"not_subset\": NotSubsetAttributeSolver,\n    \"is_empty\": IsEmptyAttributeSolver,\n    \"is_not_empty\": IsNotEmptyAttributeSolver,\n    \"length_equals\": LengthEqualsAttributeSolver,\n    \"length_not_equals\": LengthNotEqualsAttributeSolver,\n    \"length_greater_than\": LengthGreaterThanAttributeSolver,\n    \"length_greater_than_or_equal\": LengthGreaterThanOrEqualAttributeSolver,\n    \"length_less_than\": LengthLessThanAttributeSolver,\n    \"length_less_than_or_equal\": LengthLessThanOrEqualAttributeSolver,\n    \"is_true\": IsTrueAttributeSolver,\n    \"is_false\": IsFalseAttributeSolver,\n    \"intersects\": IntersectsAttributeSolver,\n    \"not_intersects\": NotIntersectsAttributeSolver\n}\n\noperators_to_complex_solver_classes: dict[str, Type[BaseComplexSolver]] = {\n    \"and\": AndSolver,\n    \"or\": OrSolver,\n    \"not\": NotSolver,\n}\n\noperator_to_connection_solver_classes: dict[str, Type[BaseConnectionSolver]] = {\n    \"exists\": ConnectionExistsSolver,\n    \"one_exists\": ConnectionOneExistsSolver,\n    \"not_exists\": ConnectionNotExistsSolver\n}\n\noperator_to_complex_connection_solver_classes: dict[str, Type[ComplexConnectionSolver]] = {\n    \"and\": AndConnectionSolver,\n    \"or\": OrConnectionSolver,\n}\n\noperator_to_filter_solver_classes: dict[str, Type[BaseFilterSolver]] = {\n    \"within\": WithinFilterSolver,\n}\n\ncondition_type_to_solver_type = {\n    \"\": SolverType.ATTRIBUTE,\n    \"attribute\": SolverType.ATTRIBUTE,\n    \"connection\": SolverType.CONNECTION,\n    \"filter\": SolverType.FILTER,\n}\n\nJSONPATH_PREFIX = \"jsonpath_\"\n\n\nclass NXGraphCheckParser(BaseGraphCheckParser):\n    def parse_raw_check(self, raw_check: Dict[str, Dict[str, Any]], **kwargs: Any) -> BaseGraphCheck:\n        policy_definition = raw_check.get(\"definition\", {})\n        check = self._parse_raw_check(policy_definition, kwargs.get(\"resources_types\"))\n        check.id = raw_check.get(\"metadata\", {}).get(\"id\", \"\")\n        check.name = raw_check.get(\"metadata\", {}).get(\"name\", \"\")\n        check.category = raw_check.get(\"metadata\", {}).get(\"category\", \"\")\n        check.frameworks = raw_check.get(\"metadata\", {}).get(\"frameworks\", [])\n        check.guideline = raw_check.get(\"metadata\", {}).get(\"guideline\")\n        solver = self.get_check_solver(check)\n        check.set_solver(solver)\n\n        return check\n\n    def _parse_raw_check(self, raw_check: Dict[str, Any], resources_types: Optional[List[str]]) -> BaseGraphCheck:\n        check = BaseGraphCheck()\n        complex_operator = get_complex_operator(raw_check)\n        if complex_operator:\n            check.type = SolverType.COMPLEX\n            check.operator = complex_operator\n            sub_solvers = raw_check.get(complex_operator, [])\n\n            # this allows flexibility for specifying the child conditions, and makes \"not\" more intuitive by\n            # not requiring an actual list\n            if isinstance(sub_solvers, dict):\n                sub_solvers = [sub_solvers]\n\n            for sub_solver in sub_solvers:\n                check.sub_checks.append(self._parse_raw_check(sub_solver, resources_types))\n            resources_types_of_sub_solvers = [\n                force_list(q.resource_types) for q in check.sub_checks if q is not None and q.resource_types is not None\n            ]\n            check.resource_types = list(set(sum(resources_types_of_sub_solvers, [])))\n            if any(q.type in [SolverType.CONNECTION, SolverType.COMPLEX_CONNECTION] for q in check.sub_checks):\n                check.type = SolverType.COMPLEX_CONNECTION\n\n        else:\n            resource_type = raw_check.get(\"resource_types\", [])\n            if (\n                    not resource_type\n                    or (isinstance(resource_type, str) and resource_type.lower() == \"all\")\n                    or (isinstance(resource_type, list) and resource_type[0].lower() == \"all\")\n            ):\n                check.resource_types = resources_types or []\n            else:\n                check.resource_types = resource_type\n\n            connected_resources_type = raw_check.get(\"connected_resource_types\", [])\n            if connected_resources_type == [\"All\"] or connected_resources_type == \"all\":\n                check.connected_resources_types = resources_types or []\n            else:\n                check.connected_resources_types = connected_resources_type\n\n            condition_type = raw_check.get(\"cond_type\", \"\")\n            check.type = condition_type_to_solver_type.get(condition_type)\n            if condition_type == \"\":\n                check.operator = \"any\"\n            else:\n                check.operator = raw_check.get(\"operator\", \"\")\n            check.attribute = raw_check.get(\"attribute\")\n            check.attribute_value = raw_check.get(\"value\")\n\n        return check\n\n    @staticmethod\n    def get_solver_type_method(check: BaseGraphCheck) -> Optional[BaseAttributeSolver]:\n        check.is_jsonpath_check = check.operator.startswith(JSONPATH_PREFIX)\n        if check.is_jsonpath_check:\n            solver = check.operator.replace(JSONPATH_PREFIX, '')\n        else:\n            solver = check.operator\n\n        return operators_to_attributes_solver_classes.get(solver, lambda *args: None)(\n            check.resource_types, check.attribute, check.attribute_value, check.is_jsonpath_check\n        )\n\n    def get_check_solver(self, check: BaseGraphCheck) -> BaseSolver:\n        sub_solvers: List[BaseSolver] = []\n        if check.sub_checks:\n            sub_solvers = []\n            for sub_solver in check.sub_checks:\n                sub_solvers.append(self.get_check_solver(sub_solver))\n\n        type_to_solver = {\n            SolverType.COMPLEX_CONNECTION: operator_to_complex_connection_solver_classes.get(\n                check.operator, lambda *args: None\n            )(sub_solvers, check.operator),\n            SolverType.COMPLEX: operators_to_complex_solver_classes.get(check.operator, lambda *args: None)(\n                sub_solvers, check.resource_types\n            ),\n            SolverType.ATTRIBUTE: self.get_solver_type_method(check),\n            SolverType.CONNECTION: operator_to_connection_solver_classes.get(check.operator, lambda *args: None)(\n                check.resource_types, check.connected_resources_types\n            ),\n            SolverType.FILTER: operator_to_filter_solver_classes.get(check.operator, lambda *args: None)(\n                check.resource_types, check.attribute, check.attribute_value\n            ),\n        }\n\n        solver = type_to_solver.get(check.type)  # type:ignore[arg-type]  # if not str will return None\n        if not solver:\n            raise NotImplementedError(f\"solver type {check.type} with operator {check.operator} is not supported\")\n        return solver\n\n\ndef get_complex_operator(raw_check: Dict[str, Any]) -> Optional[str]:\n    for operator in operators_to_complex_solver_classes.keys():\n        if raw_check.get(operator):\n            return operator\n    return None\n", "path": "checkov/common/checks_infra/checks_parser.py"}]}