aas-core-codegen 0.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. aas_core_codegen/__init__.py +6 -0
  2. aas_core_codegen/__main__.py +8 -0
  3. aas_core_codegen/common.py +500 -0
  4. aas_core_codegen/cpp/__init__.py +1 -0
  5. aas_core_codegen/cpp/aas_common/__init__.py +6 -0
  6. aas_core_codegen/cpp/aas_common/_generate.py +713 -0
  7. aas_core_codegen/cpp/common.py +681 -0
  8. aas_core_codegen/cpp/constants/__init__.py +6 -0
  9. aas_core_codegen/cpp/constants/_generate.py +568 -0
  10. aas_core_codegen/cpp/description.py +654 -0
  11. aas_core_codegen/cpp/enhancing/__init__.py +4 -0
  12. aas_core_codegen/cpp/enhancing/_generate.py +993 -0
  13. aas_core_codegen/cpp/iteration/__init__.py +6 -0
  14. aas_core_codegen/cpp/iteration/_generate.py +2332 -0
  15. aas_core_codegen/cpp/jsonization/__init__.py +6 -0
  16. aas_core_codegen/cpp/jsonization/_generate.py +2619 -0
  17. aas_core_codegen/cpp/main.py +694 -0
  18. aas_core_codegen/cpp/naming.py +170 -0
  19. aas_core_codegen/cpp/optionaling.py +557 -0
  20. aas_core_codegen/cpp/pattern/__init__.py +6 -0
  21. aas_core_codegen/cpp/pattern/_generate.py +508 -0
  22. aas_core_codegen/cpp/revm/__init__.py +6 -0
  23. aas_core_codegen/cpp/revm/_generate.py +1149 -0
  24. aas_core_codegen/cpp/stringification/__init__.py +5 -0
  25. aas_core_codegen/cpp/stringification/_generate.py +955 -0
  26. aas_core_codegen/cpp/structure/__init__.py +7 -0
  27. aas_core_codegen/cpp/structure/_generate.py +1503 -0
  28. aas_core_codegen/cpp/transpilation.py +1383 -0
  29. aas_core_codegen/cpp/unrolling.py +159 -0
  30. aas_core_codegen/cpp/verification/__init__.py +6 -0
  31. aas_core_codegen/cpp/verification/_generate.py +3073 -0
  32. aas_core_codegen/cpp/visitation/__init__.py +6 -0
  33. aas_core_codegen/cpp/visitation/_generate.py +521 -0
  34. aas_core_codegen/cpp/wstringification/__init__.py +5 -0
  35. aas_core_codegen/cpp/wstringification/_generate.py +586 -0
  36. aas_core_codegen/cpp/xmlization/__init__.py +6 -0
  37. aas_core_codegen/cpp/xmlization/_generate.py +5373 -0
  38. aas_core_codegen/cpp/yielding.py +201 -0
  39. aas_core_codegen/csharp/__init__.py +1 -0
  40. aas_core_codegen/csharp/common.py +224 -0
  41. aas_core_codegen/csharp/constants/__init__.py +5 -0
  42. aas_core_codegen/csharp/constants/_generate.py +409 -0
  43. aas_core_codegen/csharp/copying/__init__.py +4 -0
  44. aas_core_codegen/csharp/copying/_generate.py +498 -0
  45. aas_core_codegen/csharp/description.py +1103 -0
  46. aas_core_codegen/csharp/enhancing/__init__.py +4 -0
  47. aas_core_codegen/csharp/enhancing/_generate.py +667 -0
  48. aas_core_codegen/csharp/jsonization/__init__.py +4 -0
  49. aas_core_codegen/csharp/jsonization/_generate.py +1630 -0
  50. aas_core_codegen/csharp/main.py +421 -0
  51. aas_core_codegen/csharp/naming.py +157 -0
  52. aas_core_codegen/csharp/reporting/__init__.py +4 -0
  53. aas_core_codegen/csharp/reporting/_generate.py +266 -0
  54. aas_core_codegen/csharp/stringification/__init__.py +4 -0
  55. aas_core_codegen/csharp/stringification/_generate.py +243 -0
  56. aas_core_codegen/csharp/structure/__init__.py +6 -0
  57. aas_core_codegen/csharp/structure/_generate.py +1341 -0
  58. aas_core_codegen/csharp/transpilation.py +990 -0
  59. aas_core_codegen/csharp/unrolling.py +211 -0
  60. aas_core_codegen/csharp/verification/__init__.py +6 -0
  61. aas_core_codegen/csharp/verification/_generate.py +1457 -0
  62. aas_core_codegen/csharp/visitation/__init__.py +5 -0
  63. aas_core_codegen/csharp/visitation/_generate.py +579 -0
  64. aas_core_codegen/csharp/xmlization/__init__.py +4 -0
  65. aas_core_codegen/csharp/xmlization/_generate.py +1980 -0
  66. aas_core_codegen/golang/__init__.py +1 -0
  67. aas_core_codegen/golang/aas_common/__init__.py +4 -0
  68. aas_core_codegen/golang/aas_common/_generate.py +152 -0
  69. aas_core_codegen/golang/common.py +303 -0
  70. aas_core_codegen/golang/constants/__init__.py +5 -0
  71. aas_core_codegen/golang/constants/_generate.py +339 -0
  72. aas_core_codegen/golang/description.py +501 -0
  73. aas_core_codegen/golang/enhancing/__init__.py +4 -0
  74. aas_core_codegen/golang/enhancing/_generate.py +527 -0
  75. aas_core_codegen/golang/jsonization/__init__.py +4 -0
  76. aas_core_codegen/golang/jsonization/_generate.py +1740 -0
  77. aas_core_codegen/golang/main.py +368 -0
  78. aas_core_codegen/golang/naming.py +412 -0
  79. aas_core_codegen/golang/pointering.py +631 -0
  80. aas_core_codegen/golang/reporting/__init__.py +4 -0
  81. aas_core_codegen/golang/reporting/_generate.py +218 -0
  82. aas_core_codegen/golang/stringification/__init__.py +4 -0
  83. aas_core_codegen/golang/stringification/_generate.py +394 -0
  84. aas_core_codegen/golang/structure/__init__.py +6 -0
  85. aas_core_codegen/golang/structure/_generate.py +1493 -0
  86. aas_core_codegen/golang/transpilation.py +1191 -0
  87. aas_core_codegen/golang/unrolling.py +159 -0
  88. aas_core_codegen/golang/verification/__init__.py +6 -0
  89. aas_core_codegen/golang/verification/_generate.py +1513 -0
  90. aas_core_codegen/golang/xmlization/__init__.py +4 -0
  91. aas_core_codegen/golang/xmlization/_generate.py +2507 -0
  92. aas_core_codegen/infer_for_schema/__init__.py +21 -0
  93. aas_core_codegen/infer_for_schema/_inline.py +693 -0
  94. aas_core_codegen/infer_for_schema/_len.py +527 -0
  95. aas_core_codegen/infer_for_schema/_pattern.py +311 -0
  96. aas_core_codegen/infer_for_schema/_set.py +394 -0
  97. aas_core_codegen/infer_for_schema/_stringify.py +201 -0
  98. aas_core_codegen/infer_for_schema/_types.py +135 -0
  99. aas_core_codegen/infer_for_schema/match.py +122 -0
  100. aas_core_codegen/intermediate/__init__.py +78 -0
  101. aas_core_codegen/intermediate/_hierarchy.py +397 -0
  102. aas_core_codegen/intermediate/_stringify.py +989 -0
  103. aas_core_codegen/intermediate/_translate.py +5128 -0
  104. aas_core_codegen/intermediate/_types.py +2901 -0
  105. aas_core_codegen/intermediate/construction.py +750 -0
  106. aas_core_codegen/intermediate/doc.py +344 -0
  107. aas_core_codegen/intermediate/pattern_verification.py +428 -0
  108. aas_core_codegen/intermediate/revm.py +985 -0
  109. aas_core_codegen/intermediate/type_inference.py +2266 -0
  110. aas_core_codegen/java/__init__.py +1 -0
  111. aas_core_codegen/java/common.py +197 -0
  112. aas_core_codegen/java/constants/__init__.py +5 -0
  113. aas_core_codegen/java/constants/_generate.py +334 -0
  114. aas_core_codegen/java/copying/__init__.py +4 -0
  115. aas_core_codegen/java/copying/_generate.py +502 -0
  116. aas_core_codegen/java/description.py +774 -0
  117. aas_core_codegen/java/enhancing/__init__.py +4 -0
  118. aas_core_codegen/java/enhancing/_generate.py +820 -0
  119. aas_core_codegen/java/generation/__init__.py +5 -0
  120. aas_core_codegen/java/generation/_generate.py +285 -0
  121. aas_core_codegen/java/jsonization/__init__.py +4 -0
  122. aas_core_codegen/java/jsonization/_generate.py +1472 -0
  123. aas_core_codegen/java/main.py +438 -0
  124. aas_core_codegen/java/naming.py +187 -0
  125. aas_core_codegen/java/optional.py +514 -0
  126. aas_core_codegen/java/reporting/__init__.py +4 -0
  127. aas_core_codegen/java/reporting/_generate.py +248 -0
  128. aas_core_codegen/java/stringification/__init__.py +4 -0
  129. aas_core_codegen/java/stringification/_generate.py +212 -0
  130. aas_core_codegen/java/structure/__init__.py +6 -0
  131. aas_core_codegen/java/structure/_generate.py +1767 -0
  132. aas_core_codegen/java/transpilation.py +1111 -0
  133. aas_core_codegen/java/verification/__init__.py +6 -0
  134. aas_core_codegen/java/verification/_generate.py +1536 -0
  135. aas_core_codegen/java/visitation/__init__.py +5 -0
  136. aas_core_codegen/java/visitation/_generate.py +689 -0
  137. aas_core_codegen/java/xmlization/__init__.py +4 -0
  138. aas_core_codegen/java/xmlization/_generate.py +2274 -0
  139. aas_core_codegen/jsonld/__init__.py +1 -0
  140. aas_core_codegen/jsonld/main.py +455 -0
  141. aas_core_codegen/jsonschema/__init__.py +1 -0
  142. aas_core_codegen/jsonschema/main.py +982 -0
  143. aas_core_codegen/main.py +245 -0
  144. aas_core_codegen/naming.py +133 -0
  145. aas_core_codegen/opcua/__init__.py +1 -0
  146. aas_core_codegen/opcua/main.py +1525 -0
  147. aas_core_codegen/opcua/naming.py +126 -0
  148. aas_core_codegen/parse/__init__.py +46 -0
  149. aas_core_codegen/parse/_rules.py +796 -0
  150. aas_core_codegen/parse/_stringify.py +532 -0
  151. aas_core_codegen/parse/_translate.py +3940 -0
  152. aas_core_codegen/parse/_types.py +973 -0
  153. aas_core_codegen/parse/retree/__init__.py +46 -0
  154. aas_core_codegen/parse/retree/_fix.py +434 -0
  155. aas_core_codegen/parse/retree/_parse.py +1143 -0
  156. aas_core_codegen/parse/retree/_render.py +298 -0
  157. aas_core_codegen/parse/retree/_stringify.py +199 -0
  158. aas_core_codegen/parse/retree/_types.py +362 -0
  159. aas_core_codegen/parse/retree/_visitor.py +70 -0
  160. aas_core_codegen/parse/tree.py +1303 -0
  161. aas_core_codegen/protobuf/__init__.py +1 -0
  162. aas_core_codegen/protobuf/common.py +225 -0
  163. aas_core_codegen/protobuf/description.py +1102 -0
  164. aas_core_codegen/protobuf/main.py +115 -0
  165. aas_core_codegen/protobuf/naming.py +143 -0
  166. aas_core_codegen/protobuf/structure/__init__.py +6 -0
  167. aas_core_codegen/protobuf/structure/_generate.py +502 -0
  168. aas_core_codegen/py.typed +1 -0
  169. aas_core_codegen/python/__init__.py +1 -0
  170. aas_core_codegen/python/aas_common/__init__.py +4 -0
  171. aas_core_codegen/python/aas_common/_generate.py +63 -0
  172. aas_core_codegen/python/common.py +406 -0
  173. aas_core_codegen/python/constants/__init__.py +5 -0
  174. aas_core_codegen/python/constants/_generate.py +377 -0
  175. aas_core_codegen/python/description.py +508 -0
  176. aas_core_codegen/python/jsonization/__init__.py +4 -0
  177. aas_core_codegen/python/jsonization/_generate.py +1391 -0
  178. aas_core_codegen/python/main.py +323 -0
  179. aas_core_codegen/python/naming.py +255 -0
  180. aas_core_codegen/python/stringification/__init__.py +4 -0
  181. aas_core_codegen/python/stringification/_generate.py +129 -0
  182. aas_core_codegen/python/structure/__init__.py +6 -0
  183. aas_core_codegen/python/structure/_generate.py +1801 -0
  184. aas_core_codegen/python/transpilation.py +958 -0
  185. aas_core_codegen/python/unrolling.py +156 -0
  186. aas_core_codegen/python/verification/__init__.py +6 -0
  187. aas_core_codegen/python/verification/_generate.py +1471 -0
  188. aas_core_codegen/python/xmlization/__init__.py +4 -0
  189. aas_core_codegen/python/xmlization/_generate.py +3003 -0
  190. aas_core_codegen/python_protobuf/__init__.py +1 -0
  191. aas_core_codegen/python_protobuf/main.py +1424 -0
  192. aas_core_codegen/python_protobuf/naming.py +85 -0
  193. aas_core_codegen/rdf_shacl/__init__.py +1 -0
  194. aas_core_codegen/rdf_shacl/_description.py +351 -0
  195. aas_core_codegen/rdf_shacl/common.py +206 -0
  196. aas_core_codegen/rdf_shacl/main.py +114 -0
  197. aas_core_codegen/rdf_shacl/naming.py +145 -0
  198. aas_core_codegen/rdf_shacl/rdf.py +435 -0
  199. aas_core_codegen/rdf_shacl/shacl.py +453 -0
  200. aas_core_codegen/run.py +124 -0
  201. aas_core_codegen/smoke/__init__.py +1 -0
  202. aas_core_codegen/smoke/main.py +219 -0
  203. aas_core_codegen/specific_implementations.py +72 -0
  204. aas_core_codegen/stringify.py +333 -0
  205. aas_core_codegen/typescript/__init__.py +1 -0
  206. aas_core_codegen/typescript/aas_common/__init__.py +4 -0
  207. aas_core_codegen/typescript/aas_common/_generate.py +472 -0
  208. aas_core_codegen/typescript/common.py +340 -0
  209. aas_core_codegen/typescript/constants/__init__.py +5 -0
  210. aas_core_codegen/typescript/constants/_generate.py +347 -0
  211. aas_core_codegen/typescript/description.py +530 -0
  212. aas_core_codegen/typescript/jsonization/__init__.py +4 -0
  213. aas_core_codegen/typescript/jsonization/_generate.py +1510 -0
  214. aas_core_codegen/typescript/main.py +258 -0
  215. aas_core_codegen/typescript/naming.py +189 -0
  216. aas_core_codegen/typescript/stringification/__init__.py +4 -0
  217. aas_core_codegen/typescript/stringification/_generate.py +367 -0
  218. aas_core_codegen/typescript/structure/__init__.py +6 -0
  219. aas_core_codegen/typescript/structure/_generate.py +2500 -0
  220. aas_core_codegen/typescript/transpilation.py +1051 -0
  221. aas_core_codegen/typescript/unrolling.py +159 -0
  222. aas_core_codegen/typescript/verification/__init__.py +6 -0
  223. aas_core_codegen/typescript/verification/_generate.py +1578 -0
  224. aas_core_codegen/xsd/__init__.py +1 -0
  225. aas_core_codegen/xsd/main.py +1187 -0
  226. aas_core_codegen/xsd/naming.py +83 -0
  227. aas_core_codegen/yielding/__init__.py +1 -0
  228. aas_core_codegen/yielding/flow.py +139 -0
  229. aas_core_codegen/yielding/linear.py +754 -0
  230. aas_core_codegen-0.0.16.dist-info/METADATA +211 -0
  231. aas_core_codegen-0.0.16.dist-info/RECORD +604 -0
  232. aas_core_codegen-0.0.16.dist-info/WHEEL +5 -0
  233. aas_core_codegen-0.0.16.dist-info/entry_points.txt +3 -0
  234. aas_core_codegen-0.0.16.dist-info/licenses/AUTHORS +9 -0
  235. aas_core_codegen-0.0.16.dist-info/licenses/LICENSE +23 -0
  236. aas_core_codegen-0.0.16.dist-info/top_level.txt +2 -0
  237. dev/continuous_integration/__init__.py +1 -0
  238. dev/continuous_integration/check_help_in_readme.py +208 -0
  239. dev/continuous_integration/check_init_and_pyproject_consistent.py +154 -0
  240. dev/continuous_integration/precommit.py +400 -0
  241. dev/dev_scripts/__init__.py +1 -0
  242. dev/dev_scripts/compare_rendered_regexes_against_source_py.py +42 -0
  243. dev/dev_scripts/copy_to_aas_core3_cpp.py +100 -0
  244. dev/dev_scripts/copy_to_aas_core3_java.py +90 -0
  245. dev/dev_scripts/download_latest_aas_core_meta_v3.py +114 -0
  246. dev/dev_scripts/draw_bipartite_graph_based_on_lines.py +37 -0
  247. dev/dev_scripts/run_tests_with_rerecord.py +69 -0
  248. dev/dev_scripts/update_to_aas_core_meta.py +174 -0
  249. dev/integration_tests/input/jsonschema/boilerplate/main.py +55 -0
  250. dev/integration_tests/input/meta_model.py +38 -0
  251. dev/integration_tests/input/python/boilerplate/main.py +153 -0
  252. dev/integration_tests/main.py +258 -0
  253. dev/test_data/csharp/test_structure/concrete_class_with_descendants/meta_model.py +15 -0
  254. dev/test_data/csharp/test_structure/constructor_without_arguments/all_properties_optional/meta_model.py +9 -0
  255. dev/test_data/csharp/test_structure/constructor_without_arguments/no_properties/meta_model.py +6 -0
  256. dev/test_data/csharp/test_verification/builtin_functions/len/on_list/meta_model.py +20 -0
  257. dev/test_data/csharp/test_verification/builtin_functions/len/on_str/meta_model.py +16 -0
  258. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_prefix/meta_model.py +8 -0
  259. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_suffix/meta_model.py +8 -0
  260. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_group_with_quantifier/meta_model.py +8 -0
  261. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_the_middle/meta_model.py +8 -0
  262. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_union/meta_model.py +8 -0
  263. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/single_utf32_literal/meta_model.py +8 -0
  264. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_within_group/meta_model.py +8 -0
  265. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_without_group/meta_model.py +8 -0
  266. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_beginning/meta_model.py +8 -0
  267. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_end/meta_model.py +8 -0
  268. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/in_the_middle/meta_model.py +8 -0
  269. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/multiple/meta_model.py +8 -0
  270. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single/meta_model.py +8 -0
  271. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single_with_quantifier/meta_model.py +8 -0
  272. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/mixed_with_non_utf32/meta_model.py +8 -0
  273. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/more_than_two_high_surrogates/meta_model.py +8 -0
  274. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges/meta_model.py +8 -0
  275. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges_mixed_with_non_utf32/meta_model.py +8 -0
  276. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate/meta_model.py +8 -0
  277. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate_with_quantifier/meta_model.py +8 -0
  278. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/two_high_surrogates/meta_model.py +8 -0
  279. dev/test_data/intermediate/expected/class/empty/meta_model.py +6 -0
  280. dev/test_data/intermediate/expected/class/implementation_specific_method/meta_model.py +8 -0
  281. dev/test_data/intermediate/expected/class/inheritance/meta_model.py +41 -0
  282. dev/test_data/intermediate/expected/class/methods_with_contracts/meta_model.py +15 -0
  283. dev/test_data/intermediate/expected/class/only_method_no_property/meta_model.py +7 -0
  284. dev/test_data/intermediate/expected/class/only_property_no_method/meta_model.py +9 -0
  285. dev/test_data/intermediate/expected/constant/constant_set/of_enum/meta_model.py +12 -0
  286. dev/test_data/intermediate/expected/constant/constant_set/of_str/meta_model.py +4 -0
  287. dev/test_data/intermediate/expected/constant/constant_set/with_description/meta_model.py +6 -0
  288. dev/test_data/intermediate/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
  289. dev/test_data/intermediate/expected/constant/constant_str/only_value/meta_model.py +7 -0
  290. dev/test_data/intermediate/expected/constant/constant_str/with_description/meta_model.py +5 -0
  291. dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_in_literal/meta_model.py +20 -0
  292. dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_outside_literal/meta_model.py +20 -0
  293. dev/test_data/intermediate/expected/empty/meta_model.py +2 -0
  294. dev/test_data/intermediate/expected/enumeration/meta_model.py +9 -0
  295. dev/test_data/intermediate/expected/interface/basic/meta_model.py +14 -0
  296. dev/test_data/intermediate/expected/interface/empty/meta_model.py +7 -0
  297. dev/test_data/intermediate/expected/interface/inheritance/meta_model.py +27 -0
  298. dev/test_data/intermediate/expected/interface/method_signature/meta_model.py +10 -0
  299. dev/test_data/intermediate/expected/interface/only_constructor/meta_model.py +11 -0
  300. dev/test_data/intermediate/expected/method/non_mutating/implementation_specific/meta_model.py +12 -0
  301. dev/test_data/intermediate/expected/method/non_mutating/understood/meta_model.py +11 -0
  302. dev/test_data/intermediate/expected/type_annotation/atomic/meta_model.py +9 -0
  303. dev/test_data/intermediate/expected/type_annotation/subscripted/class/meta_model.py +13 -0
  304. dev/test_data/intermediate/expected/type_annotation/subscripted/primitive/meta_model.py +9 -0
  305. dev/test_data/intermediate/unexpected/constant_set/of_enum/enumeration_literals_in_subset_outside_of_superset/meta_model.py +20 -0
  306. dev/test_data/intermediate/unexpected/constant_set/of_enum/invalid_literal/meta_model.py +11 -0
  307. dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_between_enumeration_and_literal/meta_model.py +30 -0
  308. dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_in_enumerations_between_subset_and_superset/meta_model.py +21 -0
  309. dev/test_data/intermediate/unexpected/constant_set/of_str/literals_in_subset_outside_of_superset/meta_model.py +18 -0
  310. dev/test_data/intermediate/unexpected/constant_set/of_str/mismatch_between_type_annotation_and_literals/meta_model.py +10 -0
  311. dev/test_data/intermediate/unexpected/constant_set/of_str/superset_and_subset_mismatch_in_type/meta_model.py +12 -0
  312. dev/test_data/intermediate/unexpected/constraints/dangling_constraintref/meta_model.py +18 -0
  313. dev/test_data/intermediate/unexpected/constraints/duplicate_constraints/meta_model.py +20 -0
  314. dev/test_data/intermediate/unexpected/documentation/unexpected_documentation_elements/meta_model.py +34 -0
  315. dev/test_data/intermediate/unexpected/invariant/class_invariant_uses_re/meta_model.py +10 -0
  316. dev/test_data/intermediate/unexpected/invariant/invariant_of_constrained_primitive_uses_re/meta_model.py +7 -0
  317. dev/test_data/intermediate/unexpected/invariant/unexpected_argument_count_to_len/meta_model.py +20 -0
  318. dev/test_data/intermediate/unexpected/invariant/unhandled_built_in_function/meta_model.py +16 -0
  319. dev/test_data/intermediate/unexpected/method_definitions/non_constant_default/meta_model.py +7 -0
  320. dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/default_non_none/meta_model.py +16 -0
  321. dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/no_default/meta_model.py +16 -0
  322. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/after_inheritance/meta_model.py +58 -0
  323. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/type_missmatch/meta_model.py +9 -0
  324. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/within_class/meta_model.py +22 -0
  325. dev/test_data/jsonschema/test_main/regression_when_len_constraints_on_inherited_property/meta_model.py +28 -0
  326. dev/test_data/opcua/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
  327. dev/test_data/opcua/test_main/classes_with_invariants/meta_model.py +21 -0
  328. dev/test_data/opcua/test_main/concrete_class_with_descendant/meta_model.py +27 -0
  329. dev/test_data/opcua/test_main/concrete_class_with_enum/meta_model.py +21 -0
  330. dev/test_data/opcua/test_main/concrete_class_with_list_of_instances/meta_model.py +21 -0
  331. dev/test_data/opcua/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  332. dev/test_data/opcua/test_main/concrete_class_with_string/meta_model.py +13 -0
  333. dev/test_data/opcua/test_main/constrained_primitive/meta_model.py +20 -0
  334. dev/test_data/opcua/test_main/multiple_inheritance/meta_model.py +25 -0
  335. dev/test_data/parse/expected/constant/constant_set/of_enum/meta_model.py +12 -0
  336. dev/test_data/parse/expected/constant/constant_set/of_str/meta_model.py +4 -0
  337. dev/test_data/parse/expected/constant/constant_set/with_description/meta_model.py +6 -0
  338. dev/test_data/parse/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
  339. dev/test_data/parse/expected/constant/constant_str/only_value/meta_model.py +7 -0
  340. dev/test_data/parse/expected/constant/constant_str/with_description/meta_model.py +5 -0
  341. dev/test_data/parse/expected/enum/ok/meta_model.py +15 -0
  342. dev/test_data/parse/expected/implementation_specific_class/properties_and_methods_in_implementation_specific_class/meta_model.py +17 -0
  343. dev/test_data/parse/expected/inheritance/basic/meta_model.py +11 -0
  344. dev/test_data/parse/expected/inheritance/diamond/meta_model.py +26 -0
  345. dev/test_data/parse/expected/inheritance/inheritance_from_concrete_class/meta_model.py +10 -0
  346. dev/test_data/parse/expected/invariants/in_relation/meta_model.py +16 -0
  347. dev/test_data/parse/expected/method/arguments/meta_model.py +7 -0
  348. dev/test_data/parse/expected/method/basic/meta_model.py +7 -0
  349. dev/test_data/parse/expected/method/contracts/condition_as_keyword_argument/meta_model.py +8 -0
  350. dev/test_data/parse/expected/method/contracts/condition_as_positional_argument/meta_model.py +8 -0
  351. dev/test_data/parse/expected/method/contracts/description_as_keyword_argument/meta_model.py +8 -0
  352. dev/test_data/parse/expected/method/contracts/description_as_positional_argument/meta_model.py +8 -0
  353. dev/test_data/parse/expected/method/contracts/multiple_contracts_in_order/meta_model.py +17 -0
  354. dev/test_data/parse/expected/method/contracts/postcondition/basic/meta_model.py +10 -0
  355. dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_keyword_arguments/meta_model.py +9 -0
  356. dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_positional_arguments/meta_model.py +9 -0
  357. dev/test_data/parse/expected/method/default/meta_model.py +9 -0
  358. dev/test_data/parse/expected/method/description/meta_model.py +8 -0
  359. dev/test_data/parse/expected/method/is_implementation_specific/meta_model.py +8 -0
  360. dev/test_data/parse/expected/method/non_mutating/meta_model.py +11 -0
  361. dev/test_data/parse/expected/method/returns_none/meta_model.py +7 -0
  362. dev/test_data/parse/expected/method/returns_something/meta_model.py +7 -0
  363. dev/test_data/parse/expected/single_class/description/meta_model.py +12 -0
  364. dev/test_data/parse/expected/single_class/empty/meta_model.py +6 -0
  365. dev/test_data/parse/expected/single_class/property/description/meta_model.py +14 -0
  366. dev/test_data/parse/expected/single_class/property/mandatory/meta_model.py +6 -0
  367. dev/test_data/parse/expected/single_class/property/optional/meta_model.py +6 -0
  368. dev/test_data/parse/expected/single_class/property/recursion_to_entity/meta_model.py +6 -0
  369. dev/test_data/parse/unexpected/class_decorators/non_name_decorator/meta_model.py +7 -0
  370. dev/test_data/parse/unexpected/class_decorators/unknown_decorator/meta_model.py +7 -0
  371. dev/test_data/parse/unexpected/class_definitions/is_abstract_and_implementation_specific/meta_model.py +8 -0
  372. dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_before_a_method/meta_model.py +11 -0
  373. dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_for_a_pass/meta_model.py +9 -0
  374. dev/test_data/parse/unexpected/class_definitions/unexpected_double_description_for_a_property/meta_model.py +10 -0
  375. dev/test_data/parse/unexpected/class_inheritances/inheriting_from_implementation_specific_parent/meta_model.py +20 -0
  376. dev/test_data/parse/unexpected/class_inheritances/non_name_super_class/meta_model.py +6 -0
  377. dev/test_data/parse/unexpected/enum/expression_as_assignment_value/meta_model.py +6 -0
  378. dev/test_data/parse/unexpected/enum/non_assignment/meta_model.py +8 -0
  379. dev/test_data/parse/unexpected/enum/non_string_literal/meta_model.py +6 -0
  380. dev/test_data/parse/unexpected/enum/unexpected_inheritance/meta_model.py +6 -0
  381. dev/test_data/parse/unexpected/method_contracts/contract/non_lambda_condition/meta_model.py +8 -0
  382. dev/test_data/parse/unexpected/method_contracts/contract/non_string_literal_description/meta_model.py +8 -0
  383. dev/test_data/parse/unexpected/method_contracts/contract/without_any_arguments/meta_model.py +8 -0
  384. dev/test_data/parse/unexpected/method_contracts/contract/without_condition/meta_model.py +8 -0
  385. dev/test_data/parse/unexpected/method_contracts/postcondition/OLD_in_postcondition_without_snapshot/meta_model.py +8 -0
  386. dev/test_data/parse/unexpected/method_contracts/postcondition/argument_missing_in_function/meta_model.py +8 -0
  387. dev/test_data/parse/unexpected/method_contracts/precondition/argument_missing_in_function/meta_model.py +8 -0
  388. dev/test_data/parse/unexpected/method_contracts/snapshot/argument_missing_in_function/meta_model.py +8 -0
  389. dev/test_data/parse/unexpected/method_contracts/snapshot/capture_not_a_lambda/meta_model.py +8 -0
  390. dev/test_data/parse/unexpected/method_contracts/snapshot/invalid_name/meta_model.py +8 -0
  391. dev/test_data/parse/unexpected/method_contracts/snapshot/name_not_a_string_literal/meta_model.py +8 -0
  392. dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_capture/meta_model.py +8 -0
  393. dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_name/meta_model.py +8 -0
  394. dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_constructor/meta_model.py +8 -0
  395. dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_verification_function/meta_model.py +8 -0
  396. dev/test_data/parse/unexpected/method_decorators/non_name_decorator/meta_model.py +8 -0
  397. dev/test_data/parse/unexpected/method_decorators/unknown_call_decorator/meta_model.py +8 -0
  398. dev/test_data/parse/unexpected/method_decorators/unknown_name_decorator/meta_model.py +8 -0
  399. dev/test_data/parse/unexpected/method_definitions/argument_with_final/meta_model.py +7 -0
  400. dev/test_data/parse/unexpected/method_definitions/argument_without_a_type_annotation/meta_model.py +7 -0
  401. dev/test_data/parse/unexpected/method_definitions/default_for_self/meta_model.py +7 -0
  402. dev/test_data/parse/unexpected/method_definitions/dunder/meta_model.py +7 -0
  403. dev/test_data/parse/unexpected/method_definitions/init_with_return_type/meta_model.py +7 -0
  404. dev/test_data/parse/unexpected/method_definitions/with_keyword_only_arguments/meta_model.py +7 -0
  405. dev/test_data/parse/unexpected/method_definitions/with_positional_arguments/meta_model.py +7 -0
  406. dev/test_data/parse/unexpected/method_definitions/with_type_annotation_for_self/meta_model.py +7 -0
  407. dev/test_data/parse/unexpected/method_definitions/with_variable_arguments/meta_model.py +7 -0
  408. dev/test_data/parse/unexpected/method_definitions/with_variable_keyword_arguments/meta_model.py +7 -0
  409. dev/test_data/parse/unexpected/method_definitions/without_arguments/meta_model.py +7 -0
  410. dev/test_data/parse/unexpected/method_definitions/without_self/meta_model.py +7 -0
  411. dev/test_data/parse/unexpected/method_definitions/without_type_annotation_for_result/meta_model.py +7 -0
  412. dev/test_data/parse/unexpected/property_definitions/final_without_subscript/meta_model.py +6 -0
  413. dev/test_data/parse/unexpected/property_definitions/nested_final/meta_model.py +6 -0
  414. dev/test_data/parse/unexpected/property_definitions/non_simple/meta_model.py +6 -0
  415. dev/test_data/parse/unexpected/property_definitions/unexpected_assignment/meta_model.py +6 -0
  416. dev/test_data/parse/unexpected/property_definitions/unexpected_non_name_property/meta_model.py +6 -0
  417. dev/test_data/parse/unexpected/property_definitions/without_type_annotation/meta_model.py +6 -0
  418. dev/test_data/parse/unexpected/symbol_table/constant_set_with_a_non_set_subset/meta_model.py +6 -0
  419. dev/test_data/parse/unexpected/symbol_table/dangling_inheritance/meta_model.py +6 -0
  420. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_a_property/meta_model.py +6 -0
  421. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_an_argument/meta_model.py +7 -0
  422. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_constant_set/meta_model.py +6 -0
  423. dev/test_data/parse/unexpected/symbol_table/dangling_subset_in_constant_set/meta_model.py +4 -0
  424. dev/test_data/parse/unexpected/symbol_table/inheritance_from_non_class/meta_model.py +10 -0
  425. dev/test_data/parse_retree/expected/character_set/common_escaping/source.py +1 -0
  426. dev/test_data/parse_retree/expected/character_set/complementing/double_caret/source.py +1 -0
  427. dev/test_data/parse_retree/expected/character_set/complementing/multiple_ranges/source.py +1 -0
  428. dev/test_data/parse_retree/expected/character_set/complementing/suffix_dash/source.py +1 -0
  429. dev/test_data/parse_retree/expected/character_set/escape_first_caret/source.py +1 -0
  430. dev/test_data/parse_retree/expected/character_set/literals_which_need_no_escaping_in_characters_set_but_need_escaping_outside/source.py +1 -0
  431. dev/test_data/parse_retree/expected/character_set/multiple_ranges/source.py +1 -0
  432. dev/test_data/parse_retree/expected/character_set/single_literal/source.py +1 -0
  433. dev/test_data/parse_retree/expected/character_set/single_range/source.py +1 -0
  434. dev/test_data/parse_retree/expected/character_set/unescaped_dash/only_dash/source.py +1 -0
  435. dev/test_data/parse_retree/expected/character_set/unescaped_dash/prefix_dash/source.py +1 -0
  436. dev/test_data/parse_retree/expected/character_set/unescaped_dash/suffix_dash/source.py +1 -0
  437. dev/test_data/parse_retree/expected/dot/source.py +1 -0
  438. dev/test_data/parse_retree/expected/empty/group/source.py +1 -0
  439. dev/test_data/parse_retree/expected/empty/group_in_a_group/source.py +1 -0
  440. dev/test_data/parse_retree/expected/empty/group_of_union_of_empty_concatenations/source.py +1 -0
  441. dev/test_data/parse_retree/expected/empty/regex/source.py +1 -0
  442. dev/test_data/parse_retree/expected/empty/union_of_empty_concatenations/source.py +1 -0
  443. dev/test_data/parse_retree/expected/escaped_literals/source.py +1 -0
  444. dev/test_data/parse_retree/expected/formatted_value/at_the_beginning/source.py +1 -0
  445. dev/test_data/parse_retree/expected/formatted_value/at_the_end/source.py +1 -0
  446. dev/test_data/parse_retree/expected/formatted_value/in_the_middle/source.py +1 -0
  447. dev/test_data/parse_retree/expected/formatted_value/single_formatted_value/source.py +1 -0
  448. dev/test_data/parse_retree/expected/literal/source.py +1 -0
  449. dev/test_data/parse_retree/expected/quantifier/greedy/at_least_3/source.py +1 -0
  450. dev/test_data/parse_retree/expected/quantifier/greedy/at_least_one/source.py +1 -0
  451. dev/test_data/parse_retree/expected/quantifier/greedy/at_most_3/source.py +1 -0
  452. dev/test_data/parse_retree/expected/quantifier/greedy/exactly_3/source.py +1 -0
  453. dev/test_data/parse_retree/expected/quantifier/greedy/maybe/source.py +1 -0
  454. dev/test_data/parse_retree/expected/quantifier/greedy/zero_or_more/source.py +1 -0
  455. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_3/source.py +1 -0
  456. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_one/source.py +1 -0
  457. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_most_3/source.py +1 -0
  458. dev/test_data/parse_retree/expected/quantifier/non_greedy/exactly_3/source.py +1 -0
  459. dev/test_data/parse_retree/expected/quantifier/non_greedy/maybe/source.py +1 -0
  460. dev/test_data/parse_retree/expected/quantifier/non_greedy/zero_or_more/source.py +1 -0
  461. dev/test_data/parse_retree/expected/quantifier/on_a_character_set/source.py +1 -0
  462. dev/test_data/parse_retree/expected/quantifier/on_a_formatted_value/source.py +1 -0
  463. dev/test_data/parse_retree/expected/quantifier/on_a_group/source.py +1 -0
  464. dev/test_data/parse_retree/expected/quantifier/on_a_literal/source.py +1 -0
  465. dev/test_data/parse_retree/expected/start_and_stop_symbols/double_end_symbol/source.py +1 -0
  466. dev/test_data/parse_retree/expected/start_and_stop_symbols/double_start_symbol/source.py +1 -0
  467. dev/test_data/parse_retree/expected/start_and_stop_symbols/end_symbol_in_the_middle/source.py +1 -0
  468. dev/test_data/parse_retree/expected/start_and_stop_symbols/only_start_symbol/source.py +1 -0
  469. dev/test_data/parse_retree/expected/start_and_stop_symbols/only_stop_symbol/source.py +1 -0
  470. dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_at_the_beginning/source.py +1 -0
  471. dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_in_the_middle/source.py +1 -0
  472. dev/test_data/parse_retree/expected/start_and_stop_symbols/stop_symbol_at_the_end/source.py +1 -0
  473. dev/test_data/parse_retree/expected/union/of_character_sets/source.py +1 -0
  474. dev/test_data/parse_retree/expected/union/of_groups/source.py +1 -0
  475. dev/test_data/parse_retree/expected/union/of_string_literals/source.py +1 -0
  476. dev/test_data/parse_retree/expected/union/within_group/source.py +1 -0
  477. dev/test_data/parse_retree/expected/whitespace/source.py +1 -0
  478. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/Uxxxxxxxx_out_of_range/source.py +1 -0
  479. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/only_backslash/source.py +1 -0
  480. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_Uxxxxxxxx/source.py +1 -0
  481. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_uxxxx/source.py +1 -0
  482. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_x/source.py +1 -0
  483. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unexpected_escaping/source.py +1 -0
  484. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/digit/source.py +1 -0
  485. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_digit/source.py +1 -0
  486. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_whitespace/source.py +1 -0
  487. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_word/source.py +1 -0
  488. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/whitespace/source.py +1 -0
  489. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/word/source.py +1 -0
  490. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/Uxxxxxxxx_out_of_range/source.py +1 -0
  491. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/only_backslash/source.py +1 -0
  492. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_Uxxxxxxxx/source.py +1 -0
  493. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_uxxxx/source.py +1 -0
  494. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_x/source.py +1 -0
  495. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unexpected_escaping/source.py +1 -0
  496. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/digit/source.py +1 -0
  497. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_digit/source.py +1 -0
  498. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_whitespace/source.py +1 -0
  499. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_word/source.py +1 -0
  500. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/whitespace/source.py +1 -0
  501. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/word/source.py +1 -0
  502. dev/test_data/parse_retree/unexpected/invalid_character_range/source.py +1 -0
  503. dev/test_data/parse_retree/unexpected/invalid_quantifier/at_least_x/source.py +1 -0
  504. dev/test_data/parse_retree/unexpected/invalid_quantifier/between_3_and_x/source.py +1 -0
  505. dev/test_data/parse_retree/unexpected/invalid_quantifier/exactly_x/source.py +1 -0
  506. dev/test_data/parse_retree/unexpected/unhandled_group_directives/source.py +1 -0
  507. dev/test_data/parse_retree/unexpected/unterminated/character_set/source.py +1 -0
  508. dev/test_data/parse_retree/unexpected/unterminated/group/source.py +1 -0
  509. dev/test_data/parse_retree/unexpected/unterminated/group_of_union_of_empty_concatenations/source.py +1 -0
  510. dev/test_data/parse_retree/unexpected/unterminated/quantifier/source.py +1 -0
  511. dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_comma/source.py +1 -0
  512. dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_number_and_comma/source.py +1 -0
  513. dev/test_data/proto/test_main/expected/abstract_and_concrete_classes/meta_model.py +37 -0
  514. dev/test_data/proto/test_main/expected/concrete_class_with_descendants/meta_model.py +30 -0
  515. dev/test_data/proto/test_main/expected/concrete_class_with_enum/meta_model.py +21 -0
  516. dev/test_data/proto/test_main/expected/concrete_class_with_list_of_instances/meta_model.py +21 -0
  517. dev/test_data/proto/test_main/expected/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  518. dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/expected_output/pbization.py +532 -0
  519. dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
  520. dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/expected_output/pbization.py +527 -0
  521. dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/meta_model.py +27 -0
  522. dev/test_data/python_protobuf/test_main/concrete_class_with_enum/expected_output/pbization.py +290 -0
  523. dev/test_data/python_protobuf/test_main/concrete_class_with_enum/meta_model.py +21 -0
  524. dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/expected_output/pbization.py +328 -0
  525. dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/meta_model.py +23 -0
  526. dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/expected_output/pbization.py +274 -0
  527. dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  528. dev/test_data/rdf_shacl/test_main/expected/regression_when_lang_string_class_is_missing/meta_model.py +29 -0
  529. dev/test_data/rdf_shacl/test_main/expected/regression_when_len_constraints_on_inherited_property/meta_model.py +27 -0
  530. dev/test_data/rdf_shacl/test_main/unexpected/regression_len_constraint_on_class_property/meta_model.py +61 -0
  531. dev/test_data/real_meta_models/aas_core_meta.v3.py +5721 -0
  532. dev/test_data/smoke/test_main/unexpected/infer_for_schema_error/meta_model.py +12 -0
  533. dev/test_data/smoke/test_main/unexpected/intermediate_error/meta_model.py +18 -0
  534. dev/test_data/smoke/test_main/unexpected/parse_error/meta_model.py +5 -0
  535. dev/test_data/smoke/test_main/unexpected/pattern_verification_unparsable_regex/direct_match/meta_model.py +8 -0
  536. dev/test_data/smoke/test_main/unexpected/type_error/meta_model.py +18 -0
  537. dev/tests/__init__.py +1 -0
  538. dev/tests/common.py +197 -0
  539. dev/tests/cpp/__init__.py +0 -0
  540. dev/tests/cpp/test_common.py +32 -0
  541. dev/tests/cpp/test_main.py +144 -0
  542. dev/tests/cpp/test_pattern.py +188 -0
  543. dev/tests/cpp/test_verification.py +189 -0
  544. dev/tests/cpp/test_yielding.py +225 -0
  545. dev/tests/csharp/__init__.py +0 -0
  546. dev/tests/csharp/live_test_main.py +109 -0
  547. dev/tests/csharp/test_common.py +28 -0
  548. dev/tests/csharp/test_description.py +684 -0
  549. dev/tests/csharp/test_main.py +129 -0
  550. dev/tests/csharp/test_structure.py +93 -0
  551. dev/tests/csharp/test_verification.py +82 -0
  552. dev/tests/description.py +29 -0
  553. dev/tests/golang/__init__.py +0 -0
  554. dev/tests/golang/test_common.py +78 -0
  555. dev/tests/golang/test_main.py +128 -0
  556. dev/tests/infer_for_schema/__init__.py +0 -0
  557. dev/tests/infer_for_schema/common.py +47 -0
  558. dev/tests/infer_for_schema/test_len_on_properties.py +955 -0
  559. dev/tests/infer_for_schema/test_len_on_self.py +580 -0
  560. dev/tests/infer_for_schema/test_patterns_on_properties.py +686 -0
  561. dev/tests/infer_for_schema/test_patterns_on_self.py +258 -0
  562. dev/tests/infer_for_schema/test_property_in_set_of_enumeration_literals.py +600 -0
  563. dev/tests/infer_for_schema/test_property_in_set_of_primitives.py +549 -0
  564. dev/tests/intermediate/__init__.py +0 -0
  565. dev/tests/intermediate/test_constructor.py +719 -0
  566. dev/tests/intermediate/test_hierarchy.py +221 -0
  567. dev/tests/intermediate/test_revm.py +134 -0
  568. dev/tests/intermediate/test_translate.py +337 -0
  569. dev/tests/intermediate/test_type_inference.py +333 -0
  570. dev/tests/intermediate/test_types.py +169 -0
  571. dev/tests/java/__init__.py +0 -0
  572. dev/tests/java/test_common.py +20 -0
  573. dev/tests/java/test_description.py +128 -0
  574. dev/tests/java/test_main.py +234 -0
  575. dev/tests/jsonld_context/test_main.py +79 -0
  576. dev/tests/opcua/__init__.py +3 -0
  577. dev/tests/opcua/test_main.py +110 -0
  578. dev/tests/our_jsonschema/__init__.py +3 -0
  579. dev/tests/our_jsonschema/test_main.py +232 -0
  580. dev/tests/parse/__init__.py +0 -0
  581. dev/tests/parse/test_parse.py +503 -0
  582. dev/tests/parse/test_retree.py +272 -0
  583. dev/tests/proto/__init__.py +0 -0
  584. dev/tests/proto/test_main.py +112 -0
  585. dev/tests/python/__init__.py +0 -0
  586. dev/tests/python/test_common.py +124 -0
  587. dev/tests/python/test_main.py +126 -0
  588. dev/tests/python/test_xml_playground.py +254 -0
  589. dev/tests/python_protobuf/__init__.py +0 -0
  590. dev/tests/python_protobuf/test_main.py +111 -0
  591. dev/tests/rdf_shacl/__init__.py +0 -0
  592. dev/tests/rdf_shacl/test_common.py +32 -0
  593. dev/tests/rdf_shacl/test_description.py +223 -0
  594. dev/tests/rdf_shacl/test_main.py +194 -0
  595. dev/tests/smoke/__init__.py +0 -0
  596. dev/tests/smoke/test_main.py +83 -0
  597. dev/tests/test_common.py +94 -0
  598. dev/tests/typescript/__init__.py +0 -0
  599. dev/tests/typescript/test_common.py +108 -0
  600. dev/tests/typescript/test_main.py +125 -0
  601. dev/tests/xsd/__init__.py +0 -0
  602. dev/tests/xsd/test_main.py +227 -0
  603. dev/tests/yielding/__init__.py +0 -0
  604. dev/tests/yielding/test_linear.py +558 -0
