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,1740 @@
1
+ """Generate the Golang code for JSON-ization based on the intermediate representation."""
2
+
3
+ import io
4
+ from typing import Tuple, Optional, List, Union
5
+
6
+ from icontract import ensure, require
7
+
8
+ from aas_core_codegen import intermediate, naming, specific_implementations
9
+ from aas_core_codegen.common import (
10
+ Error,
11
+ Stripped,
12
+ Identifier,
13
+ assert_never,
14
+ indent_but_first_line,
15
+ assert_union_without_excluded,
16
+ )
17
+ from aas_core_codegen.golang import (
18
+ common as golang_common,
19
+ naming as golang_naming,
20
+ description as golang_description,
21
+ )
22
+ from aas_core_codegen.golang.common import (
23
+ INDENT as I,
24
+ INDENT2 as II,
25
+ INDENT3 as III,
26
+ INDENT4 as IIII,
27
+ INDENT5 as IIIII,
28
+ )
29
+
30
+
31
+ # region De-serialization
32
+
33
+
34
+ def _generate_bool_from_jsonable() -> Stripped:
35
+ """Generate the function to decode a ``bool`` from a JSON-able."""
36
+ return Stripped(
37
+ f"""\
38
+ // Parse `jsonable` as a boolean, or return an error.
39
+ func boolFromJsonable(
40
+ {I}jsonable interface{{}},
41
+ ) (result bool, err error) {{
42
+ {I}if jsonable == nil {{
43
+ {II}err = newDeserializationError(
44
+ {III}"Expected a boolean, but got null",
45
+ {II})
46
+ {II}return
47
+ {I}}}
48
+
49
+ {I}var ok bool
50
+ {I}result, ok = jsonable.(bool)
51
+ {I}if !ok {{
52
+ {II}err = newDeserializationError(
53
+ {III}fmt.Sprintf("Expected a boolean, but got %T", jsonable),
54
+ {II})
55
+
56
+ {II}return
57
+ {I}}}
58
+
59
+ {I}return
60
+ }}"""
61
+ )
62
+
63
+
64
+ def _generate_int64_from_jsonable() -> Stripped:
65
+ """Generate the function to decode an ``int64`` from a JSON-able."""
66
+ return Stripped(
67
+ f"""\
68
+ // Parse `jsonable` as a 64-bit integer, or return an error.
69
+ func int64FromJsonable(
70
+ {I}jsonable interface{{}},
71
+ ) (result int64, err error) {{
72
+ {I}if jsonable == nil {{
73
+ {II}err = newDeserializationError(
74
+ {III}"Expected an integer number, but got null",
75
+ {II})
76
+ {II}return
77
+ {I}}}
78
+
79
+ {I}f, ok := jsonable.(float64)
80
+ {I}if !ok {{
81
+ {II}err = newDeserializationError(
82
+ {III}fmt.Sprintf(
83
+ {IIII}"Expected an integer number, but got %T",
84
+ {IIII}jsonable,
85
+ {III}),
86
+ {II})
87
+ {II}return
88
+ {I}}}
89
+
90
+ {I}if math.IsNaN(f) {{
91
+ {II}err = newDeserializationError(
92
+ {III}"Expected an integer number, but got a NaN",
93
+ {II})
94
+ {II}return
95
+ {I}}}
96
+
97
+ {I}if math.IsInf(f, 0) {{
98
+ {II}err = newDeserializationError(
99
+ {III}"Expected an integer number, but got an infinity",
100
+ {II})
101
+ {II}return
102
+ {I}}}
103
+
104
+ {I}if f != math.Trunc(f) {{
105
+ {II}err = newDeserializationError(
106
+ {III}fmt.Sprintf(
107
+ {IIII}"Expected an integer number, but got a non-integer: %v",
108
+ {IIII}f,
109
+ {III}),
110
+ {II})
111
+ {II}return
112
+ {I}}}
113
+
114
+ {I}result = int64(f)
115
+ {I}if f != float64(result) {{
116
+ {II}err = newDeserializationError(
117
+ {III}fmt.Sprintf(
118
+ {IIII}"Expected an integer number fitting into int64, but got: %v",
119
+ {IIII}jsonable,
120
+ {III}),
121
+ {II})
122
+ {II}return
123
+ {I}}}
124
+
125
+ {I}return
126
+ }}"""
127
+ )
128
+
129
+
130
+ def _generate_float64_from_jsonable() -> Stripped:
131
+ """Generate the function to decode a ``float`` from a JSON-able."""
132
+ return Stripped(
133
+ f"""\
134
+ // Parse `jsonable` as a 64-bit float, or return an error.
135
+ func float64FromJsonable(
136
+ {I}jsonable interface{{}},
137
+ ) (result float64, err error) {{
138
+ {I}if jsonable == nil {{
139
+ {II}err = newDeserializationError(
140
+ {III}"Expected a number, but got null",
141
+ {II})
142
+ {II}return
143
+ {I}}}
144
+
145
+ {I}var ok bool
146
+ {I}result, ok = jsonable.(float64)
147
+ {I}if !ok {{
148
+ {II}err = newDeserializationError(
149
+ {III}fmt.Sprintf(
150
+ {IIII}"Expected a number, but got %T",
151
+ {IIII}jsonable,
152
+ {III}),
153
+ {II})
154
+ {II}return
155
+ {I}}}
156
+
157
+ {I}return
158
+ }}"""
159
+ )
160
+
161
+
162
+ def _generate_string_from_jsonable() -> Stripped:
163
+ """Generate the function to decode a ``string`` from a JSON-able."""
164
+ return Stripped(
165
+ f"""\
166
+ // Parse `jsonable` as a string, or return an error.
167
+ func stringFromJsonable(
168
+ {I}jsonable interface{{}},
169
+ ) (result string, err error) {{
170
+ {I}if jsonable == nil {{
171
+ {II}err = newDeserializationError(
172
+ {III}"Expected a string, but got null",
173
+ {II})
174
+ {II}return
175
+ {I}}}
176
+
177
+ {I}var ok bool
178
+ {I}result, ok = jsonable.(string)
179
+ {I}if ok {{
180
+ {II}return
181
+ {I}}} else {{
182
+ {II}err = newDeserializationError(
183
+ {III}fmt.Sprintf("Expected a string, but got %T", jsonable),
184
+ {II})
185
+ {II}return
186
+ {I}}}
187
+ }}"""
188
+ )
189
+
190
+
191
+ def _generate_bytes_from_jsonable() -> Stripped:
192
+ """Generate the function to decode ``[]byte`` from a JSON-able."""
193
+ return Stripped(
194
+ f"""\
195
+ // Parse `jsonable` as a byte array, or return an error.
196
+ func bytesFromJsonable(
197
+ {I}jsonable interface{{}},
198
+ ) (result []byte, err error) {{
199
+ {I}if jsonable == nil {{
200
+ {II}err = newDeserializationError(
201
+ {III}"Expected a base64-encoded string, but got null",
202
+ {II})
203
+ {II}return
204
+ {I}}}
205
+
206
+ {I}text, ok := jsonable.(string)
207
+ {I}if !ok {{
208
+ {II}err = newDeserializationError(
209
+ {III}fmt.Sprintf(
210
+ {IIII}"Expected a base64-encoded string, but got %T",
211
+ {IIII}jsonable,
212
+ {III}),
213
+ {II})
214
+ {II}return
215
+ {I}}}
216
+
217
+ {I}var decodingErr error
218
+ {I}result, decodingErr = b64.StdEncoding.DecodeString(text)
219
+ {I}if decodingErr != nil {{
220
+ {II}err = newDeserializationError(
221
+ {III}fmt.Sprintf(
222
+ {IIII}"String could not be decoded as base64: %s",
223
+ {IIII}decodingErr.Error(),
224
+ {III}),
225
+ {II})
226
+ {II}return
227
+ {I}}}
228
+
229
+ {I}return
230
+ }}"""
231
+ )
232
+
233
+
234
+ def _generate_enumeration_from_jsonable(
235
+ enumeration: intermediate.Enumeration,
236
+ ) -> Stripped:
237
+ """Generate the deserialization method for an enumeration."""
238
+ enum_name = golang_naming.enum_name(identifier=enumeration.name)
239
+
240
+ function_name = golang_naming.function_name(
241
+ Identifier(f"{enumeration.name}_from_jsonable")
242
+ )
243
+
244
+ enum_from_str = golang_naming.function_name(
245
+ Identifier(f"{enumeration.name}_from_string")
246
+ )
247
+
248
+ return Stripped(
249
+ f"""\
250
+ // Parse `jsonable` as a literal of [aastypes.{enum_name}],
251
+ // or return an error.
252
+ func {function_name}(
253
+ {I}jsonable interface{{}},
254
+ ) (result aastypes.{enum_name}, err error) {{
255
+ {I}if jsonable == nil {{
256
+ {II}err = newDeserializationError(
257
+ {III}"Expected a string representation of {enum_name}, " +
258
+ {III}"but got null",
259
+ {II})
260
+ {II}return
261
+ {I}}}
262
+
263
+ {I}text, ok := jsonable.(string)
264
+ {I}if !ok {{
265
+ {II}err = newDeserializationError(
266
+ {III}fmt.Sprintf(
267
+ {IIII}"Expected a string representation of {enum_name}, " +
268
+ {IIII}"but got %T",
269
+ {IIII}jsonable,
270
+ {III}),
271
+ {II})
272
+ {II}return
273
+ {I}}}
274
+
275
+ {I}result, ok = aasstringification.{enum_from_str}(text)
276
+ {I}if !ok {{
277
+ {II}err = newDeserializationError(
278
+ {III}fmt.Sprintf(
279
+ {IIII}"Expected a string representation of {enum_name}, " +
280
+ {IIII}"but got %v",
281
+ {IIII}text,
282
+ {III}),
283
+ {II})
284
+ {II}return
285
+ {I}}}
286
+
287
+ {I}return
288
+ }}"""
289
+ )
290
+
291
+
292
+ # fmt: off
293
+ @require(
294
+ lambda cls:
295
+ len(cls.concrete_descendants) > 0,
296
+ "A class that needs dispatch must have more than one concrete descendant"
297
+ )
298
+ # fmt: on
299
+ def _generate_class_from_map(cls: intermediate.ClassUnion) -> Stripped:
300
+ """Generate a mapping model type 🠒 de-serialization from map."""
301
+ model_types_dispatch_names = [] # type: List[Tuple[str, str]]
302
+
303
+ for descendant in cls.concrete_descendants:
304
+ model_types_dispatch_names.append(
305
+ (
306
+ naming.json_model_type(descendant.name),
307
+ golang_naming.private_function_name(
308
+ Identifier(f"{descendant.name}_from_map_without_dispatch")
309
+ ),
310
+ )
311
+ )
312
+
313
+ if isinstance(cls, intermediate.ConcreteClass):
314
+ model_types_dispatch_names.append(
315
+ (
316
+ naming.json_model_type(cls.name),
317
+ golang_naming.private_function_name(
318
+ Identifier(f"{cls.name}_from_map_without_dispatch")
319
+ ),
320
+ )
321
+ )
322
+
323
+ case_blocks = [] # type: List[Stripped]
324
+ for model_type, dispatch_name in model_types_dispatch_names:
325
+ model_type_literal = golang_common.string_literal(model_type)
326
+ case_blocks.append(
327
+ Stripped(
328
+ f"""\
329
+ case {model_type_literal}:
330
+ {I}result, err = {dispatch_name}(m)"""
331
+ )
332
+ )
333
+
334
+ interface_name = golang_naming.interface_name(cls.name)
335
+
336
+ case_blocks.append(
337
+ Stripped(
338
+ f"""\
339
+ default:
340
+ {I}err = newDeserializationError(
341
+ {II}fmt.Sprintf(
342
+ {III}"Unexpected model type " +
343
+ {III}"for {interface_name}: %s",
344
+ {III}modelType,
345
+ {II}),
346
+ {I})"""
347
+ )
348
+ )
349
+
350
+ case_blocks_joined = "\n".join(case_blocks)
351
+
352
+ function_name = golang_naming.private_function_name(
353
+ Identifier(f"{cls.name}_from_map")
354
+ )
355
+
356
+ return Stripped(
357
+ f"""\
358
+ // De-serialize an instance of [aastypes.{interface_name}]
359
+ // from a map by dispatching to the concrete `*FromMapWithoutDispatch` function.
360
+ func {function_name}(
361
+ {I}m map[string]interface{{}},
362
+ ) (
363
+ {I}result aastypes.{interface_name},
364
+ {I}err error,
365
+ ) {{
366
+ {I}var modelTypeAny interface{{}}
367
+ {I}var ok bool
368
+ {I}modelTypeAny, ok = m["modelType"];
369
+ {I}if !ok {{
370
+ {II}err = newDeserializationError(
371
+ {III}"The required property modelType is missing",
372
+ {II})
373
+ {II}return
374
+ {I}}}
375
+
376
+ {I}var modelType string
377
+ {I}modelType, ok = modelTypeAny.(string)
378
+ {I}if !ok {{
379
+ {II}err = newDeserializationError(
380
+ {III}fmt.Sprintf(
381
+ {IIII}"Expected the property modelType to be a string, " +
382
+ {IIII}"but got %T",
383
+ {IIII}modelTypeAny,
384
+ {III}),
385
+ {II})
386
+ {II}return
387
+ {I}}}
388
+
389
+ {I}switch modelType {{
390
+ {I}{indent_but_first_line(case_blocks_joined, I)}
391
+ {I}}}
392
+
393
+ {I}return
394
+ }}"""
395
+ )
396
+
397
+
398
+ def _generate_class_from_jsonable(cls: intermediate.ClassUnion) -> Stripped:
399
+ """Generate the de-serialization function for a class that involves a dispatch."""
400
+ function_name = golang_naming.function_name(Identifier(f"{cls.name}_from_jsonable"))
401
+
402
+ interface_name = golang_naming.interface_name(cls.name)
403
+
404
+ blocks = [
405
+ Stripped(
406
+ f"""\
407
+ if jsonable == nil {{
408
+ {I}err = newDeserializationError(
409
+ {II}"Expected a JSON object, but got null",
410
+ {I})
411
+ {I}return
412
+ }}"""
413
+ ),
414
+ Stripped(
415
+ f"""\
416
+ m, ok := jsonable.(map[string]interface{{}})
417
+ if !ok {{
418
+ {I}err = newDeserializationError(
419
+ {II}fmt.Sprintf(
420
+ {III}"Expected a JSON object, but got %T",
421
+ {III}jsonable,
422
+ {II}),
423
+ {I})
424
+ {I}return
425
+ }}"""
426
+ ),
427
+ ] # type: List[Stripped]
428
+
429
+ if len(cls.concrete_descendants) == 0:
430
+ assert not isinstance(cls, intermediate.AbstractClass), (
431
+ "We can not parse abstract classes without any concrete descendants "
432
+ "as we do not know the concrete structure of the map."
433
+ )
434
+
435
+ from_map_name = golang_naming.private_function_name(
436
+ Identifier(f"{cls.name}_from_map_without_dispatch")
437
+ )
438
+ else:
439
+ from_map_name = golang_naming.private_function_name(
440
+ Identifier(f"{cls.name}_from_map")
441
+ )
442
+
443
+ blocks.append(Stripped(f"result, err = {from_map_name}(m)"))
444
+ blocks.append(Stripped("return"))
445
+
446
+ body = Stripped("\n\n".join(blocks))
447
+
448
+ return Stripped(
449
+ f"""\
450
+ // Parse `jsonable` as an instance of [aastypes.{interface_name}],
451
+ // or return an error.
452
+ func {function_name}(
453
+ {I}jsonable interface{{}},
454
+ ) (
455
+ {I}result aastypes.{interface_name},
456
+ {I}err error,
457
+ ) {{
458
+ {I}{indent_but_first_line(body, I)}
459
+ }}"""
460
+ )
461
+
462
+
463
+ _PARSE_FUNCTION_BY_PRIMITIVE_TYPE = {
464
+ intermediate.PrimitiveType.BOOL: "boolFromJsonable",
465
+ intermediate.PrimitiveType.INT: "int64FromJsonable",
466
+ intermediate.PrimitiveType.FLOAT: "float64FromJsonable",
467
+ intermediate.PrimitiveType.STR: "stringFromJsonable",
468
+ intermediate.PrimitiveType.BYTEARRAY: "bytesFromJsonable",
469
+ }
470
+ assert all(
471
+ literal in _PARSE_FUNCTION_BY_PRIMITIVE_TYPE
472
+ for literal in intermediate.PrimitiveType
473
+ )
474
+
475
+
476
+ def _determine_parse_function_for_atomic_value(
477
+ type_annotation: intermediate.AtomicTypeAnnotation,
478
+ ) -> Stripped:
479
+ """Determine the parse function for deserializing an atomic non-optional value."""
480
+ function_name: str
481
+
482
+ if isinstance(type_annotation, intermediate.PrimitiveTypeAnnotation):
483
+ function_name = _PARSE_FUNCTION_BY_PRIMITIVE_TYPE[type_annotation.a_type]
484
+
485
+ elif isinstance(type_annotation, intermediate.OurTypeAnnotation):
486
+ our_type = type_annotation.our_type
487
+
488
+ if isinstance(our_type, intermediate.Enumeration):
489
+ function_name = golang_naming.function_name(
490
+ Identifier(f"{our_type.name}_from_jsonable")
491
+ )
492
+
493
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
494
+ function_name = _PARSE_FUNCTION_BY_PRIMITIVE_TYPE[our_type.constrainee]
495
+
496
+ elif isinstance(
497
+ our_type,
498
+ (
499
+ intermediate.AbstractClass,
500
+ intermediate.ConcreteClass,
501
+ ),
502
+ ):
503
+ function_name = golang_naming.function_name(
504
+ Identifier(f"{our_type.name}_from_jsonable")
505
+ )
506
+
507
+ else:
508
+ assert_never(our_type)
509
+ else:
510
+ assert_never(type_annotation)
511
+
512
+ return Stripped(function_name)
513
+
514
+
515
+ def _generate_deserialization_switch_statement(
516
+ cls: intermediate.ConcreteClass,
517
+ ) -> Stripped:
518
+ """
519
+ Generate the switch statement for de-serialization of the properties.
520
+
521
+ This statement is expected to be run in a ``for k, v := range m`` loop.
522
+ We switch on ``k`` and the value of the property is given as ``v``. The ``jsonable``
523
+ is expected to be of type ``map[string]interface{}``.
524
+
525
+ The resulting struct we parse into is ``result``, a pointer to the struct
526
+ corresponding to ``cls``. Whenever we encounter a property, we have to set
527
+ the corresponding boolean ``found*`` to ``True``.
528
+
529
+ This function was originally part of
530
+ ``_generate_concrete_class_from_map_without_dispatch``, but we refactored it out
531
+ since it was too much to read. Best if your read both functions in two vertical
532
+ editor panes.
533
+
534
+ If the serialization requires model type, we also expect that the variable
535
+ ``foundModelType`` have been initialized as a ``bool`` in the preceding generated
536
+ code. The generated case block will parse and set it in case that the model type
537
+ is correctly specified. This will be performed even though the code might have
538
+ had to parse model type before for the dispatch. We decided to double-check to cover
539
+ the case where a dispatch is *unnecessary* (*e.g.*, the caller knows the expected
540
+ runtime type), but the model type might still be invalid in the input. Hence, when
541
+ the dispatch is *necessary*, the model type JSON property will be parsed twice,
542
+ which is a cost we currently find acceptable.
543
+ """
544
+ case_blocks = [] # type: List[Stripped]
545
+
546
+ for prop in cls.properties:
547
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
548
+
549
+ optional = isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation)
550
+
551
+ prop_var = golang_naming.variable_name(Identifier(f"the_{prop.name}"))
552
+
553
+ json_prop_literal = golang_common.string_literal(
554
+ naming.json_property(prop.name)
555
+ )
556
+
557
+ case_body: Stripped
558
+
559
+ primitive_type = intermediate.try_primitive_type(type_anno)
560
+
561
+ # NOTE (mristin, 2023-05-12):
562
+ # We handle this case of the atomic value separately from the others as
563
+ # we model the optional values with pointers, so we first have to parse into
564
+ # a value, and then pass a pointer to that value to the property of
565
+ # the instance.
566
+ if optional and (
567
+ (
568
+ primitive_type is not None
569
+ and primitive_type is not intermediate.PrimitiveType.BYTEARRAY
570
+ )
571
+ or (
572
+ isinstance(type_anno, intermediate.OurTypeAnnotation)
573
+ and isinstance(type_anno.our_type, intermediate.Enumeration)
574
+ )
575
+ ):
576
+ assert isinstance(
577
+ type_anno,
578
+ (intermediate.PrimitiveTypeAnnotation, intermediate.OurTypeAnnotation),
579
+ )
580
+ parse_function = _determine_parse_function_for_atomic_value(type_anno)
581
+
582
+ value_type = golang_common.generate_type(
583
+ type_annotation=type_anno, types_package=Identifier("aastypes")
584
+ )
585
+
586
+ case_body = Stripped(
587
+ f"""\
588
+ var parsed {value_type}
589
+ parsed, err = {parse_function}(
590
+ {I}v,
591
+ )
592
+ if err != nil {{
593
+ {I}if deseriaErr, ok := err.(*DeserializationError); ok {{
594
+ {II}deseriaErr.Path.PrependName(
595
+ {III}&aasreporting.NameSegment{{
596
+ {IIII}Name: {json_prop_literal},
597
+ {III}}},
598
+ {II})
599
+ {I}}}
600
+ {I}return
601
+ }}
602
+ {prop_var} = &parsed"""
603
+ )
604
+
605
+ elif isinstance(
606
+ type_anno,
607
+ (intermediate.PrimitiveTypeAnnotation, intermediate.OurTypeAnnotation),
608
+ ):
609
+ parse_function = _determine_parse_function_for_atomic_value(type_anno)
610
+
611
+ case_body = Stripped(
612
+ f"""\
613
+ {prop_var}, err = {parse_function}(
614
+ {I}v,
615
+ )
616
+ if err != nil {{
617
+ {I}if deseriaErr, ok := err.(*DeserializationError); ok {{
618
+ {II}deseriaErr.Path.PrependName(
619
+ {III}&aasreporting.NameSegment{{
620
+ {IIII}Name: {json_prop_literal},
621
+ {III}}},
622
+ {II})
623
+ {I}}}
624
+ {I}return
625
+ }}"""
626
+ )
627
+
628
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
629
+ assert isinstance(
630
+ type_anno.items, intermediate.OurTypeAnnotation
631
+ ) and isinstance(
632
+ type_anno.items.our_type,
633
+ (intermediate.AbstractClass, intermediate.ConcreteClass),
634
+ ), (
635
+ f"NOTE (mristin, 2023-03-29): We expect only lists of classes "
636
+ f"at the moment, but you specified {type_anno}. "
637
+ f"Please contact the developers if you need this feature."
638
+ )
639
+
640
+ parse_function = _determine_parse_function_for_atomic_value(type_anno.items)
641
+
642
+ array_type = golang_common.generate_type(
643
+ type_annotation=type_anno, types_package=Identifier("aastypes")
644
+ )
645
+
646
+ item_type = golang_common.generate_type(
647
+ type_annotation=type_anno.items, types_package=Identifier("aastypes")
648
+ )
649
+
650
+ case_body = Stripped(
651
+ f"""\
652
+ jsonableArray, ok := v.([]interface{{}})
653
+ if !ok {{
654
+ {I}deseriaErr := newDeserializationError(
655
+ {II}fmt.Sprintf(
656
+ {III}"Expected an array, but got %T",
657
+ {III}v,
658
+ {II}),
659
+ {I})
660
+
661
+ {I}deseriaErr.Path.PrependName(
662
+ {II}&aasreporting.NameSegment{{
663
+ {III}Name: {json_prop_literal},
664
+ {II}}},
665
+ {I})
666
+
667
+ {I}err = deseriaErr
668
+
669
+ {I}return
670
+ }}
671
+
672
+ array := make(
673
+ {I}{array_type},
674
+ {I}len(jsonableArray),
675
+ )
676
+ for i, itemJsonable := range jsonableArray {{
677
+ {I}var item {item_type}
678
+ {I}item, err = {parse_function}(
679
+ {II}itemJsonable,
680
+ {I})
681
+ {I}if err != nil {{
682
+ {II}if deseriaErr, ok := err.(*DeserializationError); ok {{
683
+ {III}deseriaErr.Path.PrependIndex(
684
+ {IIII}&aasreporting.IndexSegment{{
685
+ {IIIII}Index: i,
686
+ {IIII}}},
687
+ {III})
688
+
689
+ {III}deseriaErr.Path.PrependName(
690
+ {IIII}&aasreporting.NameSegment{{
691
+ {IIIII}Name: {json_prop_literal},
692
+ {IIII}}},
693
+ {III})
694
+ {II}}}
695
+
696
+ {II}return
697
+ {I}}}
698
+
699
+ {I}array[i] = item
700
+ }}
701
+ {prop_var} = array"""
702
+ )
703
+
704
+ else:
705
+ assert_never(type_anno)
706
+
707
+ if not optional:
708
+ found_var = golang_naming.variable_name(Identifier(f"found_{prop.name}"))
709
+
710
+ # NOTE (mristin, 2023-04-09):
711
+ # Appending once is OK for time complexity. If you append more, please
712
+ # refactor into a list and join.
713
+ case_body = Stripped(
714
+ f"""\
715
+ {case_body}
716
+ {found_var} = true"""
717
+ )
718
+
719
+ case_blocks.append(
720
+ Stripped(
721
+ f"""\
722
+ case {json_prop_literal}:
723
+ {I}{indent_but_first_line(case_body, I)}"""
724
+ )
725
+ )
726
+
727
+ if cls.serialization.with_model_type:
728
+ # NOTE (mristin):
729
+ # We explicitly check for the model type if the meta-model instructs us to.
730
+ #
731
+ # This is crucial for the fix of the problem discovered in:
732
+ # https://github.com/aas-core-works/aas-core3.0-python/issues/32
733
+ model_type = naming.json_model_type(cls.name)
734
+ model_type_case_body = Stripped(
735
+ f"""\
736
+ var modelType string
737
+ modelType, err = stringFromJsonable(
738
+ {I}v,
739
+ )
740
+ if err != nil {{
741
+ {I}if deseriaErr, ok := err.(*DeserializationError); ok {{
742
+ {II}deseriaErr.Path.PrependName(
743
+ {III}&aasreporting.NameSegment{{
744
+ {IIII}Name: "modelType",
745
+ {III}}},
746
+ {II})
747
+ {I}}}
748
+ {I}return
749
+ }}
750
+
751
+ if modelType != "{model_type}" {{
752
+ {I}deseriaErr := newDeserializationError(
753
+ {II}fmt.Sprintf(
754
+ {III}"Expected the model type '{model_type}', but got %v",
755
+ {III}v,
756
+ {II}),
757
+ {I})
758
+
759
+ {I}deseriaErr.Path.PrependName(
760
+ {II}&aasreporting.NameSegment{{
761
+ {III}Name: "modelType",
762
+ {II}}},
763
+ {I})
764
+
765
+ {I}err = deseriaErr
766
+ {I}return
767
+ }}
768
+
769
+ foundModelType = true"""
770
+ )
771
+ case_blocks.append(
772
+ Stripped(
773
+ f"""\
774
+ case "modelType":
775
+ {I}{indent_but_first_line(model_type_case_body, I)}"""
776
+ )
777
+ )
778
+
779
+ case_blocks.append(
780
+ Stripped(
781
+ f"""\
782
+ default:
783
+ {I}err = newDeserializationError(
784
+ {II}fmt.Sprintf(
785
+ {III}"Unexpected property: %s",
786
+ {III}k,
787
+ {II}),
788
+ {I})
789
+ {I}return"""
790
+ )
791
+ )
792
+
793
+ case_blocks_joined = "\n\n".join(case_blocks)
794
+
795
+ return Stripped(
796
+ f"""\
797
+ switch k {{
798
+ {case_blocks_joined}
799
+ }}"""
800
+ )
801
+
802
+
803
+ def _generate_concrete_class_from_map_without_dispatch(
804
+ cls: intermediate.ConcreteClass,
805
+ ) -> Stripped:
806
+ """
807
+ Generate the deserialization function for a concrete class from a map.
808
+
809
+ This function performs no dispatch. If it de-serializes a concrete class with
810
+ concrete descendants, we have to provide a different name. Otherwise, it would
811
+ shadow the name for the dispatch function.
812
+ """
813
+ # fmt: off
814
+ assert (
815
+ sorted(
816
+ (arg.name, str(arg.type_annotation))
817
+ for arg in cls.constructor.arguments
818
+ ) == sorted(
819
+ (prop.name, str(prop.type_annotation))
820
+ for prop in cls.properties
821
+ )
822
+ ), (
823
+ "(mristin, 2023-04-07) We assume that the properties and constructor arguments "
824
+ "are identical at this point. If this is not the case, we have to re-write the "
825
+ "logic substantially! Please contact the developers if you see this."
826
+ )
827
+ # fmt: on
828
+
829
+ blocks = [] # type: List[Stripped]
830
+
831
+ # region Initialize
832
+
833
+ prop_var_initializations = [] # type: List[Stripped]
834
+ for prop in cls.properties:
835
+ prop_var = golang_naming.variable_name(Identifier(f"the_{prop.name}"))
836
+
837
+ prop_var_type = golang_common.generate_type(
838
+ type_annotation=prop.type_annotation, types_package=Identifier("aastypes")
839
+ )
840
+
841
+ prop_var_initializations.append(Stripped(f"var {prop_var} {prop_var_type}"))
842
+
843
+ if len(prop_var_initializations) > 0:
844
+ blocks.append(Stripped("\n".join(prop_var_initializations)))
845
+
846
+ found_var_initializations = [] # type: List[Stripped]
847
+ for prop in cls.properties:
848
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
849
+ continue
850
+
851
+ found_var = golang_naming.variable_name(Identifier(f"found_{prop.name}"))
852
+
853
+ found_var_initializations.append(Stripped(f"{found_var} := false"))
854
+
855
+ if len(found_var_initializations) > 0:
856
+ blocks.append(Stripped("\n".join(found_var_initializations)))
857
+
858
+ # endregion
859
+
860
+ # NOTE (mristin):
861
+ # We explicitly check for the model type if the meta-model instructs us to.
862
+ #
863
+ # This is crucial for the fix of the problem discovered in:
864
+ # https://github.com/aas-core-works/aas-core3.0-python/issues/32
865
+ if cls.serialization.with_model_type:
866
+ blocks.append(Stripped("var foundModelType bool"))
867
+
868
+ # region Switch on property name
869
+
870
+ switch_statement = _generate_deserialization_switch_statement(cls=cls)
871
+
872
+ # endregion
873
+
874
+ blocks.append(
875
+ Stripped(
876
+ f"""\
877
+ for k, v := range m {{
878
+ {I}{indent_but_first_line(switch_statement, I)}
879
+ }}"""
880
+ )
881
+ )
882
+
883
+ # region Check required properties
884
+
885
+ for prop in cls.properties:
886
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
887
+ continue
888
+
889
+ found_var = golang_naming.variable_name(Identifier(f"found_{prop.name}"))
890
+
891
+ message_literal = golang_common.string_literal(
892
+ f"The required property {naming.json_property(prop.name)!r} is missing"
893
+ )
894
+
895
+ blocks.append(
896
+ Stripped(
897
+ f"""\
898
+ if !{found_var} {{
899
+ {I}err = newDeserializationError(
900
+ {II}{message_literal},
901
+ {I})
902
+ {I}return
903
+ }}"""
904
+ )
905
+ )
906
+
907
+ # endregion
908
+
909
+ if cls.serialization.with_model_type:
910
+ # NOTE (mristin):
911
+ # We explicitly check for the model type if the meta-model instructs us to.
912
+ #
913
+ # This is crucial for the fix of the problem discovered in:
914
+ # https://github.com/aas-core-works/aas-core3.0-python/issues/32
915
+ blocks.append(
916
+ Stripped(
917
+ f"""\
918
+ if !foundModelType {{
919
+ {I}err = newDeserializationError(
920
+ {II}"The required property modelType is missing",
921
+ {I})
922
+ {I}return
923
+ }}"""
924
+ )
925
+ )
926
+
927
+ constructing_statements = [] # type: List[Stripped]
928
+
929
+ constructor_arguments = [
930
+ golang_naming.variable_name(Identifier(f"the_{arg.name}"))
931
+ for arg in cls.constructor.arguments
932
+ if not isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation)
933
+ ] # type: List[Stripped]
934
+
935
+ new_function = golang_naming.function_name(Identifier(f"new_{cls.name}"))
936
+
937
+ if len(constructor_arguments) > 0:
938
+ constructor_arguments_joined = "\n".join(
939
+ f"{arg}," for arg in constructor_arguments
940
+ )
941
+
942
+ constructing_statements.append(
943
+ Stripped(
944
+ f"""\
945
+ result = aastypes.{new_function}(
946
+ {I}{indent_but_first_line(constructor_arguments_joined, I)}
947
+ )"""
948
+ )
949
+ )
950
+ else:
951
+ constructing_statements.append(Stripped(f"result = aastypes.{new_function}()"))
952
+
953
+ for arg in cls.constructor.arguments:
954
+ if not isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation):
955
+ continue
956
+
957
+ setter_name = golang_naming.setter_name(arg.name)
958
+ prop_var = golang_naming.variable_name(Identifier(f"the_{arg.name}"))
959
+
960
+ constructing_statements.append(
961
+ Stripped(
962
+ f"""\
963
+ result.{setter_name}(
964
+ {I}{prop_var},
965
+ )"""
966
+ )
967
+ )
968
+
969
+ blocks.append(Stripped("\n".join(constructing_statements)))
970
+
971
+ blocks.append(Stripped("return"))
972
+
973
+ body = Stripped("\n\n".join(blocks))
974
+
975
+ interface_name = golang_naming.interface_name(cls.name)
976
+
977
+ function_name = golang_naming.private_function_name(
978
+ Identifier(f"{cls.name}_from_map_without_dispatch")
979
+ )
980
+
981
+ documentation_blocks = [
982
+ Stripped(
983
+ f"""\
984
+ Parse [aastypes.{interface_name}] from a map,
985
+ or return an error, if any."""
986
+ )
987
+ ] # type: List[Stripped]
988
+
989
+ if len(cls.concrete_descendants) > 0:
990
+ function_name_from_jsonable = golang_naming.function_name(
991
+ Identifier(f"{cls.name}_from_jsonable")
992
+ )
993
+
994
+ documentation_blocks.append(
995
+ Stripped(
996
+ f"""\
997
+ This function performs no dispatch! It is used to parse the properties
998
+ as-are, and already assumes the exact model type. Usually, this function
999
+ is called from within a from-jsonable or from-map function, and you never
1000
+ call it directly. If you want to de-serialize an instance of
1001
+ [aastypes.{interface_name}], call
1002
+ [{function_name_from_jsonable}]."""
1003
+ )
1004
+ )
1005
+
1006
+ documentation_comment = golang_description.documentation_comment(
1007
+ Stripped("\n\n".join(documentation_blocks))
1008
+ )
1009
+
1010
+ return Stripped(
1011
+ f"""\
1012
+ {documentation_comment}
1013
+ func {function_name}(
1014
+ {I}m map[string]interface{{}},
1015
+ ) (
1016
+ {I}result aastypes.{interface_name},
1017
+ {I}err error,
1018
+ ) {{
1019
+ {I}{indent_but_first_line(body, I)}
1020
+ }}"""
1021
+ )
1022
+
1023
+
1024
+ # endregion
1025
+
1026
+ # region Serialization
1027
+
1028
+
1029
+ def _generate_int64_to_jsonable() -> Stripped:
1030
+ """Generate the function to encode an ``int64`` to a JSON-able."""
1031
+ return Stripped(
1032
+ f"""\
1033
+ // Try to cast `that` to a float64, or return an error.
1034
+ func int64ToJsonable(
1035
+ {I}that int64,
1036
+ ) (result float64, err error) {{
1037
+ {I}if that > 9007199254740991 || that < -9007199254740991 {{
1038
+ {II}err = newSerializationError(
1039
+ {III}fmt.Sprintf(
1040
+ {IIII}"64-bit integer can not be represented as 64-bit float in JSON: %v",
1041
+ {IIII}that,
1042
+ {III}),
1043
+ {II})
1044
+ {II}return
1045
+ {I}}}
1046
+
1047
+ {I}result = float64(that);
1048
+ {I}return
1049
+ }}"""
1050
+ )
1051
+
1052
+
1053
+ def _generate_bytes_to_jsonable() -> Stripped:
1054
+ """Generate the function to encode ``[]byte`` to a string."""
1055
+ return Stripped(
1056
+ f"""\
1057
+ // Encode `bytes` to a base64 string.
1058
+ func bytesToJsonable(
1059
+ {I}bytes []byte,
1060
+ ) (result string, err error) {{
1061
+ {I}if bytes == nil {{
1062
+ {II}err = newSerializationError(
1063
+ {III}"Expected an array of bytes, but got nil",
1064
+ {II})
1065
+ {II}return
1066
+ {I}}}
1067
+
1068
+ {I}result = b64.StdEncoding.EncodeToString(
1069
+ {II}bytes,
1070
+ {I})
1071
+ {I}return
1072
+ }}"""
1073
+ )
1074
+
1075
+
1076
+ def _generate_enumeration_to_jsonable(
1077
+ enumeration: intermediate.Enumeration,
1078
+ ) -> Stripped:
1079
+ """Generate the serialization method for an enumeration."""
1080
+ enum_name = golang_naming.enum_name(identifier=enumeration.name)
1081
+
1082
+ function_name = golang_naming.function_name(
1083
+ Identifier(f"{enumeration.name}_to_jsonable")
1084
+ )
1085
+
1086
+ enum_to_str = golang_naming.function_name(
1087
+ Identifier(f"{enumeration.name}_to_string")
1088
+ )
1089
+
1090
+ return Stripped(
1091
+ f"""\
1092
+ // Serialize `that` to a string, or return an error.
1093
+ func {function_name}(
1094
+ {I}that aastypes.{enum_name},
1095
+ ) (result string, err error) {{
1096
+ {I}var ok bool
1097
+ {I}result, ok = aasstringification.{enum_to_str}(
1098
+ {II}that,
1099
+ {I})
1100
+ {I}if !ok {{
1101
+ {II}err = newSerializationError(
1102
+ {III}fmt.Sprintf(
1103
+ {IIII}"Got an invalid literal of {enum_name}: %v",
1104
+ {IIII}that,
1105
+ {III}),
1106
+ {II})
1107
+ {II}return
1108
+ {I}}}
1109
+
1110
+ {I}return
1111
+ }}"""
1112
+ )
1113
+
1114
+
1115
+ TypeAnnotationExceptList = Union[
1116
+ intermediate.PrimitiveTypeAnnotation,
1117
+ intermediate.OurTypeAnnotation,
1118
+ intermediate.OptionalTypeAnnotation,
1119
+ ]
1120
+
1121
+ assert_union_without_excluded(
1122
+ original_union=intermediate.TypeAnnotationUnion,
1123
+ subset_union=TypeAnnotationExceptList,
1124
+ excluded=[intermediate.ListTypeAnnotation],
1125
+ )
1126
+
1127
+
1128
+ def _generate_expression_to_serialize_atomic_value(
1129
+ access_expression: str, type_annotation: TypeAnnotationExceptList
1130
+ ) -> Tuple[Stripped, bool]:
1131
+ """
1132
+ Generate the snippet to serialize the ``access_expression``.
1133
+
1134
+ The ``access_expression`` is for example a name or a property access.
1135
+ The caller is expected to have already generated the code which checks that
1136
+ ``access_expression`` is not nil.
1137
+
1138
+ Return (expression, True if there needs to be error checking)
1139
+ """
1140
+ type_anno = intermediate.beneath_optional(type_annotation)
1141
+ assert isinstance(
1142
+ type_anno,
1143
+ (
1144
+ intermediate.PrimitiveTypeAnnotation,
1145
+ intermediate.OurTypeAnnotation,
1146
+ ),
1147
+ )
1148
+
1149
+ optional = isinstance(type_annotation, intermediate.OptionalTypeAnnotation)
1150
+
1151
+ # NOTE (mristin, 2023-04-12):
1152
+ # The following types are handled as primitive values in Golang, so we have
1153
+ # to handle them as such. They are primitive values if non-nullable, and referenced
1154
+ # if nullable, since we model optional primitive properties as pointers in
1155
+ # Golang.
1156
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation) or (
1157
+ isinstance(type_anno, intermediate.OurTypeAnnotation)
1158
+ and isinstance(
1159
+ type_anno.our_type,
1160
+ (intermediate.Enumeration, intermediate.ConstrainedPrimitive),
1161
+ )
1162
+ ):
1163
+ primitive_type = intermediate.try_primitive_type(type_anno)
1164
+
1165
+ if primitive_type is intermediate.PrimitiveType.INT:
1166
+ if not optional:
1167
+ return (
1168
+ Stripped(
1169
+ f"""\
1170
+ int64ToJsonable(
1171
+ {I}{access_expression},
1172
+ )"""
1173
+ ),
1174
+ True,
1175
+ )
1176
+ else:
1177
+ return (
1178
+ Stripped(
1179
+ f"""\
1180
+ int64ToJsonable(
1181
+ {I}*({access_expression}),
1182
+ )"""
1183
+ ),
1184
+ True,
1185
+ )
1186
+
1187
+ elif primitive_type is intermediate.PrimitiveType.BYTEARRAY:
1188
+ return (
1189
+ Stripped(
1190
+ f"""\
1191
+ bytesToJsonable(
1192
+ {I}{access_expression},
1193
+ )"""
1194
+ ),
1195
+ True,
1196
+ )
1197
+
1198
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation) and isinstance(
1199
+ type_anno.our_type, intermediate.Enumeration
1200
+ ):
1201
+ enumeration = type_anno.our_type
1202
+ enum_to_jsonable = golang_naming.function_name(
1203
+ Identifier(f"{enumeration.name}_to_jsonable")
1204
+ )
1205
+
1206
+ if not optional:
1207
+ return (
1208
+ Stripped(
1209
+ f"""\
1210
+ {enum_to_jsonable}(
1211
+ {I}{access_expression},
1212
+ )"""
1213
+ ),
1214
+ True,
1215
+ )
1216
+ else:
1217
+ return (
1218
+ Stripped(
1219
+ f"""\
1220
+ {enum_to_jsonable}(
1221
+ {I}*({access_expression}),
1222
+ )"""
1223
+ ),
1224
+ True,
1225
+ )
1226
+ else:
1227
+ if optional:
1228
+ return Stripped(f"*{access_expression}"), False
1229
+ else:
1230
+ return Stripped(access_expression), False
1231
+
1232
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
1233
+ our_type = type_anno.our_type
1234
+
1235
+ if isinstance(our_type, intermediate.Enumeration):
1236
+ raise AssertionError(f"Should have been handled before: {type_anno=}")
1237
+
1238
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1239
+ raise AssertionError(f"Should have been handled before: {type_anno=}")
1240
+
1241
+ elif isinstance(
1242
+ our_type,
1243
+ (
1244
+ intermediate.AbstractClass,
1245
+ intermediate.ConcreteClass,
1246
+ ),
1247
+ ):
1248
+ return (
1249
+ Stripped(
1250
+ f"""\
1251
+ ToJsonable(
1252
+ {I}{access_expression},
1253
+ )"""
1254
+ ),
1255
+ True,
1256
+ )
1257
+
1258
+ else:
1259
+ assert_never(our_type)
1260
+ else:
1261
+ assert_never(type_anno)
1262
+
1263
+
1264
+ def _generate_cls_to_map(cls: intermediate.ConcreteClass) -> Stripped:
1265
+ """
1266
+ Generate the function to serialize class to a JSON-able map.
1267
+
1268
+ The generated function will perform no dispatching.
1269
+ """
1270
+ blocks = [Stripped("result = make(map[string]interface{})")] # type: List[Stripped]
1271
+
1272
+ for prop in cls.properties:
1273
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1274
+
1275
+ getter_name = golang_naming.getter_name(prop.name)
1276
+
1277
+ prop_literal = golang_common.string_literal(
1278
+ f"{golang_naming.property_name(prop.name)}()"
1279
+ )
1280
+
1281
+ json_prop_literal = golang_common.string_literal(
1282
+ naming.json_property(prop.name)
1283
+ )
1284
+
1285
+ prop_jsonable_var = golang_naming.variable_name(
1286
+ Identifier(f"jsonable_{prop.name}")
1287
+ )
1288
+
1289
+ block: Stripped
1290
+
1291
+ if isinstance(type_anno, intermediate.ListTypeAnnotation):
1292
+ assert isinstance(
1293
+ type_anno.items,
1294
+ intermediate.OurTypeAnnotation,
1295
+ ) and isinstance(
1296
+ type_anno.items.our_type,
1297
+ (intermediate.AbstractClass, intermediate.ConcreteClass),
1298
+ ), (
1299
+ "(mristin, 2023-04-12): We expect only lists of our classes. "
1300
+ "Other lists are not handled yet. Please contact the developers."
1301
+ )
1302
+
1303
+ statements = [
1304
+ Stripped(
1305
+ f"""\
1306
+ {prop_jsonable_var} := make(
1307
+ {I}[]interface{{}},
1308
+ {I}len(that.{getter_name}()),
1309
+ )"""
1310
+ )
1311
+ ] # type: List[Stripped]
1312
+
1313
+ # fmt: off
1314
+ serialize_expr, needs_error_checking = (
1315
+ _generate_expression_to_serialize_atomic_value(
1316
+ access_expression="v", type_annotation=type_anno.items
1317
+ )
1318
+ )
1319
+ # fmt: on
1320
+
1321
+ if needs_error_checking:
1322
+ statements.append(
1323
+ Stripped(
1324
+ f"""\
1325
+ for i, v := range that.{getter_name}() {{
1326
+ {I}var jsonable interface{{}}
1327
+ {I}jsonable, err = {indent_but_first_line(serialize_expr, I)}
1328
+ {I}if err != nil {{
1329
+ {II}if seriaErr, ok := err.(*SerializationError); ok {{
1330
+ {III}seriaErr.Path.PrependIndex(
1331
+ {IIII}&aasreporting.IndexSegment{{
1332
+ {IIIII}Index: i,
1333
+ {IIII}}},
1334
+ {III})
1335
+
1336
+ {III}seriaErr.Path.PrependName(
1337
+ {IIII}&aasreporting.NameSegment{{
1338
+ {IIIII}Name: {prop_literal},
1339
+ {IIII}}},
1340
+ {III})
1341
+ {II}}}
1342
+
1343
+ {II}return
1344
+ {I}}}
1345
+ {I}{prop_jsonable_var}[i] = jsonable
1346
+ }}"""
1347
+ )
1348
+ )
1349
+ else:
1350
+ statements.append(
1351
+ Stripped(
1352
+ f"""\
1353
+ for _, v := range that.{getter_name}() {{
1354
+ {I}{prop_jsonable_var} = append(
1355
+ {II}{prop_jsonable_var},
1356
+ {II}{indent_but_first_line(serialize_expr, II)}
1357
+ {I})
1358
+ }}"""
1359
+ )
1360
+ )
1361
+
1362
+ statements.append(
1363
+ Stripped(
1364
+ f"""\
1365
+ result[{json_prop_literal}] = {prop_jsonable_var}"""
1366
+ )
1367
+ )
1368
+
1369
+ block = Stripped("\n".join(statements))
1370
+ else:
1371
+ assert not isinstance(prop.type_annotation, intermediate.ListTypeAnnotation)
1372
+
1373
+ # fmt: off
1374
+ serialize_expr, needs_error_checking = (
1375
+ _generate_expression_to_serialize_atomic_value(
1376
+ access_expression=f"that.{getter_name}()",
1377
+ type_annotation=prop.type_annotation
1378
+ )
1379
+ )
1380
+ # fmt: on
1381
+
1382
+ if needs_error_checking:
1383
+ block = Stripped(
1384
+ f"""\
1385
+ var {prop_jsonable_var} interface{{}}
1386
+ {prop_jsonable_var}, err = {serialize_expr}
1387
+ if err != nil {{
1388
+ {I}if seriaErr, ok := err.(*SerializationError); ok {{
1389
+ {II}seriaErr.Path.PrependName(
1390
+ {III}&aasreporting.NameSegment{{
1391
+ {IIII}Name: {prop_literal},
1392
+ {III}}},
1393
+ {II})
1394
+ {I}}}
1395
+
1396
+ {I}return
1397
+ }}
1398
+ result[{json_prop_literal}] = {prop_jsonable_var}"""
1399
+ )
1400
+ else:
1401
+ block = Stripped(
1402
+ f"""\
1403
+ result[{json_prop_literal}] = {serialize_expr}"""
1404
+ )
1405
+
1406
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1407
+ block = Stripped(
1408
+ f"""\
1409
+ if that.{getter_name}() != nil {{
1410
+ {I}{indent_but_first_line(block, I)}
1411
+ }}"""
1412
+ )
1413
+
1414
+ blocks.append(block)
1415
+
1416
+ if cls.serialization.with_model_type:
1417
+ model_type_literal = golang_common.string_literal(
1418
+ naming.json_model_type(cls.name)
1419
+ )
1420
+ blocks.append(Stripped(f'result["modelType"] = {model_type_literal}'))
1421
+
1422
+ blocks.append(Stripped("return"))
1423
+
1424
+ body = "\n\n".join(blocks)
1425
+
1426
+ function_name = golang_naming.private_function_name(
1427
+ Identifier(f"{cls.name}_to_map")
1428
+ )
1429
+
1430
+ interface_name = golang_naming.interface_name(cls.name)
1431
+
1432
+ to_jsonable = golang_naming.function_name(Identifier("to_jsonable"))
1433
+
1434
+ return Stripped(
1435
+ f"""\
1436
+ // Serialize [aastypes.{interface_name}] as a JSON-able map.
1437
+ //
1438
+ // This function performs no dispatch! It is only used to serialize
1439
+ // the properties. If you want to serialize an instance of
1440
+ // [aastypes.{interface_name}] with proper dispatch, call
1441
+ // [{to_jsonable}].
1442
+ func {function_name}(
1443
+ {I}that aastypes.{interface_name},
1444
+ ) (result map[string]interface{{}}, err error) {{
1445
+ {I}{indent_but_first_line(body, I)}
1446
+ }}"""
1447
+ )
1448
+
1449
+
1450
+ def _generate_to_jsonable(symbol_table: intermediate.SymbolTable) -> Stripped:
1451
+ """Generate the main entry point for the serialization."""
1452
+ case_blocks = [] # type: List[Stripped]
1453
+
1454
+ for cls in symbol_table.concrete_classes:
1455
+ literal = golang_naming.enum_literal_name(
1456
+ enumeration_name=Identifier("Model_type"), literal_name=cls.name
1457
+ )
1458
+
1459
+ interface_name = golang_naming.interface_name(cls.name)
1460
+
1461
+ to_map = golang_naming.private_function_name(Identifier(f"{cls.name}_to_map"))
1462
+
1463
+ case_blocks.append(
1464
+ Stripped(
1465
+ f"""\
1466
+ case aastypes.{literal}:
1467
+ {I}result, err = {to_map}(
1468
+ {II}that.(aastypes.{interface_name}),
1469
+ {I})"""
1470
+ )
1471
+ )
1472
+
1473
+ case_blocks.append(
1474
+ Stripped(
1475
+ f"""\
1476
+ default:
1477
+ {I}err = newSerializationError(
1478
+ {II}fmt.Sprintf(
1479
+ {III}"Unexpected model type literal: %v",
1480
+ {III}that.ModelType(),
1481
+ {II}),
1482
+ {I})"""
1483
+ )
1484
+ )
1485
+
1486
+ switch_body = Stripped("\n".join(case_blocks))
1487
+ model_type_getter = golang_naming.getter_name(Identifier("model_type"))
1488
+ switch_statement = Stripped(
1489
+ f"""\
1490
+ switch that.{model_type_getter}() {{
1491
+ {switch_body}
1492
+ }}"""
1493
+ )
1494
+
1495
+ return Stripped(
1496
+ f"""\
1497
+ // Serialize “that“ instance to a JSON-able representation.
1498
+ //
1499
+ // Return a structure which can be readily converted to JSON,
1500
+ // or an error if some value could not be converted.
1501
+ func ToJsonable(
1502
+ {I}that aastypes.IClass,
1503
+ ) (result map[string]interface{{}}, err error) {{
1504
+ {I}{indent_but_first_line(switch_statement, I)}
1505
+ {I}return
1506
+ }}"""
1507
+ )
1508
+
1509
+
1510
+ # endregion
1511
+
1512
+ # fmt: off
1513
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1514
+ @ensure(
1515
+ lambda result:
1516
+ not (result[0] is not None) or result[0].endswith('\n'),
1517
+ "Trailing newline mandatory for valid end-of-files"
1518
+ )
1519
+ # fmt: on
1520
+ def generate(
1521
+ symbol_table: intermediate.SymbolTable,
1522
+ spec_impls: specific_implementations.SpecificImplementations,
1523
+ repo_url: Stripped,
1524
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
1525
+ """Generate the Golang code for the general de/serialization."""
1526
+ aastypes_url_literal = golang_common.string_literal(f"{repo_url}/types")
1527
+
1528
+ aasreporting_url_literal = golang_common.string_literal(f"{repo_url}/reporting")
1529
+
1530
+ aasstringification_url_literal = golang_common.string_literal(
1531
+ f"{repo_url}/stringification"
1532
+ )
1533
+
1534
+ blocks = [
1535
+ Stripped(
1536
+ """\
1537
+ // Package jsonization de/serializes model instances to and from JSON.
1538
+ //
1539
+ // We can not use one-pass deserialization for JSON since the object
1540
+ // properties do not have fixed order, and hence we can not read
1541
+ // `modelType` property ahead of the remaining properties.
1542
+ //
1543
+ // To de-serialize, call one of the `*FromJsonable` functions.
1544
+ //
1545
+ // To serialize, call [ToJsonable] function.
1546
+ package jsonization"""
1547
+ ),
1548
+ golang_common.WARNING,
1549
+ Stripped(
1550
+ f"""\
1551
+ import (
1552
+ {I}"fmt"
1553
+ {I}"math"
1554
+ {I}b64 "encoding/base64"
1555
+ {I}aasreporting {aasreporting_url_literal}
1556
+ {I}aasstringification {aasstringification_url_literal}
1557
+ {I}aastypes {aastypes_url_literal}
1558
+ )"""
1559
+ ),
1560
+ Stripped("// region De-serialization"),
1561
+ Stripped(
1562
+ f"""\
1563
+ // Represent an error during the de-serialization.
1564
+ //
1565
+ // Implements `error`.
1566
+ type DeserializationError struct{{
1567
+ {I}Path *aasreporting.Path
1568
+ {I}Message string
1569
+ }}"""
1570
+ ),
1571
+ Stripped(
1572
+ f"""\
1573
+ func newDeserializationError(message string) *DeserializationError {{
1574
+ {I}return &DeserializationError{{
1575
+ {II}Path: &aasreporting.Path{{}},
1576
+ {II}Message: message,
1577
+ {I}}}
1578
+ }}"""
1579
+ ),
1580
+ Stripped(
1581
+ f"""\
1582
+ func (de *DeserializationError) Error() string {{
1583
+ {I}return fmt.Sprintf(
1584
+ {II}"%s: %s",
1585
+ {II}de.PathString(),
1586
+ {II}de.Message,
1587
+ {I})
1588
+ }}"""
1589
+ ),
1590
+ Stripped(
1591
+ f"""\
1592
+ // Render the path as a string.
1593
+ func (de *DeserializationError) PathString() string {{
1594
+ {I}return aasreporting.ToJSONPath(de.Path)
1595
+ }}"""
1596
+ ),
1597
+ _generate_bool_from_jsonable(),
1598
+ _generate_int64_from_jsonable(),
1599
+ _generate_float64_from_jsonable(),
1600
+ _generate_string_from_jsonable(),
1601
+ _generate_bytes_from_jsonable(),
1602
+ ] # type: List[Stripped]
1603
+
1604
+ errors = [] # type: List[Error]
1605
+
1606
+ for our_type in symbol_table.our_types:
1607
+ if isinstance(our_type, intermediate.Enumeration):
1608
+ blocks.append(_generate_enumeration_from_jsonable(enumeration=our_type))
1609
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1610
+ pass
1611
+ elif isinstance(our_type, intermediate.AbstractClass):
1612
+ blocks.append(_generate_class_from_jsonable(cls=our_type))
1613
+ elif isinstance(our_type, intermediate.ConcreteClass):
1614
+ blocks.append(_generate_class_from_jsonable(cls=our_type))
1615
+
1616
+ if our_type.is_implementation_specific:
1617
+ implementation_key = specific_implementations.ImplementationKey(
1618
+ f"Jsonization/{our_type.name}_from_map.go"
1619
+ )
1620
+
1621
+ implementation = spec_impls.get(implementation_key, None)
1622
+ if implementation is None:
1623
+ errors.append(
1624
+ Error(
1625
+ our_type.parsed.node,
1626
+ f"The jsonization snippet is missing "
1627
+ f"for the implementation-specific "
1628
+ f"class {our_type.name}: {implementation_key}",
1629
+ )
1630
+ )
1631
+ continue
1632
+ else:
1633
+ blocks.append(
1634
+ _generate_concrete_class_from_map_without_dispatch(cls=our_type)
1635
+ )
1636
+ else:
1637
+ assert_never(our_type)
1638
+
1639
+ # NOTE (mristin, 2023-04-12):
1640
+ # We add all the dispatch mappings at the end as the functions might not have been
1641
+ # defined yet.
1642
+ for cls in symbol_table.classes:
1643
+ if isinstance(cls, intermediate.AbstractClass):
1644
+ blocks.append(_generate_class_from_map(cls=cls))
1645
+ elif isinstance(cls, intermediate.ConcreteClass):
1646
+ if len(cls.concrete_descendants) > 0:
1647
+ blocks.append(_generate_class_from_map(cls=cls))
1648
+ else:
1649
+ assert_never(cls)
1650
+
1651
+ blocks.append(Stripped("// endregion"))
1652
+
1653
+ blocks.append(Stripped("// region Serialization"))
1654
+
1655
+ blocks.extend(
1656
+ [
1657
+ Stripped(
1658
+ f"""\
1659
+ // Represent an error during the serialization.
1660
+ //
1661
+ // Implements `error`.
1662
+ type SerializationError struct{{
1663
+ {I}Path *aasreporting.Path
1664
+ {I}Message string
1665
+ }}"""
1666
+ ),
1667
+ Stripped(
1668
+ f"""\
1669
+ func newSerializationError(message string) *SerializationError {{
1670
+ {I}return &SerializationError{{
1671
+ {II}Path: &aasreporting.Path{{}},
1672
+ {II}Message: message,
1673
+ {I}}}
1674
+ }}"""
1675
+ ),
1676
+ Stripped(
1677
+ f"""\
1678
+ func (se *SerializationError) Error() string {{
1679
+ {I}return fmt.Sprintf(
1680
+ {II}"%s: %s",
1681
+ {II}se.PathString(),
1682
+ {II}se.Message,
1683
+ {I})
1684
+ }}"""
1685
+ ),
1686
+ Stripped(
1687
+ f"""\
1688
+ // Render the path as a string.
1689
+ func (se *SerializationError) PathString() string {{
1690
+ {I}return aasreporting.ToGolangPath(se.Path)
1691
+ }}"""
1692
+ ),
1693
+ ]
1694
+ )
1695
+
1696
+ blocks.append(_generate_int64_to_jsonable())
1697
+ blocks.append(_generate_bytes_to_jsonable())
1698
+
1699
+ for enum in symbol_table.enumerations:
1700
+ blocks.append(_generate_enumeration_to_jsonable(enum))
1701
+
1702
+ for cls in symbol_table.concrete_classes:
1703
+ if cls.is_implementation_specific:
1704
+ implementation_key = specific_implementations.ImplementationKey(
1705
+ f"Jsonization/{cls.name}_to_map.go"
1706
+ )
1707
+
1708
+ implementation = spec_impls.get(implementation_key, None)
1709
+ if implementation is None:
1710
+ errors.append(
1711
+ Error(
1712
+ cls.parsed.node,
1713
+ f"The jsonization snippet is missing "
1714
+ f"for the implementation-specific "
1715
+ f"class {cls.name}: {implementation_key}",
1716
+ )
1717
+ )
1718
+ continue
1719
+ else:
1720
+ blocks.append(_generate_cls_to_map(cls))
1721
+
1722
+ blocks.append(_generate_to_jsonable(symbol_table))
1723
+
1724
+ blocks.append(Stripped("// endregion"))
1725
+
1726
+ if len(errors) > 0:
1727
+ return None, errors
1728
+
1729
+ blocks.append(golang_common.WARNING)
1730
+
1731
+ writer = io.StringIO()
1732
+ for i, block in enumerate(blocks):
1733
+ if i > 0:
1734
+ writer.write("\n\n")
1735
+
1736
+ writer.write(block)
1737
+
1738
+ writer.write("\n")
1739
+
1740
+ return writer.getvalue(), None