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,1472 @@
1
+ """Generate Java code for JSON-ization based on the intermediate representation."""
2
+
3
+ import io
4
+ import textwrap
5
+ from typing import Tuple, Optional, List
6
+
7
+ from icontract import ensure
8
+
9
+ from aas_core_codegen import intermediate, naming, specific_implementations
10
+ from aas_core_codegen.common import (
11
+ Error,
12
+ Stripped,
13
+ Identifier,
14
+ assert_never,
15
+ indent_but_first_line,
16
+ )
17
+ from aas_core_codegen.java import (
18
+ common as java_common,
19
+ naming as java_naming,
20
+ )
21
+ from aas_core_codegen.java.common import (
22
+ INDENT as I,
23
+ INDENT2 as II,
24
+ INDENT3 as III,
25
+ INDENT4 as IIII,
26
+ )
27
+
28
+
29
+ def _generate_from_method_for_enumeration(
30
+ enumeration: intermediate.Enumeration,
31
+ ) -> Stripped:
32
+ """Generate the deserialization method for an enumeration."""
33
+ name = java_naming.enum_name(identifier=enumeration.name)
34
+ var_name = java_naming.variable_name(identifier=enumeration.name)
35
+ method_name = java_naming.method_name(Identifier(f"{enumeration.name}_from_string"))
36
+
37
+ message_literal = java_common.string_literal(
38
+ f"Not a valid JSON representation of {name}"
39
+ )
40
+
41
+ return Stripped(
42
+ f"""\
43
+ /**
44
+ * Deserialize the enumeration {name} from the {{@code node}}.
45
+ *
46
+ * @param node JSON node to be parsed
47
+ */
48
+ private static Result<{name}> try{name}From(JsonNode node) {{
49
+ {I}final Result<String> textResult = tryStringFrom(node);
50
+ {I}if (textResult.isError()) {{
51
+ {II}return textResult.castTo({name}.class);
52
+ {I}}}
53
+ {I}final Optional<{name}> {var_name} = Stringification.{method_name}(textResult.getResult());
54
+ {I}if (!{var_name}.isPresent()) {{
55
+ {II}final Reporting.Error error = new Reporting.Error({message_literal});
56
+ {II}return Result.failure(error);
57
+ {I}}}
58
+ {I}return Result.success({var_name}.get());
59
+ }}"""
60
+ )
61
+
62
+
63
+ def _generate_from_method_for_interface(
64
+ interface: intermediate.Interface,
65
+ ) -> Stripped:
66
+ """Generate the deserialization method for an interface."""
67
+ name = java_naming.interface_name(interface.name)
68
+ interface_name = java_naming.interface_name(interface.name)
69
+
70
+ blocks = [
71
+ Stripped(
72
+ f"""\
73
+ if (node == null || !node.isObject()) {{
74
+ {I}final Reporting.Error error = new Reporting.Error(
75
+ {II}"Expected a JsonObject, but got " + (node == null ? "null" : node.getNodeType()));
76
+ {I}return Result.failure(error);
77
+ }}
78
+
79
+ final JsonNode modelTypeNode = node.get("modelType");
80
+ if (modelTypeNode == null) {{
81
+ {I}final Reporting.Error error = new Reporting.Error(
82
+ {III}"Expected a model type, but none is present");
83
+ {I}return Result.failure(error);
84
+ }}
85
+ final Result<String> modelTypeResult = tryStringFrom(modelTypeNode);
86
+ if (modelTypeResult.isError()) {{
87
+ {I}return modelTypeResult.castTo({interface_name}.class);
88
+ }}"""
89
+ ),
90
+ ] # type: List[Stripped]
91
+
92
+ # region Write the switch block
93
+
94
+ switch_writer = io.StringIO()
95
+ switch_writer.write(
96
+ """\
97
+ switch (modelTypeResult.getResult())
98
+ {
99
+ """
100
+ )
101
+
102
+ for implementer in interface.implementers:
103
+ model_type = naming.json_model_type(implementer.name)
104
+ implementer_name = java_naming.class_name(implementer.name)
105
+ switch_writer.write(
106
+ f"""\
107
+ {I}case {java_common.string_literal(model_type)}: {{
108
+ {II}return try{implementer_name}From(node);
109
+ }}"""
110
+ )
111
+
112
+ switch_writer.write(
113
+ f"""\
114
+ {I}default: {{
115
+ {II}final Reporting.Error error = new Reporting.Error(
116
+ {III}"Unexpected model type for {name}: " + modelTypeResult.getResult());
117
+ {II}return Result.failure(error);
118
+ {I}}}
119
+ }}"""
120
+ )
121
+ blocks.append(Stripped(switch_writer.getvalue()))
122
+
123
+ # endregion
124
+
125
+ writer = io.StringIO()
126
+
127
+ writer.write(
128
+ f"""\
129
+ /**
130
+ * Deserialize an instance of {name} by dispatching
131
+ * based on {{@code modelType}} property of the {{@code node}}.
132
+ *
133
+ * @param node JSON node to be parsed
134
+ */
135
+ public static Result<? extends {name}> try{name}From(JsonNode node) {{
136
+ """
137
+ )
138
+
139
+ for i, block in enumerate(blocks):
140
+ if i > 0:
141
+ writer.write("\n\n")
142
+ writer.write(textwrap.indent(block, I))
143
+
144
+ writer.write("\n}")
145
+
146
+ return Stripped(writer.getvalue())
147
+
148
+
149
+ _PARSE_METHOD_BY_PRIMITIVE_TYPE = {
150
+ intermediate.PrimitiveType.BOOL: "tryBooleanFrom",
151
+ intermediate.PrimitiveType.INT: "tryLongFrom",
152
+ intermediate.PrimitiveType.FLOAT: "tryDoubleFrom",
153
+ intermediate.PrimitiveType.STR: "tryStringFrom",
154
+ intermediate.PrimitiveType.BYTEARRAY: "tryBytesFrom",
155
+ }
156
+ assert all(
157
+ literal in _PARSE_METHOD_BY_PRIMITIVE_TYPE for literal in intermediate.PrimitiveType
158
+ )
159
+
160
+
161
+ def _parse_method_for_atomic_value(
162
+ type_annotation: intermediate.AtomicTypeAnnotation,
163
+ ) -> Stripped:
164
+ """Determine the parse method for deserializing an atomic non-optional value."""
165
+ parse_method = None # type: Optional[str]
166
+
167
+ if isinstance(type_annotation, intermediate.PrimitiveTypeAnnotation):
168
+ parse_method = _PARSE_METHOD_BY_PRIMITIVE_TYPE[type_annotation.a_type]
169
+
170
+ elif isinstance(type_annotation, intermediate.OurTypeAnnotation):
171
+ our_type = type_annotation.our_type
172
+ if isinstance(our_type, intermediate.Enumeration):
173
+ enum_name = java_naming.enum_name(our_type.name)
174
+ parse_method = f"try{enum_name}From"
175
+
176
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
177
+ parse_method = _PARSE_METHOD_BY_PRIMITIVE_TYPE[our_type.constrainee]
178
+
179
+ elif isinstance(
180
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
181
+ ):
182
+ if our_type.interface is not None:
183
+ interface_name = java_naming.interface_name(our_type.interface.name)
184
+ parse_method = f"try{interface_name}From"
185
+ else:
186
+ cls_name = java_naming.class_name(our_type.name)
187
+ parse_method = f"try{cls_name}From"
188
+
189
+ else:
190
+ assert_never(our_type)
191
+ else:
192
+ assert_never(type_annotation)
193
+
194
+ return Stripped(parse_method)
195
+
196
+
197
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
198
+ def _generate_deserialize_constructor_argument(
199
+ arg: intermediate.Argument,
200
+ cls: intermediate.ConcreteClass,
201
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
202
+ """Generate the code snippet for de-serializing the constructor argument ``arg``."""
203
+ type_anno = intermediate.beneath_optional(arg.type_annotation)
204
+
205
+ # Prefix the variables to avoid naming conflicts
206
+ target_var = java_naming.variable_name(Identifier(f"the_{arg.name}"))
207
+
208
+ json_name = naming.json_property(arg.name)
209
+ assert not java_common.needs_escaping(json_name)
210
+
211
+ json_literal = java_common.string_literal(json_name)
212
+
213
+ parse_block = None # type: Optional[Stripped]
214
+ if isinstance(
215
+ type_anno,
216
+ (intermediate.PrimitiveTypeAnnotation, intermediate.OurTypeAnnotation),
217
+ ):
218
+ parse_method = _parse_method_for_atomic_value(type_anno)
219
+
220
+ value_type = java_common.generate_type(type_anno)
221
+
222
+ cls_name = java_naming.class_name(cls.name)
223
+
224
+ parse_block = Stripped(
225
+ f"""\
226
+ final Result<? extends {value_type}> {target_var}Result = {parse_method}(currentNode.getValue());
227
+ if ({target_var}Result.isError()) {{
228
+ {I}{target_var}Result.getError()
229
+ {II}.prependSegment(new Reporting.NameSegment("{json_name}"));
230
+ {I}return {target_var}Result.castTo({cls_name}.class);
231
+ }}
232
+ {target_var} = {target_var}Result.getResult();"""
233
+ )
234
+
235
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
236
+ assert not isinstance(
237
+ type_anno.items,
238
+ (intermediate.OptionalTypeAnnotation, intermediate.ListTypeAnnotation),
239
+ ), (
240
+ "We chose to implement only a very limited pattern matching; "
241
+ "see intermediate._translate_._verify_only_simple_type_patterns"
242
+ )
243
+
244
+ item_type = java_common.generate_type(type_anno.items)
245
+
246
+ array_var = java_naming.variable_name(Identifier(f"array_{arg.name}"))
247
+ index_var = java_naming.variable_name(Identifier(f"index_{arg.name}"))
248
+
249
+ cls_name = java_naming.class_name(cls.name)
250
+
251
+ parse_method = _parse_method_for_atomic_value(type_anno.items)
252
+
253
+ parse_block = Stripped(
254
+ f"""\
255
+ final JsonNode {array_var} = currentNode.getValue();
256
+ if (!{array_var}.isArray()) {{
257
+ {I}final Reporting.Error error = new Reporting.Error(
258
+ {II}"Expected a JsonArray, but got " + {array_var}.getNodeType());
259
+ {I}error.prependSegment(
260
+ {II}new Reporting.NameSegment(
261
+ {III}{json_literal}));
262
+ {I}return Result.failure(error);
263
+ }}
264
+ {target_var} = new ArrayList<>(
265
+ {I}{array_var}.size());
266
+ int {index_var} = 0;
267
+ for (JsonNode item : {array_var}) {{
268
+ {I}if (item == null) {{
269
+ {II}final Reporting.Error error = new Reporting.Error(
270
+ {III}"Expected a non-null item, but got a null");
271
+ {II}error.prependSegment(
272
+ {III}new Reporting.IndexSegment(
273
+ {IIII}{index_var}));
274
+ {II}error.prependSegment(
275
+ {III}new Reporting.NameSegment(
276
+ {IIII}{json_literal}));
277
+ {II}return Result.failure(error);
278
+ {I}}}
279
+ {I}final Result<? extends {item_type}> parsedItemResult =
280
+ {II}{parse_method}(item);
281
+ {I}if (parsedItemResult.isError()) {{
282
+ {II}parsedItemResult
283
+ {III}.getError()
284
+ {III}.prependSegment(
285
+ {III}new Reporting.IndexSegment(
286
+ {IIII}{index_var}));
287
+ {II}parsedItemResult
288
+ {III}.getError()
289
+ {III}.prependSegment(
290
+ {III}new Reporting.NameSegment(
291
+ {IIII}{json_literal}));
292
+ {II}return parsedItemResult.castTo({cls_name}.class);
293
+ {I}}}
294
+ {I}{target_var}.add(
295
+ {II}parsedItemResult.getResult());
296
+ {I}{index_var}++;
297
+ }}"""
298
+ )
299
+ else:
300
+ assert_never(arg.type_annotation)
301
+
302
+ return parse_block, None
303
+
304
+
305
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
306
+ def _generate_from_method_for_class(
307
+ cls: intermediate.ConcreteClass,
308
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
309
+ """Generate the deserialization method for a concrete class."""
310
+ errors = [] # type: List[Error]
311
+
312
+ name = java_naming.class_name(cls.name)
313
+
314
+ blocks = [
315
+ Stripped(
316
+ f"""\
317
+ if (node == null || !node.isObject()) {{
318
+ {I}final Reporting.Error error = new Reporting.Error(
319
+ {II}"Expected a JsonObject, but got " + (node == null ? "null" : node.getNodeType()));
320
+ {I}return Result.failure(error);
321
+ }}"""
322
+ ),
323
+ ] # type: List[Stripped]
324
+
325
+ # region Initialize argument variables to null
326
+
327
+ args_init_writer = io.StringIO()
328
+ for i, arg in enumerate(cls.constructor.arguments):
329
+ arg_var = java_naming.variable_name(Identifier(f"the_{arg.name}"))
330
+ type_anno = intermediate.beneath_optional(arg.type_annotation)
331
+ arg_type = java_common.generate_type(type_anno)
332
+
333
+ if i > 0:
334
+ args_init_writer.write("\n")
335
+ args_init_writer.write(f"{arg_type} {arg_var} = null;")
336
+
337
+ blocks.append(Stripped(args_init_writer.getvalue()))
338
+
339
+ if cls.serialization.with_model_type:
340
+ blocks.append(Stripped("String modelType = null;"))
341
+
342
+ # endregion
343
+
344
+ # region Switch on property name
345
+
346
+ cases = [] # type: List[Stripped]
347
+ for arg in cls.constructor.arguments:
348
+ case_body, error = _generate_deserialize_constructor_argument(arg=arg, cls=cls)
349
+ if error is not None:
350
+ errors.append(error)
351
+ else:
352
+ assert case_body is not None
353
+ json_name = naming.json_property(arg.name)
354
+
355
+ # NOTE (empwilli, 2024-01-18):
356
+ # We put ``if (currentNode.getValue() == null)`` here instead of the outer loop
357
+ # since we want to detect the unexpected additional properties even
358
+ # though their value can be set to null.
359
+
360
+ cases.append(
361
+ Stripped(
362
+ f"""\
363
+ case {java_common.string_literal(json_name)}: {{
364
+ {I}if (currentNode.getValue() == null) {{
365
+ {II}continue;
366
+ {I}}}
367
+
368
+ {I}{indent_but_first_line(case_body, I)}
369
+ {I}break;
370
+ }}"""
371
+ )
372
+ )
373
+
374
+ if len(errors) > 0:
375
+ return None, errors
376
+
377
+ if cls.serialization.with_model_type:
378
+ cls_name = java_naming.class_name(cls.name)
379
+ model_type = naming.json_model_type(cls.name)
380
+
381
+ cases.append(
382
+ Stripped(
383
+ f"""\
384
+ case "modelType": {{
385
+ {I}if (currentNode.getValue() == null) {{
386
+ {II}final Reporting.Error error = new Reporting.Error(
387
+ {III}"Expected a model type, but got null");
388
+ {II}return Result.failure(error);
389
+ {I}}}
390
+ {I}final Result<? extends String> modelTypeResult =
391
+ {II}DeserializeImplementation.tryStringFrom(currentNode.getValue());
392
+ {I}if (modelTypeResult.isError()) {{
393
+ {II}modelTypeResult.getError()
394
+ {III}.prependSegment(new Reporting.NameSegment("modelType"));
395
+ {II}return modelTypeResult.castTo({cls_name}.class);
396
+ {I}}}
397
+ {I}modelType = modelTypeResult.getResult();
398
+
399
+ {I}if (!modelType.equals("{model_type}")) {{
400
+ {II}final Reporting.Error error = new Reporting.Error(
401
+ {III}"Expected the model type '{model_type}', " +
402
+ {III}"but got '" + modelType + "'");
403
+ {III}error.prependSegment(new Reporting.NameSegment("modelType"));
404
+ {III}return Result.failure(error);
405
+ {I}}}
406
+ {I}break;
407
+ }}"""
408
+ )
409
+ )
410
+
411
+ cases.append(
412
+ Stripped(
413
+ f"""\
414
+ default: {{
415
+ {I}final Reporting.Error error = new Reporting.Error(
416
+ {II}"Unexpected property: " + currentNode.getKey());
417
+ {I}return Result.failure(error);
418
+ }}"""
419
+ )
420
+ )
421
+
422
+ foreach_writer = io.StringIO()
423
+ foreach_writer.write(
424
+ f"""\
425
+ for (Iterator<Map.Entry<String, JsonNode>> iterator = node.fields(); iterator.hasNext(); ) {{
426
+ {I}Map.Entry<String, JsonNode> currentNode = iterator.next();
427
+
428
+ {I}switch (currentNode.getKey()) {{"""
429
+ )
430
+
431
+ for case_block in cases:
432
+ foreach_writer.write("\n")
433
+ foreach_writer.write(textwrap.indent(case_block, II))
434
+
435
+ foreach_writer.write(f"\n{I}}}\n}}")
436
+
437
+ blocks.append(Stripped(foreach_writer.getvalue()))
438
+
439
+ # endregion
440
+
441
+ # region Check required
442
+
443
+ if cls.serialization.with_model_type:
444
+ blocks.append(
445
+ Stripped(
446
+ f"""\
447
+ if (modelType == null) {{
448
+ {I}final Reporting.Error error = new Reporting.Error(
449
+ {II}"Required property \\"modelType\\" is missing");
450
+ {I}return Result.failure(error);
451
+ }}"""
452
+ )
453
+ )
454
+
455
+ required_check_writer = io.StringIO()
456
+ for i, arg in enumerate(cls.constructor.arguments):
457
+ if isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation):
458
+ continue
459
+
460
+ arg_var = java_naming.variable_name(Identifier(f"the_{arg.name}"))
461
+ json_name = naming.json_property(arg.name)
462
+ assert not java_common.needs_escaping(json_name)
463
+
464
+ if i > 0:
465
+ required_check_writer.write("\n\n")
466
+
467
+ required_check_writer.write(
468
+ f"""\
469
+ if ({arg_var} == null) {{
470
+ {I}final Reporting.Error error = new Reporting.Error(
471
+ {II}"Required property \\\"{json_name}\\\" is missing");
472
+ {I}return Result.failure(error);
473
+ }}"""
474
+ )
475
+
476
+ blocks.append(Stripped(required_check_writer.getvalue()))
477
+
478
+ # endregion
479
+
480
+ # region Pass in arguments to the constructor
481
+
482
+ property_names = [prop.name for prop in cls.properties]
483
+ constructor_argument_names = [arg.name for arg in cls.constructor.arguments]
484
+
485
+ # fmt: off
486
+ assert (
487
+ set(prop.name for prop in cls.properties)
488
+ == set(arg.name for arg in cls.constructor.arguments)
489
+ ), (
490
+ f"Expected the properties to coincide with constructor arguments, "
491
+ f"but they do not for {cls.name!r}:"
492
+ f"{property_names=}, {constructor_argument_names=}"
493
+ )
494
+ # fmt: on
495
+
496
+ if len(cls.constructor.arguments) == 0:
497
+ blocks.append(Stripped(f"return Result.success(new{name}());"))
498
+ else:
499
+ init_writer = io.StringIO()
500
+ init_writer.write(f"return Result.success(new {name}(\n")
501
+
502
+ for i, arg in enumerate(cls.constructor.arguments):
503
+ prop = cls.properties_by_name[arg.name]
504
+
505
+ # NOTE (empwilli, 2024-01-18):
506
+ # The argument to the constructor may be optional while the property
507
+ # might be required, since we can set the default value in the body of
508
+ # the constructor. However, we can not have an optional property and a
509
+ # required constructor argument as we then would not know how to create
510
+ # the instance.
511
+
512
+ if not (
513
+ intermediate.type_annotations_equal(
514
+ arg.type_annotation, prop.type_annotation
515
+ )
516
+ or intermediate.type_annotations_equal(
517
+ intermediate.beneath_optional(arg.type_annotation),
518
+ prop.type_annotation,
519
+ )
520
+ ):
521
+ errors.append(
522
+ Error(
523
+ arg.parsed.node,
524
+ f"Expected type annotation for property {prop.name!r} "
525
+ f"and constructor argument {arg.name!r} "
526
+ f"of the class {cls.name!r} to have matching types, "
527
+ f"but they do not: "
528
+ f"property type is {prop.type_annotation} "
529
+ f"and argument type is {arg.type_annotation}. "
530
+ f"Hence we do not know how to generate the call "
531
+ f"to the constructor in the JSON de-serialization.",
532
+ )
533
+ )
534
+ continue
535
+
536
+ arg_var = java_naming.variable_name(Identifier(f"the_{arg.name}"))
537
+
538
+ init_writer.write(f"{I}{arg_var}")
539
+
540
+ if i < len(cls.constructor.arguments) - 1:
541
+ init_writer.write(",\n")
542
+ else:
543
+ init_writer.write("));")
544
+
545
+ if len(errors) > 0:
546
+ return None, errors
547
+
548
+ blocks.append(Stripped(init_writer.getvalue()))
549
+ # endregion
550
+
551
+ writer = io.StringIO()
552
+
553
+ writer.write(
554
+ f"""\
555
+ /**
556
+ * Deserialize an instance of {name} from {{@param node}}.
557
+ *
558
+ * @param node JSON node to be parsed
559
+ * @param elem Error, if any, during the deserialization
560
+ */
561
+ private static Result<{name}> try{name}From(JsonNode node) {{
562
+ """
563
+ )
564
+
565
+ for i, block in enumerate(blocks):
566
+ if i > 0:
567
+ writer.write("\n\n")
568
+ writer.write(textwrap.indent(block, I))
569
+
570
+ writer.write("\n}")
571
+
572
+ return Stripped(writer.getvalue()), None
573
+
574
+
575
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
576
+ def _generate_deserialize_impl(
577
+ symbol_table: intermediate.SymbolTable,
578
+ spec_impls: specific_implementations.SpecificImplementations,
579
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
580
+ """Generate the implementation of the deserialization."""
581
+ errors = [] # type: List[Error]
582
+ blocks = [
583
+ Stripped(
584
+ f"""\
585
+ /** Convert {{@code value}} to a string.
586
+ * @param node JSON node to be parsed
587
+ */
588
+ private static Result<String> tryStringFrom(JsonNode value) {{
589
+ {I}if (!value.isTextual()) {{
590
+ {II}final Reporting.Error error = new Reporting.Error(
591
+ {III}"Expected a JsonValue of String, but got " + value.getNodeType());
592
+ {II}return Result.failure(error);
593
+ {I}}}
594
+ {I}return Result.success(value.asText());
595
+ }}"""
596
+ ),
597
+ Stripped(
598
+ f"""\
599
+ /** Convert {{@code value}} to a boolean.
600
+ * @param node JSON node to be parsed
601
+ */
602
+ private static Result<Boolean> tryBooleanFrom(JsonNode value) {{
603
+ {I}if (!value.isBoolean()) {{
604
+ {II}final Reporting.Error error = new Reporting.Error(
605
+ {III}"Expected a JsonValue of Boolean, but got " + value.getNodeType());
606
+ {II}return Result.failure(error);
607
+ {I}}}
608
+ {I}return Result.success(value.asBoolean());
609
+ }}"""
610
+ ),
611
+ Stripped(
612
+ f"""\
613
+ /** Convert {{@code value}} to a long 64-bit integer.
614
+ * @param node JSON node to be parsed
615
+ */
616
+ private static Result<Long> tryLongFrom(JsonNode value) {{
617
+ {I}if (!value.isLong()) {{
618
+ {II}final Reporting.Error error = new Reporting.Error(
619
+ {III}"Expected a JsonValue of Long, but got " + value.getNodeType());
620
+ {II}return Result.failure(error);
621
+ {I}}}
622
+ {I}return Result.success(value.asLong());
623
+ }}"""
624
+ ),
625
+ Stripped(
626
+ f"""\
627
+ /** Convert {{@code value}} to a double-precision 64-bit float.
628
+ * @param node JSON node to be parsed
629
+ */
630
+ private static Result<Double> tryDoubleFrom(JsonNode value) {{
631
+ {I}if (!value.isDouble()) {{
632
+ {II}final Reporting.Error error = new Reporting.Error(
633
+ {III}"Expected a JsonValue of Double, but got " + value.getNodeType());
634
+ {II}return Result.failure(error);
635
+ {I}}}
636
+ {I}return Result.success(value.asDouble());
637
+ }}"""
638
+ ),
639
+ Stripped(
640
+ f"""\
641
+ private static Result<byte[]> tryBytesFrom(JsonNode value) {{
642
+ {I}if (!value.isTextual()) {{
643
+ {II}final Reporting.Error error = new Reporting.Error(
644
+ {III}"Expected a JsonValue of String, but got " + value.getNodeType());
645
+ {II}return Result.failure(error);
646
+ {I}}}
647
+ {I}final byte[] decodedData;
648
+ {I}Base64.Decoder decoder = Base64.getDecoder();
649
+
650
+ {I}try {{
651
+ {II}decodedData = decoder.decode(value.textValue());
652
+ {I}}} catch (Exception exception) {{
653
+ {II}final Reporting.Error error = new Reporting.Error(
654
+ {III}"Expected Base-64 encoded bytes, but the conversion failed " +
655
+ {IIII}"because: " + exception.getMessage());
656
+ {II}return Result.failure(error);
657
+ {I}}}
658
+
659
+ {I}return Result.success(decodedData);
660
+ }}"""
661
+ ),
662
+ ] # type: List[Stripped]
663
+
664
+ for our_type in symbol_table.our_types:
665
+ if isinstance(our_type, intermediate.Enumeration):
666
+ blocks.append(_generate_from_method_for_enumeration(enumeration=our_type))
667
+
668
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
669
+ continue
670
+
671
+ elif isinstance(
672
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
673
+ ):
674
+ if our_type.interface is not None:
675
+ blocks.append(
676
+ _generate_from_method_for_interface(interface=our_type.interface)
677
+ )
678
+
679
+ if isinstance(our_type, intermediate.ConcreteClass):
680
+ if our_type.is_implementation_specific:
681
+ implementation_key = specific_implementations.ImplementationKey(
682
+ f"Jsonization/DeserializeImplementation/{our_type.name}_from.java"
683
+ )
684
+
685
+ implementation = spec_impls.get(implementation_key, None)
686
+ if implementation is None:
687
+ errors.append(
688
+ Error(
689
+ our_type.parsed.node,
690
+ f"The jsonization snippet is missing "
691
+ f"for the implementation-specific "
692
+ f"class {our_type.name}: {implementation_key}",
693
+ )
694
+ )
695
+ continue
696
+
697
+ blocks.append(spec_impls[implementation_key])
698
+ else:
699
+ block, cls_errors = _generate_from_method_for_class(cls=our_type)
700
+ if cls_errors is not None:
701
+ errors.extend(cls_errors)
702
+ continue
703
+ else:
704
+ assert block is not None
705
+ blocks.append(block)
706
+ else:
707
+ assert_never(our_type)
708
+
709
+ if len(errors) > 0:
710
+ return None, errors
711
+
712
+ writer = io.StringIO()
713
+
714
+ writer.write(
715
+ """\
716
+ /**
717
+ * Implement the deserialization of meta-model classes from JSON nodes.
718
+ *
719
+ * <p>The implementation propagates an {@link Reporting.Error} instead
720
+ * of relying on exceptions. Under the assumption that incorrect data is much
721
+ * less frequent than correct data, this makes the deserialization more
722
+ * efficient.
723
+ *
724
+ * However, we do not want to force the client to deal with
725
+ * the {@link Reporting.Error} class as this is not intuitive. Therefore
726
+ * we distinguish the implementation, realized in
727
+ * {@link DeserializeImplementation}, and the facade given in
728
+ * {@link Deserialize} class.
729
+ */
730
+ private static class DeserializeImplementation {
731
+ """
732
+ )
733
+
734
+ for i, block in enumerate(blocks):
735
+ if i > 0:
736
+ writer.write("\n\n")
737
+ writer.write(textwrap.indent(block, I))
738
+
739
+ writer.write("\n}")
740
+
741
+ return Stripped(writer.getvalue()), None
742
+
743
+
744
+ def _generate_deserialize_from(name: str) -> Stripped:
745
+ """Generate the facade deserialization method for the type with C# ``name``."""
746
+ writer = io.StringIO()
747
+ writer.write(
748
+ f"""\
749
+ /**
750
+ * Deserialize an instance of {name} from {{@code node}}.
751
+ *
752
+ * @param node JSON node to be parsed
753
+ */
754
+ """
755
+ )
756
+
757
+ writer.write(
758
+ f"""\
759
+ public static {name} deserialize{name}(JsonNode node) {{
760
+ {I}final Result<? extends {name}> result =
761
+ {II}DeserializeImplementation.try{name}From(
762
+ {III}node);
763
+
764
+ {I}return result.onError(error -> {{
765
+ {II}throw new DeserializeException(
766
+ {III}Reporting.generateJsonPath(error.getPathSegments()),
767
+ {III}error.getCause());
768
+ {I}}});
769
+ }}"""
770
+ )
771
+
772
+ return Stripped(writer.getvalue())
773
+
774
+
775
+ def _generate_deserialize(
776
+ symbol_table: intermediate.SymbolTable,
777
+ ) -> Stripped:
778
+ """Generate the deserializer with a deserialization method for each class."""
779
+ blocks = [] # type: List[Stripped]
780
+ for our_type in symbol_table.our_types:
781
+ if isinstance(our_type, intermediate.Enumeration):
782
+ blocks.append(
783
+ _generate_deserialize_from(name=java_naming.enum_name(our_type.name))
784
+ )
785
+
786
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
787
+ continue
788
+
789
+ elif isinstance(
790
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
791
+ ):
792
+ if our_type.interface is not None:
793
+ blocks.append(
794
+ _generate_deserialize_from(
795
+ name=java_naming.interface_name(our_type.interface.name)
796
+ )
797
+ )
798
+
799
+ if isinstance(our_type, intermediate.ConcreteClass):
800
+ blocks.append(
801
+ _generate_deserialize_from(
802
+ name=java_naming.class_name(our_type.name)
803
+ )
804
+ )
805
+ else:
806
+ assert_never(our_type)
807
+
808
+ writer = io.StringIO()
809
+
810
+ writer.write(
811
+ """\
812
+ /**
813
+ * Deserialize instances of meta-model classes from JSON nodes.
814
+ *
815
+ """
816
+ )
817
+
818
+ first_cls = (
819
+ symbol_table.classes[0] if len(symbol_table.classes) > 0 else None
820
+ ) # type: Optional[intermediate.ClassUnion]
821
+
822
+ if first_cls is not None:
823
+ cls_name = None # type: Optional[str]
824
+ if isinstance(first_cls, intermediate.AbstractClass):
825
+ cls_name = java_naming.interface_name(first_cls.name)
826
+ elif isinstance(first_cls, intermediate.ConcreteClass):
827
+ cls_name = java_naming.class_name(first_cls.name)
828
+ else:
829
+ assert_never(first_cls)
830
+
831
+ an_instance_variable = java_naming.variable_name(Identifier("an_instance"))
832
+
833
+ writer.write(
834
+ f"""\
835
+ * Here is an example how to parse an instance of {cls_name}:
836
+ * <pre>{{@code
837
+ * String someString = "... some JSON ...";
838
+ * ObjectMapper objectMapper = new ObjectMapper();
839
+ * JsonNode node = objectMapper.readTree(someString);
840
+ * {cls_name} {an_instance_variable} = Deserialize.deserialize{cls_name}(
841
+ * {I}node);
842
+ * }}</pre>
843
+ */
844
+ """
845
+ )
846
+
847
+ writer.write(
848
+ """\
849
+ public static class Deserialize
850
+ {
851
+ """
852
+ )
853
+
854
+ for i, block in enumerate(blocks):
855
+ if i > 0:
856
+ writer.write("\n\n")
857
+ writer.write(textwrap.indent(block, I))
858
+
859
+ writer.write("\n}")
860
+
861
+ return Stripped(writer.getvalue())
862
+
863
+
864
+ def _generate_serialize_primitive_value(
865
+ primitive_type: intermediate.PrimitiveType, source_expr: Stripped
866
+ ) -> Stripped:
867
+ """
868
+ Generate the snippet to serialize ``source_expr`` to JSON.
869
+
870
+ Source expression is expected to be of ``primitive_type``.
871
+ """
872
+ if primitive_type is intermediate.PrimitiveType.BOOL:
873
+ # We can not use textwrap due to indent_but_first_line.
874
+ return Stripped(
875
+ f"""\
876
+ JsonNodeFactory.instance.booleanNode(
877
+ {I}{indent_but_first_line(source_expr, I)})"""
878
+ )
879
+ elif primitive_type is intermediate.PrimitiveType.FLOAT:
880
+ # We can not use textwrap due to indent_but_first_line.
881
+ return Stripped(
882
+ f"""\
883
+ JsonNodeFactory.instance.numberNode(
884
+ {I}{indent_but_first_line(source_expr, I)})"""
885
+ )
886
+ elif primitive_type is intermediate.PrimitiveType.STR:
887
+ # We can not use textwrap due to indent_but_first_line.
888
+ return Stripped(
889
+ f"""\
890
+ JsonNodeFactory.instance.textNode(
891
+ {I}{indent_but_first_line(source_expr, I)})"""
892
+ )
893
+ elif primitive_type is intermediate.PrimitiveType.INT:
894
+ # We can not use textwrap due to indent_but_first_line.
895
+ return Stripped(
896
+ f"""\
897
+ Transformer.toJsonValue(
898
+ {I}{indent_but_first_line(source_expr, I)})"""
899
+ )
900
+ elif primitive_type is intermediate.PrimitiveType.BYTEARRAY:
901
+ # We can not use textwrap due to indent_but_first_line.
902
+ return Stripped(
903
+ f"""\
904
+ JsonNodeFactory.instance.textNode(
905
+ {II}Base64.getEncoder()
906
+ {III}.encodeToString({indent_but_first_line(source_expr, II)}))"""
907
+ )
908
+ else:
909
+ assert_never(primitive_type)
910
+
911
+
912
+ def _generate_serialize_atomic_value(
913
+ type_annotation: intermediate.AtomicTypeAnnotation, source_expr: Stripped
914
+ ) -> Stripped:
915
+ """Generate the snippet to serialize ``source_expr`` to JSON."""
916
+ if isinstance(type_annotation, intermediate.PrimitiveTypeAnnotation):
917
+ return _generate_serialize_primitive_value(
918
+ primitive_type=type_annotation.a_type, source_expr=source_expr
919
+ )
920
+ elif isinstance(type_annotation, intermediate.OurTypeAnnotation):
921
+ our_type = type_annotation.our_type
922
+ if isinstance(our_type, intermediate.Enumeration):
923
+ method_name = java_naming.method_name(
924
+ Identifier(f"{our_type.name}_to_json_value")
925
+ )
926
+
927
+ # We can not use textwrap due to indent_but_first_line.
928
+ return Stripped(
929
+ f"""\
930
+ Serialize.{method_name}(
931
+ {I}{indent_but_first_line(source_expr, I)})"""
932
+ )
933
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
934
+ return _generate_serialize_primitive_value(
935
+ primitive_type=our_type.constrainee, source_expr=source_expr
936
+ )
937
+ elif isinstance(
938
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
939
+ ):
940
+ # We can not use textwrap due to indent_but_first_line.
941
+ return Stripped(
942
+ f"""\
943
+ transform(
944
+ {I}{indent_but_first_line(source_expr, I)})"""
945
+ )
946
+ else:
947
+ assert_never(our_type)
948
+ else:
949
+ assert_never(type_annotation)
950
+
951
+
952
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
953
+ def _generate_transform_property(
954
+ prop: intermediate.Property,
955
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
956
+ """Generate the snippet to transform a property into a JSON node."""
957
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
958
+
959
+ stmts = [] # type: List[Stripped]
960
+
961
+ getter_name = java_naming.getter_name(prop.name)
962
+ prop_literal = java_common.string_literal(naming.json_property(prop.name))
963
+
964
+ source_expr: Stripped
965
+
966
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
967
+ source_expr = Stripped(f"that.{getter_name}().get()")
968
+ else:
969
+ source_expr = Stripped(f"that.{getter_name}()")
970
+
971
+ if isinstance(
972
+ type_anno,
973
+ intermediate.PrimitiveTypeAnnotation,
974
+ ):
975
+ conversion_expr = _generate_serialize_atomic_value(
976
+ type_annotation=type_anno, source_expr=source_expr
977
+ )
978
+
979
+ # NOTE (empwilli, 2024-02-06):
980
+ # We have to use ObjectNode.put for Strings but the function is deprecated for JsonObjects.
981
+ if type_anno.a_type == intermediate.PrimitiveType.STR:
982
+ stmts.append(Stripped(f"result.put({prop_literal}, {conversion_expr});"))
983
+ else:
984
+ stmts.append(Stripped(f"result.set({prop_literal}, {conversion_expr});"))
985
+ elif isinstance(
986
+ type_anno,
987
+ intermediate.OurTypeAnnotation,
988
+ ):
989
+ conversion_expr = _generate_serialize_atomic_value(
990
+ type_annotation=type_anno, source_expr=source_expr
991
+ )
992
+ stmts.append(Stripped(f"result.set({prop_literal}, {conversion_expr});"))
993
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
994
+ assert not isinstance(
995
+ type_anno.items,
996
+ (intermediate.OptionalTypeAnnotation, intermediate.ListTypeAnnotation),
997
+ ), (
998
+ "We chose to implement only a very limited pattern matching; "
999
+ "see intermediate._translate._verify_only_simple_type_patterns."
1000
+ )
1001
+
1002
+ item_type = java_common.generate_type(type_anno.items)
1003
+ array_var = java_naming.variable_name(Identifier(f"array_{prop.name}"))
1004
+
1005
+ item_conversion_expr = _generate_serialize_atomic_value(
1006
+ type_annotation=type_anno.items, source_expr=Stripped("item")
1007
+ )
1008
+
1009
+ # We cannot use textwrap due to indent_but_first_line.
1010
+ stmts.append(
1011
+ Stripped(
1012
+ f"""\
1013
+ final ArrayNode {array_var} = JsonNodeFactory.instance.arrayNode();
1014
+ for ({item_type} item : {source_expr}) {{
1015
+ {I}{array_var}.add(
1016
+ {II}{indent_but_first_line(item_conversion_expr, II)});
1017
+ }}
1018
+ result.set({prop_literal}, {array_var});"""
1019
+ )
1020
+ )
1021
+ else:
1022
+ assert_never(type_anno)
1023
+
1024
+ serialize_block = Stripped("\n".join(stmts))
1025
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1026
+ return (
1027
+ Stripped(
1028
+ f"""\
1029
+ if (that.{getter_name}().isPresent()) {{
1030
+ {I}{indent_but_first_line(serialize_block, I)}
1031
+ }}"""
1032
+ ),
1033
+ None,
1034
+ )
1035
+ else:
1036
+ return serialize_block, None
1037
+
1038
+
1039
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1040
+ def _generate_transform_for_class(
1041
+ cls: intermediate.ConcreteClass,
1042
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1043
+ """Generate the transform method to a JSON object for the given concrete class."""
1044
+ errors = [] # type: List[Error]
1045
+
1046
+ blocks = [
1047
+ Stripped("final ObjectNode result = JsonNodeFactory.instance.objectNode();"),
1048
+ ] # type: List[Stripped]
1049
+
1050
+ for prop in cls.properties:
1051
+ block, error = _generate_transform_property(prop=prop)
1052
+ if error is not None:
1053
+ errors.append(error)
1054
+ else:
1055
+ assert block is not None
1056
+ blocks.append(block)
1057
+
1058
+ if len(errors) > 0:
1059
+ return None, errors
1060
+
1061
+ if cls.serialization is not None and cls.serialization.with_model_type:
1062
+ model_type = java_common.string_literal(naming.json_model_type(cls.name))
1063
+ blocks.append(Stripped(f"""result.put("modelType", {model_type});"""))
1064
+
1065
+ blocks.append(Stripped("return result;"))
1066
+
1067
+ writer = io.StringIO()
1068
+
1069
+ interface_name = java_naming.interface_name(cls.name)
1070
+ transform_name = java_naming.method_name(Identifier(f"transform_{cls.name}"))
1071
+
1072
+ writer.write(
1073
+ f"""\
1074
+ @Override
1075
+ public JsonNode {transform_name}(
1076
+ {I}{interface_name} that
1077
+ ) {{
1078
+ """
1079
+ )
1080
+
1081
+ for i, stmt in enumerate(blocks):
1082
+ if i > 0:
1083
+ writer.write("\n\n")
1084
+ writer.write(textwrap.indent(stmt, I))
1085
+
1086
+ writer.write("\n}")
1087
+
1088
+ return Stripped(writer.getvalue()), None
1089
+
1090
+
1091
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1092
+ def _generate_transformer(
1093
+ symbol_table: intermediate.SymbolTable,
1094
+ spec_impls: specific_implementations.SpecificImplementations,
1095
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1096
+ """Generate a transformer which transforms instances of the meta-model to JSON."""
1097
+ errors = [] # type: List[Error]
1098
+
1099
+ blocks = [
1100
+ Stripped(
1101
+ f"""\
1102
+ /**
1103
+ * Convert {{@code that}} 64-bit long integer to a JSON value.
1104
+ *
1105
+ * @param that value to be converted
1106
+ */
1107
+ private static JsonNode toJsonNode(Long that) {{
1108
+ {I}// We need to check that we can perform a lossless conversion.
1109
+ {I}long primitiveThat = that.longValue();
1110
+ {I}if ((long)((double)primitiveThat) != primitiveThat) {{
1111
+ {II}throw new IllegalArgumentException(
1112
+ {III}"The number can not be losslessly represented in JSON: " + that);
1113
+ {I}}}
1114
+ {I}return JsonNodeFactory.instance.numberNode(that);
1115
+ }}"""
1116
+ ),
1117
+ ] # type: List[Stripped]
1118
+
1119
+ for our_type in symbol_table.our_types:
1120
+ if isinstance(our_type, intermediate.Enumeration):
1121
+ continue
1122
+
1123
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1124
+ continue
1125
+
1126
+ elif isinstance(our_type, intermediate.AbstractClass):
1127
+ # The abstract classes are directly dispatched by the transformer,
1128
+ # so we do not need to handle them separately.
1129
+ pass
1130
+
1131
+ elif isinstance(our_type, intermediate.ConcreteClass):
1132
+ if our_type.is_implementation_specific:
1133
+ implementation_key = specific_implementations.ImplementationKey(
1134
+ f"Jsonization/Transformer/transform_{our_type.name}.java"
1135
+ )
1136
+
1137
+ implementation = spec_impls.get(implementation_key, None)
1138
+ if implementation is None:
1139
+ errors.append(
1140
+ Error(
1141
+ our_type.parsed.node,
1142
+ f"The jsonization snippet is missing "
1143
+ f"for the implementation-specific "
1144
+ f"class {our_type.name}: {implementation_key}",
1145
+ )
1146
+ )
1147
+ continue
1148
+
1149
+ blocks.append(spec_impls[implementation_key])
1150
+ else:
1151
+ block, cls_errors = _generate_transform_for_class(cls=our_type)
1152
+ if cls_errors is not None:
1153
+ errors.extend(cls_errors)
1154
+ else:
1155
+ assert block is not None
1156
+ blocks.append(block)
1157
+ else:
1158
+ assert_never(our_type)
1159
+
1160
+ if len(errors) > 0:
1161
+ return None, errors
1162
+
1163
+ writer = io.StringIO()
1164
+ writer.write(
1165
+ """\
1166
+ private static class Transformer extends AbstractTransformer<JsonNode> {
1167
+ """
1168
+ )
1169
+
1170
+ for i, block in enumerate(blocks):
1171
+ if i > 0:
1172
+ writer.write("\n\n")
1173
+ writer.write(textwrap.indent(block, I))
1174
+
1175
+ writer.write("\n}")
1176
+
1177
+ return Stripped(writer.getvalue()), None
1178
+
1179
+
1180
+ def _generate_serialize(
1181
+ symbol_table: intermediate.SymbolTable,
1182
+ ) -> Stripped:
1183
+ """Generate the static serializer."""
1184
+ blocks = [
1185
+ Stripped("private static final Transformer transformer = new Transformer();"),
1186
+ Stripped(
1187
+ f"""\
1188
+ /**
1189
+ * Serialize an instance of the meta-model into a JSON object.
1190
+ */
1191
+ public static JsonNode toJsonObject(IClass that) {{
1192
+ {I}return transformer.transform(that);
1193
+ }}"""
1194
+ ),
1195
+ ] # type: List[Stripped]
1196
+
1197
+ for enum in symbol_table.enumerations:
1198
+ name = java_naming.enum_name(enum.name)
1199
+ method_name = java_naming.method_name(Identifier(f"{enum.name}_to_json_value"))
1200
+ blocks.append(
1201
+ Stripped(
1202
+ f"""\
1203
+ /**
1204
+ * Serialize a literal of {name} into a JSON string.
1205
+ */
1206
+ public static JsonNode {method_name}({name} that) {{
1207
+ {I}Optional<String> text = Stringification.toString(that);
1208
+ {I}if (!text.isPresent()) {{
1209
+ {II}throw new IllegalArgumentException("Invalid {name}: " + that);
1210
+ {I}}}
1211
+
1212
+ {I}return JsonNodeFactory.instance.textNode(text.get());
1213
+ }}"""
1214
+ )
1215
+ )
1216
+
1217
+ writer = io.StringIO()
1218
+
1219
+ writer.write(
1220
+ """\
1221
+ /**
1222
+ * Serialize instances of meta-model classes to JSON elements.
1223
+ *
1224
+ """
1225
+ )
1226
+
1227
+ first_cls = (
1228
+ symbol_table.classes[0] if len(symbol_table.classes) > 0 else None
1229
+ ) # type: Optional[intermediate.ClassUnion]
1230
+
1231
+ if first_cls is not None:
1232
+ cls_name = None # type: Optional[str]
1233
+ if isinstance(first_cls, intermediate.AbstractClass):
1234
+ cls_name = java_naming.interface_name(first_cls.name)
1235
+ elif isinstance(first_cls, intermediate.ConcreteClass):
1236
+ cls_name = java_naming.class_name(first_cls.name)
1237
+ else:
1238
+ assert_never(first_cls)
1239
+
1240
+ an_instance_variable = java_naming.variable_name(Identifier("an_instance"))
1241
+
1242
+ writer.write(
1243
+ f"""\
1244
+ * Here is an example how to serialize an instance of {cls_name}:
1245
+ * <pre>{{@code
1246
+ * {cls_name} {an_instance_variable} = new {cls_name}(
1247
+ * // ... some constructor arguments ...
1248
+ * );
1249
+ * JsonNode element = Jsonization.Serialize.toJsonObject(
1250
+ * {II}{an_instance_variable}));
1251
+ * }}</pre>
1252
+ */
1253
+ """
1254
+ )
1255
+
1256
+ writer.write(
1257
+ """\
1258
+ public static class Serialize
1259
+ {
1260
+ """
1261
+ )
1262
+
1263
+ for i, block in enumerate(blocks):
1264
+ if i > 0:
1265
+ writer.write("\n\n")
1266
+ writer.write(textwrap.indent(block, I))
1267
+
1268
+ writer.write("\n}")
1269
+
1270
+ return Stripped(writer.getvalue())
1271
+
1272
+
1273
+ # fmt: off
1274
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1275
+ @ensure(
1276
+ lambda result:
1277
+ not (result[0] is not None) or result[0].endswith('\n'),
1278
+ "Trailing newline mandatory for valid end-of-files"
1279
+ )
1280
+ # fmt: on
1281
+ def generate(
1282
+ symbol_table: intermediate.SymbolTable,
1283
+ package: java_common.PackageIdentifier,
1284
+ spec_impls: specific_implementations.SpecificImplementations,
1285
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
1286
+ """
1287
+ Generate the Java code for the general serialization.
1288
+
1289
+ The ``package`` defines the AAS Java package.
1290
+ """
1291
+ errors = [] # type: List[Error]
1292
+
1293
+ imports = [
1294
+ Stripped("import aas_core.aas3_0.reporting.Reporting;"),
1295
+ Stripped("import aas_core.aas3_0.types.enums.*;"),
1296
+ Stripped("import aas_core.aas3_0.types.impl.*;"),
1297
+ Stripped("import aas_core.aas3_0.types.model.*;"),
1298
+ Stripped("import aas_core.aas3_0.stringification.Stringification;"),
1299
+ Stripped("import aas_core.aas3_0.visitation.AbstractTransformer;"),
1300
+ Stripped("import com.fasterxml.jackson.databind.JsonNode;"),
1301
+ Stripped("import com.fasterxml.jackson.databind.node.ArrayNode;"),
1302
+ Stripped("import com.fasterxml.jackson.databind.node.JsonNodeFactory;"),
1303
+ Stripped("import com.fasterxml.jackson.databind.node.ObjectNode;"),
1304
+ Stripped("import java.util.*;"),
1305
+ Stripped("import java.util.function.Function;"),
1306
+ ] # type: List[Stripped]
1307
+
1308
+ deserialize_impl_block, deserialize_impl_errors = _generate_deserialize_impl(
1309
+ symbol_table=symbol_table, spec_impls=spec_impls
1310
+ )
1311
+ if deserialize_impl_errors is not None:
1312
+ errors.extend(deserialize_impl_errors)
1313
+
1314
+ deserialize_block = _generate_deserialize(symbol_table=symbol_table)
1315
+
1316
+ transformer_block, transformer_errors = _generate_transformer(
1317
+ symbol_table=symbol_table, spec_impls=spec_impls
1318
+ )
1319
+ if transformer_errors is not None:
1320
+ errors.extend(transformer_errors)
1321
+
1322
+ if len(errors) > 0:
1323
+ return None, errors
1324
+
1325
+ assert deserialize_impl_block is not None
1326
+ assert deserialize_block is not None
1327
+ assert transformer_block is not None
1328
+
1329
+ serialize_block = _generate_serialize(
1330
+ symbol_table=symbol_table,
1331
+ )
1332
+
1333
+ exception_block = Stripped(
1334
+ f"""\
1335
+ /**
1336
+ * Represent a critical error during the deserialization.
1337
+ */
1338
+ @SuppressWarnings("serial")
1339
+ {I}public static class DeserializeException extends RuntimeException {{
1340
+ {II}private final String path;
1341
+ {II}private final String reason;
1342
+
1343
+ {II}public DeserializeException(String path, String reason) {{
1344
+ {III}super(reason + " at: " + ("".equals(path) ? "the beginning" : path));
1345
+ {III}this.path = path;
1346
+ {III}this.reason = reason;
1347
+ {II}}}
1348
+
1349
+ {II}public Optional<String> getPath() {{
1350
+ {III}return Optional.ofNullable(path);
1351
+ {II}}}
1352
+
1353
+ {II}public Optional<String> getReason() {{
1354
+ {III}return Optional.ofNullable(reason);
1355
+ {II}}}
1356
+ {I}}}"""
1357
+ )
1358
+
1359
+ result_block = Stripped(
1360
+ f"""\
1361
+ private static class Result<T> {{
1362
+ {I}private final T result;
1363
+ {I}private final Reporting.Error error;
1364
+ {I}private final boolean success;
1365
+
1366
+ {I}private Result(T result, Reporting.Error error, boolean success) {{
1367
+ {II}this.result = result;
1368
+ {II}this.error = error;
1369
+ {II}this.success = success;
1370
+ {I}}}
1371
+
1372
+ {I}public static <T> Result<T> success(T result) {{
1373
+ {II}if (result == null) throw new IllegalArgumentException("Result must not be null.");
1374
+ {II}return new Result<>(result, null, true);
1375
+ {I}}}
1376
+
1377
+ {I}public static <T> Result<T> failure(Reporting.Error error) {{
1378
+ {II}if (error == null) throw new IllegalArgumentException("Error must not be null.");
1379
+ {II}return new Result<>(null, error, false);
1380
+ {I}}}
1381
+
1382
+ {I}@SuppressWarnings("unchecked")
1383
+ {I}public <I> Result<I> castTo(Class<I> type) {{
1384
+ {II}if (isError() || type.isInstance(result)) return (Result<I>) this;
1385
+ {II}throw new IllegalStateException("Result of type "
1386
+ {III}+ result.getClass().getName()
1387
+ {III}+ " is not an instance of "
1388
+ {III}+ type.getName());
1389
+ {I}}}
1390
+
1391
+ {I}public T getResult() {{
1392
+ {II}if (!isSuccess()) throw new IllegalStateException("Result is not present.");
1393
+ {II}return result;
1394
+ {I}}}
1395
+
1396
+ {I}public boolean isSuccess() {{
1397
+ {II}return success;
1398
+ {I}}}
1399
+
1400
+ {I}public boolean isError() {{
1401
+ {II}return !success;
1402
+ {I}}}
1403
+
1404
+ {I}public Reporting.Error getError() {{
1405
+ {II}if (isSuccess()) throw new IllegalStateException("Result is present.");
1406
+ {II}return error;
1407
+ {I}}}
1408
+
1409
+ {I}public <R> R map(Function<T, R> successFunction, Function<Reporting.Error, R> errorFunction) {{
1410
+ {II}return isSuccess() ? successFunction.apply(result) : errorFunction.apply(error);
1411
+ {I}}}
1412
+
1413
+ {I}public T onError(Function<Reporting.Error, T> errorFunction) {{
1414
+ {II}return map(Function.identity(), errorFunction);
1415
+ {I}}}
1416
+ }}"""
1417
+ )
1418
+
1419
+ jsonization_blocks = [
1420
+ deserialize_impl_block,
1421
+ exception_block,
1422
+ result_block,
1423
+ deserialize_block,
1424
+ transformer_block,
1425
+ serialize_block,
1426
+ ] # type: List[Stripped]
1427
+
1428
+ jsonization_writer = io.StringIO()
1429
+ jsonization_writer.write(
1430
+ """\
1431
+ /**
1432
+ * Provide de/serialization of meta-model classes to/from JSON.
1433
+ *
1434
+ * <p>We can not use one-pass deserialization for JSON since the object
1435
+ * properties do not have fixed order, and hence we can not read
1436
+ * {@code modelType} property ahead of the remaining properties.
1437
+ */
1438
+ public class Jsonization {
1439
+ """
1440
+ )
1441
+
1442
+ for i, deserialize_block in enumerate(jsonization_blocks):
1443
+ if i > 0:
1444
+ jsonization_writer.write("\n\n")
1445
+
1446
+ jsonization_writer.write(textwrap.indent(deserialize_block, II))
1447
+
1448
+ jsonization_writer.write("\n}")
1449
+
1450
+ if len(errors) > 0:
1451
+ return None, errors
1452
+
1453
+ blocks = [
1454
+ java_common.WARNING,
1455
+ Stripped(f"package {package}.jsonization;"),
1456
+ Stripped("\n".join(imports)),
1457
+ Stripped(jsonization_writer.getvalue()),
1458
+ java_common.WARNING,
1459
+ ] # type: List[Stripped]
1460
+
1461
+ writer = io.StringIO()
1462
+ for i, block in enumerate(blocks):
1463
+ if i > 0:
1464
+ writer.write("\n\n")
1465
+
1466
+ assert not block.startswith("\n")
1467
+ assert not block.endswith("\n")
1468
+ writer.write(block)
1469
+
1470
+ writer.write("\n")
1471
+
1472
+ return writer.getvalue(), None