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,1510 @@
1
+ """Generate TypeScript code for JSON-ization based on the intermediate representation."""
2
+
3
+ import io
4
+ import textwrap
5
+ from typing import Tuple, Optional, List
6
+
7
+ from icontract import ensure
8
+
9
+ from aas_core_codegen import intermediate, naming, specific_implementations
10
+ from aas_core_codegen.common import (
11
+ Error,
12
+ Stripped,
13
+ Identifier,
14
+ assert_never,
15
+ indent_but_first_line,
16
+ )
17
+ from aas_core_codegen.typescript import (
18
+ common as typescript_common,
19
+ naming as typescript_naming,
20
+ description as typescript_description,
21
+ )
22
+ from aas_core_codegen.typescript.common import (
23
+ INDENT as I,
24
+ INDENT2 as II,
25
+ INDENT3 as III,
26
+ INDENT4 as IIII,
27
+ )
28
+
29
+
30
+ # region De-serialization
31
+
32
+
33
+ def _generate_bool_from_jsonable() -> Stripped:
34
+ """Generate the function to decode a ``bool`` from a JSON-able."""
35
+ return Stripped(
36
+ f"""\
37
+ /**
38
+ * Parse `jsonable` as a boolean.
39
+ *
40
+ * @param jsonable - to be parsed
41
+ * @returns parsed boolean value, or an error
42
+ */
43
+ function booleanFromJsonable(
44
+ {I}jsonable: JsonValue
45
+ ): AasCommon.Either<boolean, DeserializationError> {{
46
+ {I}// `typeof` seems to be optimized these days, so we use it instead of
47
+ {I}// literal comparison, see:
48
+ {I}// https://stackoverflow.com/questions/61786250/is-typeof-faster-than-literal-comparison
49
+
50
+ {I}if (jsonable === null) {{
51
+ {II}return newDeserializationError<boolean>(
52
+ {III}"Expected a boolean, but got null"
53
+ {II});
54
+ {I}}}
55
+ {I}if (typeof jsonable !== "boolean") {{
56
+ {II}return newDeserializationError<boolean>(
57
+ {III}`Expected a boolean, but got ${{typeof jsonable}}`
58
+ {II});
59
+ {I}}}
60
+
61
+ {I}return new AasCommon.Either<boolean, DeserializationError>(jsonable, null);
62
+ }}"""
63
+ )
64
+
65
+
66
+ def _generate_int_from_jsonable() -> Stripped:
67
+ """Generate the function to decode an ``int`` from a JSON-able."""
68
+ return Stripped(
69
+ f"""\
70
+ /**
71
+ * Parse `jsonable` as an integer.
72
+ *
73
+ * @param jsonable - to be parsed
74
+ * @returns parsed integer value, or an error
75
+ */
76
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
77
+ function integerFromJsonable(
78
+ {I}jsonable: JsonValue
79
+ ): AasCommon.Either<number, DeserializationError> {{
80
+ {I}if (jsonable === null) {{
81
+ {II}return newDeserializationError<number>(
82
+ {III}"Expected an integer number, but got null"
83
+ {II});
84
+ {I}}}
85
+ {I}if (typeof jsonable !== "number") {{
86
+ {II}return newDeserializationError<number>(
87
+ {III}`Expected an integer number, but got: ${{typeof jsonable}}`
88
+ {II});
89
+ {I}}}
90
+
91
+ {I}if (!Number.isInteger(jsonable)) {{
92
+ {II}return newDeserializationError<number>(
93
+ {III}`Expected an integer number, but got: ${{jsonable}}`
94
+ {II});
95
+ {I}}}
96
+
97
+ {I}return new AasCommon.Either<number, DeserializationError>(jsonable, null);
98
+ }}"""
99
+ )
100
+
101
+
102
+ def _generate_float_from_jsonable() -> Stripped:
103
+ """Generate the function to decode a ``float`` from a JSON-able."""
104
+ return Stripped(
105
+ f"""\
106
+ /**
107
+ * Parse `jsonable` as a number.
108
+ *
109
+ * @param jsonable - to be parsed
110
+ * @returns parsed numeric value, or an error
111
+ */
112
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
113
+ function numberFromJsonable(
114
+ {I}jsonable: JsonValue
115
+ ): AasCommon.Either<number, DeserializationError> {{
116
+ {I}if (jsonable === null) {{
117
+ {II}return newDeserializationError<number>(
118
+ {III}"Expected a number, but got null"
119
+ {II});
120
+ {I}}}
121
+ {I}if (typeof jsonable !== "number") {{
122
+ {II}return newDeserializationError<number>(
123
+ {III}`Expected a number, but got: ${{typeof jsonable}}`
124
+ {II});
125
+ {I}}}
126
+
127
+ {I}return new AasCommon.Either<number, DeserializationError>(jsonable, null);
128
+ }}"""
129
+ )
130
+
131
+
132
+ def _generate_str_from_jsonable() -> Stripped:
133
+ """Generate the function to decode a ``str`` from a JSON-able."""
134
+ return Stripped(
135
+ f"""\
136
+ /**
137
+ * Parse `jsonable` as a string.
138
+ *
139
+ * @param jsonable - to be parsed
140
+ * @returns parsed string value, or an error
141
+ */
142
+ function stringFromJsonable(
143
+ {I}jsonable: JsonValue
144
+ ): AasCommon.Either<string, DeserializationError> {{
145
+ {I}if (jsonable === null) {{
146
+ {II}return newDeserializationError<string>(
147
+ {III}"Expected a string, but got null"
148
+ {II});
149
+ {I}}}
150
+ {I}if (typeof jsonable !== "string") {{
151
+ {II}return newDeserializationError<string>(
152
+ {III}`Expected a string, but got: ${{typeof jsonable}}`
153
+ {II});
154
+ {I}}}
155
+
156
+ {I}return new AasCommon.Either<string, DeserializationError>(jsonable, null);
157
+ }}"""
158
+ )
159
+
160
+
161
+ def _generate_bytes_from_jsonable() -> Stripped:
162
+ """Generate the function to decode ``bytes`` from a JSON-able."""
163
+ return Stripped(
164
+ f"""\
165
+ /**
166
+ * Parse `jsonable` as a byte array.
167
+ *
168
+ * @param jsonable - to be parsed
169
+ * @returns parsed byte array, or an error
170
+ */
171
+ function bytesFromJsonable(
172
+ {I}jsonable: JsonValue
173
+ ): AasCommon.Either<Uint8Array, DeserializationError> {{
174
+ {I}if (jsonable === null) {{
175
+ {II}return newDeserializationError<Uint8Array>(
176
+ {III}"Expected a base64-encoded string, but got null"
177
+ {II});
178
+ {I}}}
179
+ {I}if (typeof jsonable !== "string") {{
180
+ {II}return newDeserializationError<Uint8Array>(
181
+ {III}`Expected a base64-encoded string, but got: ${{typeof jsonable}}`
182
+ {II});
183
+ {I}}}
184
+
185
+ {I}const either = AasCommon.base64Decode(jsonable);
186
+ {I}if (either.error !== null) {{
187
+ {II}return newDeserializationError<Uint8Array>(either.error);
188
+ {I}}}
189
+ {I}return new AasCommon.Either<Uint8Array, DeserializationError>(
190
+ {II}either.mustValue(), null
191
+ {I});
192
+ }}"""
193
+ )
194
+
195
+
196
+ def _generate_enumeration_from_jsonable(
197
+ enumeration: intermediate.Enumeration,
198
+ ) -> Stripped:
199
+ """Generate the deserialization method for an enumeration."""
200
+ enum_name = typescript_naming.enum_name(identifier=enumeration.name)
201
+
202
+ function_name = typescript_naming.function_name(
203
+ Identifier(f"{enumeration.name}_from_jsonable")
204
+ )
205
+
206
+ enum_from_str = typescript_naming.function_name(
207
+ Identifier(f"{enumeration.name}_from_string")
208
+ )
209
+
210
+ return Stripped(
211
+ f"""\
212
+ /**
213
+ * Parse `jsonable` structure as a literal
214
+ * of {{@link {typescript_common.TYPES_MODULE}!{enum_name}}}.
215
+ *
216
+ * @param jsonable - to be parsed
217
+ * @returns parsed literal, or an error if `jsonable` invalid
218
+ */
219
+ export function {function_name}(
220
+ {I}jsonable: JsonValue
221
+ ): AasCommon.Either<AasTypes.{enum_name}, DeserializationError> {{
222
+ {I}if (typeof jsonable !== "string") {{
223
+ {II}return newDeserializationError<AasTypes.{enum_name}>(
224
+ {III}`Expected a string, but got: ${{typeof jsonable}}`
225
+ {II});
226
+ {I}}}
227
+
228
+ {I}const literal = AasStringification.{enum_from_str}(jsonable);
229
+ {I}if (literal === null) {{
230
+ {II}return newDeserializationError<AasTypes.{enum_name}>(
231
+ {III}"Not a valid string representation of " +
232
+ {IIII}`a literal of {enum_name}: ${{jsonable}}`
233
+ {II});
234
+ {I}}}
235
+
236
+ {I}return new AasCommon.Either<
237
+ {II}AasTypes.{enum_name},
238
+ {II}DeserializationError
239
+ {I}>(literal, null);
240
+ }}"""
241
+ )
242
+
243
+
244
+ def _generate_dispatch_map_for_interface(
245
+ interface: intermediate.Interface,
246
+ ) -> Stripped:
247
+ """Generate a mapping model type 🠒 de-serialization function."""
248
+ assert len(interface.base.concrete_descendants) > 0, (
249
+ "Expected a class to have concrete descendants. "
250
+ "Otherwise we do not know how to de-serialize it."
251
+ )
252
+
253
+ mapping_name = typescript_naming.constant_name(
254
+ Identifier(f"{interface.name}_from_jsonable_dispatch")
255
+ )
256
+
257
+ interface_name = typescript_naming.interface_name(interface.name)
258
+
259
+ mapping_writer = io.StringIO()
260
+ mapping_writer.write(
261
+ f"""\
262
+ const {mapping_name} =
263
+ {I}new Map<
264
+ {II}string,
265
+ {II}(JsonValue) => AasCommon.Either<
266
+ {III}AasTypes.{interface_name},
267
+ {III}DeserializationError
268
+ {II}>
269
+ {I}>(
270
+ {II}[
271
+ """
272
+ )
273
+
274
+ for i, implementer in enumerate(interface.implementers):
275
+ if len(implementer.concrete_descendants) == 0:
276
+ function_name_for_implementer = typescript_naming.function_name(
277
+ Identifier(f"{implementer.name}_from_jsonable")
278
+ )
279
+ else:
280
+ # NOTE (mristin, 2022-11-25):
281
+ # We can not use the public function as it would end in an endless dispatch
282
+ # loop. Hence, we introduce a function which assumes the type and explicitly
283
+ # does not dispatch.
284
+ function_name_for_implementer = typescript_naming.function_name(
285
+ Identifier(f"{implementer.name}_from_jsonable_without_dispatch")
286
+ )
287
+
288
+ implementer_literal = typescript_common.string_literal(
289
+ naming.json_model_type(implementer.name)
290
+ )
291
+
292
+ mapping_writer.write(
293
+ f"""\
294
+ {III}[
295
+ {IIII}{implementer_literal},
296
+ {IIII}{function_name_for_implementer}
297
+ {III}]"""
298
+ )
299
+
300
+ if i < len(interface.implementers) - 1:
301
+ mapping_writer.write(",\n")
302
+ else:
303
+ mapping_writer.write("\n")
304
+
305
+ mapping_writer.write(
306
+ f"""\
307
+ {II}]
308
+ {I});"""
309
+ )
310
+
311
+ return Stripped(mapping_writer.getvalue())
312
+
313
+
314
+ def _generate_dispatch_from_jsonable(interface: intermediate.Interface) -> Stripped:
315
+ """Generate the de-serialization dispatch for an abstract class."""
316
+ function_name = typescript_naming.function_name(
317
+ Identifier(f"{interface.name}_from_jsonable")
318
+ )
319
+
320
+ interface_name = typescript_naming.interface_name(interface.name)
321
+
322
+ mapping_name = typescript_naming.constant_name(
323
+ Identifier(f"{interface.name}_from_jsonable_dispatch")
324
+ )
325
+
326
+ return Stripped(
327
+ f"""\
328
+ /**
329
+ * Parse `jsonable` as an instance
330
+ * of {{@link {typescript_common.TYPES_MODULE}!{interface_name}}}.
331
+ *
332
+ * @param jsonable - to be parsed
333
+ * @returns parsed instance, or error if `jsonable` is invalid
334
+ */
335
+ export function {function_name}(
336
+ {I}jsonable: JsonValue
337
+ ): AasCommon.Either<
338
+ {I}AasTypes.{interface_name},
339
+ {I}DeserializationError
340
+ > {{
341
+ {I}if (jsonable === null) {{
342
+ {II}return newDeserializationError<AasTypes.{interface_name}>(
343
+ {III}"Expected a JSON object, but got null"
344
+ {II});
345
+ {I}}}
346
+ {I}if (Array.isArray(jsonable)) {{
347
+ {II}return newDeserializationError<AasTypes.{interface_name}>(
348
+ {III}"Expected a JSON object, but got a JSON array"
349
+ {II});
350
+ {I}}}
351
+ {I}if (typeof jsonable !== "object") {{
352
+ {II}return newDeserializationError<AasTypes.{interface_name}>(
353
+ {III}`Expected a JSON object, but got: ${{typeof jsonable}}`
354
+ {II});
355
+ {I}}}
356
+
357
+ {I}const modelType = jsonable["modelType"];
358
+ {I}if (modelType === undefined) {{
359
+ {II}return newDeserializationError<AasTypes.{interface_name}>(
360
+ {III}"The required property modelType is missing"
361
+ {II});
362
+ {I}}}
363
+
364
+ {I}if (typeof modelType !== "string") {{
365
+ {II}return newDeserializationError<AasTypes.{interface_name}>(
366
+ {III}`Expected the property modelType to be a string, but got: ${{typeof modelType}}`
367
+ {II});
368
+ {I}}}
369
+
370
+ {I}const dispatch = {mapping_name}.get(modelType);
371
+ {I}if (dispatch === undefined) {{
372
+ {II}return newDeserializationError<AasTypes.{interface_name}>(
373
+ {III}`Unexpected model type for {interface_name}: ${{modelType}}`
374
+ {II});
375
+ {I}}}
376
+
377
+ {I}return dispatch(jsonable);
378
+ }}"""
379
+ )
380
+
381
+
382
+ _PARSE_FUNCTION_BY_PRIMITIVE_TYPE = {
383
+ intermediate.PrimitiveType.BOOL: "booleanFromJsonable",
384
+ intermediate.PrimitiveType.INT: "integerFromJsonable",
385
+ intermediate.PrimitiveType.FLOAT: "numberFromJsonable",
386
+ intermediate.PrimitiveType.STR: "stringFromJsonable",
387
+ intermediate.PrimitiveType.BYTEARRAY: "bytesFromJsonable",
388
+ }
389
+ assert all(
390
+ literal in _PARSE_FUNCTION_BY_PRIMITIVE_TYPE
391
+ for literal in intermediate.PrimitiveType
392
+ )
393
+
394
+
395
+ def _parse_function_for_atomic_value(
396
+ type_annotation: intermediate.AtomicTypeAnnotation,
397
+ ) -> Stripped:
398
+ """Determine the parse function for deserializing an atomic non-optional value."""
399
+ function_name: str
400
+
401
+ if isinstance(type_annotation, intermediate.PrimitiveTypeAnnotation):
402
+ function_name = _PARSE_FUNCTION_BY_PRIMITIVE_TYPE[type_annotation.a_type]
403
+
404
+ elif isinstance(type_annotation, intermediate.OurTypeAnnotation):
405
+ our_type = type_annotation.our_type
406
+
407
+ if isinstance(our_type, intermediate.Enumeration):
408
+ function_name = typescript_naming.function_name(
409
+ Identifier(f"{our_type.name}_from_jsonable")
410
+ )
411
+
412
+ elif isinstance(
413
+ our_type,
414
+ (
415
+ intermediate.AbstractClass,
416
+ intermediate.ConcreteClass,
417
+ ),
418
+ ):
419
+ if our_type.interface is not None:
420
+ assert our_type.interface.name == our_type.name, (
421
+ "Assume that the interface name and the class name in "
422
+ "the intermediate representation are the same, so that the "
423
+ "``*_from_jsonable`` name makes sense in all cases"
424
+ )
425
+
426
+ function_name = typescript_naming.function_name(
427
+ Identifier(f"{our_type.name}_from_jsonable")
428
+ )
429
+
430
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
431
+ function_name = _PARSE_FUNCTION_BY_PRIMITIVE_TYPE[our_type.constrainee]
432
+
433
+ else:
434
+ assert_never(our_type)
435
+ else:
436
+ assert_never(type_annotation)
437
+
438
+ return Stripped(function_name)
439
+
440
+
441
+ def _generate_setter(cls: intermediate.ConcreteClass) -> Stripped:
442
+ """Generate a class which allows us to dispatch de-serialization for properties."""
443
+ blocks = [] # type: List[Stripped]
444
+
445
+ for i, prop in enumerate(cls.properties):
446
+ prop_name = typescript_naming.property_name(prop.name)
447
+ prop_type = typescript_common.generate_type(
448
+ prop.type_annotation, types_module=Identifier("AasTypes")
449
+ )
450
+
451
+ # NOTE (mristin, 2022-11-25):
452
+ # We make all the properties optional since we switch over the properties
453
+ # during the de-serialization.
454
+ if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
455
+ prop_type = Stripped(f"{prop_type} | null")
456
+
457
+ blocks.append(Stripped(f"{prop_name}: {prop_type} = null;"))
458
+
459
+ if cls.serialization.with_model_type:
460
+ # NOTE (mristin):
461
+ # If the serialization requires a model type, we consequently parse and set it
462
+ # in the setter. The model type thus obtained is *not* used for any dispatch. We
463
+ # only use this value for verification to make sure that the model type
464
+ # of the instances is consistent with the expected value for its concrete
465
+ # class. This will be performed even though the code might have had to parse
466
+ # model type before for the dispatch. We decided to double-check to cover the
467
+ # case where a dispatch is *unnecessary* (*e.g.*, the caller knows the expected
468
+ # runtime type), but the model type might still be invalid in the input. Hence,
469
+ # when the dispatch is *necessary*, the model type JSON property will be parsed
470
+ # twice, which is a cost we currently find acceptable.
471
+ prop_name = typescript_naming.property_name(Identifier("model_type"))
472
+ blocks.append(
473
+ Stripped(
474
+ f"""\
475
+ // Used only for verification, not for dispatch!
476
+ {prop_name}: string | null = null;"""
477
+ )
478
+ )
479
+
480
+ for i, prop in enumerate(cls.properties):
481
+ prop_name = typescript_naming.property_name(prop.name)
482
+
483
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
484
+ if isinstance(
485
+ type_anno,
486
+ (intermediate.PrimitiveTypeAnnotation, intermediate.OurTypeAnnotation),
487
+ ):
488
+ function_name = _parse_function_for_atomic_value(type_anno)
489
+ body = Stripped(
490
+ f"""\
491
+ const parsedOrError = {function_name}(
492
+ {I}jsonable
493
+ );
494
+ if (parsedOrError.error !== null) {{
495
+ {I}return parsedOrError.error;
496
+ }} else {{
497
+ {I}this.{prop_name} = parsedOrError.mustValue();
498
+ {I}return null;
499
+ }}"""
500
+ )
501
+
502
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
503
+ assert not isinstance(
504
+ type_anno.items,
505
+ (intermediate.OptionalTypeAnnotation, intermediate.ListTypeAnnotation),
506
+ ), (
507
+ "We chose to implement only a very limited pattern matching; "
508
+ "see intermediate._translate_._verify_only_simple_type_patterns"
509
+ )
510
+
511
+ items_type = typescript_common.generate_type(
512
+ type_anno.items, types_module=Identifier("AasTypes")
513
+ )
514
+ parse_function = _parse_function_for_atomic_value(type_anno.items)
515
+
516
+ body = Stripped(
517
+ f"""\
518
+ if (jsonable === null) {{
519
+ {I}return new DeserializationError(
520
+ {II}"Expected an iterable, but got null"
521
+ {I});
522
+ }}
523
+ if (typeof jsonable !== "object") {{
524
+ {I}return new DeserializationError(
525
+ {II}`Expected an iterable, but got: ${{typeof jsonable}}`
526
+ {I});
527
+ }}
528
+ if (typeof jsonable[Symbol.iterator] !== "function") {{
529
+ {I}return new DeserializationError(
530
+ {II}"Expected an iterable with iterator function, " +
531
+ {III}`but got iterator of type: ${{typeof jsonable[Symbol.iterator]}}`
532
+ {I});
533
+ }}
534
+
535
+ const iterable = <Iterable<JsonValue>>jsonable;
536
+
537
+ const items =
538
+ {I}new Array<{items_type}>();
539
+
540
+ let i = 0;
541
+ for (const jsonableItem of iterable) {{
542
+ {I}const itemOrError = {parse_function}(
543
+ {II}jsonableItem
544
+ {I});
545
+
546
+ {I}if (itemOrError.error !== null) {{
547
+ {II}itemOrError.error.path.prepend(
548
+ {III}new IndexSegment(
549
+ {IIII}iterable,
550
+ {IIII}i
551
+ {III})
552
+ {II});
553
+ {II}return itemOrError.error;
554
+ {I}}}
555
+
556
+ {I}items.push(itemOrError.mustValue());
557
+ {I}i++;
558
+ }}
559
+
560
+ this.{prop_name} = items;
561
+ return null;"""
562
+ )
563
+
564
+ else:
565
+ assert_never(type_anno)
566
+
567
+ method_name = typescript_naming.method_name(
568
+ Identifier(f"set_{prop.name}_from_jsonable")
569
+ )
570
+
571
+ method_writer = io.StringIO()
572
+ method_writer.write(
573
+ f"""\
574
+ /**
575
+ * Parse `jsonable` as the value of {{@link {prop_name}}}.
576
+ *
577
+ * @param jsonable - to be parsed
578
+ * @returns error, if any
579
+ */
580
+ {method_name}(
581
+ {I}jsonable: JsonValue
582
+ ): DeserializationError | null {{
583
+ {I}{indent_but_first_line(body, I)}
584
+ }}"""
585
+ )
586
+
587
+ blocks.append(Stripped(method_writer.getvalue()))
588
+
589
+ if cls.serialization.with_model_type:
590
+ method_name = typescript_naming.method_name(
591
+ Identifier("set_model_type_from_jsonable")
592
+ )
593
+ prop_name = typescript_naming.property_name(Identifier("model_type"))
594
+
595
+ blocks.append(
596
+ Stripped(
597
+ f"""\
598
+ /**
599
+ * Parse `jsonable` as the model type of the concrete instance.
600
+ *
601
+ * This is intended only for verification, and no dispatch is performed.
602
+ *
603
+ * @param jsonable - to be parsed
604
+ * @returns error, if any
605
+ */
606
+ {method_name}(
607
+ {I}jsonable: JsonValue
608
+ ): DeserializationError | null {{
609
+ {I}const parsedOrError = stringFromJsonable(
610
+ {II}jsonable
611
+ {I});
612
+ {I}if (parsedOrError.error !== null) {{
613
+ {II}return parsedOrError.error;
614
+ {I}}} else {{
615
+ {II}this.{prop_name} = parsedOrError.mustValue();
616
+ {II}return null;
617
+ {I}}}
618
+ }}"""
619
+ )
620
+ )
621
+
622
+ cls_name = typescript_naming.class_name(cls.name)
623
+ setter_cls_name = typescript_naming.class_name(Identifier(f"Setter_for_{cls.name}"))
624
+
625
+ writer = io.StringIO()
626
+ writer.write(
627
+ f"""\
628
+ /**
629
+ * Provide de-serialize & set methods for properties
630
+ * of {{@link {typescript_common.TYPES_MODULE}!{cls_name}}}.
631
+ */
632
+ class {setter_cls_name} {{
633
+ """
634
+ )
635
+
636
+ for i, block in enumerate(blocks):
637
+ if i > 0:
638
+ writer.write("\n\n")
639
+
640
+ writer.write(textwrap.indent(block, I))
641
+
642
+ writer.write("\n}")
643
+
644
+ return Stripped(writer.getvalue())
645
+
646
+
647
+ def _generate_setter_map(cls: intermediate.ConcreteClass) -> Stripped:
648
+ """Generate a map ``JSON property name`` -> deserialization on a setter."""
649
+ # fmt: off
650
+ assert (
651
+ sorted(
652
+ (arg.name, str(arg.type_annotation))
653
+ for arg in cls.constructor.arguments
654
+ ) == sorted(
655
+ (prop.name, str(prop.type_annotation))
656
+ for prop in cls.properties
657
+ )
658
+ ), (
659
+ "(mristin, 2022-11-25) We assume that the properties and constructor arguments "
660
+ "are identical at this point. If this is not the case, we have to re-write the "
661
+ "logic substantially! Please contact the developers if you see this."
662
+ )
663
+ # fmt: on
664
+
665
+ identifiers_expressions = [] # type: List[Tuple[Identifier, Stripped]]
666
+
667
+ setter_cls_name = typescript_naming.class_name(Identifier(f"Setter_for_{cls.name}"))
668
+
669
+ for prop in cls.properties:
670
+ json_identifier = naming.json_property(prop.name)
671
+ method_name = typescript_naming.method_name(
672
+ Identifier(f"set_{prop.name}_from_jsonable")
673
+ )
674
+
675
+ identifiers_expressions.append(
676
+ (json_identifier, Stripped(f"{setter_cls_name}.prototype.{method_name}"))
677
+ )
678
+
679
+ map_name = typescript_naming.constant_name(Identifier(f"setter_map_for_{cls.name}"))
680
+
681
+ writer = io.StringIO()
682
+ writer.write(
683
+ f"""\
684
+ const {map_name} =
685
+ {I}new Map<
686
+ {II}string,
687
+ {II}(
688
+ {III}jsonable: JsonValue
689
+ {II}) => DeserializationError | null
690
+ {I}>(
691
+ {II}[
692
+ """
693
+ )
694
+
695
+ for identifier, expression in identifiers_expressions:
696
+ writer.write(
697
+ f"""\
698
+ {III}[
699
+ {IIII}{typescript_common.string_literal(identifier)},
700
+ {IIII}{indent_but_first_line(expression, IIII)}
701
+ {III}],
702
+ """
703
+ )
704
+
705
+ if cls.serialization.with_model_type:
706
+ # NOTE (mristin):
707
+ # If the serialization requires a model type, we consequently parse and set it
708
+ # in the setter. The model type thus obtained is *not* used for any dispatch. We
709
+ # only use this value for verification to make sure that the model type
710
+ # of the instances is consistent with the expected value for its concrete
711
+ # class. This will be performed even though the code might have had to parse
712
+ # model type before for the dispatch. We decided to double-check to cover the
713
+ # case where a dispatch is *unnecessary* (*e.g.*, the caller knows the expected
714
+ # runtime type), but the model type might still be invalid in the input. Hence,
715
+ # when the dispatch is *necessary*, the model type JSON property will be parsed
716
+ # twice, which is a cost we currently find acceptable.
717
+ json_identifier = naming.json_property(Identifier("model_type"))
718
+ method_name = typescript_naming.method_name(
719
+ Identifier("set_model_type_from_jsonable")
720
+ )
721
+ expression = Stripped(f"{setter_cls_name}.prototype.{method_name}")
722
+
723
+ writer.write(
724
+ f"""\
725
+ {III}[
726
+ {IIII}// The model type here is used only for verification, not for dispatch.
727
+ {IIII}{typescript_common.string_literal(json_identifier)},
728
+ {IIII}{indent_but_first_line(expression, IIII)}
729
+ {III}],
730
+ """
731
+ )
732
+
733
+ writer.write(
734
+ f"""\
735
+ {II}]
736
+ {I});"""
737
+ )
738
+
739
+ return Stripped(writer.getvalue())
740
+
741
+
742
+ def _generate_concrete_class_from_jsonable(
743
+ cls: intermediate.ConcreteClass,
744
+ ) -> Stripped:
745
+ """
746
+ Generate the deserialization function for a concrete class.
747
+
748
+ This function performs no dispatch. If it de-serializes a concrete class with
749
+ concrete descendants, we have to provide a different name. Otherwise, it would
750
+ shadow the name for the dispatch function.
751
+ """
752
+ # fmt: off
753
+ assert (
754
+ sorted(
755
+ (arg.name, str(arg.type_annotation))
756
+ for arg in cls.constructor.arguments
757
+ ) == sorted(
758
+ (prop.name, str(prop.type_annotation))
759
+ for prop in cls.properties
760
+ )
761
+ ), (
762
+ "(mristin, 2022-11-30) We assume that the properties and constructor arguments "
763
+ "are identical at this point. If this is not the case, we have to re-write the "
764
+ "logic substantially! Please contact the developers if you see this."
765
+ )
766
+ # fmt: on
767
+
768
+ cls_name = typescript_naming.class_name(cls.name)
769
+
770
+ setter_cls_name = typescript_naming.class_name(Identifier(f"Setter_for_{cls.name}"))
771
+
772
+ blocks = [
773
+ Stripped(
774
+ f"""\
775
+ if (jsonable === null) {{
776
+ {I}return newDeserializationError<AasTypes.{cls_name}>(
777
+ {II}"Expected a JSON object, but got null"
778
+ {I});
779
+ }}
780
+ {I}if (Array.isArray(jsonable)) {{
781
+ {II}return newDeserializationError<AasTypes.{cls_name}>(
782
+ {III}"Expected a JSON object, but got a JSON array"
783
+ {II});
784
+ {I}}}
785
+ if (typeof jsonable !== "object") {{
786
+ {I}return newDeserializationError<AasTypes.{cls_name}>(
787
+ {II}`Expected a JSON object, but got: ${{typeof jsonable}}`
788
+ {I});
789
+ }}"""
790
+ ),
791
+ Stripped(f"const setter = new {setter_cls_name}();"),
792
+ ] # type: List[Stripped]
793
+
794
+ # region Switch on property name
795
+
796
+ map_name = typescript_naming.constant_name(Identifier(f"setter_map_for_{cls.name}"))
797
+
798
+ blocks.append(
799
+ Stripped(
800
+ f"""\
801
+ for (const key in jsonable) {{
802
+ {I}const jsonableValue = jsonable[key];
803
+ {I}const setterMethod =
804
+ {II}{map_name}.get(key);
805
+
806
+ {I}// NOTE (mristin, 2022-11-30):
807
+ {I}// Since we conflate here a JavaScript object with a JSON object, we ignore
808
+ {I}// properties which we do not know how to de-serialize and assume they are
809
+ {I}// related to the *JavaScript* properties of the object or `Object` prototype.
810
+ {I}if (setterMethod === undefined) {{
811
+ {II}continue;
812
+ {I}}}
813
+
814
+ {I}const error = setterMethod.call(setter, jsonableValue);
815
+ {I}if (error !== null) {{
816
+ {II}error.path.prepend(
817
+ {III}new PropertySegment(<JsonObject>jsonable, key)
818
+ {II});
819
+ {II}return new AasCommon.Either<
820
+ {III}AasTypes.{cls_name},
821
+ {III}DeserializationError
822
+ {II}>(
823
+ {IIII}null,
824
+ {IIII}error
825
+ {III});
826
+ {I}}}
827
+ }}"""
828
+ )
829
+ )
830
+
831
+ # region Check required properties
832
+
833
+ required_checks = [] # type: List[Stripped]
834
+ for i, prop in enumerate(cls.properties):
835
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
836
+ continue
837
+
838
+ prop_name = typescript_naming.property_name(prop.name)
839
+
840
+ message_literal = typescript_common.string_literal(
841
+ f"The required property {naming.json_property(prop.name)!r} is missing"
842
+ )
843
+ required_checks.append(
844
+ Stripped(
845
+ f"""\
846
+ if (setter.{prop_name} === null) {{
847
+ {I}return newDeserializationError<
848
+ {II}AasTypes.{cls_name}
849
+ {I}>(
850
+ {II}{message_literal}
851
+ {I});
852
+ }}"""
853
+ )
854
+ )
855
+
856
+ if len(required_checks) > 0:
857
+ blocks.append(Stripped("\n\n".join(required_checks)))
858
+
859
+ # endregion
860
+
861
+ if cls.serialization.with_model_type:
862
+ model_type = naming.json_model_type(cls.name)
863
+ prop_name = typescript_naming.property_name(Identifier("model_type"))
864
+
865
+ blocks.append(
866
+ Stripped(
867
+ f"""\
868
+ if (setter.{prop_name} === null) {{
869
+ {I}return newDeserializationError<
870
+ {II}AasTypes.{cls_name}
871
+ {I}>(
872
+ {II}"The required property 'modelType' is missing"
873
+ {I});
874
+ }} else if (setter.{prop_name} != "{model_type}") {{
875
+ {I}return newDeserializationError<
876
+ {II}AasTypes.{cls_name}
877
+ {I}>(
878
+ {II}"Expected model type '{model_type}', " +
879
+ {II}`but got: ${{setter.{prop_name}}}`
880
+ {I});
881
+ }}"""
882
+ )
883
+ )
884
+
885
+ # region Pass in arguments to the constructor
886
+
887
+ cls_name = typescript_naming.class_name(cls.name)
888
+
889
+ if len(cls.constructor.arguments) == 0:
890
+ blocks.append(
891
+ Stripped(
892
+ f"""\
893
+ return new AasCommon.Either<
894
+ {I}AasTypes.{cls_name},
895
+ {I}DeserializationError
896
+ >(
897
+ {I}new AasTypes.{cls_name}(),
898
+ {I}null
899
+ );"""
900
+ )
901
+ )
902
+ else:
903
+ init_writer = io.StringIO()
904
+ init_writer.write(
905
+ f"""\
906
+ return new AasCommon.Either<
907
+ {I}AasTypes.{cls_name},
908
+ {I}DeserializationError
909
+ >(
910
+ {I}new AasTypes.{cls_name}(
911
+ """
912
+ )
913
+
914
+ for i, arg in enumerate(cls.constructor.arguments):
915
+ prop = cls.properties_by_name[arg.name]
916
+
917
+ prop_name = typescript_naming.property_name(prop.name)
918
+
919
+ init_writer.write(f"{II}setter.{prop_name}")
920
+
921
+ if i < len(cls.constructor.arguments) - 1:
922
+ init_writer.write(",\n")
923
+ else:
924
+ init_writer.write("\n")
925
+
926
+ init_writer.write(
927
+ f"""\
928
+ {I}),
929
+ {I}null
930
+ );"""
931
+ )
932
+
933
+ blocks.append(Stripped(init_writer.getvalue()))
934
+ # endregion
935
+
936
+ writer = io.StringIO()
937
+
938
+ if len(cls._concrete_descendants) == 0:
939
+ function_name = typescript_naming.function_name(
940
+ Identifier(f"{cls.name}_from_jsonable")
941
+ )
942
+ else:
943
+ function_name = typescript_naming.function_name(
944
+ Identifier(f"{cls.name}_from_jsonable_without_dispatch")
945
+ )
946
+
947
+ description_blocks = [
948
+ Stripped(
949
+ f"""\
950
+ Parse an instance of {{@link {typescript_common.TYPES_MODULE}!{cls_name}}} from the JSON-able
951
+ structure `jsonable`."""
952
+ )
953
+ ] # type: List[Stripped]
954
+
955
+ if len(cls.concrete_descendants) > 0:
956
+ function_name_with_dispatch = typescript_naming.function_name(
957
+ Identifier(f"{cls.name}_from_jsonable")
958
+ )
959
+
960
+ description_blocks.append(
961
+ Stripped(
962
+ f"""\
963
+ This function performs no dispatch! It is used to parse the properties
964
+ as-are, and already assumes the exact model type. Usually, this function
965
+ is called from within a dispatching function, and you never call it
966
+ directly. If you want to de-serialize an instance of
967
+ {{@link {typescript_common.TYPES_MODULE}!{cls_name}}}, call
968
+ {{@link {function_name_with_dispatch}}}."""
969
+ )
970
+ )
971
+
972
+ description_blocks.append(
973
+ Stripped(
974
+ f"""\
975
+ @param jsonable - structure to be parsed
976
+ @returns parsed instance of {{@link {typescript_common.TYPES_MODULE}!{cls_name}}},
977
+ or an error if any"""
978
+ )
979
+ )
980
+
981
+ description = "\n\n".join(description_blocks)
982
+ description_comment = typescript_description.documentation_comment(
983
+ Stripped(description)
984
+ )
985
+
986
+ # NOTE (mristin, 2022-11-30):
987
+ # We export it only if the de-serialization of the class is equivalent to
988
+ # the de-serialization without a dispatch.
989
+ maybe_export_prefix = "export " if len(cls.concrete_descendants) == 0 else ""
990
+
991
+ writer.write(
992
+ f"""\
993
+ {description_comment}
994
+ {maybe_export_prefix}function {function_name}(
995
+ {I}jsonable: JsonValue
996
+ ): AasCommon.Either<
997
+ {I}AasTypes.{cls_name},
998
+ {I}DeserializationError
999
+ > {{
1000
+ """
1001
+ )
1002
+
1003
+ for i, block in enumerate(blocks):
1004
+ if i > 0:
1005
+ writer.write("\n\n")
1006
+ writer.write(textwrap.indent(block, I))
1007
+
1008
+ writer.write("\n}")
1009
+
1010
+ return Stripped(writer.getvalue())
1011
+
1012
+
1013
+ # endregion
1014
+
1015
+ # region Serialization
1016
+
1017
+
1018
+ def _generate_transform_atomic_value(
1019
+ access_expression: str, type_anno: intermediate.AtomicTypeAnnotation
1020
+ ) -> Stripped:
1021
+ """
1022
+ Generate the snippet to transform the ``access_expression``.
1023
+
1024
+ The ``access_expression`` should either be a name or a member access.
1025
+ """
1026
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation) or (
1027
+ isinstance(type_anno, intermediate.OurTypeAnnotation)
1028
+ and isinstance(type_anno.our_type, intermediate.ConstrainedPrimitive)
1029
+ ):
1030
+ a_type = intermediate.try_primitive_type(type_anno)
1031
+ assert a_type is not None
1032
+
1033
+ if (
1034
+ a_type is intermediate.PrimitiveType.BOOL
1035
+ or a_type is intermediate.PrimitiveType.INT
1036
+ or a_type is intermediate.PrimitiveType.FLOAT
1037
+ or a_type is intermediate.PrimitiveType.STR
1038
+ ):
1039
+ return Stripped(f"{access_expression}")
1040
+
1041
+ elif a_type is intermediate.PrimitiveType.BYTEARRAY:
1042
+ return Stripped(f"AasCommon.base64Encode({access_expression})")
1043
+
1044
+ else:
1045
+ assert_never(a_type)
1046
+
1047
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
1048
+ if isinstance(type_anno.our_type, intermediate.Enumeration):
1049
+ must_to_str_name = typescript_naming.function_name(
1050
+ Identifier(f"must_{type_anno.our_type.name}_to_string")
1051
+ )
1052
+
1053
+ return Stripped(
1054
+ f"""\
1055
+ AasStringification.{must_to_str_name}(
1056
+ {I}{indent_but_first_line(access_expression, I)}
1057
+ )"""
1058
+ )
1059
+
1060
+ elif isinstance(type_anno.our_type, intermediate.ConstrainedPrimitive):
1061
+ raise AssertionError("This case should have been handled before.")
1062
+
1063
+ elif isinstance(
1064
+ type_anno.our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
1065
+ ):
1066
+ return Stripped(f"this.transform({access_expression})")
1067
+
1068
+ else:
1069
+ assert_never(type_anno.our_type)
1070
+
1071
+ else:
1072
+ assert_never(type_anno.our_type)
1073
+
1074
+
1075
+ def _generate_transform(cls: intermediate.ConcreteClass) -> Stripped:
1076
+ """Generate the ``transformX`` method to serialize an instance into a JSON-able."""
1077
+ blocks = [Stripped("const jsonable: JsonObject = {};")] # type: List[Stripped]
1078
+
1079
+ for prop in cls.properties:
1080
+ key_literal = typescript_common.string_literal(naming.json_property(prop.name))
1081
+ prop_name = typescript_naming.property_name(prop.name)
1082
+
1083
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1084
+
1085
+ block: Stripped
1086
+
1087
+ if isinstance(
1088
+ type_anno,
1089
+ (intermediate.PrimitiveTypeAnnotation, intermediate.OurTypeAnnotation),
1090
+ ):
1091
+ transformation_expression = _generate_transform_atomic_value(
1092
+ access_expression=Stripped(f"that.{prop_name}"), type_anno=type_anno
1093
+ )
1094
+
1095
+ block = Stripped(
1096
+ f"""\
1097
+ jsonable[{key_literal}] =
1098
+ {I}{indent_but_first_line(transformation_expression, I)};"""
1099
+ )
1100
+
1101
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
1102
+ assert isinstance(
1103
+ type_anno.items,
1104
+ (intermediate.PrimitiveType, intermediate.OurTypeAnnotation),
1105
+ ), (
1106
+ "We expect only lists of primitive and our types. Lists of optionals "
1107
+ "and nested lists are not handled yet. Please contact the developers."
1108
+ )
1109
+
1110
+ transformation_expression = _generate_transform_atomic_value(
1111
+ access_expression=Stripped("item"), type_anno=type_anno.items
1112
+ )
1113
+
1114
+ var_name = typescript_naming.variable_name(Identifier(f"{prop.name}_array"))
1115
+
1116
+ block = Stripped(
1117
+ f"""\
1118
+ const {var_name} = new Array<JsonObject>();
1119
+ for (const item of that.{prop_name}) {{
1120
+ {I}{var_name}.push(
1121
+ {II}{indent_but_first_line(transformation_expression, II)}
1122
+ {I});
1123
+ }}
1124
+ jsonable[{key_literal}] = {var_name};"""
1125
+ )
1126
+
1127
+ else:
1128
+ assert_never(type_anno)
1129
+
1130
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1131
+ block = Stripped(
1132
+ f"""\
1133
+ if (that.{prop_name} !== null) {{
1134
+ {I}{indent_but_first_line(block, I)}
1135
+ }}"""
1136
+ )
1137
+
1138
+ blocks.append(block)
1139
+
1140
+ if cls.serialization.with_model_type:
1141
+ model_type_literal = typescript_common.string_literal(
1142
+ naming.json_model_type(cls.name)
1143
+ )
1144
+ blocks.append(Stripped(f"""jsonable["modelType"] = {model_type_literal};"""))
1145
+
1146
+ blocks.append(Stripped("return jsonable;"))
1147
+
1148
+ method_name = typescript_naming.method_name(Identifier(f"transform_{cls.name}"))
1149
+
1150
+ cls_name = typescript_naming.class_name(cls.name)
1151
+
1152
+ writer = io.StringIO()
1153
+
1154
+ writer.write(
1155
+ f"""\
1156
+ /**
1157
+ * Serialize `that` to a JSON-able representation.
1158
+ *
1159
+ * @param that - instance to be serialization
1160
+ * @returns JSON-able representation
1161
+ */
1162
+ {method_name}(
1163
+ {I}that: AasTypes.{cls_name}
1164
+ ): JsonObject {{
1165
+ """
1166
+ )
1167
+
1168
+ for i, block in enumerate(blocks):
1169
+ if i > 0:
1170
+ writer.write("\n\n")
1171
+ writer.write(textwrap.indent(block, I))
1172
+
1173
+ writer.write("\n}")
1174
+
1175
+ return Stripped(writer.getvalue())
1176
+
1177
+
1178
+ def _generate_transformer(symbol_table: intermediate.SymbolTable) -> Stripped:
1179
+ methods = [] # type: List[Stripped]
1180
+
1181
+ for cls in symbol_table.concrete_classes:
1182
+ methods.append(_generate_transform(cls))
1183
+
1184
+ writer = io.StringIO()
1185
+ writer.write(
1186
+ """\
1187
+ /**
1188
+ * Transform the instance to its JSON-able representation.
1189
+ */
1190
+ class Serializer extends AasTypes.AbstractTransformer<JsonObject> {
1191
+ """
1192
+ )
1193
+
1194
+ for method in methods:
1195
+ writer.write("\n\n")
1196
+ writer.write(textwrap.indent(method, I))
1197
+
1198
+ writer.write("\n}")
1199
+
1200
+ return Stripped(writer.getvalue())
1201
+
1202
+
1203
+ # endregion
1204
+
1205
+ # fmt: off
1206
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1207
+ @ensure(
1208
+ lambda result:
1209
+ not (result[0] is not None) or result[0].endswith('\n'),
1210
+ "Trailing newline mandatory for valid end-of-files"
1211
+ )
1212
+ # fmt: on
1213
+ def generate(
1214
+ symbol_table: intermediate.SymbolTable,
1215
+ spec_impls: specific_implementations.SpecificImplementations,
1216
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
1217
+ """Generate the TypeScript code for the general de/serialization."""
1218
+ blocks = [
1219
+ typescript_description.documentation_comment(
1220
+ Stripped(
1221
+ """\
1222
+ Provide de/serialization of AAS classes to/from JSON.
1223
+
1224
+ We can not use one-pass deserialization for JSON since the object
1225
+ properties do not have fixed order, and hence we can not read
1226
+ `modelType` property ahead of the remaining properties."""
1227
+ )
1228
+ ),
1229
+ typescript_common.WARNING,
1230
+ Stripped(
1231
+ """\
1232
+ import * as AasCommon from "./common";
1233
+ import * as AasTypes from "./types";
1234
+ import * as AasStringification from "./stringification";"""
1235
+ ),
1236
+ Stripped(
1237
+ """\
1238
+ export type JsonValue = string | number | boolean | JsonObject | JsonArray;
1239
+
1240
+ export type JsonArray = Iterable<JsonValue>;
1241
+ export type JsonObject = { [prop: string]: JsonValue };"""
1242
+ ),
1243
+ Stripped(
1244
+ f"""\
1245
+ /**
1246
+ * Represent a property on a path to the erroneous value.
1247
+ */
1248
+ export class PropertySegment {{
1249
+ {I}/**
1250
+ {I} * Instance that contains the property
1251
+ {I} */
1252
+ {I}readonly instance: JsonObject;
1253
+
1254
+ {I}/**
1255
+ {I} * Name of the property
1256
+ {I} */
1257
+ {I}readonly name: string;
1258
+
1259
+ {I}constructor(instance: JsonObject, name: string) {{
1260
+ {II}this.instance = instance;
1261
+ {II}this.name = name;
1262
+ {I}}}
1263
+ }}"""
1264
+ ),
1265
+ Stripped(
1266
+ f"""\
1267
+ /**
1268
+ * Represent an index access on a path to the erroneous value.
1269
+ */
1270
+ export class IndexSegment {{
1271
+ {I}/**
1272
+ {I} * Container that contains the item
1273
+ {I} */
1274
+ {I}readonly container: JsonArray;
1275
+
1276
+ {I}/**
1277
+ {I} * Index of the item
1278
+ {I} */
1279
+ {I}readonly index: number;
1280
+
1281
+ {I}constructor(container: JsonArray, index: number) {{
1282
+ {II}if (!Number.isInteger(index)) {{
1283
+ {III}throw new Error(`Expected an integer for the index, but got: ${{index}}`);
1284
+ {II}}}
1285
+
1286
+ {II}this.container = container;
1287
+ {II}this.index = index;
1288
+ {I}}}
1289
+ }}"""
1290
+ ),
1291
+ Stripped(
1292
+ """\
1293
+ export type Segment = PropertySegment | IndexSegment;"""
1294
+ ),
1295
+ Stripped(
1296
+ f"""\
1297
+ /**
1298
+ * Represent the relative path to the erroneous value.
1299
+ */
1300
+ export class Path {{
1301
+ {I}private readonly _segments = new Array<Segment>();
1302
+
1303
+ {I}/**
1304
+ {I} * Get the segments of the path.
1305
+ {I} */
1306
+ {I}segments(): Array<Segment> {{
1307
+ {II}return this._segments;
1308
+ {I}}}
1309
+
1310
+ {I}/**
1311
+ {I} * Insert the `segment` in front of the {{@link segments}}.
1312
+ {I} *
1313
+ {I} * @param segment - segment to be prepended to {{@link segments}}
1314
+ {I} */
1315
+ {I}prepend(segment: Segment): void {{
1316
+ {II}this._segments.unshift(segment);
1317
+ {I}}}
1318
+
1319
+ {I}toString(): string {{
1320
+ {II}if (this._segments.length === 0) {{
1321
+ {III}return "";
1322
+ {II}}}
1323
+
1324
+ {II}const parts = new Array<string>();
1325
+
1326
+ {II}let segment = this._segments[0];
1327
+
1328
+ {II}if (segment instanceof PropertySegment) {{
1329
+ {III}parts.push(segment.name);
1330
+ {II}}} else if (segment instanceof IndexSegment) {{
1331
+ {III}parts.push(`[${{segment.index}}]`);
1332
+ {II}}} else {{
1333
+ {III}throw new Error(`Unexpected segment: ${{segment}}`);
1334
+ {II}}}
1335
+
1336
+ {II}for (let i = 1; i < this._segments.length; i++) {{
1337
+ {III}segment = this._segments[i];
1338
+ {III}if (segment instanceof PropertySegment) {{
1339
+ {IIII}parts.push(`.${{segment.name}}`);
1340
+ {III}}} else if (segment instanceof IndexSegment) {{
1341
+ {IIII}parts.push(`[${{segment.index}}]`);
1342
+ {III}}} else {{
1343
+ {IIII}throw new Error(`Unexpected segment: ${{segment}}`);
1344
+ {III}}}
1345
+ {II}}}
1346
+
1347
+ {II}return parts.join("");
1348
+ {I}}}
1349
+ }}"""
1350
+ ),
1351
+ Stripped("// region De-serialization"),
1352
+ Stripped(
1353
+ f"""\
1354
+ /**
1355
+ * Signal that the JSON de-serialization could not be performed.
1356
+ */
1357
+ export class DeserializationError {{
1358
+ {I}/**
1359
+ {I} * Human-readable explanation of the error
1360
+ {I} */
1361
+ {I}readonly message: string;
1362
+
1363
+ {I}/**
1364
+ {I} * Relative path to the erroneous value
1365
+ {I} */
1366
+ {I}readonly path: Path;
1367
+
1368
+ {I}constructor(message: string, path: Path | null = null) {{
1369
+ {II}this.message = message;
1370
+ {II}this.path = path ?? new Path();
1371
+ {I}}}
1372
+ }}"""
1373
+ ),
1374
+ Stripped(
1375
+ f"""\
1376
+ /**
1377
+ * Create an error as {{@link common.Either}}.
1378
+ *
1379
+ * @param message - human-readable explanation of the error
1380
+ * @returns An {{@link common.Either }} with the error set
1381
+ * @typeParam T - type of the value if there had been no error
1382
+ */
1383
+ function newDeserializationError<T>(
1384
+ {I}message: string
1385
+ ): AasCommon.Either<T, DeserializationError> {{
1386
+ {I}return new AasCommon.Either<T, DeserializationError>(
1387
+ {II}null,
1388
+ {II}new DeserializationError(message)
1389
+ {I});
1390
+ }}"""
1391
+ ),
1392
+ _generate_bool_from_jsonable(),
1393
+ _generate_int_from_jsonable(),
1394
+ _generate_float_from_jsonable(),
1395
+ _generate_str_from_jsonable(),
1396
+ _generate_bytes_from_jsonable(),
1397
+ ] # type: List[Stripped]
1398
+
1399
+ errors = [] # type: List[Error]
1400
+
1401
+ for our_type in symbol_table.our_types:
1402
+ if isinstance(our_type, intermediate.Enumeration):
1403
+ blocks.append(_generate_enumeration_from_jsonable(enumeration=our_type))
1404
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1405
+ pass
1406
+ elif isinstance(our_type, intermediate.AbstractClass):
1407
+ blocks.append(
1408
+ _generate_dispatch_from_jsonable(interface=our_type.interface)
1409
+ )
1410
+ elif isinstance(our_type, intermediate.ConcreteClass):
1411
+ if len(our_type.concrete_descendants) > 0:
1412
+ assert our_type.interface is not None
1413
+ blocks.append(
1414
+ _generate_dispatch_from_jsonable(interface=our_type.interface)
1415
+ )
1416
+
1417
+ if our_type.is_implementation_specific:
1418
+ implementation_key = specific_implementations.ImplementationKey(
1419
+ f"Jsonization/{our_type.name}_from_jsonable.ts"
1420
+ )
1421
+
1422
+ implementation = spec_impls.get(implementation_key, None)
1423
+ if implementation is None:
1424
+ errors.append(
1425
+ Error(
1426
+ our_type.parsed.node,
1427
+ f"The jsonization snippet is missing "
1428
+ f"for the implementation-specific "
1429
+ f"class {our_type.name}: {implementation_key}",
1430
+ )
1431
+ )
1432
+ continue
1433
+ else:
1434
+ # NOTE (mristin, 2022-11-25):
1435
+ # While TypeScript supports ``switch`` statement, it is not guaranteed
1436
+ # to run in sublinear time. Hence, we have to create a map with set
1437
+ # methods, see:
1438
+ # https://stackoverflow.com/questions/41109196/is-javascript-switch-statement-linear-or-constant-time
1439
+ blocks.append(_generate_setter(cls=our_type))
1440
+
1441
+ blocks.append(_generate_concrete_class_from_jsonable(cls=our_type))
1442
+ else:
1443
+ assert_never(our_type)
1444
+
1445
+ # NOTE (mristin, 2022-11-25):
1446
+ # We add all the dispatch mappings at the end as the functions might not have been
1447
+ # defined yet.
1448
+ for cls in symbol_table.classes:
1449
+ if isinstance(cls, intermediate.AbstractClass):
1450
+ blocks.append(_generate_dispatch_map_for_interface(interface=cls.interface))
1451
+ elif isinstance(cls, intermediate.ConcreteClass):
1452
+ if len(cls.concrete_descendants) > 0:
1453
+ assert (
1454
+ cls.interface is not None
1455
+ ), "Expected an interface on a class with concrete descendants"
1456
+
1457
+ blocks.append(
1458
+ _generate_dispatch_map_for_interface(interface=cls.interface)
1459
+ )
1460
+
1461
+ if not cls.is_implementation_specific:
1462
+ blocks.append(_generate_setter_map(cls=cls))
1463
+
1464
+ else:
1465
+ assert_never(cls)
1466
+
1467
+ blocks.append(Stripped("// endregion"))
1468
+
1469
+ blocks.append(Stripped("// region Serialization"))
1470
+
1471
+ blocks.append(_generate_transformer(symbol_table=symbol_table))
1472
+
1473
+ blocks.append(Stripped("const SERIALIZER = new Serializer();"))
1474
+
1475
+ # pylint: disable=line-too-long
1476
+ blocks.append(
1477
+ Stripped(
1478
+ f"""\
1479
+ /**
1480
+ * Convert `that` to a JSON-able structure.
1481
+ *
1482
+ * @param that - AAS data to be recursively converted to a JSON-able structure
1483
+ * @returns
1484
+ * JSON-able structure which can be further processed with, say,
1485
+ * {{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify|JSON.stringify}})
1486
+ */
1487
+ export function toJsonable(that: AasTypes.Class): JsonObject {{
1488
+ {I}return SERIALIZER.transform(that);
1489
+ }}"""
1490
+ )
1491
+ )
1492
+ # pylint: enable=line-too-long
1493
+
1494
+ blocks.append(Stripped("// endregion"))
1495
+
1496
+ if len(errors) > 0:
1497
+ return None, errors
1498
+
1499
+ blocks.append(typescript_common.WARNING)
1500
+
1501
+ writer = io.StringIO()
1502
+ for i, block in enumerate(blocks):
1503
+ if i > 0:
1504
+ writer.write("\n\n")
1505
+
1506
+ writer.write(block)
1507
+
1508
+ writer.write("\n")
1509
+
1510
+ return writer.getvalue(), None