@@ -0,0 +1,1471 @@
1
+ """Generate the invariant verifiers from the intermediate representation."""
2
+ import io
3
+ import textwrap
4
+ from typing import (
5
+ Tuple,
6
+ Optional,
7
+ List,
8
+ Sequence,
9
+ Mapping,
10
+ Union,
11
+ )
12
+
13
+ from icontract import ensure, require
14
+
15
+ from aas_core_codegen import intermediate, specific_implementations
16
+ from aas_core_codegen.common import (
17
+ Error,
18
+ Stripped,
19
+ assert_never,
20
+ Identifier,
21
+ indent_but_first_line,
22
+ wrap_text_into_lines,
23
+ assert_union_without_excluded,
24
+ )
25
+ from aas_core_codegen.python.common import (
26
+ INDENT as I,
27
+ INDENT2 as II,
28
+ INDENT3 as III,
29
+ INDENT4 as IIII,
30
+ )
31
+ from aas_core_codegen.intermediate import type_inference as intermediate_type_inference
32
+ from aas_core_codegen.parse import tree as parse_tree, retree as parse_retree
33
+ from aas_core_codegen.python import (
34
+ common as python_common,
35
+ naming as python_naming,
36
+ description as python_description,
37
+ transpilation as python_transpilation,
38
+ )
39
+
40
+
41
+ # region Verify
42
+
43
+
44
+ def verify(
45
+ spec_impls: specific_implementations.SpecificImplementations,
46
+ verification_functions: Sequence[intermediate.Verification],
47
+ ) -> Optional[List[str]]:
48
+ """Verify all the implementation snippets related to verification."""
49
+ errors = [] # type: List[str]
50
+
51
+ expected_keys = [] # type: List[specific_implementations.ImplementationKey]
52
+
53
+ for func in verification_functions:
54
+ if isinstance(func, intermediate.ImplementationSpecificVerification):
55
+ expected_keys.append(
56
+ specific_implementations.ImplementationKey(
57
+ f"Verification/{func.name}.py"
58
+ ),
59
+ )
60
+
61
+ for key in expected_keys:
62
+ if key not in spec_impls:
63
+ errors.append(f"The implementation snippet is missing for: {key}")
64
+
65
+ if len(errors) == 0:
66
+ return None
67
+
68
+ return errors
69
+
70
+
71
+ # endregion
72
+
73
+ # region Generate
74
+
75
+
76
+ class _PatternVerificationTranspiler(
77
+ parse_tree.RestrictedTransformer[Tuple[Optional[Stripped], Optional[Error]]]
78
+ ):
79
+ """Transpile a statement of a pattern verification into Python."""
80
+
81
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
82
+ def _transform_joined_str_values(
83
+ self, values: Sequence[Union[str, parse_tree.FormattedValue]]
84
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
85
+ """Transform the values of a joined string to a Python string literal."""
86
+ # If we do not need interpolation, simply return the string literals
87
+ # joined together by newlines.
88
+ needs_interpolation = any(
89
+ isinstance(value, parse_tree.FormattedValue) for value in values
90
+ )
91
+ if not needs_interpolation:
92
+ return (
93
+ Stripped(
94
+ python_common.string_literal(
95
+ "".join(value for value in values) # type: ignore
96
+ )
97
+ ),
98
+ None,
99
+ )
100
+
101
+ parts = [] # type: List[str]
102
+
103
+ # NOTE (mristin, 2022-09-30):
104
+ # See which quotes occur more often in the non-interpolated parts, so that we
105
+ # pick the escaping scheme which will result in as little escapes as possible.
106
+ double_quotes_count = 0
107
+ single_quotes_count = 0
108
+
109
+ for value in values:
110
+ if isinstance(value, str):
111
+ double_quotes_count += value.count('"')
112
+ single_quotes_count += value.count("'")
113
+
114
+ elif isinstance(value, parse_tree.FormattedValue):
115
+ pass
116
+ else:
117
+ assert_never(value)
118
+
119
+ # Pick the escaping scheme
120
+ if single_quotes_count <= double_quotes_count:
121
+ enclosing = "'"
122
+ quoting = python_common.StringQuoting.SINGLE_QUOTES
123
+ else:
124
+ enclosing = '"'
125
+ quoting = python_common.StringQuoting.DOUBLE_QUOTES
126
+
127
+ for value in values:
128
+ if isinstance(value, str):
129
+ parts.append(
130
+ python_common.string_literal(
131
+ value,
132
+ quoting=quoting,
133
+ without_enclosing=True,
134
+ duplicate_curly_brackets=True,
135
+ )
136
+ )
137
+
138
+ elif isinstance(value, parse_tree.FormattedValue):
139
+ code, error = self.transform(value.value)
140
+ if error is not None:
141
+ return None, error
142
+
143
+ assert code is not None
144
+
145
+ assert (
146
+ "\n" not in code
147
+ ), f"New-lines are not expected in formatted values, but got: {code}"
148
+
149
+ parts.append(f"{{{code}}}")
150
+ else:
151
+ assert_never(value)
152
+
153
+ writer = io.StringIO()
154
+ writer.write("f")
155
+ writer.write(enclosing)
156
+ for part in parts:
157
+ writer.write(part)
158
+ writer.write(enclosing)
159
+
160
+ return Stripped(writer.getvalue()), None
161
+
162
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
163
+ def transform_constant(
164
+ self, node: parse_tree.Constant
165
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
166
+ if isinstance(node.value, str):
167
+ # NOTE (mristin, 2022-06-11):
168
+ # We assume that all the string constants are valid regular expressions.
169
+
170
+ regex, parse_error = parse_retree.parse(values=[node.value])
171
+ if parse_error is not None:
172
+ regex_line, pointer_line = parse_retree.render_pointer(
173
+ parse_error.cursor
174
+ )
175
+
176
+ return (
177
+ None,
178
+ Error(
179
+ node.original_node,
180
+ f"The string constant could not be parsed "
181
+ f"as a regular expression: \n"
182
+ f"{parse_error.message}\n"
183
+ f"{regex_line}\n"
184
+ f"{pointer_line}",
185
+ ),
186
+ )
187
+
188
+ assert regex is not None
189
+
190
+ # NOTE (mristin, 2022-09-30):
191
+ # Strictly speaking, this is a joined string with a single value, a string
192
+ # literal.
193
+ return self._transform_joined_str_values(
194
+ values=parse_retree.render(regex=regex)
195
+ )
196
+ else:
197
+ raise AssertionError(f"Unexpected {node=}")
198
+
199
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
200
+ def transform_name(
201
+ self, node: parse_tree.Name
202
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
203
+ return Stripped(python_naming.variable_name(node.identifier)), None
204
+
205
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
206
+ def transform_joined_str(
207
+ self, node: parse_tree.JoinedStr
208
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
209
+ regex, parse_error = parse_retree.parse(values=node.values)
210
+ if parse_error is not None:
211
+ regex_line, pointer_line = parse_retree.render_pointer(parse_error.cursor)
212
+
213
+ return (
214
+ None,
215
+ Error(
216
+ node.original_node,
217
+ f"The joined string could not be parsed "
218
+ f"as a regular expression: \n"
219
+ f"{parse_error.message}\n"
220
+ f"{regex_line}\n"
221
+ f"{pointer_line}",
222
+ ),
223
+ )
224
+
225
+ assert regex is not None
226
+
227
+ return self._transform_joined_str_values(
228
+ values=parse_retree.render(regex=regex)
229
+ )
230
+
231
+ def transform_assignment(
232
+ self, node: parse_tree.Assignment
233
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
234
+ assert isinstance(node.target, parse_tree.Name)
235
+ variable = python_naming.variable_name(node.target.identifier)
236
+ code, error = self.transform(node.value)
237
+ if error is not None:
238
+ return None, error
239
+ assert code is not None
240
+
241
+ return Stripped(f"{variable} = {code}"), None
242
+
243
+
244
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
245
+ def _transpile_pattern_verification(
246
+ verification: intermediate.PatternVerification,
247
+ aas_module: python_common.QualifiedModuleName,
248
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
249
+ """Generate the verification function that checks the regular expressions."""
250
+ # NOTE (mristin, 2022-09-30):
251
+ # We assume that we performed all the checks at the intermediate stage.
252
+
253
+ construct_name = python_naming.function_name(
254
+ Identifier(f"_construct_{verification.name}")
255
+ )
256
+
257
+ blocks = [] # type: List[Stripped]
258
+
259
+ # region Construct block
260
+
261
+ writer = io.StringIO()
262
+ writer.write(
263
+ f"""\
264
+ # noinspection SpellCheckingInspection
265
+ def {construct_name}() -> Pattern[str]:
266
+ """
267
+ )
268
+
269
+ transpiler = _PatternVerificationTranspiler()
270
+
271
+ for i, stmt in enumerate(verification.parsed.body):
272
+ if i == len(verification.parsed.body) - 1:
273
+ break
274
+
275
+ code, error = transpiler.transform(stmt)
276
+ if error is not None:
277
+ return None, error
278
+ assert code is not None
279
+
280
+ writer.write(textwrap.indent(code, I))
281
+ writer.write("\n")
282
+
283
+ if len(verification.parsed.body) >= 2:
284
+ writer.write("\n")
285
+
286
+ pattern_expr, error = transpiler.transform(verification.pattern_expr)
287
+ if error is not None:
288
+ return None, error
289
+ assert pattern_expr is not None
290
+
291
+ # A pragmatic heuristics for breaking lines
292
+ if len(pattern_expr) < 50:
293
+ writer.write(textwrap.indent(f"return re.compile({pattern_expr})", I))
294
+ else:
295
+ writer.write(
296
+ textwrap.indent(
297
+ f"""\
298
+ return re.compile(
299
+ {I}{indent_but_first_line(pattern_expr, I)}
300
+ )""",
301
+ I,
302
+ )
303
+ )
304
+
305
+ blocks.append(Stripped(writer.getvalue()))
306
+
307
+ # endregion
308
+
309
+ # region Initialize the regex
310
+
311
+ regex_name = python_naming.constant_name(Identifier(f"_regex_{verification.name}"))
312
+
313
+ blocks.append(Stripped(f"{regex_name} = {construct_name}()"))
314
+
315
+ assert len(verification.arguments) == 1
316
+ assert isinstance(
317
+ verification.arguments[0].type_annotation, intermediate.PrimitiveTypeAnnotation
318
+ )
319
+ # noinspection PyUnresolvedReferences
320
+ assert (
321
+ verification.arguments[0].type_annotation.a_type
322
+ == intermediate.PrimitiveType.STR
323
+ )
324
+
325
+ arg_name = python_naming.argument_name(verification.arguments[0].name)
326
+
327
+ function_name = python_naming.function_name(verification.name)
328
+
329
+ writer = io.StringIO()
330
+ writer.write(
331
+ f"""\
332
+ def {function_name}({arg_name}: str) -> bool:
333
+ """
334
+ )
335
+
336
+ if verification.description is not None:
337
+ (
338
+ docstring,
339
+ docstring_errors,
340
+ ) = python_description.generate_docstring_for_signature(
341
+ description=verification.description,
342
+ context=python_description.Context(
343
+ aas_module=aas_module,
344
+ module=Identifier("verification"),
345
+ cls_or_enum=None,
346
+ ),
347
+ )
348
+ if docstring_errors is not None:
349
+ return None, Error(
350
+ verification.description.parsed.node,
351
+ "Failed to generate the docstring",
352
+ docstring_errors,
353
+ )
354
+
355
+ assert docstring is not None
356
+
357
+ writer.write(textwrap.indent(docstring, I))
358
+ writer.write("\n")
359
+
360
+ writer.write(f"{I}return {regex_name}.match({arg_name}) is not None")
361
+
362
+ blocks.append(Stripped(writer.getvalue()))
363
+
364
+ # endregion
365
+
366
+ writer = io.StringIO()
367
+ for i, block in enumerate(blocks):
368
+ if i > 0:
369
+ writer.write("\n\n\n")
370
+
371
+ writer.write(block)
372
+
373
+ return Stripped(writer.getvalue()), None
374
+
375
+
376
+ class _TranspilableVerificationTranspiler(python_transpilation.Transpiler):
377
+ """Transpile the body of a :class:`.TranspilableVerification`."""
378
+
379
+ # fmt: off
380
+ @require(
381
+ lambda environment, verification:
382
+ all(
383
+ environment.find(arg.name) is not None
384
+ for arg in verification.arguments
385
+ ),
386
+ "All arguments defined in the environment"
387
+ )
388
+ # fmt: on
389
+ def __init__(
390
+ self,
391
+ type_map: Mapping[
392
+ parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
393
+ ],
394
+ environment: intermediate_type_inference.Environment,
395
+ symbol_table: intermediate.SymbolTable,
396
+ verification: intermediate.TranspilableVerification,
397
+ ) -> None:
398
+ """Initialize with the given values."""
399
+ python_transpilation.Transpiler.__init__(
400
+ self, type_map=type_map, environment=environment
401
+ )
402
+
403
+ self._symbol_table = symbol_table
404
+
405
+ self._argument_name_set = frozenset(arg.name for arg in verification.arguments)
406
+
407
+ def transform_name(
408
+ self, node: parse_tree.Name
409
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
410
+ if node.identifier in self._variable_name_set:
411
+ return Stripped(python_naming.variable_name(node.identifier)), None
412
+
413
+ if node.identifier in self._argument_name_set:
414
+ return Stripped(python_naming.argument_name(node.identifier)), None
415
+
416
+ if node.identifier in self._symbol_table.constants_by_name:
417
+ constant_name = python_naming.constant_name(node.identifier)
418
+ return Stripped(f"aas_constants.{constant_name}"), None
419
+
420
+ if node.identifier in self._symbol_table.verification_functions_by_name:
421
+ return Stripped(python_naming.function_name(node.identifier)), None
422
+
423
+ our_type = self._symbol_table.find_our_type(name=node.identifier)
424
+ if isinstance(our_type, intermediate.Enumeration):
425
+ return (
426
+ Stripped(f"aas_types.{python_naming.enum_name(node.identifier)}"),
427
+ None,
428
+ )
429
+
430
+ return None, Error(
431
+ node.original_node,
432
+ f"We can not determine how to transpile the name {node.identifier!r} "
433
+ f"to Python. We could not find it neither in the constants, nor in "
434
+ f"verification functions, nor as an enumeration. "
435
+ f"If you expect this name to be transpilable, please contact "
436
+ f"the developers.",
437
+ )
438
+
439
+
440
+ def _transpile_transpilable_verification(
441
+ verification: intermediate.TranspilableVerification,
442
+ symbol_table: intermediate.SymbolTable,
443
+ environment: intermediate_type_inference.Environment,
444
+ aas_module: python_common.QualifiedModuleName,
445
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
446
+ """Transpile a verification function."""
447
+ # fmt: off
448
+ type_inference, error = (
449
+ intermediate_type_inference.infer_for_verification(
450
+ verification=verification,
451
+ base_environment=environment
452
+ )
453
+ )
454
+ # fmt: on
455
+
456
+ if error is not None:
457
+ return None, error
458
+
459
+ assert type_inference is not None
460
+
461
+ transpiler = _TranspilableVerificationTranspiler(
462
+ type_map=type_inference.type_map,
463
+ environment=type_inference.environment_with_args,
464
+ symbol_table=symbol_table,
465
+ verification=verification,
466
+ )
467
+
468
+ body = [] # type: List[Stripped]
469
+ for node in verification.parsed.body:
470
+ stmt, error = transpiler.transform(node)
471
+ if error is not None:
472
+ return None, Error(
473
+ verification.parsed.node,
474
+ f"Failed to transpile the verification function {verification.name!r}",
475
+ [error],
476
+ )
477
+
478
+ assert stmt is not None
479
+ body.append(stmt)
480
+
481
+ writer = io.StringIO()
482
+
483
+ function_name = python_naming.function_name(verification.name)
484
+
485
+ if verification.returns is None:
486
+ return_type = "None"
487
+ else:
488
+ return_type = python_common.generate_type(
489
+ type_annotation=verification.returns, types_module=Identifier("aas_types")
490
+ )
491
+
492
+ arg_defs = [] # type: List[Stripped]
493
+ for arg in verification.arguments:
494
+ arg_type = python_common.generate_type(
495
+ arg.type_annotation, types_module=Identifier("aas_types")
496
+ )
497
+ arg_name = python_naming.argument_name(arg.name)
498
+ arg_defs.append(Stripped(f"{arg_name}: {arg_type}"))
499
+
500
+ if len(arg_defs) == 0:
501
+ writer.write(
502
+ f"""\
503
+ def {function_name}() -> {return_type}:"""
504
+ )
505
+ else:
506
+ writer.write(
507
+ f"""\
508
+ def {function_name}(
509
+ """
510
+ )
511
+
512
+ for i, arg_def in enumerate(arg_defs):
513
+ if i > 0:
514
+ writer.write(",\n")
515
+ writer.write(textwrap.indent(arg_def, I))
516
+
517
+ writer.write("\n")
518
+ writer.write(
519
+ f"""\
520
+ ) -> {return_type}:"""
521
+ )
522
+
523
+ docstring = None # type: Optional[Stripped]
524
+ if verification.description is not None:
525
+ (
526
+ docstring,
527
+ docstring_errors,
528
+ ) = python_description.generate_docstring_for_signature(
529
+ description=verification.description,
530
+ context=python_description.Context(
531
+ aas_module=aas_module,
532
+ module=Identifier("verification"),
533
+ cls_or_enum=None,
534
+ ),
535
+ )
536
+ if docstring_errors is not None:
537
+ return None, Error(
538
+ verification.description.parsed.node,
539
+ "Failed to generate the docstring",
540
+ docstring_errors,
541
+ )
542
+
543
+ assert docstring is not None
544
+
545
+ writer.write("\n")
546
+ writer.write(textwrap.indent(docstring, I))
547
+
548
+ writer.write(f"\n{I}# pylint: disable=all")
549
+
550
+ if docstring is None and len(body) == 0:
551
+ writer.write(f"\n{I}pass")
552
+
553
+ for stmt in body:
554
+ writer.write("\n")
555
+ writer.write(textwrap.indent(stmt, I))
556
+
557
+ return Stripped(writer.getvalue()), None
558
+
559
+
560
+ class _InvariantTranspiler(python_transpilation.Transpiler):
561
+ def __init__(
562
+ self,
563
+ type_map: Mapping[
564
+ parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
565
+ ],
566
+ environment: intermediate_type_inference.Environment,
567
+ symbol_table: intermediate.SymbolTable,
568
+ ) -> None:
569
+ """Initialize with the given values."""
570
+ python_transpilation.Transpiler.__init__(
571
+ self, type_map=type_map, environment=environment
572
+ )
573
+
574
+ self._symbol_table = symbol_table
575
+
576
+ def transform_name(
577
+ self, node: parse_tree.Name
578
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
579
+ if node.identifier in self._variable_name_set:
580
+ return Stripped(python_naming.variable_name(node.identifier)), None
581
+
582
+ if node.identifier == "self":
583
+ # The ``that`` refers to the argument of the verification function.
584
+ return Stripped("that"), None
585
+
586
+ if node.identifier in self._symbol_table.constants_by_name:
587
+ constant_name = python_naming.constant_name(node.identifier)
588
+ return Stripped(f"aas_constants.{constant_name}"), None
589
+
590
+ if node.identifier in self._symbol_table.verification_functions_by_name:
591
+ return Stripped(python_naming.function_name(node.identifier)), None
592
+
593
+ our_type = self._symbol_table.find_our_type(name=node.identifier)
594
+ if isinstance(our_type, intermediate.Enumeration):
595
+ return (
596
+ Stripped(f"aas_types.{python_naming.enum_name(node.identifier)}"),
597
+ None,
598
+ )
599
+
600
+ return None, Error(
601
+ node.original_node,
602
+ f"We can not determine how to transpile the name {node.identifier!r} "
603
+ f"to Python. We could not find it neither in the local variables, "
604
+ f"nor in the global constants, nor in verification functions, "
605
+ f"nor as an enumeration. If you expect this name to be transpilable, "
606
+ f"please contact the developers.",
607
+ )
608
+
609
+
610
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
611
+ def _transpile_invariant(
612
+ invariant: intermediate.Invariant,
613
+ symbol_table: intermediate.SymbolTable,
614
+ environment: intermediate_type_inference.Environment,
615
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
616
+ """Translate the invariant from the meta-model into Python code."""
617
+ # fmt: off
618
+ type_map, inference_error = (
619
+ intermediate_type_inference.infer_for_invariant(
620
+ invariant=invariant,
621
+ environment=environment
622
+ )
623
+ )
624
+ # fmt: on
625
+
626
+ if inference_error is not None:
627
+ return None, inference_error
628
+
629
+ assert type_map is not None
630
+
631
+ transpiler = _InvariantTranspiler(
632
+ type_map=type_map,
633
+ environment=environment,
634
+ symbol_table=symbol_table,
635
+ )
636
+
637
+ expr, error = transpiler.transform(invariant.parsed.body)
638
+ if error is not None:
639
+ return None, error
640
+
641
+ assert expr is not None
642
+
643
+ writer = io.StringIO()
644
+ if len(expr) > 50 or "\n" in expr:
645
+ writer.write("if not (\n")
646
+ writer.write(textwrap.indent(expr, I))
647
+ writer.write("\n):\n")
648
+ else:
649
+ no_parenthesis_type_in_this_context = (
650
+ parse_tree.Index,
651
+ parse_tree.Name,
652
+ parse_tree.Member,
653
+ parse_tree.MethodCall,
654
+ parse_tree.FunctionCall,
655
+ )
656
+
657
+ if isinstance(invariant.parsed.body, no_parenthesis_type_in_this_context):
658
+ not_expr = f"not {expr}"
659
+ else:
660
+ not_expr = f"not ({expr})"
661
+
662
+ writer.write(f"if {not_expr}:\n")
663
+
664
+ writer.write(f"{I}yield Error(\n")
665
+
666
+ # NOTE (mristin, 2022-09-30):
667
+ # We need to wrap the description in multiple literals as a single long
668
+ # string literal is often too much for the readability.
669
+ invariant_description_lines = wrap_text_into_lines(invariant.description)
670
+
671
+ for i, literal in enumerate(invariant_description_lines):
672
+ if i < len(invariant_description_lines) - 1:
673
+ writer.write(f"{II}{python_common.string_literal(literal)} +\n")
674
+ else:
675
+ writer.write(f"{II}{python_common.string_literal(literal)}\n")
676
+ writer.write(f"{I})")
677
+
678
+ return Stripped(writer.getvalue()), None
679
+
680
+
681
+ OurTypeExceptEnumeration = Union[
682
+ intermediate.ConstrainedPrimitive,
683
+ intermediate.AbstractClass,
684
+ intermediate.ConcreteClass,
685
+ ]
686
+ assert_union_without_excluded(
687
+ original_union=intermediate.OurType,
688
+ subset_union=OurTypeExceptEnumeration,
689
+ excluded=[intermediate.Enumeration],
690
+ )
691
+
692
+
693
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
694
+ def _generate_verify_property_snippet(
695
+ prop: intermediate.Property,
696
+ generator_for_loop_variables: python_common.GeneratorForLoopVariables,
697
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
698
+ """
699
+ Generate the snippet to transform a property to verification errors.
700
+
701
+ Return an empty string if there is nothing to be verified for the given property.
702
+ """
703
+ # NOTE (mristin, 2022-10-01):
704
+ # Instead of writing here a complex but general solution with unrolling we choose
705
+ # to provide a simple, but limited, solution. First, the meta-model is quite
706
+ # limited itself at the moment, so the complexity of the general solution is not
707
+ # warranted. Second, we hope that there will be fewer bugs in the simple solution
708
+ # which is particularly important at this early adoption stage.
709
+ #
710
+ # We anticipate that in the future we will indeed need a general and complex
711
+ # solution. Here are just some thoughts on how to approach it:
712
+ # * Leave the pattern matching to produce more readable code for simple cases,
713
+ # * Unroll only in case of composite types and optional composite types.
714
+
715
+ type_anno = (
716
+ prop.type_annotation
717
+ if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation)
718
+ else prop.type_annotation.value
719
+ )
720
+
721
+ if isinstance(type_anno, intermediate.OptionalTypeAnnotation):
722
+ return None, Error(
723
+ prop.parsed.node,
724
+ "We currently implemented verification based on a very limited "
725
+ "pattern matching due to code simplicity. We did not handle "
726
+ "the case of nested optional values. Please contact "
727
+ "the developers if you need this functionality.",
728
+ )
729
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
730
+ if isinstance(type_anno.items, intermediate.OptionalTypeAnnotation):
731
+ return None, Error(
732
+ prop.parsed.node,
733
+ "We currently implemented verification based on a very limited "
734
+ "pattern matching due to code simplicity. We did not handle "
735
+ "the case of lists of optional values. Please contact "
736
+ "the developers if you need this functionality.",
737
+ )
738
+ elif isinstance(type_anno.items, intermediate.ListTypeAnnotation):
739
+ return None, Error(
740
+ prop.parsed.node,
741
+ "We currently implemented verification based on a very limited "
742
+ "pattern matching due to code simplicity. We did not handle "
743
+ "the case of lists of lists. Please contact "
744
+ "the developers if you need this functionality.",
745
+ )
746
+ else:
747
+ pass
748
+ else:
749
+ pass
750
+
751
+ stmts = [] # type: List[Stripped]
752
+
753
+ prop_name = python_naming.property_name(prop.name)
754
+ prop_name_literal = python_common.string_literal(prop_name)
755
+
756
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
757
+ # There is nothing that we check for primitive types explicitly. The values
758
+ # of the primitive properties are checked at the level of class invariants.
759
+ return Stripped(""), None
760
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
761
+ if isinstance(type_anno.our_type, intermediate.Enumeration):
762
+ # We rely on mypy to check for valid enumerations, so we do not check
763
+ # the enumerations on our side.
764
+ return Stripped(""), None
765
+
766
+ elif isinstance(type_anno.our_type, intermediate.ConstrainedPrimitive):
767
+ function_name = python_naming.function_name(
768
+ Identifier(f"verify_{type_anno.our_type.name}")
769
+ )
770
+
771
+ for_error_in_verify = f"for error in {function_name}(that.{prop_name})"
772
+ # Heuristic to break the lines, very rudimentary
773
+ if len(for_error_in_verify) > 70:
774
+ for_error_in_verify = f"""\
775
+ for error in {function_name}(
776
+ {II}that.{prop_name}
777
+ )"""
778
+
779
+ stmts.append(
780
+ Stripped(
781
+ f"""\
782
+ {for_error_in_verify}:
783
+ {I}error.path._prepend(
784
+ {II}PropertySegment(
785
+ {III}that,
786
+ {III}{prop_name_literal}
787
+ {II})
788
+ {I})
789
+ {I}yield error"""
790
+ )
791
+ )
792
+
793
+ elif isinstance(
794
+ type_anno.our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
795
+ ):
796
+ for_error_in_self_transform = (
797
+ f"for error in self.transform(that.{prop_name})"
798
+ )
799
+ # Heuristic to break the lines, very rudimentary
800
+ if len(for_error_in_self_transform) > 70:
801
+ for_error_in_self_transform = f"""\
802
+ for error in self.transform(
803
+ {II}that.{prop_name}
804
+ )"""
805
+
806
+ stmts.append(
807
+ Stripped(
808
+ f"""\
809
+ {for_error_in_self_transform}:
810
+ {I}error.path._prepend(
811
+ {II}PropertySegment(
812
+ {III}that,
813
+ {III}{prop_name_literal}
814
+ {II})
815
+ {I})
816
+ {I}yield error"""
817
+ )
818
+ )
819
+ else:
820
+ assert_never(type_anno.our_type)
821
+
822
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
823
+ assert not isinstance(
824
+ type_anno.items,
825
+ (intermediate.OptionalTypeAnnotation, intermediate.ListTypeAnnotation),
826
+ ), (
827
+ "We chose to implement only a very limited pattern matching; "
828
+ "see the note above in the code."
829
+ )
830
+
831
+ # NOTE (mristin, 2022-10-01):
832
+ # We only descend into our classes here.
833
+ if not isinstance(type_anno.items, intermediate.OurTypeAnnotation):
834
+ return Stripped(""), None
835
+
836
+ loop_variable = next(generator_for_loop_variables)
837
+
838
+ for_i_item_in_that_prop = (
839
+ f"for i, {loop_variable} in enumerate(that.{prop_name})"
840
+ )
841
+
842
+ # Rudimentary heuristics for line breaking
843
+ if len(for_i_item_in_that_prop) > 70:
844
+ for_i_item_in_that_prop = f"""\
845
+ for i, {loop_variable} in enumerate(
846
+ {II}that.{prop_name}
847
+ )"""
848
+
849
+ for_error_in_self_transform = f"for error in self.transform({loop_variable})"
850
+ if len(for_error_in_self_transform) > 70:
851
+ for_error_in_self_transform = f"""\
852
+ for error in self.transform(
853
+ {II}{loop_variable}
854
+ )"""
855
+
856
+ stmts.append(
857
+ Stripped(
858
+ f"""\
859
+ {for_i_item_in_that_prop}:
860
+ {I}{indent_but_first_line(for_error_in_self_transform, I)}:
861
+ {II}error.path._prepend(
862
+ {III}IndexSegment(
863
+ {IIII}that.{prop_name},
864
+ {IIII}i
865
+ {III})
866
+ {II})
867
+ {II}error.path._prepend(
868
+ {III}PropertySegment(
869
+ {IIII}that,
870
+ {IIII}{prop_name_literal}
871
+ {III})
872
+ {II})
873
+ {II}yield error"""
874
+ )
875
+ )
876
+
877
+ else:
878
+ assert_never(type_anno)
879
+
880
+ verify_block = Stripped("\n".join(stmts))
881
+
882
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
883
+ return (
884
+ Stripped(
885
+ f"""\
886
+ if that.{prop_name} is not None:
887
+ {I}{indent_but_first_line(verify_block, I)}"""
888
+ ),
889
+ None,
890
+ )
891
+
892
+ return verify_block, None
893
+
894
+
895
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
896
+ def _generate_transform_for_class(
897
+ cls: intermediate.ConcreteClass,
898
+ symbol_table: intermediate.SymbolTable,
899
+ base_environment: intermediate_type_inference.Environment,
900
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
901
+ """Generate the transform method to errors for the given concrete class."""
902
+ errors = [] # type: List[Error]
903
+ blocks = [] # type: List[Stripped]
904
+
905
+ environment = intermediate_type_inference.MutableEnvironment(
906
+ parent=base_environment
907
+ )
908
+
909
+ assert environment.find(Identifier("self")) is None
910
+ environment.set(
911
+ identifier=Identifier("self"),
912
+ type_annotation=intermediate_type_inference.OurTypeAnnotation(our_type=cls),
913
+ )
914
+
915
+ for invariant in cls.invariants:
916
+ invariant_code, error = _transpile_invariant(
917
+ invariant=invariant, symbol_table=symbol_table, environment=environment
918
+ )
919
+ if error is not None:
920
+ errors.append(
921
+ Error(
922
+ cls.parsed.node,
923
+ f"Failed to transpile the invariant of the class {cls.name!r}",
924
+ [error],
925
+ )
926
+ )
927
+ continue
928
+
929
+ assert invariant_code is not None
930
+
931
+ blocks.append(invariant_code)
932
+
933
+ if len(errors) > 0:
934
+ return None, errors
935
+
936
+ # NOTE (mristin, 2022-10-14):
937
+ # We need to generate unique loop variable for each loop since Python tracks
938
+ # the variables in function scope, not block scope.
939
+ generator_for_loop_variables = python_common.GeneratorForLoopVariables()
940
+
941
+ for prop in cls.properties:
942
+ block, error = _generate_verify_property_snippet(
943
+ prop=prop, generator_for_loop_variables=generator_for_loop_variables
944
+ )
945
+ if error is not None:
946
+ errors.append(error)
947
+ else:
948
+ assert block is not None
949
+ if block != "":
950
+ blocks.append(block)
951
+
952
+ if len(errors) > 0:
953
+ return None, errors
954
+
955
+ cls_name = python_naming.class_name(cls.name)
956
+
957
+ if len(blocks) == 0:
958
+ blocks.append(
959
+ Stripped(
960
+ f"""\
961
+ # No verification has been defined for {cls_name}.
962
+ return
963
+ # For this uncommon return-yield construction, see:
964
+ # https://stackoverflow.com/questions/13243766/how-to-define-an-empty-generator-function
965
+ # noinspection PyUnreachableCode
966
+ yield"""
967
+ )
968
+ )
969
+
970
+ transform_name = python_naming.method_name(Identifier(f"transform_{cls.name}"))
971
+
972
+ writer = io.StringIO()
973
+ writer.write(
974
+ f"""\
975
+ # noinspection PyMethodMayBeStatic
976
+ def {transform_name}(
977
+ {II}self,
978
+ {II}that: aas_types.{cls_name}
979
+ ) -> Iterator[Error]:
980
+ """
981
+ )
982
+
983
+ for i, stmt in enumerate(blocks):
984
+ if i > 0:
985
+ writer.write("\n\n")
986
+ writer.write(textwrap.indent(stmt, I))
987
+
988
+ return Stripped(writer.getvalue()), None
989
+
990
+
991
+ def _generate_transformer(
992
+ symbol_table: intermediate.SymbolTable,
993
+ base_environment: intermediate_type_inference.Environment,
994
+ spec_impls: specific_implementations.SpecificImplementations,
995
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
996
+ """Generate a transformer to double-dispatch an instance to errors."""
997
+ errors = [] # type: List[Error]
998
+
999
+ blocks = [] # type: List[Stripped]
1000
+
1001
+ # The abstract classes are directly dispatched by the transformer,
1002
+ # so we do not need to handle them separately.
1003
+
1004
+ for cls in symbol_table.concrete_classes:
1005
+ if cls.is_implementation_specific:
1006
+ transform_key = specific_implementations.ImplementationKey(
1007
+ f"Verification/transform_{cls.name}.py"
1008
+ )
1009
+
1010
+ implementation = spec_impls.get(transform_key, None)
1011
+ if implementation is None:
1012
+ errors.append(
1013
+ Error(
1014
+ cls.parsed.node,
1015
+ f"The transformation snippet is missing "
1016
+ f"for the implementation-specific "
1017
+ f"class {cls.name}: {transform_key}",
1018
+ )
1019
+ )
1020
+ continue
1021
+
1022
+ blocks.append(spec_impls[transform_key])
1023
+ else:
1024
+ block, cls_errors = _generate_transform_for_class(
1025
+ cls=cls,
1026
+ symbol_table=symbol_table,
1027
+ base_environment=base_environment,
1028
+ )
1029
+ if cls_errors is not None:
1030
+ errors.extend(cls_errors)
1031
+ else:
1032
+ assert block is not None
1033
+ blocks.append(block)
1034
+
1035
+ if len(errors) > 0:
1036
+ return None, errors
1037
+
1038
+ writer = io.StringIO()
1039
+ writer.write(
1040
+ f"""\
1041
+ class _Transformer(
1042
+ {II}aas_types.AbstractTransformer[
1043
+ {III}Iterator[Error]
1044
+ {II}]
1045
+ ):
1046
+ """
1047
+ )
1048
+
1049
+ for i, block in enumerate(blocks):
1050
+ if i > 0:
1051
+ writer.write("\n\n")
1052
+ writer.write(textwrap.indent(block, I))
1053
+
1054
+ return Stripped(writer.getvalue()), None
1055
+
1056
+
1057
+ def _generate_verify_constrained_primitive(
1058
+ constrained_primitive: intermediate.ConstrainedPrimitive,
1059
+ symbol_table: intermediate.SymbolTable,
1060
+ base_environment: intermediate_type_inference.Environment,
1061
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1062
+ """Generate the verify function for the constrained primitives."""
1063
+ errors = [] # type: List[Error]
1064
+ blocks = [] # type: List[Stripped]
1065
+
1066
+ environment = intermediate_type_inference.MutableEnvironment(
1067
+ parent=base_environment
1068
+ )
1069
+
1070
+ assert environment.find(Identifier("self")) is None
1071
+ environment.set(
1072
+ identifier=Identifier("self"),
1073
+ type_annotation=intermediate_type_inference.OurTypeAnnotation(
1074
+ our_type=constrained_primitive
1075
+ ),
1076
+ )
1077
+
1078
+ for invariant in constrained_primitive.invariants:
1079
+ invariant_code, error = _transpile_invariant(
1080
+ invariant=invariant, symbol_table=symbol_table, environment=environment
1081
+ )
1082
+ if error is not None:
1083
+ errors.append(
1084
+ Error(
1085
+ constrained_primitive.parsed.node,
1086
+ f"Failed to transpile the invariant of "
1087
+ f"the constrained primitive {constrained_primitive.name!r}",
1088
+ [error],
1089
+ )
1090
+ )
1091
+ continue
1092
+
1093
+ assert invariant_code is not None
1094
+
1095
+ blocks.append(invariant_code)
1096
+
1097
+ if len(errors) > 0:
1098
+ return None, errors
1099
+
1100
+ no_verification_specified = False
1101
+ if len(blocks) == 0:
1102
+ no_verification_specified = True
1103
+ blocks.append(
1104
+ Stripped(
1105
+ """\
1106
+ # There is no verification specified.
1107
+ return
1108
+
1109
+ # Empty generator according to:
1110
+ # https://stackoverflow.com/a/13243870/1600678
1111
+ # noinspection PyUnreachableCode
1112
+ yield"""
1113
+ )
1114
+ )
1115
+
1116
+ function_name = python_naming.function_name(
1117
+ Identifier(f"verify_{constrained_primitive.name}")
1118
+ )
1119
+
1120
+ that_type = python_common.PRIMITIVE_TYPE_MAP[constrained_primitive.constrainee]
1121
+
1122
+ writer = io.StringIO()
1123
+
1124
+ if no_verification_specified:
1125
+ # NOTE (mristin, 2022-10-02):
1126
+ # We provide a function for evolvability even though it does nothing.
1127
+ writer.write("# noinspection PyUnusedLocal\n")
1128
+
1129
+ writer.write(
1130
+ f"""\
1131
+ def {function_name}(
1132
+ {II}that: {that_type}
1133
+ ) -> Iterator[Error]:
1134
+ {I}\"\"\"Verify the constraints of :paramref:`that`.\"\"\"
1135
+ """
1136
+ )
1137
+
1138
+ for i, block in enumerate(blocks):
1139
+ if i > 0:
1140
+ writer.write("\n\n")
1141
+ writer.write(textwrap.indent(block, I))
1142
+
1143
+ assert len(errors) == 0
1144
+ return Stripped(writer.getvalue()), None
1145
+
1146
+
1147
+ def _generate_module_docstring(
1148
+ symbol_table: intermediate.SymbolTable,
1149
+ aas_module: python_common.QualifiedModuleName,
1150
+ ) -> Stripped:
1151
+ """Generate the docstring for the module."""
1152
+ docstring_blocks = [
1153
+ Stripped("Verify that the instances of the meta-model satisfy the invariants.")
1154
+ ] # type: List[Stripped]
1155
+
1156
+ first_cls = (
1157
+ symbol_table.concrete_classes[0]
1158
+ if len(symbol_table.concrete_classes) > 0
1159
+ else None
1160
+ ) # type: Optional[intermediate.ConcreteClass]
1161
+
1162
+ if first_cls is not None:
1163
+ cls_name = python_naming.class_name(first_cls.name)
1164
+ an_instance_variable = python_naming.variable_name(Identifier("an_instance"))
1165
+
1166
+ docstring_blocks.append(
1167
+ Stripped(
1168
+ f"""\
1169
+ Here is an example how to verify an instance of :py:class:`{aas_module}.types.{cls_name}`:
1170
+
1171
+ .. code-block::
1172
+
1173
+ import {aas_module}.types as aas_types
1174
+ import {aas_module}.verification as aas_verification
1175
+
1176
+ {an_instance_variable} = aas_types.{cls_name}(
1177
+ # ... some constructor arguments ...
1178
+ )
1179
+
1180
+ for error in aas_verification.verify({an_instance_variable}):
1181
+ print(f"{{error.cause}} at: {{error.path}}")"""
1182
+ )
1183
+ )
1184
+
1185
+ # endregion
1186
+
1187
+ if len(docstring_blocks) == 1:
1188
+ doc_escaped = docstring_blocks[0].replace('"""', '\\"\\"\\"')
1189
+ docstring = f'"""{doc_escaped}"""'
1190
+ else:
1191
+ doc_escaped = ("\n\n".join(docstring_blocks)).replace('"""', '\\"\\"\\"')
1192
+ docstring = f'''\
1193
+ """
1194
+ {doc_escaped}
1195
+ """'''
1196
+
1197
+ return Stripped(docstring)
1198
+
1199
+
1200
+ # fmt: off
1201
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1202
+ @ensure(
1203
+ lambda result:
1204
+ not (result[0] is not None) or result[0].endswith('\n'),
1205
+ "Trailing newline mandatory for valid end-of-files"
1206
+ )
1207
+ # fmt: on
1208
+ def generate(
1209
+ symbol_table: intermediate.SymbolTable,
1210
+ aas_module: python_common.QualifiedModuleName,
1211
+ spec_impls: specific_implementations.SpecificImplementations,
1212
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
1213
+ """
1214
+ Generate the Python code for verification based on the symbol table.
1215
+
1216
+ The ``aas_module`` indicates the fully-qualified name of the base module.
1217
+ """
1218
+ # region Module docstring
1219
+ blocks = [
1220
+ _generate_module_docstring(symbol_table=symbol_table, aas_module=aas_module),
1221
+ python_common.WARNING,
1222
+ Stripped(
1223
+ f"""\
1224
+ import math
1225
+ import re
1226
+ import struct
1227
+ import sys
1228
+ from typing import (
1229
+ {I}Callable,
1230
+ {I}Iterable,
1231
+ {I}Iterator,
1232
+ {I}List,
1233
+ {I}Mapping,
1234
+ {I}Optional,
1235
+ {I}Pattern,
1236
+ {I}Sequence,
1237
+ {I}Set,
1238
+ {I}Union
1239
+ )
1240
+
1241
+ if sys.version_info >= (3, 8):
1242
+ {I}from typing import Final
1243
+ else:
1244
+ {I}from typing_extensions import Final
1245
+
1246
+ from {aas_module} import (
1247
+ {I}constants as aas_constants,
1248
+ {I}types as aas_types,
1249
+ )"""
1250
+ ),
1251
+ Stripped(
1252
+ f"""\
1253
+ class PropertySegment:
1254
+ {I}\"\"\"Represent a property access on a path to an erroneous value.\"\"\"
1255
+
1256
+ {I}#: Instance containing the property
1257
+ {I}instance: Final[aas_types.Class]
1258
+
1259
+ {I}#: Name of the property
1260
+ {I}name: Final[str]
1261
+
1262
+ {I}def __init__(
1263
+ {III}self,
1264
+ {III}instance: aas_types.Class,
1265
+ {III}name: str
1266
+ {I}) -> None:
1267
+ {II}\"\"\"Initialize with the given values.\"\"\"
1268
+ {II}self.instance = instance
1269
+ {II}self.name = name
1270
+
1271
+ {I}def __str__(self) -> str:
1272
+ {II}return f'.{{self.name}}'"""
1273
+ ),
1274
+ Stripped(
1275
+ f"""\
1276
+ class IndexSegment:
1277
+ {I}\"\"\"Represent an index access on a path to an erroneous value.\"\"\"
1278
+
1279
+ {I}#: Sequence containing the item at :py:attr:`~index`
1280
+ {I}sequence: Final[Sequence[aas_types.Class]]
1281
+
1282
+ {I}#: Index of the item
1283
+ {I}index: Final[int]
1284
+
1285
+ {I}def __init__(
1286
+ {III}self,
1287
+ {III}sequence: Sequence[aas_types.Class],
1288
+ {III}index: int
1289
+ {I}) -> None:
1290
+ {II}\"\"\"Initialize with the given values.\"\"\"
1291
+ {II}self.sequence = sequence
1292
+ {II}self.index = index
1293
+
1294
+ {I}def __str__(self) -> str:
1295
+ {II}return f'[{{self.index}}]'"""
1296
+ ),
1297
+ Stripped("Segment = Union[PropertySegment, IndexSegment]"),
1298
+ Stripped(
1299
+ f"""\
1300
+ class Path:
1301
+ {I}\"\"\"Represent the relative path to the erroneous value.\"\"\"
1302
+
1303
+ {I}def __init__(self) -> None:
1304
+ {II}\"\"\"Initialize as an empty path.\"\"\"
1305
+ {II}self._segments = [] # type: List[Segment]
1306
+
1307
+ {I}@property
1308
+ {I}def segments(self) -> Sequence[Segment]:
1309
+ {II}\"\"\"Get the segments of the path.\"\"\"
1310
+ {II}return self._segments
1311
+
1312
+ {I}def _prepend(self, segment: Segment) -> None:
1313
+ {II}\"\"\"Insert the :paramref:`segment` in front of other segments.\"\"\"
1314
+ {II}self._segments.insert(0, segment)
1315
+
1316
+ {I}def __str__(self) -> str:
1317
+ {II}return "".join(str(segment) for segment in self._segments)"""
1318
+ ),
1319
+ Stripped(
1320
+ f"""\
1321
+ class Error:
1322
+ {I}\"\"\"Represent a verification error in the data.\"\"\"
1323
+
1324
+ {I}#: Human-readable description of the error
1325
+ {I}cause: Final[str]
1326
+
1327
+ {I}#: Path to the erroneous value
1328
+ {I}path: Final[Path]
1329
+
1330
+ {I}def __init__(self, cause: str) -> None:
1331
+ {II}\"\"\"Initialize as an error with an empty path.\"\"\"
1332
+ {II}self.cause = cause
1333
+ {II}self.path = Path()
1334
+
1335
+ {I}def __repr__(self) -> str:
1336
+ {II}return f"Error(path={{self.path}}, cause={{self.cause}})\""""
1337
+ ),
1338
+ ] # type: List[Stripped]
1339
+
1340
+ errors = [] # type: List[Error]
1341
+
1342
+ base_environment = intermediate_type_inference.populate_base_environment(
1343
+ symbol_table=symbol_table
1344
+ )
1345
+
1346
+ for verification in symbol_table.verification_functions:
1347
+ if isinstance(verification, intermediate.ImplementationSpecificVerification):
1348
+ implementation_key = specific_implementations.ImplementationKey(
1349
+ f"Verification/{verification.name}.py"
1350
+ )
1351
+
1352
+ implementation = spec_impls.get(implementation_key, None)
1353
+ if implementation is None:
1354
+ errors.append(
1355
+ Error(
1356
+ None,
1357
+ f"The snippet for the verification function "
1358
+ f"{verification.name!r} is missing: {implementation_key}",
1359
+ )
1360
+ )
1361
+ else:
1362
+ blocks.append(implementation)
1363
+
1364
+ elif isinstance(verification, intermediate.PatternVerification):
1365
+ implementation, error = _transpile_pattern_verification(
1366
+ verification=verification, aas_module=aas_module
1367
+ )
1368
+
1369
+ if error is not None:
1370
+ errors.append(error)
1371
+ else:
1372
+ assert implementation is not None
1373
+ blocks.append(implementation)
1374
+
1375
+ elif isinstance(verification, intermediate.TranspilableVerification):
1376
+ implementation, error = _transpile_transpilable_verification(
1377
+ verification=verification,
1378
+ symbol_table=symbol_table,
1379
+ environment=base_environment,
1380
+ aas_module=aas_module,
1381
+ )
1382
+
1383
+ if error is not None:
1384
+ errors.append(error)
1385
+ else:
1386
+ assert implementation is not None
1387
+ blocks.append(implementation)
1388
+
1389
+ else:
1390
+ assert_never(verification)
1391
+
1392
+ transformer_block, transformer_errors = _generate_transformer(
1393
+ symbol_table=symbol_table,
1394
+ base_environment=base_environment,
1395
+ spec_impls=spec_impls,
1396
+ )
1397
+ if transformer_errors is not None:
1398
+ errors.extend(transformer_errors)
1399
+ else:
1400
+ assert transformer_block is not None
1401
+ blocks.append(transformer_block)
1402
+
1403
+ blocks.append(Stripped("_TRANSFORMER = _Transformer()"))
1404
+
1405
+ blocks.append(
1406
+ Stripped(
1407
+ f"""\
1408
+ def verify(
1409
+ {II}that: aas_types.Class
1410
+ ) -> Iterator[Error]:
1411
+ {I}\"\"\"
1412
+ {I}Verify the constraints of :paramref:`that` recursively.
1413
+
1414
+ {I}:param that: instance whose constraints we want to verify
1415
+ {I}:yield: constraint violations
1416
+ {I}\"\"\"
1417
+ {I}yield from _TRANSFORMER.transform(that)"""
1418
+ )
1419
+ )
1420
+
1421
+ for our_type in symbol_table.our_types:
1422
+ if isinstance(our_type, intermediate.Enumeration):
1423
+ # NOTE (mristin, 2022-10-01):
1424
+ # We do not verify the enumerations explicitly in Python as mypy
1425
+ # is capable enough to spot invalid enum literals.
1426
+ pass
1427
+
1428
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1429
+ (
1430
+ constrained_primitive_block,
1431
+ constrained_primitive_errors,
1432
+ ) = _generate_verify_constrained_primitive(
1433
+ constrained_primitive=our_type,
1434
+ symbol_table=symbol_table,
1435
+ base_environment=base_environment,
1436
+ )
1437
+
1438
+ if constrained_primitive_errors is not None:
1439
+ errors.extend(constrained_primitive_errors)
1440
+ else:
1441
+ assert constrained_primitive_block is not None
1442
+ blocks.append(constrained_primitive_block)
1443
+
1444
+ elif isinstance(
1445
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
1446
+ ):
1447
+ # NOTE (mristin, 2022-10-01):
1448
+ # We provide a general dispatch function for the most abstract
1449
+ # class ``Class``.
1450
+ pass
1451
+ else:
1452
+ assert_never(our_type)
1453
+
1454
+ blocks.append(python_common.WARNING)
1455
+
1456
+ if len(errors) > 0:
1457
+ return None, errors
1458
+
1459
+ writer = io.StringIO()
1460
+ for i, block in enumerate(blocks):
1461
+ if i > 0:
1462
+ writer.write("\n\n\n")
1463
+
1464
+ writer.write(block)
1465
+
1466
+ writer.write("\n")
1467
+
1468
+ return writer.getvalue(), None
1469
+
1470
+
1471
+ # endregion