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,2274 @@
1
+ """Generate Java code for XML-ization based on the intermediate representation."""
2
+ import io
3
+ import textwrap
4
+
5
+ from typing import Tuple, Optional, List
6
+
7
+ from icontract import ensure, require
8
+
9
+ from aas_core_codegen import intermediate, naming, specific_implementations
10
+ from aas_core_codegen.common import (
11
+ assert_never,
12
+ Error,
13
+ Identifier,
14
+ indent_but_first_line,
15
+ Stripped,
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
+ INDENT5 as IIIII,
27
+ INDENT6 as IIIIII,
28
+ )
29
+
30
+ # region Generate
31
+
32
+
33
+ def _generate_result() -> Stripped:
34
+ """Generate the class to represent XML de/serialize results."""
35
+ return Stripped(
36
+ f"""\
37
+ private static class Result<T> {{
38
+ {I}private final T result;
39
+ {I}private final Reporting.Error error;
40
+ {I}private final boolean success;
41
+
42
+ {I}private Result(T result, Reporting.Error error, boolean success) {{
43
+ {II}this.result = result;
44
+ {II}this.error = error;
45
+ {II}this.success = success;
46
+ {I}}}
47
+
48
+ {I}public static <T> Result<T> success(T result) {{
49
+ {II}if(result == null) throw new IllegalArgumentException("Result must not be null.");
50
+ {II}return new Result<>(result, null, true);
51
+ {I}}}
52
+
53
+ {I}public static <T> Result<T> failure(Reporting.Error error) {{
54
+ {II}if(error == null) throw new IllegalArgumentException("Error must not be null.");
55
+ {II}return new Result<>(null, error, false);
56
+ {I}}}
57
+
58
+ {I}@SuppressWarnings("unchecked")
59
+ {I}public <I> Result<I> castTo(Class<I> type){{
60
+ {II}if(isError() || type.isInstance(result)) return (Result<I>) this;
61
+ {II}throw new IllegalStateException("Result of type "
62
+ {III}+ result.getClass().getName()
63
+ {III}+ " is not an instance of "
64
+ {III}+ type.getName());
65
+ {I}}}
66
+
67
+ {I}public T getResult() {{
68
+ {II}if (!isSuccess()) throw new IllegalStateException("Result is not present.");
69
+ {II}return result;
70
+ {I}}}
71
+
72
+ {I}public boolean isSuccess() {{
73
+ {II}return success;
74
+ {I}}}
75
+
76
+ {I}public boolean isError(){{return !success;}}
77
+
78
+ {I}public Reporting.Error getError() {{
79
+ {II}if (isSuccess()) throw new IllegalStateException("Result is present.");
80
+ {II}return error;
81
+ {I}}}
82
+
83
+ {I}public <R> R map(Function<T, R> successFunction, Function<Reporting.Error, R> errorFunction) {{
84
+ {II}return isSuccess() ? successFunction.apply(result) : errorFunction.apply(error);
85
+ {I}}}
86
+
87
+ {I}public T onError(Function<Reporting.Error, T> errorFunction){{
88
+ {II}return map(Function.identity(), errorFunction);
89
+ {I}}}
90
+ }}"""
91
+ )
92
+
93
+
94
+ def _generate_current_event() -> Stripped:
95
+ """Generate the function to a single XML event."""
96
+
97
+ return Stripped(
98
+ f"""\
99
+ private static XMLEvent currentEvent(XMLEventReader reader) {{
100
+ {I}try {{
101
+ {II}return reader.peek();
102
+ {I}}} catch (XMLStreamException xmlStreamException) {{
103
+ {II}throw new Xmlization.DeserializeException("",
104
+ {III}"Failed in method peek because of: " +
105
+ {III}xmlStreamException.getMessage());
106
+ {I}}}
107
+ }}"""
108
+ )
109
+
110
+
111
+ def _generate_try_content_for_primitives() -> Stripped:
112
+ """Generate the function to read textual content."""
113
+
114
+ return Stripped(
115
+ f"""\
116
+ private static String readContentAsString(XMLEventReader reader) throws XMLStreamException {{
117
+ {I}final StringBuilder content = new StringBuilder();
118
+
119
+ {I}while (reader.peek().isCharacters() || reader.peek().getEventType() == XMLStreamConstants.COMMENT) {{
120
+ {II}if (reader.peek().isCharacters()) {{
121
+ {III}content.append(reader.peek().asCharacters().getData());
122
+ {II}}}
123
+ {II}reader.nextEvent();
124
+ {I}}}
125
+
126
+ {I}return content.toString();
127
+ }}
128
+
129
+ private static Boolean readContentAsBool(XMLEventReader reader) throws XMLStreamException {{
130
+ {I}final StringBuilder content = new StringBuilder();
131
+
132
+ {I}while (reader.peek().isCharacters() || reader.peek().getEventType() == XMLStreamConstants.COMMENT) {{
133
+ {II}if (reader.peek().isCharacters()) {{
134
+ {III}content.append(reader.peek().asCharacters().getData());
135
+ {II}}}
136
+ {II}reader.nextEvent();
137
+ {I}}}
138
+ {I}if(!("true".equals(content.toString()) || "false".equals(content.toString()))){{
139
+ {II}throw new IllegalStateException("Content cannot be converted to the type Boolean.");
140
+ {I}}}
141
+ {I}return Boolean.valueOf(content.toString());
142
+ }}
143
+
144
+ private static Long readContentAsLong(XMLEventReader reader) throws XMLStreamException {{
145
+ {I}final StringBuilder content = new StringBuilder();
146
+
147
+ {I}while (reader.peek().isCharacters() || reader.peek().getEventType() == XMLStreamConstants.COMMENT) {{
148
+ {II}if (reader.peek().isCharacters()) {{
149
+ {III}content.append(reader.peek().asCharacters().getData());
150
+ {II}}}
151
+ {II}reader.nextEvent();
152
+ {I}}}
153
+
154
+ {I}return Long.valueOf(content.toString());
155
+ }}
156
+
157
+ private static Double readContentAsDouble(XMLEventReader reader) throws XMLStreamException {{
158
+ {I}final StringBuilder content = new StringBuilder();
159
+
160
+ {I}while (reader.peek().isCharacters() || reader.peek().getEventType() == XMLStreamConstants.COMMENT) {{
161
+ {II}if (reader.peek().isCharacters()) {{
162
+ {III}content.append(reader.peek().asCharacters().getData());
163
+ {II}}}
164
+ {II}reader.nextEvent();
165
+ {I}}}
166
+
167
+ {I}return Double.valueOf(content.toString());
168
+ }}
169
+
170
+ /**
171
+ * Read the whole content of an element into memory.
172
+ */
173
+ private static byte[] readContentAsBase64(
174
+ {I}XMLEventReader reader) throws XMLStreamException {{
175
+ {I}final StringBuilder content = new StringBuilder();
176
+ {I}while (reader.peek().isCharacters() || reader.peek().getEventType() == XMLStreamConstants.COMMENT) {{
177
+ {II}if (reader.peek().isCharacters()) {{
178
+ {III}content.append(reader.peek().asCharacters().getData());
179
+ {II}}}
180
+ {II}reader.nextEvent();
181
+ {I}}}
182
+
183
+ {I}String encodedData = content.toString();
184
+ {I}final byte[] decodedData;
185
+ {I}Base64.Decoder decoder = Base64.getDecoder();
186
+
187
+ {I}try {{
188
+ {II}decodedData = decoder.decode(encodedData);
189
+ {I}}} catch (IllegalArgumentException exception) {{
190
+ {II}throw new XMLStreamException(
191
+ {III}"Failed to read base64 encoded data: " +
192
+ {III}exception.getMessage());
193
+ {I}}}
194
+
195
+ {I}return decodedData;
196
+ }}"""
197
+ )
198
+
199
+
200
+ def _generate_skip_whitespace_and_comments() -> Stripped:
201
+ """Generate the function to skip whitespace text and XML comments."""
202
+ return Stripped(
203
+ f"""\
204
+ private static void skipWhitespaceAndComments(XMLEventReader reader) {{
205
+ {I}while (whiteSpaceOrComment(reader)) {{
206
+ {II}reader.next();
207
+ {I}}}
208
+ }}
209
+
210
+ private static boolean whiteSpaceOrComment(XMLEventReader reader) {{
211
+ {I}final XMLEvent currentEvent = currentEvent(reader);
212
+ {I}final boolean isComment = (currentEvent != null &&
213
+ {II}currentEvent.getEventType() == XMLStreamConstants.COMMENT);
214
+ {I}final boolean isWhiteSpace = (currentEvent != null &&
215
+ {II}currentEvent.getEventType() == XMLStreamConstants.CHARACTERS &&
216
+ {II}currentEvent.asCharacters().isWhiteSpace());
217
+ {I}return isComment || isWhiteSpace;
218
+ }}"""
219
+ )
220
+
221
+
222
+ def _generate_skip_start_document() -> Stripped:
223
+ """Generate the function to skip start document."""
224
+ return Stripped(
225
+ f"""\
226
+ private static void skipStartDocument(XMLEventReader reader){{
227
+ {I}if (currentEvent(reader).isStartDocument()){{
228
+ {II}reader.next();
229
+ {I}}}
230
+ }}"""
231
+ )
232
+
233
+
234
+ def _generate_is_empty_element() -> Stripped:
235
+ """Generate the function to check if an element is empty."""
236
+ return Stripped(
237
+ f"""\
238
+ private static boolean isEmptyElement(XMLEventReader reader) {{
239
+ {I}// Skip the element node and go to the content
240
+ {I}try {{
241
+ {II}reader.nextEvent();
242
+ {I}}} catch (XMLStreamException xmlStreamException) {{
243
+ {II}throw new Xmlization.DeserializeException("",
244
+ {III}"Failed in method isEmptyElement because of: " +
245
+ {III}xmlStreamException.getMessage());
246
+ {I}}}
247
+ {I}return currentEvent(reader).isEndElement();
248
+ }}"""
249
+ )
250
+
251
+
252
+ def _generate_deserialize_primitive_property(
253
+ prop: intermediate.Property, cls: intermediate.ConcreteClass
254
+ ) -> Stripped:
255
+ """Generate the snippet to deserialize a property ``prop`` of primitive type."""
256
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
257
+
258
+ a_type = intermediate.try_primitive_type(type_anno)
259
+ assert a_type is not None, f"Unexpected type annotation: {prop.type_annotation}"
260
+
261
+ deserialization_expr: str
262
+ if a_type is intermediate.PrimitiveType.BOOL:
263
+ deserialization_expr = "readContentAsBool(reader)"
264
+ elif a_type is intermediate.PrimitiveType.INT:
265
+ deserialization_expr = "readContentAsInt(reader)"
266
+ elif a_type is intermediate.PrimitiveType.FLOAT:
267
+ deserialization_expr = "readContentAsFloat(reader)"
268
+ elif a_type is intermediate.PrimitiveType.STR:
269
+ deserialization_expr = "readContentAsString(reader)"
270
+ elif a_type is intermediate.PrimitiveType.BYTEARRAY:
271
+ deserialization_expr = "readContentAsBase64(reader)"
272
+ else:
273
+ assert_never(a_type)
274
+
275
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
276
+
277
+ prop_name = java_naming.property_name(prop.name)
278
+ cls_name = java_naming.class_name(cls.name)
279
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
280
+
281
+ if a_type is intermediate.PrimitiveType.STR:
282
+ empty_handling_body = Stripped(f'{target_var} = "";')
283
+ else:
284
+ empty_handling_body = Stripped(
285
+ f"""\
286
+ final Reporting.Error error = new Reporting.Error(
287
+ {I}"The property {prop_name} of an instance of class {cls_name} " +
288
+ {I}"can not be de-serialized from a self-closing element " +
289
+ {I}"since it needs content");
290
+ error.prependSegment(
291
+ {I}new Reporting.NameSegment(
292
+ {II}{xml_prop_name_literal}));
293
+ return Result.failure(error);"""
294
+ )
295
+
296
+ return Stripped(
297
+ f"""\
298
+ if (isEmptyProperty) {{
299
+ {I}{indent_but_first_line(empty_handling_body, I)}
300
+ }}
301
+ else {{
302
+ {I}if (currentEvent(reader).isEndDocument()) {{
303
+ {II}final Reporting.Error error = new Reporting.Error(
304
+ {III}"Expected an XML content representing " +
305
+ {III}"the property {prop_name} of an instance of class {cls_name}, " +
306
+ {III}"but reached the end-of-file");
307
+ {II}return Result.failure(error);
308
+ {I}}}
309
+
310
+ {I}try {{
311
+ {II}{target_var} = {deserialization_expr};
312
+ {I}}} catch (Exception e) {{
313
+ {II}final Reporting.Error error = new Reporting.Error(
314
+ {III}"The property {prop_name} of an instance of class {cls_name} "
315
+ {IIII}+ " could not be de-serialized: " + e.getMessage());
316
+ {II}error.prependSegment(
317
+ {III}new Reporting.NameSegment(
318
+ {IIII}"{prop_name}"));
319
+ {II}return Result.failure(error);
320
+ {I}}}
321
+ }}"""
322
+ )
323
+
324
+
325
+ def _generate_get_event_type_as_string() -> Stripped:
326
+ """Generate the function to map XML event types to their string representations."""
327
+
328
+ return Stripped(
329
+ f"""\
330
+ private static String getEventTypeAsString(XMLEvent event) {{
331
+ {I}switch (event.getEventType()) {{
332
+ {II}case XMLStreamConstants.START_ELEMENT:
333
+ {III}return "Start-Element";
334
+ {II}case XMLStreamConstants.END_ELEMENT:
335
+ {III}return "End-Element";
336
+ {II}case XMLStreamConstants.PROCESSING_INSTRUCTION:
337
+ {III}return "Processing-Instruction";
338
+ {II}case XMLStreamConstants.CHARACTERS:
339
+ {III}return "Characters";
340
+ {II}case XMLStreamConstants.COMMENT:
341
+ {III}return "Comment";
342
+ {II}case XMLStreamConstants.SPACE:
343
+ {III}return "Space";
344
+ {II}case XMLStreamConstants.START_DOCUMENT:
345
+ {III}return "Start-Document";
346
+ {II}case XMLStreamConstants.END_DOCUMENT:
347
+ {III}return "End-Document";
348
+ {II}case XMLStreamConstants.ENTITY_REFERENCE:
349
+ {III}return "Entity-Reference";
350
+ {II}case XMLStreamConstants.ATTRIBUTE:
351
+ {III}return "Attribute";
352
+ {II}case XMLStreamConstants.NOTATION_DECLARATION:
353
+ {III}return "Notation-Declaration";
354
+ {II}default:
355
+ {III}return "Unknown-Type";
356
+ {I}}}
357
+ }}"""
358
+ )
359
+
360
+
361
+ def _generate_try_element_name() -> Stripped:
362
+ """Generate the function to strip the prefix and check the namespace."""
363
+ return Stripped(
364
+ f"""\
365
+ private static boolean invalidNameSpace(XMLEvent event) {{
366
+ {I}if (event.isStartElement()) {{
367
+ {II}return !AAS_NAME_SPACE.equals(event.asStartElement().getName().getNamespaceURI());
368
+ {I}}} else {{
369
+ {II}return !AAS_NAME_SPACE.equals(event.asEndElement().getName().getNamespaceURI());
370
+ {I}}}
371
+ }}
372
+
373
+ /**
374
+ * Check the namespace and extract the element's name.
375
+ */
376
+ private static Result<String> tryElementName(XMLEventReader reader) {{
377
+ {I}final XMLEvent currentEvent = currentEvent(reader);
378
+ {I}final boolean precondition = currentEvent.isStartElement() || currentEvent.isEndElement();
379
+ {I}if (!precondition) {{
380
+ {II}throw new IllegalStateException("Expected to be at a start or an end element "
381
+ {IIII}+ "but got: " + getEventTypeAsString(currentEvent));
382
+ {I}}}
383
+
384
+ {I}if (invalidNameSpace(currentEvent)) {{
385
+ {II}String namespace = currentEvent.isStartElement()
386
+ {IIII}? currentEvent.asStartElement().getName().getNamespaceURI()
387
+ {IIII}: currentEvent.asEndElement().getName().getNamespaceURI();
388
+ {II}final Reporting.Error error = new Reporting.Error(
389
+ {IIII}"Expected an element within a namespace " +
390
+ {IIII}AAS_NAME_SPACE + ", " + "but got: " + namespace);
391
+ {II}return Result.failure(error);
392
+ {I}}}
393
+ {I}return Result.success(currentEvent.isStartElement()
394
+ {III}? currentEvent.asStartElement().getName().getLocalPart()
395
+ {III}: currentEvent.asEndElement().getName().getLocalPart());
396
+ }}"""
397
+ )
398
+
399
+
400
+ def _generate_verify_closing_tag_for_class() -> Stripped:
401
+ return Stripped(
402
+ f"""\
403
+ private static boolean isWrongClosingTag(
404
+ {I}Result<String> tryElementName,
405
+ {I}Result<String> tryEndElementName) {{
406
+ {I}return !tryElementName.getResult().equals(tryEndElementName.getResult());
407
+ }}
408
+
409
+ private static Result<XMLEvent> verifyClosingTagForClass(
410
+ {I}String className,
411
+ {I}XMLEventReader reader,
412
+ {I}Result<String> tryElementName) {{
413
+ {I}final XMLEvent currentEvent = currentEvent(reader);
414
+ {I}if (currentEvent.isEndDocument()) {{
415
+ {II}final Reporting.Error error = new Reporting.Error(
416
+ {IIII}"Expected an XML end element to conclude a property of class " + className
417
+ {IIIIII}+ " with the element name " + tryElementName.getResult() + ", "
418
+ {IIIIII}+ "but got the end-of-file.");
419
+ {II}return Result.failure(error);
420
+ {I}}}
421
+
422
+ {I}if (!currentEvent.isEndElement()) {{
423
+ {II}final Reporting.Error error = new Reporting.Error(
424
+ {IIII}"Expected an XML end element to conclude a property of class " + className
425
+ {IIIIII}+ " with the element name " + tryElementName.getResult() + ", "
426
+ {IIIIII}+ "but got the node of type " + getEventTypeAsString(currentEvent)
427
+ {IIIIII}+ " with the value " + currentEvent);
428
+ {II}return Result.failure(error);
429
+ {I}}}
430
+ {I}final Result<String> tryEndElementName = tryElementName(reader);
431
+ {I}if (tryEndElementName.isError()) {{
432
+ {II}return tryEndElementName.castTo(XMLEvent.class);
433
+ {I}}}
434
+ {I}if (isWrongClosingTag(tryElementName, tryEndElementName)) {{
435
+ {II}final Reporting.Error error = new Reporting.Error(
436
+ {IIII}"Expected an XML end element to conclude a property of class " + className
437
+ {IIIIII}+ " with the element name " + tryElementName.getResult() + ", "
438
+ {IIIIII}+ "but got the end element with the name " + tryEndElementName.getResult());
439
+ {II}return Result.failure(error);
440
+ {I}}}
441
+ {I}try {{
442
+ {II}return Result.success(reader.nextEvent());
443
+ {I}}} catch (XMLStreamException xmlStreamException) {{
444
+ {II}throw new Xmlization.DeserializeException("",
445
+ {III}"Failed in method verifyClosingTagForClass because of: " +
446
+ {III}xmlStreamException.getMessage());
447
+ {I}}}
448
+ }}"""
449
+ )
450
+
451
+
452
+ def _generate_deserialize_enumeration_property(
453
+ prop: intermediate.Property, cls: intermediate.ConcreteClass
454
+ ) -> Stripped:
455
+ """Generate the snippet to deserialize a property ``prop`` as an enum."""
456
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
457
+
458
+ assert isinstance(type_anno, intermediate.OurTypeAnnotation)
459
+
460
+ our_type = type_anno.our_type
461
+ assert isinstance(our_type, intermediate.Enumeration)
462
+
463
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
464
+ text_target_var = java_naming.variable_name(Identifier(f"text_{prop.name}"))
465
+ optional_target_var = java_naming.variable_name(Identifier(f"optional_{prop.name}"))
466
+ cls_name = java_naming.class_name(cls.name)
467
+ prop_name = java_naming.property_name(prop.name)
468
+ prop_type_name = java_naming.enum_name(our_type.name)
469
+ from_str_name = java_naming.private_property_name(
470
+ Identifier(f"{our_type.name}_from_string")
471
+ )
472
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
473
+
474
+ return Stripped(
475
+ f"""\
476
+ if (isEmptyProperty) {{
477
+ {I}final Reporting.Error error = new Reporting.Error(
478
+ {II}"The property {prop_name} of an instance of class {cls_name} " +
479
+ {II}"can not be de-serialized from a self-closing element " +
480
+ {II}"since it needs content");
481
+ {I}error.prependSegment(
482
+ {II}new Reporting.NameSegment(
483
+ {III}{xml_prop_name_literal}));
484
+ {I}return Result.failure(error);
485
+ }}
486
+
487
+ if (currentEvent(reader).isEndDocument()) {{
488
+ {I}final Reporting.Error error = new Reporting.Error(
489
+ {III}"Expected an XML content representing "
490
+ {IIIII}+ "the property {prop_name} of an instance of class {cls_name}, "
491
+ {IIIII}+ "but reached the end-of-file");
492
+ {I}return Result.failure(error);
493
+ }}
494
+
495
+ String {text_target_var};
496
+ try {{
497
+ {I}{text_target_var} = readContentAsString(reader);
498
+ }} catch (Exception e) {{
499
+ {I}final Reporting.Error error = new Reporting.Error(
500
+ {III}"The property {prop_name} of an instance of class {cls_name}"
501
+ {IIIII}+ " could not be de-serialized: " + e.getMessage());
502
+ {I}error.prependSegment(
503
+ {III}new Reporting.NameSegment(
504
+ {IIIII}"{prop_name}"));
505
+ {I}return Result.failure(error);
506
+ }}
507
+
508
+ final Optional<{prop_type_name}> {optional_target_var} =
509
+ {I}Stringification.{from_str_name}(
510
+ {II}{text_target_var});
511
+
512
+ if ({optional_target_var}.isPresent()) {{
513
+ {I}{target_var} = {optional_target_var}.get();
514
+ }} else {{
515
+ {I}final Reporting.Error error = new Reporting.Error(
516
+ {III}"The property {prop_name} of an instance of class {cls_name}" +
517
+ {IIIII}" could not be de-serialized from an unexpected enumeration literal: " +
518
+ {IIIII}{text_target_var});
519
+ {I}error.prependSegment(
520
+ {III}new Reporting.NameSegment(
521
+ {IIIII}"{prop_name}"));
522
+ {I}return Result.failure(error);
523
+ }}"""
524
+ )
525
+
526
+
527
+ def _generate_deserialize_interface_property(
528
+ prop: intermediate.Property,
529
+ cls: intermediate.ConcreteClass,
530
+ ) -> Stripped:
531
+ """Generate the snippet to deserialize a property ``prop`` as an interface."""
532
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
533
+
534
+ assert isinstance(type_anno, intermediate.OurTypeAnnotation)
535
+
536
+ our_type = type_anno.our_type
537
+ assert isinstance(
538
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
539
+ )
540
+ assert our_type.interface is not None
541
+
542
+ prop_name = java_naming.property_name(prop.name)
543
+ cls_name = java_naming.class_name(cls.name)
544
+
545
+ interface_name = java_naming.interface_name(our_type.interface.name)
546
+
547
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
548
+ try_target_var = java_naming.variable_name(Identifier(f"try_{prop.name}"))
549
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
550
+
551
+ return Stripped(
552
+ f"""\
553
+ if (isEmptyProperty) {{
554
+ {I}final Reporting.Error error = new Reporting.Error(
555
+ {II}"Expected an XML element within the element " + tryElementName.getResult() + " representing " +
556
+ {II}"the property {prop_name} of an instance of class {cls_name}, " +
557
+ {II}"but encountered a self-closing element.");
558
+ {I}return Result.failure(error);
559
+ }}
560
+
561
+ // We need to skip the whitespace here in order to be able to look ahead
562
+ // the discriminator element shortly.
563
+ skipWhitespaceAndComments(reader);
564
+
565
+ if (currentEvent(reader).isEndDocument()) {{
566
+ {I}final Reporting.Error error = new Reporting.Error(
567
+ {II}"Expected an XML element within the element " + tryElementName.getResult() + " representing " +
568
+ {II}"the property {prop_name} of an instance of class {cls_name}, " +
569
+ {II}"but reached the end-of-file");
570
+ {I}return Result.failure(error);
571
+ }}
572
+
573
+ // Try to look ahead the discriminator name;
574
+ // we need this name only for the error reporting below.
575
+ // {interface_name}FromElement will perform more sophisticated
576
+ // checks.
577
+ String discriminatorElementName = null;
578
+ if (currentEvent(reader).isStartElement()) {{
579
+ {I}Result<String> tryDiscriminatorElementName = tryElementName(reader);
580
+ {I}assert(!tryDiscriminatorElementName.isError());
581
+ {I}discriminatorElementName = tryDiscriminatorElementName.getResult();
582
+ }}
583
+
584
+ Result<? extends {interface_name}> {try_target_var} = try{interface_name}FromElement(reader);
585
+
586
+ if ({try_target_var}.isError()) {{
587
+ {I}if (discriminatorElementName != null) {{
588
+ {II}{try_target_var}.getError().
589
+ {III}prependSegment(
590
+ {IIII}new Reporting.NameSegment(
591
+ {IIIII}discriminatorElementName));
592
+ {I}}}
593
+
594
+ {I}{try_target_var}.getError()
595
+ {II}.prependSegment(
596
+ {III}new Reporting.NameSegment(
597
+ {IIII}{xml_prop_name_literal}));
598
+ {I}return {try_target_var}.castTo({cls_name}.class);
599
+ }}
600
+
601
+ {target_var} = {try_target_var}.getResult();"""
602
+ )
603
+
604
+
605
+ def _generate_deserialize_cls_property(
606
+ prop: intermediate.Property, cls: intermediate.ConcreteClass
607
+ ) -> Stripped:
608
+ """Generate the snippet to deserialize a property ``prop`` as a concrete class."""
609
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
610
+
611
+ assert isinstance(type_anno, intermediate.OurTypeAnnotation)
612
+
613
+ our_type = type_anno.our_type
614
+ assert isinstance(our_type, intermediate.ConcreteClass)
615
+
616
+ target_cls_name = java_naming.class_name(our_type.name)
617
+
618
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
619
+
620
+ try_target_var = java_naming.variable_name(Identifier(f"try_{prop.name}"))
621
+
622
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
623
+
624
+ cls_name = java_naming.class_name(cls.name)
625
+
626
+ return Stripped(
627
+ f"""\
628
+ Result<{target_cls_name}> {try_target_var} = try{target_cls_name}FromSequence(
629
+ {I}reader, isEmptyProperty);
630
+
631
+ if ({try_target_var}.isError()) {{
632
+ {I}{try_target_var}.getError()
633
+ {II}.prependSegment(
634
+ {III}new Reporting.NameSegment(
635
+ {IIII}{xml_prop_name_literal}));
636
+ {I}return {try_target_var}.castTo({cls_name}.class);
637
+ }}
638
+
639
+ {target_var} = {try_target_var}.getResult();"""
640
+ )
641
+
642
+
643
+ def _generate_deserialize_list_property(
644
+ prop: intermediate.Property, cls: intermediate.ConcreteClass
645
+ ) -> Stripped:
646
+ """Generate the code to de-serialize a property ``prop`` as a list."""
647
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
648
+
649
+ # fmt: off
650
+ assert (
651
+ isinstance(type_anno, intermediate.ListTypeAnnotation)
652
+ and isinstance(type_anno.items, intermediate.OurTypeAnnotation)
653
+ and isinstance(
654
+ type_anno.items.our_type,
655
+ (intermediate.AbstractClass, intermediate.ConcreteClass)
656
+ )
657
+ ), "See intermediate._translate._verify_only_simple_type_patterns"
658
+ # fmt: on
659
+
660
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
661
+
662
+ item_our_type = type_anno.items.our_type
663
+
664
+ if (
665
+ isinstance(item_our_type, intermediate.AbstractClass)
666
+ or len(item_our_type.concrete_descendants) > 0
667
+ ):
668
+ interface_name = java_naming.interface_name(type_anno.items.our_type.name)
669
+ deserialize_method = f"{interface_name}FromElement"
670
+ else:
671
+ class_name = java_naming.class_name(type_anno.items.our_type.name)
672
+ deserialize_method = f"{class_name}FromElement"
673
+
674
+ item_type = java_common.generate_type(type_anno.items)
675
+
676
+ cls_name = java_naming.class_name(cls.name)
677
+
678
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
679
+
680
+ return Stripped(
681
+ f"""\
682
+ {target_var} = new ArrayList<>();
683
+ if (!isEmptyProperty) {{
684
+ {I}skipWhitespaceAndComments(reader);
685
+ {I}int index = 0;
686
+ {I}if(!currentEvent(reader).isStartElement()){{
687
+ {II}final Reporting.Error error = new Reporting.Error(
688
+ {II}"Expected a start element opening an instance of {item_type}, but got an XML "
689
+ {III}+ getEventTypeAsString(currentEvent(reader)));
690
+ {II}error.prependSegment(new Reporting.IndexSegment(index));
691
+ {II}error.prependSegment(new Reporting.NameSegment({xml_prop_name_literal}));
692
+ {II}return Result.failure(error);
693
+ {I}}}
694
+ {I}while (currentEvent(reader).isStartElement()) {{
695
+
696
+ {II}Result<? extends {item_type}> itemResult = try{deserialize_method}(reader);
697
+
698
+ {II}if (itemResult.isError()) {{
699
+ {III}itemResult.getError()
700
+ {IIII}.prependSegment(
701
+ {IIIII}new Reporting.IndexSegment(index));
702
+ {III}itemResult.getError()
703
+ {IIII}.prependSegment(
704
+ {IIIII}new Reporting.NameSegment({xml_prop_name_literal}));
705
+ {III}return itemResult.castTo({cls_name}.class);
706
+ {II}}}
707
+
708
+ {II}{target_var}.add(itemResult.getResult());
709
+ {II}index++;
710
+ {II}skipWhitespaceAndComments(reader);
711
+ {I}}}
712
+ }}"""
713
+ )
714
+
715
+
716
+ @require(lambda prop, cls: id(prop) in cls.property_id_set)
717
+ def _generate_deserialize_property(
718
+ prop: intermediate.Property, cls: intermediate.ConcreteClass
719
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
720
+ """Generate the snippet to deserialize the property ``prop`` from the content."""
721
+ blocks = [] # type: List[Stripped]
722
+
723
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
724
+
725
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
726
+ blocks.append(_generate_deserialize_primitive_property(prop=prop, cls=cls))
727
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
728
+ our_type = type_anno.our_type
729
+ if isinstance(our_type, intermediate.Enumeration):
730
+ blocks.append(
731
+ _generate_deserialize_enumeration_property(prop=prop, cls=cls)
732
+ )
733
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
734
+ # NOTE (empwilli, 2023-12-18):
735
+ # The constrained primitives are only verified, but not represented as
736
+ # separate classes in the XSD.
737
+ blocks.append(_generate_deserialize_primitive_property(prop=prop, cls=cls))
738
+ elif isinstance(
739
+ our_type, (intermediate.ConcreteClass, intermediate.AbstractClass)
740
+ ):
741
+ if (
742
+ isinstance(our_type, intermediate.AbstractClass)
743
+ or len(our_type.concrete_descendants) > 0
744
+ ):
745
+ blocks.append(
746
+ _generate_deserialize_interface_property(prop=prop, cls=cls)
747
+ )
748
+ else:
749
+ blocks.append(_generate_deserialize_cls_property(prop=prop, cls=cls))
750
+ else:
751
+ assert_never(our_type)
752
+
753
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
754
+ blocks.append(_generate_deserialize_list_property(prop=prop, cls=cls))
755
+
756
+ else:
757
+ assert_never(type_anno)
758
+
759
+ return Stripped("\n\n".join(blocks)), None
760
+
761
+
762
+ def _generate_deserialize_impl_cls_from_sequence(
763
+ cls: intermediate.ConcreteClass,
764
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
765
+ """Generate the function to de-serialize the ``cls`` from an XML sequence."""
766
+ name = java_naming.class_name(identifier=cls.name)
767
+
768
+ description = Stripped(
769
+ f"""\
770
+ /**
771
+ * Deserialize an instance of class {name} from a sequence of XML elements.
772
+ *
773
+ * <p>If {{@code isEmptySequence}} is set, we should try to deserialize
774
+ * the instance from an empty sequence. That is, the parent element
775
+ * was a self-closing element.
776
+ */"""
777
+ )
778
+
779
+ # NOTE (empwilli, 2023-12-18):
780
+ # Hard-wire for the case when no sequence is read
781
+ if len(cls.constructor.arguments) == 0:
782
+ return (
783
+ Stripped(
784
+ f"""\
785
+ {description}
786
+ private static Result<{name}> try{name}FromSequence(
787
+ {I}XMLEventReader reader,
788
+ {I}boolean isEmptySequence) {{
789
+ {I}return Result.success(new {name}());
790
+ }}"""
791
+ ),
792
+ None,
793
+ )
794
+
795
+ errors = [] # type: List[Error]
796
+
797
+ blocks = [] # type: List[Stripped]
798
+
799
+ assert len(cls.constructor.arguments) > 0, "Otherwise expected hard-wiring above"
800
+ init_target_var_stmts = [] # type: List[Stripped]
801
+ for prop in cls.properties:
802
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
803
+
804
+ assert isinstance(
805
+ type_anno,
806
+ (
807
+ intermediate.PrimitiveTypeAnnotation,
808
+ intermediate.OurTypeAnnotation,
809
+ intermediate.ListTypeAnnotation,
810
+ ),
811
+ )
812
+
813
+ target_type = java_common.generate_type(type_anno)
814
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
815
+
816
+ init_target_var_stmts.append(Stripped(f"{target_type} {target_var} = null;"))
817
+ blocks.append(Stripped("\n".join(init_target_var_stmts)))
818
+
819
+ # noinspection PyListCreation
820
+ blocks_for_non_empty = [] # type: List[Stripped]
821
+
822
+ blocks_for_non_empty.append(
823
+ Stripped(
824
+ f"""\
825
+ skipWhitespaceAndComments(reader);
826
+ if (currentEvent(reader).isEndDocument()) {{
827
+ {I}final Reporting.Error error = new Reporting.Error(
828
+ {II}"Expected an XML element representing " +
829
+ {II}"a property of an instance of class {name}, " +
830
+ {II}"but reached the end-of-file");
831
+ {I}return Result.failure(error);
832
+ }}"""
833
+ )
834
+ )
835
+
836
+ case_blocks = [] # type: List[Stripped]
837
+ for prop in cls.properties:
838
+ case_body, error = _generate_deserialize_property(prop=prop, cls=cls)
839
+ if error is not None:
840
+ errors.append(error)
841
+ continue
842
+
843
+ assert case_body is not None
844
+
845
+ xml_prop_name = naming.xml_property(prop.name)
846
+ xml_prop_name_literal = java_common.string_literal(xml_prop_name)
847
+ case_blocks.append(
848
+ Stripped(
849
+ f"""\
850
+ case {xml_prop_name_literal}:
851
+ {{
852
+ {I}{indent_but_first_line(case_body, I)}
853
+ {I}break;
854
+ }}"""
855
+ )
856
+ )
857
+
858
+ if len(errors) > 0:
859
+ return None, errors
860
+
861
+ case_blocks.append(
862
+ Stripped(
863
+ f"""\
864
+ default:
865
+ {I}final Reporting.Error error = new Reporting.Error(
866
+ {II}"We expected properties of the class {name}, " +
867
+ {II}"but got an unexpected element " +
868
+ {II}"with the name " + elementName);
869
+ {I}return Result.failure(error);"""
870
+ )
871
+ )
872
+
873
+ switch_body = "\n".join(case_blocks)
874
+
875
+ blocks_for_non_empty.append(
876
+ Stripped(
877
+ f"""\
878
+ while (true) {{
879
+ {I}skipWhitespaceAndComments(reader);
880
+
881
+ {I}if (currentEvent(reader).isEndElement() || currentEvent(reader).isEndDocument()) {{
882
+ {II}break;
883
+ {I}}}
884
+
885
+ {I}if (!currentEvent(reader).isStartElement()) {{
886
+ {II}final Reporting.Error error = new Reporting.Error(
887
+ {III}"Expected an XML start element representing " +
888
+ {III}"a property of an instance of class {name}, " +
889
+ {III}"but got the node of type " + getEventTypeAsString(currentEvent(reader)) +
890
+ {III}" with the value " + currentEvent(reader));
891
+ {II}return Result.failure(error);
892
+ {I}}}
893
+
894
+ {I}final Result<String> tryElementName = tryElementName(reader);
895
+ {I}if (tryElementName.isError()) {{
896
+ {II}return tryElementName.castTo({name}.class);
897
+ {I}}}
898
+
899
+ {I}final boolean isEmptyProperty = isEmptyElement(reader);
900
+ {I}final String elementName = tryElementName.getResult();
901
+
902
+ {I}switch (tryElementName.getResult()) {{
903
+ {II}{indent_but_first_line(switch_body, II)}
904
+ {I}}}
905
+
906
+ {I}skipWhitespaceAndComments(reader);
907
+
908
+
909
+ {I}final Result<XMLEvent> checkEndElement = verifyClosingTagForClass(
910
+ {II}"{name}",
911
+ {II}reader,
912
+ {II}tryElementName);
913
+ {I}if (checkEndElement.isError()) return checkEndElement.castTo({name}.class);
914
+
915
+ }}"""
916
+ )
917
+ )
918
+
919
+ body_for_non_empty_sequence = "\n".join(blocks_for_non_empty)
920
+ blocks.append(
921
+ Stripped(
922
+ f"""\
923
+ if (!isEmptySequence) {{
924
+ {I}{indent_but_first_line(body_for_non_empty_sequence, I)}
925
+ }}"""
926
+ )
927
+ )
928
+
929
+ # region Check that the mandatory properties have been set
930
+
931
+ for prop in cls.properties:
932
+ prop_java = java_naming.property_name(prop.name)
933
+ target_var = java_naming.variable_name(Identifier(f"the_{prop.name}"))
934
+
935
+ if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
936
+ blocks.append(
937
+ Stripped(
938
+ f"""\
939
+ if ({target_var} == null) {{
940
+ {I}final Reporting.Error error = new Reporting.Error(
941
+ {II}"The required property {prop_java} has not been given " +
942
+ {II}"in the XML representation of an instance of class {name}");
943
+ {I}return Result.failure(error);
944
+ }}"""
945
+ )
946
+ )
947
+
948
+ # endregion
949
+
950
+ # region Pass in properties as arguments to the constructor
951
+
952
+ property_names = [prop.name for prop in cls.properties]
953
+ constructor_argument_names = [arg.name for arg in cls.constructor.arguments]
954
+
955
+ # fmt: off
956
+ assert (
957
+ set(prop.name for prop in cls.properties)
958
+ == set(arg.name for arg in cls.constructor.arguments)
959
+ ), (
960
+ f"Expected the properties to coincide with constructor arguments, "
961
+ f"but they do not for {cls.name!r}:"
962
+ f"{property_names=}, {constructor_argument_names=}"
963
+ )
964
+ # fmt: on
965
+
966
+ init_writer = io.StringIO()
967
+ init_writer.write(f"return Result.success(new {name}(\n")
968
+
969
+ for i, arg in enumerate(cls.constructor.arguments):
970
+ prop = cls.properties_by_name[arg.name]
971
+
972
+ # NOTE (empwilli, 2023-12-18):
973
+ # The argument to the constructor may be optional while the property might
974
+ # be required, since we can set the default value in the body of the
975
+ # constructor. However, we can not have an optional property and a required
976
+ # constructor argument as we then would not know how to create the instance.
977
+
978
+ if not (
979
+ intermediate.type_annotations_equal(
980
+ arg.type_annotation, prop.type_annotation
981
+ )
982
+ or intermediate.type_annotations_equal(
983
+ intermediate.beneath_optional(arg.type_annotation),
984
+ prop.type_annotation,
985
+ )
986
+ ):
987
+ errors.append(
988
+ Error(
989
+ arg.parsed.node,
990
+ f"Expected type annotation for property {prop.name!r} "
991
+ f"and constructor argument {arg.name!r} "
992
+ f"of the class {cls.name!r} to have matching types, "
993
+ f"but they do not: "
994
+ f"property type is {prop.type_annotation} "
995
+ f"and argument type is {arg.type_annotation}. "
996
+ f"Hence we do not know how to generate the call "
997
+ f"to the constructor in the XML de-serialization.",
998
+ )
999
+ )
1000
+ continue
1001
+
1002
+ arg_var = java_naming.variable_name(Identifier(f"the_{arg.name}"))
1003
+
1004
+ init_writer.write(f"{I}{arg_var}")
1005
+
1006
+ if i < len(cls.constructor.arguments) - 1:
1007
+ init_writer.write(",\n")
1008
+ else:
1009
+ init_writer.write("));")
1010
+
1011
+ if len(errors) > 0:
1012
+ return None, errors
1013
+
1014
+ # endregion
1015
+
1016
+ blocks.append(Stripped(init_writer.getvalue()))
1017
+
1018
+ writer = io.StringIO()
1019
+ writer.write(
1020
+ f"""\
1021
+ {description}
1022
+ private static Result<{name}> try{name}FromSequence(
1023
+ {I}XMLEventReader reader,
1024
+ {I}boolean isEmptySequence) {{
1025
+ """
1026
+ )
1027
+
1028
+ for i, block in enumerate(blocks):
1029
+ if i > 0:
1030
+ writer.write("\n\n")
1031
+ writer.write(textwrap.indent(block, I))
1032
+
1033
+ writer.write("\n}")
1034
+
1035
+ return Stripped(writer.getvalue()), None
1036
+
1037
+
1038
+ def _generate_deserialize_impl_concrete_cls_from_element(
1039
+ cls: intermediate.ConcreteClass,
1040
+ ) -> Stripped:
1041
+ """Generate the function to de-serialize a concrete ``cls`` from an XML element."""
1042
+ name = java_naming.class_name(cls.name)
1043
+ xml_name = naming.xml_class_name(cls.name)
1044
+ xml_name_literal = java_common.string_literal(xml_name)
1045
+
1046
+ body = Stripped(
1047
+ f"""\
1048
+ skipWhitespaceAndComments(reader);
1049
+
1050
+ final XMLEvent currentEvent = currentEvent(reader);
1051
+ if (currentEvent.getEventType() == XMLStreamConstants.END_DOCUMENT) {{
1052
+ {I}final Reporting.Error error = new Reporting.Error(
1053
+ {II}"Expected an XML element representing an instance of class {name}, " +
1054
+ {II}"but reached the end-of-file");
1055
+ {I}return Result.failure(error);
1056
+ }}
1057
+
1058
+ if (currentEvent.getEventType() != XMLStreamConstants.START_ELEMENT) {{
1059
+ {I}final Reporting.Error error = new Reporting.Error(
1060
+ {II}"Expected an XML element representing an instance of class {name}, " +
1061
+ {II}"but got a node of type " + getEventTypeAsString(currentEvent) +
1062
+ {II}" with value " + currentEvent);
1063
+ {I}return Result.failure(error);
1064
+ }}
1065
+
1066
+ final Result<String> tryElementName = tryElementName(reader);
1067
+ if (tryElementName.isError()) {{
1068
+ {I}return tryElementName.castTo({name}.class);
1069
+ }}
1070
+
1071
+ final String elementName = tryElementName.getResult();
1072
+ if (!{xml_name_literal}.equals(tryElementName.getResult())) {{
1073
+ {I}final Reporting.Error error = new Reporting.Error(
1074
+ {II}"Expected an element representing an instance of class {name} " +
1075
+ {II}"with element name {xml_name}, but got: " + elementName);
1076
+ {I}return Result.failure(error);
1077
+ }}
1078
+
1079
+ final boolean isEmptyElement = isEmptyElement(reader);
1080
+
1081
+ Result<{name}> result = try{name}FromSequence(
1082
+ {I}reader,
1083
+ {I}isEmptyElement);
1084
+ if (result.isError()) return result.castTo({name}.class);
1085
+
1086
+
1087
+ final Result<XMLEvent> checkEndElement = verifyClosingTagForClass(
1088
+ {I}"{name}",
1089
+ {I}reader,
1090
+ {I}tryElementName);
1091
+ if (checkEndElement.isError()) return checkEndElement.castTo({name}.class);
1092
+
1093
+
1094
+ return result;"""
1095
+ )
1096
+
1097
+ return Stripped(
1098
+ f"""\
1099
+ /**
1100
+ * Deserialize an instance of class {name} from an XML element.
1101
+ */
1102
+ private static Result<{name}> try{name}FromElement(
1103
+ {I}XMLEventReader reader) {{
1104
+ {I}{indent_but_first_line(body, I)}
1105
+ }}"""
1106
+ )
1107
+
1108
+
1109
+ def _generate_deserialize_impl_interface_from_element(
1110
+ interface: intermediate.Interface,
1111
+ ) -> Stripped:
1112
+ """Generate the function to de-serialize an ``interface`` from an XML element."""
1113
+ name = java_naming.interface_name(interface.name)
1114
+
1115
+ blocks = [
1116
+ Stripped(
1117
+ f"""\
1118
+ skipWhitespaceAndComments(reader);
1119
+
1120
+ final XMLEvent currentEvent = currentEvent(reader);
1121
+ if (currentEvent.getEventType() == XMLStreamConstants.END_DOCUMENT) {{
1122
+ {I}final Reporting.Error error = new Reporting.Error(
1123
+ {II}"Expected an XML element, but reached end-of-file");
1124
+ {I}return Result.failure(error);
1125
+ }}
1126
+
1127
+ if (currentEvent.getEventType() != XMLStreamConstants.START_ELEMENT) {{
1128
+ {I}final Reporting.Error error = new Reporting.Error(
1129
+ {II}"Expected an XML element representing an instance of class {name}, " +
1130
+ {II}"but got a node of type " + getEventTypeAsString(currentEvent) +
1131
+ {II}" with value " + currentEvent);
1132
+ {I}return Result.failure(error);
1133
+ }}"""
1134
+ )
1135
+ ] # type: List[Stripped]
1136
+
1137
+ case_stmts = [] # type: List[Stripped]
1138
+ for implementer in interface.implementers:
1139
+ implementer_xml_name_literal = java_common.string_literal(
1140
+ naming.xml_class_name(implementer.name)
1141
+ )
1142
+
1143
+ implementer_name = java_naming.class_name(implementer.name)
1144
+
1145
+ case_stmts.append(
1146
+ Stripped(
1147
+ f"""\
1148
+ case {implementer_xml_name_literal}:
1149
+ {I}return try{implementer_name}FromElement(reader);"""
1150
+ )
1151
+ )
1152
+
1153
+ case_stmts.append(
1154
+ Stripped(
1155
+ f"""\
1156
+ default:
1157
+ {I}final Reporting.Error error = new Reporting.Error(
1158
+ {II}"Unexpected element with the name " + getEventTypeAsString(currentEvent));
1159
+ {I}return Result.failure(error);"""
1160
+ )
1161
+ )
1162
+
1163
+ switch_writer = io.StringIO()
1164
+ switch_writer.write(
1165
+ f"""\
1166
+ Result<String> tryElementName = tryElementName(
1167
+ {I}reader);
1168
+ if (tryElementName.isError()) {{
1169
+ {I}return tryElementName.castTo({name}.class);
1170
+ }}
1171
+
1172
+ final String elementName = tryElementName.getResult();
1173
+ switch (elementName) {{
1174
+ """
1175
+ )
1176
+ for i, case_stmt in enumerate(case_stmts):
1177
+ if i > 0:
1178
+ switch_writer.write("\n")
1179
+ switch_writer.write(textwrap.indent(case_stmt, I))
1180
+
1181
+ switch_writer.write("\n}")
1182
+
1183
+ blocks.append(Stripped(switch_writer.getvalue()))
1184
+
1185
+ writer = io.StringIO()
1186
+ writer.write(
1187
+ f"""\
1188
+ /**
1189
+ * Deserialize an instance of {name} from an XML element.
1190
+ */
1191
+ private static Result<? extends {name}> try{name}FromElement(
1192
+ {I}XMLEventReader reader) {{
1193
+ """
1194
+ )
1195
+
1196
+ for i, block in enumerate(blocks):
1197
+ if i > 0:
1198
+ writer.write("\n\n")
1199
+ writer.write(textwrap.indent(block, I))
1200
+
1201
+ writer.write("\n}")
1202
+
1203
+ return Stripped(writer.getvalue())
1204
+
1205
+
1206
+ def _generate_deserialize_impl(
1207
+ symbol_table: intermediate.SymbolTable,
1208
+ spec_impls: specific_implementations.SpecificImplementations,
1209
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1210
+ """Generate the implementation for deserialization functions."""
1211
+ blocks = [
1212
+ _generate_current_event(),
1213
+ _generate_get_event_type_as_string(),
1214
+ _generate_is_empty_element(),
1215
+ _generate_verify_closing_tag_for_class(),
1216
+ _generate_skip_whitespace_and_comments(),
1217
+ _generate_skip_start_document(),
1218
+ _generate_try_element_name(),
1219
+ _generate_try_content_for_primitives(),
1220
+ ] # type: List[Stripped]
1221
+
1222
+ errors = [] # type: List[Error]
1223
+
1224
+ # NOTE (empwilli, 2023-12-18):
1225
+ # Enumerations are going to be directly deserialized using
1226
+ # ``Stringification``.
1227
+
1228
+ # NOTE (empwilli, 2023-12-18):
1229
+ # Constrained primitives are only verified, but do not represent a C# type.
1230
+
1231
+ for cls in symbol_table.classes:
1232
+ if cls.is_implementation_specific:
1233
+ implementation_keys = [
1234
+ specific_implementations.ImplementationKey(
1235
+ f"Xmlization/DeserializeImplementation/"
1236
+ f"{cls.name}_from_element.java"
1237
+ ),
1238
+ specific_implementations.ImplementationKey(
1239
+ f"Xmlization/DeserializeImplementation/"
1240
+ f"{cls.name}_from_sequence.java"
1241
+ ),
1242
+ ]
1243
+
1244
+ for implementation_key in implementation_keys:
1245
+ implementation = spec_impls.get(implementation_key, None)
1246
+ if implementation is None:
1247
+ errors.append(
1248
+ Error(
1249
+ cls.parsed.node,
1250
+ f"The xmlization snippet is missing "
1251
+ f"for the implementation-specific "
1252
+ f"class {cls.name}: {implementation_key}",
1253
+ )
1254
+ )
1255
+ continue
1256
+ else:
1257
+ blocks.append(spec_impls[implementation_key])
1258
+ else:
1259
+ if isinstance(cls, intermediate.ConcreteClass):
1260
+ (
1261
+ block,
1262
+ generation_errors,
1263
+ ) = _generate_deserialize_impl_cls_from_sequence(cls=cls)
1264
+ if generation_errors is not None:
1265
+ errors.append(
1266
+ Error(
1267
+ cls.parsed.node,
1268
+ f"Failed to generate the XML deserialization code "
1269
+ f"for the class {cls.name}",
1270
+ generation_errors,
1271
+ )
1272
+ )
1273
+ else:
1274
+ assert block is not None
1275
+ blocks.append(block)
1276
+
1277
+ if cls.interface is not None:
1278
+ blocks.append(
1279
+ _generate_deserialize_impl_interface_from_element(
1280
+ interface=cls.interface
1281
+ )
1282
+ )
1283
+
1284
+ if isinstance(cls, intermediate.ConcreteClass):
1285
+ blocks.append(
1286
+ _generate_deserialize_impl_concrete_cls_from_element(cls=cls)
1287
+ )
1288
+
1289
+ if len(errors) > 0:
1290
+ return None, errors
1291
+
1292
+ writer = io.StringIO()
1293
+
1294
+ writer.write(
1295
+ """\
1296
+ /**
1297
+ * Implement the deserialization of meta-model classes from XML.
1298
+ *
1299
+ * <p>The implementation propagates an {@link Reporting.Error} instead of
1300
+ * relying on exceptions. Under the assumption that incorrect data is much less
1301
+ * frequent than correct data, this makes the deserialization more
1302
+ * efficient.
1303
+ *
1304
+ * <p>However, we do not want to force the client to deal with
1305
+ * the {@link Reporting.Error} class as this is not intuitive.
1306
+ * Therefore we distinguish the implementation, realized in
1307
+ * {@link DeserializeImplementation}, and the facade given in
1308
+ * {@link Deserialize} class.
1309
+ */
1310
+ private static class DeserializeImplementation
1311
+ {
1312
+ """
1313
+ )
1314
+
1315
+ for i, block in enumerate(blocks):
1316
+ if i > 0:
1317
+ writer.write("\n\n")
1318
+ writer.write(textwrap.indent(block, I))
1319
+
1320
+ writer.write("\n}")
1321
+
1322
+ return Stripped(writer.getvalue()), None
1323
+
1324
+
1325
+ def _generate_deserialize_from(name: Identifier) -> Stripped:
1326
+ """Generate the facade method for deserialization of the class or interface."""
1327
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(name))
1328
+ writer = io.StringIO()
1329
+
1330
+ writer.write(
1331
+ f"""\
1332
+ /**
1333
+ * Deserialize an instance of {name} from {{@code reader}}.
1334
+ *
1335
+ * @param reader Initialized XML reader with reader.peek() set to the element
1336
+ */
1337
+ """
1338
+ )
1339
+ writer.write(
1340
+ f"""\
1341
+ public static {name} deserialize{name}(
1342
+ {I}XMLEventReader reader) {{
1343
+
1344
+ {I}DeserializeImplementation.skipStartDocument(reader);
1345
+ {I}DeserializeImplementation.skipWhitespaceAndComments(reader);
1346
+
1347
+ {I}Result<? extends {name}> result =
1348
+ {II}DeserializeImplementation.try{name}FromElement(
1349
+ {III}reader);
1350
+
1351
+ {I}return result.onError(error -> {{
1352
+ {II}error.prependSegment(new Reporting.NameSegment({xml_prop_name_literal}));
1353
+ {II}throw new DeserializeException(
1354
+ {III}Reporting.generateRelativeXPath(error.getPathSegments()),
1355
+ {III}error.getCause());
1356
+ {I}}});
1357
+ }}"""
1358
+ )
1359
+
1360
+ return Stripped(writer.getvalue())
1361
+
1362
+
1363
+ def _generate_deserialize(symbol_table: intermediate.SymbolTable) -> Stripped:
1364
+ """Generate the public class ``Deserialize``."""
1365
+ blocks = [] # type: List[Stripped]
1366
+
1367
+ # NOTE (empwilli, 2023-12-18):
1368
+ # We use stringification for de-serialization of enumerations.
1369
+
1370
+ # NOTE (empwilli, 2023-12-18):
1371
+ # Constrained primitives are not handled as separate classes, but as
1372
+ # primitives, and only verified in the verification.
1373
+
1374
+ for cls in symbol_table.classes:
1375
+ if cls.interface is not None:
1376
+ blocks.append(
1377
+ _generate_deserialize_from(
1378
+ name=java_naming.interface_name(cls.interface.name)
1379
+ )
1380
+ )
1381
+
1382
+ if isinstance(cls, intermediate.ConcreteClass):
1383
+ blocks.append(
1384
+ _generate_deserialize_from(name=java_naming.class_name(cls.name))
1385
+ )
1386
+
1387
+ writer = io.StringIO()
1388
+ writer.write(
1389
+ """\
1390
+ /**
1391
+ * Deserialize instances of meta-model classes from XML.
1392
+ */
1393
+ """
1394
+ )
1395
+
1396
+ first_cls = symbol_table.classes[0] if len(symbol_table.classes) > 0 else None
1397
+
1398
+ if first_cls is not None:
1399
+ cls_name = None # type: Optional[str]
1400
+ if isinstance(first_cls, intermediate.AbstractClass):
1401
+ cls_name = java_naming.interface_name(first_cls.name)
1402
+ elif isinstance(first_cls, intermediate.ConcreteClass):
1403
+ cls_name = java_naming.class_name(first_cls.name)
1404
+ else:
1405
+ assert_never(first_cls)
1406
+
1407
+ an_instance_variable = java_naming.variable_name(Identifier("an_instance"))
1408
+
1409
+ writer.write(
1410
+ f"""\
1411
+ /** <pre>
1412
+ * Here is an example how to parse an instance of class {cls_name}:
1413
+ * {{@code
1414
+ * XMLEventReader reader = xmlFactory.createXMLEventReader(...some arguments...);
1415
+ * {cls_name} {an_instance_variable} = Deserialize.deserialize{cls_name}(
1416
+ * {I}reader);
1417
+ * }}
1418
+ * </pre>
1419
+ *
1420
+ * <pre>
1421
+ * If the elements live in a namespace, you have to supply it. For example:
1422
+ * {{@code
1423
+ * XMLEventReader reader = xmlFactory.createXMLEventReader(...some arguments...);
1424
+ * {cls_name} {an_instance_variable} = Deserialize.deserialize{cls_name}(
1425
+ * {I}reader,
1426
+ * {I}"http://www.example.com/5/12");
1427
+ * }}
1428
+ * </pre>
1429
+ */
1430
+ """
1431
+ )
1432
+
1433
+ writer.write(
1434
+ """\
1435
+ public static class Deserialize
1436
+ {
1437
+ """
1438
+ )
1439
+
1440
+ for i, block in enumerate(blocks):
1441
+ if i > 0:
1442
+ writer.write("\n\n")
1443
+ writer.write(textwrap.indent(block, I))
1444
+
1445
+ writer.write("\n}")
1446
+
1447
+ return Stripped(writer.getvalue())
1448
+
1449
+
1450
+ def _generate_serialize_primitive_property_as_content(
1451
+ prop: intermediate.Property,
1452
+ ) -> Stripped:
1453
+ """Generate the serialization of the primitive-type ``prop`` as XML content."""
1454
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1455
+
1456
+ a_type = intermediate.try_primitive_type(type_anno)
1457
+ assert (
1458
+ a_type is not None
1459
+ ), f"Unexpected non-primitive type of the property {prop.name!r}: {type_anno}"
1460
+
1461
+ prop_name = java_naming.property_name(prop.name)
1462
+ getter_name = java_naming.getter_name(prop.name)
1463
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
1464
+
1465
+ write_value_block: Stripped
1466
+
1467
+ if (
1468
+ a_type is intermediate.PrimitiveType.BOOL
1469
+ or a_type is intermediate.PrimitiveType.INT
1470
+ or a_type is intermediate.PrimitiveType.FLOAT
1471
+ or a_type is intermediate.PrimitiveType.STR
1472
+ ):
1473
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1474
+ write_value_block = Stripped(
1475
+ f"""\
1476
+ if (that.{getter_name}().isPresent()) {{
1477
+ {I}writer.writeStartElement(
1478
+ {II}{xml_prop_name_literal});
1479
+ {I}if (topLevel) {{
1480
+ {II}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1481
+ {II}topLevel = false;
1482
+ {I}}}
1483
+
1484
+ {I}writer.writeCharacters(
1485
+ {II}that.{getter_name}().get().toString());
1486
+
1487
+ {I}writer.writeEndElement();
1488
+ }}"""
1489
+ )
1490
+ else:
1491
+ write_value_block = Stripped(
1492
+ f"""\
1493
+ writer.writeStartElement(
1494
+ {I}{xml_prop_name_literal});
1495
+ if (topLevel) {{
1496
+ {I}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1497
+ {I}topLevel = false;
1498
+ }}
1499
+ writer.writeCharacters(
1500
+ {I}that.{getter_name}().toString());
1501
+ writer.writeEndElement();"""
1502
+ )
1503
+ elif a_type is intermediate.PrimitiveType.BYTEARRAY:
1504
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1505
+ base64_prop_name = java_naming.property_name(
1506
+ Identifier(f"the_b64_{prop_name}")
1507
+ )
1508
+ write_value_block = Stripped(
1509
+ f"""\
1510
+ if (that.{getter_name}().isPresent()) {{
1511
+ {I}writer.writeStartElement({xml_prop_name_literal});
1512
+ {I}if (topLevel) {{
1513
+ {II}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1514
+ {II}topLevel = false;
1515
+ {I}}}
1516
+ {I}String {base64_prop_name} = Base64.getEncoder().encodeToString(
1517
+ {II}that.{getter_name}().get());
1518
+ {I}writer.writeCharacters({base64_prop_name});
1519
+ {I}writer.writeEndElement();
1520
+ }}"""
1521
+ )
1522
+ else:
1523
+ base64_prop_name = java_naming.property_name(
1524
+ Identifier(f"the_b64_{prop_name}")
1525
+ )
1526
+ write_value_block = Stripped(
1527
+ f"""\
1528
+ String {base64_prop_name} = Base64.getEncoder().encodeToString(
1529
+ {I}that.{getter_name}());
1530
+ writer.writeCharacters({base64_prop_name});"""
1531
+ )
1532
+ else:
1533
+ assert_never(a_type)
1534
+
1535
+ assert write_value_block is not None
1536
+
1537
+ write_value_block = Stripped(
1538
+ f"""\
1539
+ try {{
1540
+ {I}{indent_but_first_line(write_value_block, I)}
1541
+ }} catch (Exception exception) {{
1542
+ {I}throw new SerializeException("",exception.getMessage());
1543
+ }}"""
1544
+ )
1545
+
1546
+ return write_value_block
1547
+
1548
+
1549
+ def _generate_serialize_enumeration_property_as_content(
1550
+ prop: intermediate.Property,
1551
+ ) -> Stripped:
1552
+ """Generate the serialization of an enumeration ``prop`` as XML content."""
1553
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1554
+ assert isinstance(type_anno, intermediate.OurTypeAnnotation) and isinstance(
1555
+ type_anno.our_type, intermediate.Enumeration
1556
+ ), "See intermediate._translate._verify_only_simple_type_patterns"
1557
+
1558
+ enumeration = type_anno.our_type
1559
+
1560
+ getter_name = java_naming.getter_name(prop.name)
1561
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
1562
+
1563
+ enum_name = java_naming.enum_name(enumeration.name)
1564
+
1565
+ text_var = java_naming.variable_name(Identifier(f"text_{prop.name}"))
1566
+
1567
+ write_value_block: Stripped
1568
+
1569
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1570
+ write_value_block = Stripped(
1571
+ f"""\
1572
+ if (that.{getter_name}().isPresent()) {{
1573
+ {I}writer.writeStartElement(
1574
+ {II}{xml_prop_name_literal});
1575
+ {I}if (topLevel) {{
1576
+ {II}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1577
+ {II}topLevel = false;
1578
+ {I}}}
1579
+
1580
+ {I}Optional<String> {text_var} = Stringification.toString(
1581
+ {II}that.{getter_name}().get());
1582
+
1583
+ {I}if (!{text_var}.isPresent()) {{
1584
+ {II}throw new IllegalArgumentException(
1585
+ {III}"Invalid literal for the enumeration {enum_name}: " +
1586
+ {III}that.{getter_name}().get().toString());
1587
+ {I}}}
1588
+
1589
+ {I}writer.writeCharacters({text_var}.get());
1590
+
1591
+ {I}writer.writeEndElement();
1592
+ }}"""
1593
+ )
1594
+ else:
1595
+ write_value_block = Stripped(
1596
+ f"""\
1597
+ writer.writeStartElement(
1598
+ {I}{xml_prop_name_literal});
1599
+ if (topLevel) {{
1600
+ {I}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1601
+ {I}topLevel = false;
1602
+ }}
1603
+
1604
+ Optional<String> {text_var} = Stringification.toString(
1605
+ {I}that.{getter_name}());
1606
+
1607
+ if (!{text_var}.isPresent()) {{
1608
+ {I}throw new IllegalArgumentException(
1609
+ {II}"Invalid literal for the enumeration {enum_name}: " +
1610
+ {II}that.{getter_name}().toString());
1611
+ }}
1612
+
1613
+ writer.writeCharacters({text_var}.get());
1614
+
1615
+ writer.writeEndElement();"""
1616
+ )
1617
+
1618
+ write_value_block = Stripped(
1619
+ f"""\
1620
+ try {{
1621
+ {I}{indent_but_first_line(write_value_block, I)}
1622
+ }} catch (Exception exception) {{
1623
+ {I}throw new SerializeException("",exception.getMessage());
1624
+ }}"""
1625
+ )
1626
+
1627
+ return write_value_block
1628
+
1629
+
1630
+ def _generate_serialize_interface_property_as_content(
1631
+ prop: intermediate.Property,
1632
+ ) -> Stripped:
1633
+ """Generate the serialization of an interface as XML content."""
1634
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1635
+
1636
+ # fmt: off
1637
+ assert (
1638
+ isinstance(type_anno, intermediate.OurTypeAnnotation)
1639
+ and (
1640
+ isinstance(type_anno.our_type, intermediate.AbstractClass)
1641
+ or (
1642
+ isinstance(type_anno.our_type, intermediate.ConcreteClass)
1643
+ and len(type_anno.our_type.concrete_descendants) > 0
1644
+ )
1645
+ )
1646
+ ), "See intermediate._translate._verify_only_simple_type_patterns"
1647
+ # fmt: on
1648
+
1649
+ getter_name = java_naming.getter_name(prop.name)
1650
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
1651
+
1652
+ result: Stripped
1653
+
1654
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1655
+ result = Stripped(
1656
+ f"""\
1657
+ if (that.{getter_name}().isPresent()) {{
1658
+ {I}writer.writeStartElement(
1659
+ {II}{xml_prop_name_literal});
1660
+ {I}if (topLevel) {{
1661
+ {II}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1662
+ {II}topLevel = false;
1663
+ {I}}}
1664
+
1665
+ {I}this.visit(
1666
+ {II}that.{getter_name}().get(),
1667
+ {II}writer);
1668
+
1669
+ {I}writer.writeEndElement();
1670
+ }}"""
1671
+ )
1672
+ else:
1673
+ result = Stripped(
1674
+ f"""\
1675
+ writer.writeStartElement(
1676
+ {I}{xml_prop_name_literal});
1677
+ if (topLevel) {{
1678
+ {I}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1679
+ {I}topLevel = false;
1680
+ }}
1681
+
1682
+ this.visit(
1683
+ {I}that.{getter_name}(),
1684
+ {I}writer);
1685
+
1686
+ writer.writeEndElement();"""
1687
+ )
1688
+
1689
+ result = Stripped(
1690
+ f"""\
1691
+ try {{
1692
+ {I}{indent_but_first_line(result, I)}
1693
+ }} catch (XMLStreamException exception) {{
1694
+ {I}throw new SerializeException("",exception.getMessage());
1695
+ }}"""
1696
+ )
1697
+
1698
+ return result
1699
+
1700
+
1701
+ def _generate_serialize_concrete_class_property_as_sequence(
1702
+ prop: intermediate.Property,
1703
+ ) -> Stripped:
1704
+ """Generate the serialization of the class ``prop`` as a sequence of properties."""
1705
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1706
+ assert isinstance(type_anno, intermediate.OurTypeAnnotation)
1707
+ assert isinstance(type_anno.our_type, intermediate.ConcreteClass)
1708
+
1709
+ cls_to_sequence = java_naming.method_name(
1710
+ Identifier(f"{type_anno.our_type.name}_to_sequence")
1711
+ )
1712
+
1713
+ getter_name = java_naming.getter_name(prop.name)
1714
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
1715
+
1716
+ result: Stripped
1717
+
1718
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1719
+ result = Stripped(
1720
+ f"""\
1721
+ if (that.{getter_name}().isPresent()) {{
1722
+ {I}writer.writeStartElement(
1723
+ {II}{xml_prop_name_literal});
1724
+ {I}if (topLevel) {{
1725
+ {II}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1726
+ {II}topLevel = false;
1727
+ {I}}}
1728
+
1729
+ {I}this.{cls_to_sequence}(
1730
+ {II}that.{getter_name}().get(),
1731
+ {II}writer);
1732
+
1733
+ {I}writer.writeEndElement();
1734
+ }}"""
1735
+ )
1736
+ else:
1737
+ result = Stripped(
1738
+ f"""\
1739
+ writer.writeStartElement(
1740
+ {I}{xml_prop_name_literal});
1741
+ if (topLevel) {{
1742
+ {I}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1743
+ {I}topLevel = false;
1744
+ }}
1745
+
1746
+ this.{cls_to_sequence}(
1747
+ {I}that.{getter_name}(),
1748
+ {I}writer);
1749
+
1750
+ writer.writeEndElement();"""
1751
+ )
1752
+
1753
+ result = Stripped(
1754
+ f"""\
1755
+ try {{
1756
+ {I}{indent_but_first_line(result, I)}
1757
+ }} catch (XMLStreamException exception) {{
1758
+ {I}throw new SerializeException("",exception.getMessage());
1759
+ }}"""
1760
+ )
1761
+
1762
+ return result
1763
+
1764
+
1765
+ def _generate_serialize_list_property_as_content(
1766
+ prop: intermediate.Property,
1767
+ ) -> Stripped:
1768
+ """Generate the serialization of a list ``prop`` as a sequence of elements."""
1769
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1770
+
1771
+ # fmt: off
1772
+ assert (
1773
+ isinstance(type_anno, intermediate.ListTypeAnnotation)
1774
+ and isinstance(type_anno.items, intermediate.OurTypeAnnotation)
1775
+ and isinstance(
1776
+ type_anno.items.our_type,
1777
+ (intermediate.AbstractClass, intermediate.ConcreteClass)
1778
+ )
1779
+ ), "See intermediate._translate._verify_only_simple_type_patterns"
1780
+ # fmt: on
1781
+
1782
+ getter_name = java_naming.getter_name(prop.name)
1783
+ xml_prop_name_literal = java_common.string_literal(naming.xml_property(prop.name))
1784
+
1785
+ result: Stripped
1786
+
1787
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1788
+ result = Stripped(
1789
+ f"""\
1790
+ if (that.{getter_name}().isPresent()) {{
1791
+ {I}writer.writeStartElement(
1792
+ {I}{xml_prop_name_literal});
1793
+ {I}if (topLevel) {{
1794
+ {II}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1795
+ {II}topLevel = false;
1796
+ {I}}}
1797
+ {I}for (IClass item : that.{getter_name}().get()) {{
1798
+ {II}this.visit(
1799
+ {III}item,
1800
+ {III}writer);
1801
+ {II}}}
1802
+ {I}writer.writeEndElement();
1803
+ }}"""
1804
+ )
1805
+ else:
1806
+ result = Stripped(
1807
+ f"""\
1808
+ writer.writeStartElement(
1809
+ {I}{xml_prop_name_literal});
1810
+ if (topLevel) {{
1811
+ {I}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1812
+ {I}topLevel = false;
1813
+ }}
1814
+
1815
+ for (IClass item : that.{getter_name}()) {{
1816
+ {I}this.visit(
1817
+ {II}item,
1818
+ {II}writer);
1819
+ }}
1820
+
1821
+ writer.writeEndElement();"""
1822
+ )
1823
+
1824
+ result = Stripped(
1825
+ f"""\
1826
+ try {{
1827
+ {I}{indent_but_first_line(result, I)}
1828
+ }} catch (XMLStreamException exception) {{
1829
+ {I}throw new SerializeException("",exception.getMessage());
1830
+ }}"""
1831
+ )
1832
+
1833
+ return result
1834
+
1835
+
1836
+ def _generate_serialize_property_as_content(prop: intermediate.Property) -> Stripped:
1837
+ """Generate the code to serialize the ``prop`` as content of an XML element."""
1838
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1839
+
1840
+ body = None # type: Optional[Stripped]
1841
+
1842
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
1843
+ body = _generate_serialize_primitive_property_as_content(prop=prop)
1844
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
1845
+ our_type = type_anno.our_type
1846
+
1847
+ if isinstance(our_type, intermediate.Enumeration):
1848
+ body = _generate_serialize_enumeration_property_as_content(prop=prop)
1849
+
1850
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1851
+ body = _generate_serialize_primitive_property_as_content(prop=prop)
1852
+
1853
+ elif isinstance(
1854
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
1855
+ ):
1856
+ if (
1857
+ isinstance(our_type, intermediate.AbstractClass)
1858
+ or len(our_type.concrete_descendants) > 0
1859
+ ):
1860
+ body = _generate_serialize_interface_property_as_content(prop=prop)
1861
+ else:
1862
+ body = _generate_serialize_concrete_class_property_as_sequence(
1863
+ prop=prop
1864
+ )
1865
+
1866
+ else:
1867
+ assert_never(our_type)
1868
+
1869
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
1870
+ body = _generate_serialize_list_property_as_content(prop=prop)
1871
+
1872
+ else:
1873
+ assert_never(type_anno)
1874
+
1875
+ return body
1876
+
1877
+
1878
+ def _generate_class_to_sequence(cls: intermediate.ConcreteClass) -> Stripped:
1879
+ """Generate the method to write ``cls`` as a sequence of properties as XML."""
1880
+ blocks = [] # type: List[Stripped]
1881
+
1882
+ for prop in cls.properties:
1883
+ body = _generate_serialize_property_as_content(prop=prop)
1884
+ blocks.append(body)
1885
+
1886
+ interface_name = java_naming.interface_name(cls.name)
1887
+ method_name = java_naming.method_name(Identifier(f"{cls.name}_to_sequence"))
1888
+
1889
+ writer = io.StringIO()
1890
+
1891
+ if len(cls.properties) == 0:
1892
+ blocks.append(Stripped("// Intentionally empty."))
1893
+
1894
+ writer.write(
1895
+ f"""\
1896
+ private void {method_name}(
1897
+ {I}{interface_name} that,
1898
+ {I}XMLStreamWriter writer) {{
1899
+ """
1900
+ )
1901
+
1902
+ for i, block in enumerate(blocks):
1903
+ if i > 0:
1904
+ writer.write("\n\n")
1905
+ writer.write(textwrap.indent(block, I))
1906
+
1907
+ writer.write("\n}")
1908
+
1909
+ return Stripped(writer.getvalue())
1910
+
1911
+
1912
+ def _generate_visit_for_class(cls: intermediate.ConcreteClass) -> Stripped:
1913
+ """Generate the method to write the ``cls`` as an XML element."""
1914
+ interface_name = java_naming.interface_name(cls.name)
1915
+ visit_name = java_naming.method_name(Identifier(f"visit_{cls.name}"))
1916
+
1917
+ cls_to_sequence_name = java_naming.method_name(
1918
+ Identifier(f"{cls.name}_to_sequence")
1919
+ )
1920
+
1921
+ xml_cls_name_literal = java_common.string_literal(naming.xml_class_name(cls.name))
1922
+
1923
+ writer = io.StringIO()
1924
+
1925
+ writer.write(
1926
+ f"""\
1927
+ @Override
1928
+ public void {visit_name}(
1929
+ {I}{interface_name} that,
1930
+ {I}XMLStreamWriter writer) {{
1931
+ {I}try {{
1932
+ {II}writer.writeStartElement(
1933
+ {III}{xml_cls_name_literal});
1934
+ {II}if (topLevel) {{
1935
+ {III}writer.writeNamespace("xmlns", AAS_NAME_SPACE);
1936
+ {III}topLevel = false;
1937
+ {II}}}
1938
+ {II}this.{cls_to_sequence_name}(
1939
+ {III}that,
1940
+ {III}writer);
1941
+ {II}writer.writeEndElement();
1942
+ {I}}} catch (XMLStreamException exception) {{
1943
+ {II}throw new SerializeException("", exception.getMessage());
1944
+ {I}}}
1945
+ }}"""
1946
+ )
1947
+
1948
+ return Stripped(writer.getvalue())
1949
+
1950
+
1951
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1952
+ def _generate_visitor(
1953
+ symbol_table: intermediate.SymbolTable,
1954
+ spec_impls: specific_implementations.SpecificImplementations,
1955
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1956
+ """Generate a visitor which serializes instances of the meta-model to XML."""
1957
+ errors = [] # type: List[Error]
1958
+
1959
+ blocks = [] # type: List[Stripped]
1960
+
1961
+ # The abstract classes are directly dispatched by the transformer,
1962
+ # so we do not need to handle them separately.
1963
+
1964
+ for cls in symbol_table.concrete_classes:
1965
+ if cls.is_implementation_specific:
1966
+ implementation_keys = [
1967
+ specific_implementations.ImplementationKey(
1968
+ f"Xmlization/VisitorWithWriter/visit_{cls.name}.java"
1969
+ ),
1970
+ specific_implementations.ImplementationKey(
1971
+ f"Xmlization/VisitorWithWriter/{cls.name}_to_sequence.java"
1972
+ ),
1973
+ ]
1974
+
1975
+ for implementation_key in implementation_keys:
1976
+ implementation = spec_impls.get(implementation_key, None)
1977
+ if implementation is None:
1978
+ errors.append(
1979
+ Error(
1980
+ cls.parsed.node,
1981
+ f"The xmlization snippet is missing "
1982
+ f"for the implementation-specific "
1983
+ f"class {cls.name}: {implementation_key}",
1984
+ )
1985
+ )
1986
+ continue
1987
+
1988
+ blocks.append(spec_impls[implementation_key])
1989
+ else:
1990
+ blocks.append(_generate_class_to_sequence(cls=cls))
1991
+
1992
+ blocks.append(_generate_visit_for_class(cls=cls))
1993
+
1994
+ if len(errors) > 0:
1995
+ return None, errors
1996
+
1997
+ writer = io.StringIO()
1998
+ writer.write(
1999
+ f"""\
2000
+ /**
2001
+ * Serialize recursively the instances as XML elements.
2002
+ */
2003
+ static class VisitorWithWriter
2004
+ {I}extends AbstractVisitorWithContext<XMLStreamWriter> {{
2005
+
2006
+ {I}private boolean topLevel = true;
2007
+
2008
+ """
2009
+ )
2010
+
2011
+ for i, block in enumerate(blocks):
2012
+ if i > 0:
2013
+ writer.write("\n\n")
2014
+ writer.write(textwrap.indent(block, I))
2015
+
2016
+ writer.write("\n}")
2017
+
2018
+ return Stripped(writer.getvalue()), None
2019
+
2020
+
2021
+ def _generate_serialize(
2022
+ symbol_table: intermediate.SymbolTable,
2023
+ ) -> Stripped:
2024
+ """Generate the static serializer."""
2025
+ blocks = [
2026
+ Stripped(
2027
+ f"""\
2028
+ /**
2029
+ * Serialize an instance of the meta-model to XML.
2030
+ */
2031
+ public static void to(
2032
+ {I}IClass that,
2033
+ {I}XMLStreamWriter writer) throws SerializeException {{
2034
+ {I}VisitorWithWriter visitor = new VisitorWithWriter();
2035
+ {I}visitor.visit(
2036
+ {II}that, writer);
2037
+ }}"""
2038
+ ),
2039
+ ] # type: List[Stripped]
2040
+
2041
+ writer = io.StringIO()
2042
+ writer.write(
2043
+ """\
2044
+ /**
2045
+ * Serialize instances of meta-model classes to XML.
2046
+ */
2047
+ """
2048
+ )
2049
+
2050
+ first_cls = (
2051
+ symbol_table.classes[0] if len(symbol_table.classes) > 0 else None
2052
+ ) # type: Optional[intermediate.ClassUnion]
2053
+
2054
+ if first_cls is not None:
2055
+ cls_name = None # type: Optional[str]
2056
+ if isinstance(first_cls, intermediate.AbstractClass):
2057
+ cls_name = java_naming.interface_name(first_cls.name)
2058
+ elif isinstance(first_cls, intermediate.ConcreteClass):
2059
+ cls_name = java_naming.class_name(first_cls.name)
2060
+ else:
2061
+ assert_never(first_cls)
2062
+
2063
+ an_instance_variable = java_naming.variable_name(Identifier("an_instance"))
2064
+
2065
+ writer.write(
2066
+ f"""\
2067
+ /**
2068
+ * <pre>
2069
+ * Here is an example how to serialize an instance of {cls_name}:
2070
+ * {{@code
2071
+ * IClass {an_instance_variable} = new {cls_name}(
2072
+ * ... some constructor arguments ...
2073
+ * );
2074
+ * XMLStreamWriter writer = xmlWriterFactory.createXMLStreamWriter(...some arguments...);
2075
+ * Serialize.to(
2076
+ * {I}{an_instance_variable},
2077
+ * {I}writer);
2078
+ * }}
2079
+ * </pre>
2080
+ */
2081
+ """
2082
+ )
2083
+
2084
+ writer.write(
2085
+ """\
2086
+ public static class Serialize
2087
+ {
2088
+ """
2089
+ )
2090
+
2091
+ for i, block in enumerate(blocks):
2092
+ if i > 0:
2093
+ writer.write("\n\n")
2094
+ writer.write(textwrap.indent(block, I))
2095
+
2096
+ writer.write("\n}")
2097
+
2098
+ return Stripped(writer.getvalue())
2099
+
2100
+
2101
+ # fmt: off
2102
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
2103
+ @ensure(
2104
+ lambda result:
2105
+ not (result[0] is not None) or result[0].endswith('\n'),
2106
+ "Trailing newline mandatory for valid end-of-files"
2107
+ )
2108
+ # fmt: on
2109
+ def generate(
2110
+ symbol_table: intermediate.SymbolTable,
2111
+ package: java_common.PackageIdentifier,
2112
+ spec_impls: specific_implementations.SpecificImplementations,
2113
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
2114
+ """
2115
+ Generate the Java code for the general serialization.
2116
+
2117
+ The ``package`` defines the root Java package.
2118
+ """
2119
+ errors = [] # type: List[Error]
2120
+
2121
+ imports = [
2122
+ Stripped("import javax.xml.stream.events.XMLEvent;"),
2123
+ Stripped("import javax.xml.stream.XMLEventReader;"),
2124
+ Stripped("import javax.xml.stream.XMLStreamConstants;"),
2125
+ Stripped("import javax.xml.stream.XMLStreamException;"),
2126
+ Stripped("import javax.xml.stream.XMLStreamWriter;"),
2127
+ Stripped("import java.util.ArrayList;"),
2128
+ Stripped("import java.util.Base64;"),
2129
+ Stripped("import java.util.function.Function;"),
2130
+ Stripped("import java.util.List;"),
2131
+ Stripped("import java.util.Optional;"),
2132
+ Stripped(f"import {package}.reporting.Reporting;"),
2133
+ Stripped(f"import {package}.stringification.Stringification;"),
2134
+ Stripped(f"import {package}.types.enums.*;"),
2135
+ Stripped(f"import {package}.types.impl.*;"),
2136
+ Stripped(f"import {package}.types.model.*;"),
2137
+ Stripped(f"import {package}.visitation.*;"),
2138
+ ] # type: List[Stripped]
2139
+
2140
+ # region Deserialization helpers
2141
+
2142
+ xml_result_class = _generate_result()
2143
+
2144
+ xml_namespace_literal = java_common.string_literal(
2145
+ symbol_table.meta_model.xml_namespace
2146
+ )
2147
+
2148
+ # endregion
2149
+
2150
+ # region Deserialization Implementation
2151
+
2152
+ deserialize_impl_block, deserialize_impl_errors = _generate_deserialize_impl(
2153
+ symbol_table=symbol_table, spec_impls=spec_impls
2154
+ )
2155
+ if deserialize_impl_errors is not None:
2156
+ errors.extend(deserialize_impl_errors)
2157
+
2158
+ assert deserialize_impl_block is not None
2159
+
2160
+ # endregion
2161
+
2162
+ # region Deserialization
2163
+
2164
+ deserialize_block = _generate_deserialize(symbol_table=symbol_table)
2165
+
2166
+ # endregion
2167
+
2168
+ # region Visitor
2169
+
2170
+ visitor_block, visitor_errors = _generate_visitor(
2171
+ symbol_table=symbol_table, spec_impls=spec_impls
2172
+ )
2173
+ if visitor_errors is not None:
2174
+ errors.extend(visitor_errors)
2175
+
2176
+ assert visitor_block is not None
2177
+
2178
+ # endregion
2179
+
2180
+ # region Serialization
2181
+
2182
+ serialization_block = _generate_serialize(symbol_table=symbol_table)
2183
+
2184
+ # endregion
2185
+
2186
+ xmlization_blocks = [
2187
+ Stripped(
2188
+ f"""\
2189
+ /**
2190
+ * Provide de/serialization of meta-model classes to/from XML.
2191
+ */
2192
+ public class Xmlization {{
2193
+ {I}/**
2194
+ {I} * Represent a critical error during the deserialization.
2195
+ {I} */
2196
+ {I}@SuppressWarnings("serial")
2197
+ {I}public static class DeserializeException extends RuntimeException {{
2198
+ {II}private final String path;
2199
+ {II}private final String reason;
2200
+
2201
+ {II}public DeserializeException(String path, String reason) {{
2202
+ {III}super(reason + " at: " + ("".equals(path) ? "the beginning" : path));
2203
+ {III}this.path = path;
2204
+ {III}this.reason = reason;
2205
+ {II}}}
2206
+
2207
+ {II}public Optional<String> getPath() {{
2208
+ {III}return Optional.ofNullable(path);
2209
+ {II}}}
2210
+
2211
+ {II}public Optional<String> getReason() {{
2212
+ {III}return Optional.ofNullable(reason);
2213
+ {II}}}
2214
+ {I}}}
2215
+
2216
+ {I}/**
2217
+ {I} * Represent a critical error during the serialization.
2218
+ {I} */
2219
+ {I}@SuppressWarnings("serial")
2220
+ {I}public static class SerializeException extends RuntimeException {{
2221
+ {II}private final String path;
2222
+ {II}private final String reason;
2223
+
2224
+ {II}public SerializeException(String path, String reason) {{
2225
+ {III}super(reason + " at: " + ("".equals(path) ? "the beginning" : path));
2226
+ {III}this.path = path;
2227
+ {III}this.reason = reason;
2228
+ {II}}}
2229
+
2230
+ {II}public Optional<String> getPath() {{
2231
+ {III}return Optional.ofNullable(path);
2232
+ {II}}}
2233
+
2234
+ {II}public Optional<String> getReason() {{
2235
+ {III}return Optional.ofNullable(reason);
2236
+ {II}}}
2237
+ {I}}}
2238
+
2239
+ {I}/**
2240
+ {I} * The XML namespace of the meta-model
2241
+ {I} */
2242
+ {I}public static final String AAS_NAME_SPACE =
2243
+ {II}{xml_namespace_literal};
2244
+
2245
+ {I}{indent_but_first_line(xml_result_class, I)}
2246
+
2247
+ {I}{indent_but_first_line(deserialize_impl_block, I)}
2248
+
2249
+ {I}{indent_but_first_line(deserialize_block, I)}
2250
+
2251
+ {I}{indent_but_first_line(visitor_block, I)}
2252
+
2253
+ {I}{indent_but_first_line(serialization_block, I)}
2254
+ }}"""
2255
+ ),
2256
+ ] # type: List[Stripped]
2257
+
2258
+ if len(errors) > 0:
2259
+ return None, errors
2260
+
2261
+ blocks = [
2262
+ java_common.WARNING,
2263
+ Stripped(f"package {package}.xmlization;"),
2264
+ Stripped("\n".join(imports)),
2265
+ Stripped("\n\n".join(xmlization_blocks)),
2266
+ java_common.WARNING,
2267
+ ] # type: List[Stripped]
2268
+
2269
+ code = "\n\n".join(blocks)
2270
+
2271
+ return f"{code}\n", None
2272
+
2273
+
2274
+ # endregion