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,2507 @@
1
+ """Generate the Golang code for XML-ization based on the intermediate representation."""
2
+
3
+ import io
4
+ from typing import Tuple, Optional, List
5
+
6
+ from icontract import ensure, require
7
+
8
+ from aas_core_codegen import intermediate, naming, specific_implementations
9
+ from aas_core_codegen.common import (
10
+ Error,
11
+ Stripped,
12
+ Identifier,
13
+ assert_never,
14
+ indent_but_first_line,
15
+ )
16
+ from aas_core_codegen.golang import (
17
+ common as golang_common,
18
+ naming as golang_naming,
19
+ pointering as golang_pointering,
20
+ )
21
+ from aas_core_codegen.golang.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
+
31
+ # region De-serialization
32
+
33
+
34
+ def _generate_deserialization_error_and_its_methods() -> List[Stripped]:
35
+ """Generate the code to represent the deserialization error."""
36
+ return [
37
+ Stripped(
38
+ f"""\
39
+ // Represent an error during the de-serialization.
40
+ //
41
+ // Implements `error`.
42
+ type DeserializationError struct{{
43
+ {I}Path *aasreporting.Path
44
+ {I}Message string
45
+ }}"""
46
+ ),
47
+ Stripped(
48
+ f"""\
49
+ func newDeserializationError(message string) *DeserializationError {{
50
+ {I}return &DeserializationError{{
51
+ {II}Path: &aasreporting.Path{{}},
52
+ {II}Message: message,
53
+ {I}}}
54
+ }}"""
55
+ ),
56
+ Stripped(
57
+ f"""\
58
+ func (de *DeserializationError) Error() string {{
59
+ {I}return fmt.Sprintf(
60
+ {II}"%s: %s",
61
+ {II}de.PathString(),
62
+ {II}de.Message,
63
+ {I})
64
+ }}"""
65
+ ),
66
+ Stripped(
67
+ f"""\
68
+ // Render the path as a string.
69
+ func (de *DeserializationError) PathString() string {{
70
+ {I}return aasreporting.ToRelativeXPath(de.Path)
71
+ }}"""
72
+ ),
73
+ ]
74
+
75
+
76
+ def _generate_is_whitespace() -> Stripped:
77
+ return Stripped(
78
+ f"""\
79
+ // Check if the string `s` consists only of whitespace.
80
+ //
81
+ // An empty string causes panic — please cover that case before.
82
+ func isWhitespace(s string) bool {{
83
+ {I}if len(s) == 0 {{
84
+ {II}panic("Unexpected empty string")
85
+ {I}}}
86
+ {I}for _, c := range s {{
87
+ {II}if !unicode.IsSpace(c) {{
88
+ {III}return false
89
+ {II}}}
90
+ {I}}}
91
+ {I}return true
92
+ }}"""
93
+ )
94
+
95
+
96
+ def _generate_read_next() -> Stripped:
97
+ return Stripped(
98
+ f"""\
99
+ // Read the next token from the `decoder` given the `current` token.
100
+ //
101
+ // If `current` token is [eof], return [eof].
102
+ func readNext(decoder *xml.Decoder, current xml.Token) (next xml.Token, err error) {{
103
+ {I}if _, isEOF := current.(eof); isEOF {{
104
+ {II}next = current
105
+ {II}return
106
+ {I}}}
107
+
108
+ {I}var tokenErr error
109
+ {I}next, tokenErr = decoder.Token()
110
+ {I}if tokenErr != nil {{
111
+ {II}if tokenErr == io.EOF {{
112
+ {III}next = &eof{{}}
113
+ {III}return
114
+ {II}}}
115
+
116
+ {II}err = tokenErr
117
+ {II}return
118
+ {I}}}
119
+
120
+ {I}return
121
+ }}"""
122
+ )
123
+
124
+
125
+ def _generate_skip_empty_text_whitespace_and_comments() -> Stripped:
126
+ return Stripped(
127
+ f"""\
128
+ // Read all the possible whitespace and comments.
129
+ //
130
+ // Return the `next` token which is neither empty text, nor whitespace nor comment,
131
+ // or [eof], if we reached the end-of-file.
132
+ //
133
+ // If we already reached the end-of-file, simply return [eof].
134
+ func skipEmptyTextWhitespaceAndComments(
135
+ {I}decoder *xml.Decoder,
136
+ {I}current xml.Token,
137
+ ) (next xml.Token, err error) {{
138
+ {I}stop := false
139
+ {I}for !stop {{
140
+ {II}if _, isEOF := current.(eof); isEOF {{
141
+ {III}break
142
+ {II}}}
143
+
144
+ {II}switch et := current.(type) {{
145
+ {II}case xml.CharData:
146
+ {III}text := string(et)
147
+ {III}if len(text) != 0 && !isWhitespace(text) {{
148
+ {IIII}stop = true
149
+ {III}}} else {{
150
+ {IIII}// We should proceed to the next token.
151
+ {III}}}
152
+ {II}case xml.Comment:
153
+ {III}// We should proceed to the next token.
154
+ {II}default:
155
+ {III}stop = true
156
+ {II}}}
157
+
158
+ {II}if !stop {{
159
+ {III}current, err = readNext(decoder, current)
160
+ {III}if err != nil {{
161
+ {IIII}return
162
+ {III}}}
163
+ {II}}}
164
+ {I}}}
165
+
166
+ {I}next = current
167
+ {I}return
168
+ }}"""
169
+ )
170
+
171
+
172
+ def _generate_read_text() -> Stripped:
173
+ return Stripped(
174
+ f"""\
175
+ // Consume the text tokens (char data).
176
+ //
177
+ // Any comment tokens are skipped.
178
+ //
179
+ // The resulting `next` token points to the first token which is neither text
180
+ // nor comment.
181
+ //
182
+ // If we reached the end-of-file, `next` is an [eof] sentinel token.
183
+ func readText(
184
+ {I}decoder *xml.Decoder,
185
+ {I}current xml.Token,
186
+ ) (text string, next xml.Token, err error) {{
187
+ {I}b := &strings.Builder{{}}
188
+
189
+ {I}stop := false
190
+ {I}for {{
191
+ {II}if _, isEOF := current.(eof); isEOF {{
192
+ {III}err = newDeserializationError(
193
+ {IIII}"Expected to read text, but reached the end-of-file",
194
+ {III})
195
+ {III}return
196
+ {II}}}
197
+
198
+ {II}switch et := current.(type) {{
199
+ {II}case xml.CharData:
200
+ {III}b.WriteString(string(et))
201
+ {III}// Proceed to the next token.
202
+ {II}case xml.Comment:
203
+ {III}// Proceed to the next token.
204
+ {II}default:
205
+ {III}stop = true
206
+ {II}}}
207
+
208
+ {II}if !stop {{
209
+ {III}current, err = readNext(decoder, current)
210
+ {III}if err != nil {{
211
+ {IIII}return
212
+ {III}}}
213
+ {II}}} else {{
214
+ {III}break
215
+ {II}}}
216
+ {I}}}
217
+
218
+ {I}next = current
219
+ {I}text = b.String()
220
+ {I}return
221
+ }}"""
222
+ )
223
+
224
+
225
+ def _generate_read_text_as_boolean() -> Stripped:
226
+ return Stripped(
227
+ f"""\
228
+ // Consume the text tokens (char data) as a representation of a `xs:boolean`.
229
+ //
230
+ // Any comment tokens are skipped.
231
+ //
232
+ // The resulting `next` token points to the first token which is neither text
233
+ // nor comment.
234
+ //
235
+ // If we reached the end-of-file, `next` is an [eof] sentinel token.
236
+ func readTextAsBoolean(
237
+ {I}decoder *xml.Decoder,
238
+ {I}current xml.Token,
239
+ ) (value bool, next xml.Token, err error) {{
240
+ {I}var text string
241
+ {I}text, next, err = readText(decoder, current)
242
+ {I}if err != nil {{
243
+ {II}return
244
+ {I}}}
245
+
246
+ {I}switch text {{
247
+ {I}case "1":
248
+ {II}value = true
249
+ {I}case "true":
250
+ {II}value = true
251
+ {I}case "0":
252
+ {II}value = false
253
+ {I}case "false":
254
+ {II}value = false
255
+ {I}default:
256
+ {II}err = newDeserializationError(
257
+ {III}fmt.Sprintf(
258
+ {IIII}"Expected a value as xs:boolean, but got: %s",
259
+ {IIII}text,
260
+ {III}),
261
+ {II})
262
+ {I}}}
263
+ {I}if err != nil {{
264
+ {II}return
265
+ {I}}}
266
+
267
+ {I}return
268
+ }}"""
269
+ )
270
+
271
+
272
+ def _generate_read_text_as_long() -> Stripped:
273
+ return Stripped(
274
+ f"""\
275
+ // Consume the text tokens (char data) as a representation of a `xs:long`.
276
+ //
277
+ // Any comment tokens are skipped.
278
+ //
279
+ // The resulting `next` token points to the first token which is neither text
280
+ // nor comment.
281
+ //
282
+ // If we reached the end-of-file, `next` is an [eof] sentinel token.
283
+ func readTextAsLong(
284
+ {I}decoder *xml.Decoder,
285
+ {I}current xml.Token,
286
+ ) (value int64, next xml.Token, err error) {{
287
+ {I}var text string
288
+ {I}text, next, err = readText(decoder, current)
289
+ {I}if err != nil {{
290
+ {II}return
291
+ {I}}}
292
+
293
+ {I}value, err = strconv.ParseInt(text, 10, 64)
294
+
295
+ {I}return
296
+ }}"""
297
+ )
298
+
299
+
300
+ def _generate_read_text_as_double() -> Stripped:
301
+ return Stripped(
302
+ f"""\
303
+ // Consume the text tokens (char data) as a representation of a `xs:double`.
304
+ //
305
+ // Any comment tokens are skipped.
306
+ //
307
+ // The resulting `next` token points to the first token which is neither text
308
+ // nor comment.
309
+ //
310
+ // If we reached the end-of-file, `next` is an [eof] sentinel token.
311
+ func readTextAsDouble(
312
+ {I}decoder *xml.Decoder,
313
+ {I}current xml.Token,
314
+ ) (value float64, next xml.Token, err error) {{
315
+ {I}var text string
316
+ {I}text, next, err = readText(decoder, current)
317
+ {I}if err != nil {{
318
+ {II}return
319
+ {I}}}
320
+
321
+ {I}// We need to check explicitly for the regular expression since
322
+ {I}// strconv.ParseFloat is too permissive. For example, it accepts "nan"
323
+ {I}// although only "NaN" is valid.
324
+ {I}// See: https://www.w3.org/TR/xmlschema-2/#double
325
+ {I}if !aasverification.MatchesXsDouble(text) {{
326
+ {II}err = newDeserializationError(
327
+ {III}fmt.Sprintf(
328
+ {IIII}"Expected a value as xs:double, but got: %s",
329
+ {IIII}text,
330
+ {III}),
331
+ {II})
332
+ {II}return
333
+ {I}}}
334
+
335
+ {I}var parseErr error
336
+ {I}value, parseErr = strconv.ParseFloat(text, 64)
337
+ {I}if parseErr != nil {{
338
+ {II}err = newDeserializationError(
339
+ {III}fmt.Sprintf(
340
+ {IIII}"Expected a value as xs:double, but it could not be parsed: %s: %s",
341
+ {IIII}parseErr.Error(), text,
342
+ {III}),
343
+ {II})
344
+ {II}return
345
+ {I}}}
346
+
347
+ {I}// NOTE (2023-06-14):
348
+ {I}// We explicitly do not check for loss of precision, as the majority of people will
349
+ {I}// use string representation of the floating point numbers ignoring the precision
350
+ {I}// issues. For example, the closest double-precision number to the number `359.9` is
351
+ {I}// `359.8999999999999772626324556767940521240234375`, but most people will simply
352
+ {I}// give `359.9` as the value.
353
+
354
+ {I}return
355
+ }}"""
356
+ )
357
+
358
+
359
+ def _generate_read_text_as_base64_encoded_bytes() -> Stripped:
360
+ return Stripped(
361
+ f"""\
362
+ // Consume the text tokens (char data) as a base64-encoded bytes.
363
+ //
364
+ // Any comment tokens are skipped.
365
+ //
366
+ // The resulting `next` token points to the first token which is neither text
367
+ // nor comment.
368
+ //
369
+ // If we reached the end-of-file, `next` is an [eof] sentinel token.
370
+ func readTextAsBase64EncodedBytes(
371
+ {I}decoder *xml.Decoder,
372
+ {I}current xml.Token,
373
+ ) (value []byte, next xml.Token, err error) {{
374
+ {I}var text string
375
+ {I}text, next, err = readText(decoder, current)
376
+ {I}if err != nil {{
377
+ {II}return
378
+ {I}}}
379
+
380
+ {I}var decodingErr error
381
+ {I}value, decodingErr = b64.StdEncoding.DecodeString(text)
382
+ {I}if decodingErr != nil {{
383
+ {II}err = newDeserializationError(
384
+ {III}fmt.Sprintf(
385
+ {IIII}"Text could not be decoded as base64: %s",
386
+ {IIII}decodingErr.Error(),
387
+ {III}),
388
+ {II})
389
+ {II}return
390
+ {I}}}
391
+
392
+ {I}return
393
+ }}"""
394
+ )
395
+
396
+
397
+ def _generate_check_start_element() -> Stripped:
398
+ return Stripped(
399
+ f"""\
400
+ // Check that the `current` token is a valid start element, *i.e.*, lives in [Namespace]
401
+ // and contains no attributes.
402
+ func checkStartElement(
403
+ {I}current xml.StartElement,
404
+ ) (err error) {{
405
+ {I}const xmlnsLen = len("xmlns")
406
+
407
+ {I}unexpectedAttr := 0
408
+ {I}for _, attr := range current.Attr {{
409
+ {II}if (attr.Name.Space == "" && attr.Name.Local == "xmlns") ||
410
+ {III}attr.Name.Space == "xmlns" {{
411
+ {III}continue
412
+ {II}}}
413
+
414
+ {II}unexpectedAttr++
415
+ {I}}}
416
+ {I}if unexpectedAttr != 0 {{
417
+ {II}err = newDeserializationError(
418
+ {III}fmt.Sprintf(
419
+ {IIII}"Expected no attributes except 'xmlns' in the start element, "+
420
+ {IIIII}"but got %d in the start element %s",
421
+ {IIII}unexpectedAttr, current.Name.Local,
422
+ {III}),
423
+ {II})
424
+ {II}return
425
+ {I}}}
426
+
427
+ {I}if current.Name.Space != Namespace {{
428
+ {II}err = newDeserializationError(
429
+ {III}fmt.Sprintf(
430
+ {IIII}"Expected only start elements in the namespace %s, "+
431
+ {IIIII}"but got a start element %s in the namespace %s",
432
+ {IIII}Namespace, current.Name.Local, current.Name.Space,
433
+ {III}),
434
+ {II})
435
+ {II}return
436
+ {I}}}
437
+
438
+ {I}return
439
+ }}"""
440
+ )
441
+
442
+
443
+ def _generate_extract_local_name_from_start_element() -> Stripped:
444
+ return Stripped(
445
+ f"""\
446
+ // Expect a valid start element (as defined in [checkStartElement]) and extract its
447
+ // `local` name.
448
+ //
449
+ // This function is meant to be called whenever you know the runtime type of a token.
450
+ // If you do not know the runtime type, call [parseAsStartElementAndExtractLocalName]
451
+ // so that you can succinctly check the runtime type as well.
452
+ func extractLocalNameFromStartElement(
453
+ {I}current xml.StartElement,
454
+ ) (local string, err error) {{
455
+ {I}err = checkStartElement(current)
456
+ {I}if err != nil {{
457
+ {II}return
458
+ {I}}}
459
+
460
+ {I}local = current.Name.Local
461
+ {I}return
462
+ }}"""
463
+ )
464
+
465
+
466
+ def _generate_parse_as_start_element_and_extract_local_name() -> Stripped:
467
+ return Stripped(
468
+ f"""\
469
+ // Expect a valid start element (as defined in [checkStartElement]) and extract its
470
+ // local name.
471
+ //
472
+ // Valid means that we check that the start element lives in [Namespace] and contains
473
+ // no attributes.
474
+ //
475
+ // If you know the runtime type of `current` token, call
476
+ // [parseLocalNameFromStartElement] instead to save a cast.
477
+ func parseAsStartElementAndExtractLocalName(
478
+ {I}current xml.Token,
479
+ ) (local string, err error) {{
480
+ {I}if _, isEOF := current.(eof); isEOF {{
481
+ {II}err = newDeserializationError(
482
+ {III}"Expected a start element, but reached the end-of-file",
483
+ {II})
484
+ {II}return
485
+ {I}}}
486
+
487
+ {I}et, ok := current.(xml.StartElement)
488
+ {I}if !ok {{
489
+ {II}switch v := current.(type) {{
490
+ {II}case xml.EndElement:
491
+ {III}err = newDeserializationError(
492
+ {IIII}fmt.Sprintf(
493
+ {IIIII}"Expected a start element, but got an end element %s in namespace %s",
494
+ {IIIII}v.Name.Local, v.Name.Space,
495
+ {IIII}),
496
+ {III})
497
+ {II}case xml.CharData:
498
+ {III}err = newDeserializationError(
499
+ {IIII}fmt.Sprintf(
500
+ {IIIII}"Expected a start element, but got text %s",
501
+ {IIIII}string(v),
502
+ {IIII}),
503
+ {III})
504
+ {II}default:
505
+ {III}err = newDeserializationError(
506
+ {IIII}fmt.Sprintf(
507
+ {IIIII}"Expected a start element, but got %T: %v",
508
+ {IIIII}current, current,
509
+ {IIII}),
510
+ {III})
511
+ {II}}}
512
+ {II}return
513
+ {I}}}
514
+
515
+ {I}local, err = extractLocalNameFromStartElement(et)
516
+ {I}return
517
+ }}"""
518
+ )
519
+
520
+
521
+ def _generate_check_end_element() -> Stripped:
522
+ return Stripped(
523
+ f"""\
524
+ // Check that the `current` token is an end element, living in [Namespace], and
525
+ // having the `local` name.
526
+ func checkEndElement(current xml.Token, local string) (err error) {{
527
+ {I}if _, isEOF := current.(eof); isEOF {{
528
+ {II}err = newDeserializationError(
529
+ {III}fmt.Sprintf(
530
+ {IIII}"Expected an end element %s, but reached the end-of-file",
531
+ {IIII}local,
532
+ {III}),
533
+ {II})
534
+ {II}return
535
+ {I}}}
536
+
537
+ {I}et, ok := current.(xml.EndElement)
538
+ {I}if !ok {{
539
+ {II}switch v := current.(type) {{
540
+ {II}case xml.StartElement:
541
+ {III}err = newDeserializationError(
542
+ {IIII}fmt.Sprintf(
543
+ {IIIII}"Expected an end element %s, but got a start element %s in namespace %s",
544
+ {IIIII}local, v.Name.Local, v.Name.Space,
545
+ {IIII}),
546
+ {III})
547
+ {II}case xml.CharData:
548
+ {III}err = newDeserializationError(
549
+ {IIII}fmt.Sprintf(
550
+ {IIIII}"Expected an end element %s, but got text %s",
551
+ {IIIII}local, string(v),
552
+ {IIII}),
553
+ {III})
554
+ {II}default:
555
+ {III}err = newDeserializationError(
556
+ {IIII}fmt.Sprintf(
557
+ {IIIII}"Expected an end element %s, but got %T: %v",
558
+ {IIIII}local, current, current,
559
+ {IIII}),
560
+ {III})
561
+ {II}}}
562
+ {II}return
563
+ {I}}}
564
+
565
+ {I}if et.Name.Space != Namespace {{
566
+ {II}err = newDeserializationError(
567
+ {III}fmt.Sprintf(
568
+ {IIII}"Expected an end element %s in the namespace %s, "+
569
+ {IIIII}"but got an end element in the namespace %s",
570
+ {IIII}local, Namespace, et.Name.Space,
571
+ {III}),
572
+ {II})
573
+ {II}return
574
+ {I}}}
575
+
576
+ {I}if et.Name.Local != local {{
577
+ {II}err = newDeserializationError(
578
+ {III}fmt.Sprintf(
579
+ {IIII}"Expected an end element %s, but got an end element %s",
580
+ {IIII}local, et.Name.Local,
581
+ {III}),
582
+ {II})
583
+ {II}return
584
+ {I}}}
585
+
586
+ {I}return
587
+ }}"""
588
+ )
589
+
590
+
591
+ def _generate_read_list() -> Stripped:
592
+ return Stripped(
593
+ f"""\
594
+ // Read a list of AAS instances as a sequence of XML elements.
595
+ //
596
+ // Every start element is considered to mark the start of an instance serialization. We
597
+ // stop the reading as soon as we encounter a non-start element.
598
+ //
599
+ // That last non-start element is returned as `next` element.
600
+ func readList[T aastypes.IClass](
601
+ {I}decoder *xml.Decoder,
602
+ {I}current xml.Token,
603
+ {I}readTWithLookahead func(
604
+ {II}aDecoder *xml.Decoder,
605
+ {II}aCurrent xml.Token,
606
+ {I}) (anInstance T, anErr error),
607
+ ) (instances []T, next xml.Token, err error) {{
608
+ {I}i := 0
609
+ {I}for {{
610
+ {II}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
611
+ {II}if err != nil {{
612
+ {III}return
613
+ {II}}}
614
+
615
+ {II}if _, ok := current.(xml.StartElement); !ok {{
616
+ {III}break
617
+ {II}}}
618
+
619
+ {II}var instance T
620
+ {II}var instanceErr error
621
+ {II}instance, instanceErr = readTWithLookahead(decoder, current)
622
+ {II}if instanceErr != nil {{
623
+ {III}if deseriaErr, ok := instanceErr.(*DeserializationError); ok {{
624
+ {IIII}deseriaErr.Path.PrependIndex(
625
+ {IIIII}&aasreporting.IndexSegment{{Index: i}},
626
+ {IIII})
627
+ {III}}}
628
+ {III}err = instanceErr
629
+ {III}return
630
+ {II}}}
631
+
632
+ {II}instances = append(instances, instance)
633
+
634
+ {II}i++
635
+
636
+ {II}current, err = readNext(decoder, nil)
637
+ {II}if err != nil {{
638
+ {III}return
639
+ {II}}}
640
+ {I}}}
641
+
642
+ {I}next = current
643
+ {I}return
644
+ }}"""
645
+ )
646
+
647
+
648
+ def _generate_read_text_as_enumeration(
649
+ enumeration: intermediate.Enumeration,
650
+ ) -> Stripped:
651
+ enum_name = golang_naming.enum_name(enumeration.name)
652
+ from_string_name = golang_naming.function_name(
653
+ Identifier(f"{enumeration.name}_from_string")
654
+ )
655
+
656
+ function_name = golang_naming.private_function_name(
657
+ Identifier(f"read_text_as_{enumeration.name}")
658
+ )
659
+
660
+ return Stripped(
661
+ f"""\
662
+ // Consume the text tokens (char data) as a string-encoded literal of
663
+ // [aastypes.{enum_name}].
664
+ //
665
+ // Any comment tokens are skipped.
666
+ //
667
+ // The resulting `next` token points to the first token which is neither text
668
+ // nor comment.
669
+ //
670
+ // If we reached the end-of-file, `next` is an [eof] sentinel token.
671
+ func {function_name}(
672
+ {I}decoder *xml.Decoder,
673
+ {I}current xml.Token,
674
+ ) (value aastypes.{enum_name},
675
+ {I}next xml.Token,
676
+ {I}err error,
677
+ ) {{
678
+ {I}var text string
679
+ {I}text, next, err = readText(decoder, current)
680
+ {I}if err != nil {{
681
+ {II}return
682
+ {I}}}
683
+
684
+ {I}var ok bool
685
+ {I}value, ok = aasstringification.{from_string_name}(text)
686
+ {I}if !ok {{
687
+ {II}err = newDeserializationError(
688
+ {III}fmt.Sprintf(
689
+ {IIII}"Unexpected literal of {enum_name}: %v",
690
+ {IIII}text,
691
+ {III}),
692
+ {II})
693
+ {II}return
694
+ {I}}}
695
+
696
+ {I}return
697
+ }}"""
698
+ )
699
+
700
+
701
+ _READ_FUNCTION_BY_PRIMITIVE_TYPE = {
702
+ intermediate.PrimitiveType.BOOL: "readTextAsBoolean",
703
+ intermediate.PrimitiveType.INT: "readTextAsLong",
704
+ intermediate.PrimitiveType.FLOAT: "readTextAsDouble",
705
+ intermediate.PrimitiveType.STR: "readText",
706
+ intermediate.PrimitiveType.BYTEARRAY: "readTextAsBase64EncodedBytes",
707
+ }
708
+ assert all(
709
+ literal in _READ_FUNCTION_BY_PRIMITIVE_TYPE
710
+ for literal in intermediate.PrimitiveType
711
+ )
712
+
713
+
714
+ def _generate_snippet_to_switch_on_property_deserialization(
715
+ cls: intermediate.ConcreteClass,
716
+ ) -> Stripped:
717
+ """
718
+ Generate the switch block to dispatch how to read a property.
719
+
720
+ The start element is expected to have been read. The variable ``local`` denotes
721
+ the local name of the start element.
722
+
723
+ The decoder points to the first token of the property content.
724
+
725
+ The variables ``the*`` and ``found*`` will be set as well as ``valueErr``.
726
+ """
727
+ case_blocks = [] # type: List[Stripped]
728
+
729
+ for prop in cls.properties:
730
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
731
+
732
+ prop_var = golang_naming.variable_name(Identifier(f"the_{prop.name}"))
733
+
734
+ xml_prop_literal = golang_common.string_literal(naming.xml_property(prop.name))
735
+
736
+ case_body_blocks = [] # type: List[Stripped]
737
+
738
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation) or (
739
+ isinstance(type_anno, intermediate.OurTypeAnnotation)
740
+ and isinstance(
741
+ type_anno.our_type,
742
+ (intermediate.ConstrainedPrimitive, intermediate.Enumeration),
743
+ )
744
+ ):
745
+ primitive_type = intermediate.try_primitive_type(type_anno)
746
+
747
+ if primitive_type is not None:
748
+ read_function = _READ_FUNCTION_BY_PRIMITIVE_TYPE[primitive_type]
749
+ else:
750
+ assert isinstance(
751
+ type_anno, intermediate.OurTypeAnnotation
752
+ ) and isinstance(type_anno.our_type, intermediate.Enumeration)
753
+
754
+ read_function = golang_naming.private_function_name(
755
+ Identifier(f"read_text_as_{type_anno.our_type.name}")
756
+ )
757
+
758
+ pointer = golang_pointering.is_pointer_type(prop.type_annotation)
759
+
760
+ if pointer:
761
+ # NOTE (mristin, 2023-06-17):
762
+ # We explicitly pass in ``type_anno`` to the type as the read function
763
+ # will return a non-optional.
764
+ value_type = golang_common.generate_type(
765
+ type_annotation=type_anno, types_package=Identifier("aastypes")
766
+ )
767
+
768
+ case_body_blocks.append(
769
+ Stripped(
770
+ f"""\
771
+ var value {value_type}
772
+ value, current, valueErr = {read_function}(
773
+ {I}decoder,
774
+ {I}current,
775
+ )
776
+ {prop_var} = &value"""
777
+ )
778
+ )
779
+ else:
780
+ case_body_blocks.append(
781
+ Stripped(
782
+ f"""\
783
+ {prop_var}, current, valueErr = {read_function}(
784
+ {I}decoder,
785
+ {I}current,
786
+ )"""
787
+ )
788
+ )
789
+
790
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
791
+ our_type = type_anno.our_type
792
+
793
+ if isinstance(our_type, intermediate.Enumeration):
794
+ raise AssertionError("Must have been handled before")
795
+
796
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
797
+ raise AssertionError("Must have been handled before")
798
+
799
+ elif isinstance(
800
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
801
+ ):
802
+ if (
803
+ isinstance(our_type, intermediate.ConcreteClass)
804
+ and len(our_type.concrete_descendants) == 0
805
+ ):
806
+ read_function = golang_naming.private_function_name(
807
+ Identifier(f"read_{type_anno.our_type.name}_as_sequence")
808
+ )
809
+
810
+ case_body_blocks.append(
811
+ Stripped(
812
+ f"""\
813
+ {prop_var}, current, valueErr = {read_function}(
814
+ {I}decoder,
815
+ {I}current,
816
+ )"""
817
+ )
818
+ )
819
+
820
+ else:
821
+ read_with_lookahead_function = golang_naming.private_function_name(
822
+ Identifier(f"read_{type_anno.our_type.name}_with_lookahead")
823
+ )
824
+
825
+ case_body_blocks.append(
826
+ Stripped(
827
+ f"""\
828
+ {prop_var}, valueErr = {read_with_lookahead_function}(
829
+ {I}decoder,
830
+ {I}current,
831
+ )
832
+ // {read_with_lookahead_function} stops at the end element,
833
+ // so we look ahead to the next element, just after the end element.
834
+ if valueErr == nil {{
835
+ {I}current, valueErr = readNext(decoder, current)
836
+ }}"""
837
+ )
838
+ )
839
+
840
+ else:
841
+ assert_never(our_type)
842
+
843
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
844
+ assert isinstance(
845
+ type_anno.items, intermediate.OurTypeAnnotation
846
+ ) and isinstance(
847
+ type_anno.items.our_type,
848
+ (intermediate.AbstractClass, intermediate.ConcreteClass),
849
+ ), (
850
+ f"NOTE (mristin, 2023-03-29): We expect only lists of classes "
851
+ f"at the moment, but you specified {type_anno}. "
852
+ f"Please contact the developers if you need this feature."
853
+ )
854
+
855
+ read_item_function = golang_naming.private_function_name(
856
+ Identifier(f"read_{type_anno.items.our_type.name}_with_lookahead")
857
+ )
858
+
859
+ case_body_blocks.append(
860
+ Stripped(
861
+ f"""\
862
+ {prop_var}, current, valueErr = readList(
863
+ {I}decoder,
864
+ {I}current,
865
+ {I}{read_item_function},
866
+ )"""
867
+ )
868
+ )
869
+ else:
870
+ assert_never(type_anno)
871
+
872
+ assert len(case_body_blocks) > 0
873
+
874
+ if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
875
+ found_var = golang_naming.variable_name(Identifier(f"found_{prop.name}"))
876
+ case_body_blocks.append(Stripped(f"{found_var} = true"))
877
+
878
+ case_body = "\n".join(case_body_blocks)
879
+ case_blocks.append(
880
+ Stripped(
881
+ f"""\
882
+ case {xml_prop_literal}:
883
+ {I}{indent_but_first_line(case_body, I)}"""
884
+ )
885
+ )
886
+
887
+ case_blocks.append(
888
+ Stripped(
889
+ f"""\
890
+ default:
891
+ {I}valueErr = newDeserializationError(
892
+ {II}fmt.Sprintf(
893
+ {III}"Unexpected property",
894
+ {II}),
895
+ {I})"""
896
+ )
897
+ )
898
+
899
+ case_blocks_joined = "\n\n".join(case_blocks)
900
+
901
+ return Stripped(
902
+ f"""\
903
+ var valueErr error
904
+ switch local {{
905
+ {case_blocks_joined}
906
+ }}"""
907
+ )
908
+
909
+
910
+ def _generate_read_as_sequence(cls: intermediate.ConcreteClass) -> Stripped:
911
+ interface_name = golang_naming.interface_name(cls.name)
912
+
913
+ # region Initialize
914
+
915
+ initialization_blocks = [] # type: List[Stripped]
916
+
917
+ prop_var_initializations = [] # type: List[Stripped]
918
+ for prop in cls.properties:
919
+ prop_var = golang_naming.variable_name(Identifier(f"the_{prop.name}"))
920
+
921
+ prop_var_type = golang_common.generate_type(
922
+ type_annotation=prop.type_annotation, types_package=Identifier("aastypes")
923
+ )
924
+
925
+ prop_var_initializations.append(Stripped(f"var {prop_var} {prop_var_type}"))
926
+
927
+ if len(prop_var_initializations) > 0:
928
+ initialization_blocks.append(Stripped("\n".join(prop_var_initializations)))
929
+
930
+ found_var_initializations = [] # type: List[Stripped]
931
+ for prop in cls.properties:
932
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
933
+ continue
934
+
935
+ found_var = golang_naming.variable_name(Identifier(f"found_{prop.name}"))
936
+
937
+ found_var_initializations.append(Stripped(f"{found_var} := false"))
938
+
939
+ if len(found_var_initializations) > 0:
940
+ initialization_blocks.append(Stripped("\n".join(found_var_initializations)))
941
+
942
+ if len(initialization_blocks) == 0:
943
+ initialization_blocks.append(
944
+ Stripped(
945
+ f"""\
946
+ // No initialization as there are no properties
947
+ // in {interface_name}."""
948
+ )
949
+ )
950
+
951
+ initialization = "\n\n".join(initialization_blocks)
952
+
953
+ # endregion
954
+
955
+ switch_snippet = _generate_snippet_to_switch_on_property_deserialization(cls=cls)
956
+
957
+ # region Construct
958
+
959
+ construct_blocks = [] # type: List[Stripped]
960
+
961
+ for prop in cls.properties:
962
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
963
+ continue
964
+
965
+ found_var = golang_naming.variable_name(Identifier(f"found_{prop.name}"))
966
+
967
+ message_literal = golang_common.string_literal(
968
+ f"The required property {naming.json_property(prop.name)!r} is missing"
969
+ )
970
+
971
+ construct_blocks.append(
972
+ Stripped(
973
+ f"""\
974
+ if !{found_var} {{
975
+ {I}err = newDeserializationError(
976
+ {II}{message_literal},
977
+ {I})
978
+ {I}return
979
+ }}"""
980
+ )
981
+ )
982
+
983
+ constructing_statements = [] # type: List[Stripped]
984
+
985
+ constructor_arguments = [
986
+ golang_naming.variable_name(Identifier(f"the_{arg.name}"))
987
+ for arg in cls.constructor.arguments
988
+ if not isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation)
989
+ ] # type: List[Stripped]
990
+
991
+ new_function = golang_naming.function_name(Identifier(f"new_{cls.name}"))
992
+
993
+ if len(constructor_arguments) > 0:
994
+ constructor_arguments_joined = "\n".join(
995
+ f"{arg}," for arg in constructor_arguments
996
+ )
997
+
998
+ constructing_statements.append(
999
+ Stripped(
1000
+ f"""\
1001
+ instance = aastypes.{new_function}(
1002
+ {I}{indent_but_first_line(constructor_arguments_joined, I)}
1003
+ )"""
1004
+ )
1005
+ )
1006
+ else:
1007
+ constructing_statements.append(
1008
+ Stripped(f"instance = aastypes.{new_function}()")
1009
+ )
1010
+
1011
+ for arg in cls.constructor.arguments:
1012
+ if not isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation):
1013
+ continue
1014
+
1015
+ setter_name = golang_naming.setter_name(arg.name)
1016
+ prop_var = golang_naming.variable_name(Identifier(f"the_{arg.name}"))
1017
+
1018
+ constructing_statements.append(
1019
+ Stripped(
1020
+ f"""\
1021
+ instance.{setter_name}(
1022
+ {I}{prop_var},
1023
+ )"""
1024
+ )
1025
+ )
1026
+
1027
+ construct_blocks.append(Stripped("\n".join(constructing_statements)))
1028
+
1029
+ construct = "\n\n".join(construct_blocks)
1030
+
1031
+ # endregion
1032
+
1033
+ function_name = golang_naming.private_function_name(
1034
+ Identifier(f"read_{cls.name}_as_sequence")
1035
+ )
1036
+
1037
+ return Stripped(
1038
+ f"""\
1039
+ // De-serialize the instance of [aastypes.{interface_name}]
1040
+ // as a sequence of XML elements, each representing a property
1041
+ // of [aastypes.{interface_name}].
1042
+ //
1043
+ // The reading stops as soon as we encounter a non-start element, and we return
1044
+ // that token as the `next` token.
1045
+ func {function_name}(
1046
+ {I}decoder *xml.Decoder,
1047
+ {I}current xml.Token,
1048
+ ) (instance aastypes.{interface_name},
1049
+ {I}next xml.Token,
1050
+ {I}err error,
1051
+ ) {{
1052
+ {I}{indent_but_first_line(initialization, I)}
1053
+
1054
+ {I}for {{
1055
+ {II}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
1056
+ {II}if err != nil {{
1057
+ {III}return
1058
+ {II}}}
1059
+
1060
+ {II}if _, isEOF := current.(eof); isEOF {{
1061
+ {III}break
1062
+ {II}}}
1063
+
1064
+ {II}startElement, ok := current.(xml.StartElement)
1065
+ {II}if !ok {{
1066
+ {III}if charData, isCharData := current.(xml.CharData); isCharData {{
1067
+ {IIII}err = newDeserializationError(
1068
+ {IIIII}fmt.Sprintf(
1069
+ {IIIIII}"Expected a sequence of XML elements representing properties "+
1070
+ {IIIIII}"of {interface_name}, but got text: %s",
1071
+ {IIIIII}string(charData),
1072
+ {IIIII}),
1073
+ {IIII})
1074
+ {IIII}return
1075
+ {III}}}
1076
+
1077
+ {III}break
1078
+ {II}}}
1079
+
1080
+ {II}var local string
1081
+ {II}local, err = extractLocalNameFromStartElement(startElement)
1082
+ {II}if err != nil {{
1083
+ {III}return
1084
+ {II}}}
1085
+
1086
+ {II}// Move the current to the content of the XML element
1087
+ {II}current, err = readNext(decoder, nil)
1088
+ {II}if err != nil {{
1089
+ {III}return
1090
+ {II}}}
1091
+
1092
+ {II}{indent_but_first_line(switch_snippet, II)}
1093
+
1094
+ {II}if valueErr != nil {{
1095
+ {III}if deseriaErr, ok := valueErr.(*DeserializationError); ok {{
1096
+ {IIII}deseriaErr.Path.PrependName(
1097
+ {IIIII}&aasreporting.NameSegment{{Name: local}},
1098
+ {IIII})
1099
+ {III}}}
1100
+ {III}err = valueErr
1101
+ {II}}}
1102
+
1103
+ {II}if err != nil {{
1104
+ {III}return
1105
+ {II}}}
1106
+
1107
+ {II}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
1108
+ {II}if err != nil {{
1109
+ {III}return
1110
+ {II}}}
1111
+
1112
+ {II}err = checkEndElement(current, local)
1113
+ {II}if err != nil {{
1114
+ {III}return
1115
+ {II}}}
1116
+
1117
+ {II}current, err = readNext(decoder, current)
1118
+ {II}if err != nil {{
1119
+ {III}return
1120
+ {II}}}
1121
+ {I}}}
1122
+
1123
+ {I}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
1124
+ {I}if err != nil {{
1125
+ {II}return
1126
+ {I}}}
1127
+
1128
+ {I}next = current
1129
+
1130
+ {I}{indent_but_first_line(construct, I)}
1131
+ {I}return
1132
+ }}"""
1133
+ )
1134
+
1135
+
1136
+ def _generate_read_with_lookahead_without_dispatch(
1137
+ cls: intermediate.ConcreteClass,
1138
+ ) -> Stripped:
1139
+ interface_name = golang_naming.interface_name(cls.name)
1140
+ function_name = golang_naming.private_function_name(
1141
+ Identifier(f"read_{cls.name}_with_lookahead")
1142
+ )
1143
+
1144
+ xml_class_name_literal = golang_common.string_literal(
1145
+ naming.xml_class_name(cls.name)
1146
+ )
1147
+
1148
+ read_as_sequence_name = golang_naming.private_function_name(
1149
+ Identifier(f"read_{cls.name}_as_sequence")
1150
+ )
1151
+
1152
+ return Stripped(
1153
+ f"""\
1154
+ // De-serialize an instance of [aastypes.{interface_name}]
1155
+ // as an XML element where the start element is expected to have been already
1156
+ // read as `current` token.
1157
+ //
1158
+ // The de-serialization stops by consuming the final end element. The next call to
1159
+ // the `decoder.Token()` will return the element just after the end element.
1160
+ func {function_name}(
1161
+ {I}decoder *xml.Decoder,
1162
+ {I}current xml.Token,
1163
+ ) (instance aastypes.{interface_name},
1164
+ {I}err error,
1165
+ ) {{
1166
+ {I}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
1167
+ {I}if err != nil {{
1168
+ {II}return
1169
+ {I}}}
1170
+
1171
+ {I}var local string
1172
+ {I}local, err = parseAsStartElementAndExtractLocalName(
1173
+ {II}current,
1174
+ {I})
1175
+ {I}if err != nil {{
1176
+ {II}return
1177
+ {I}}}
1178
+
1179
+ {I}expectedLocal := {xml_class_name_literal}
1180
+ {I}if local != expectedLocal {{
1181
+ {II}err = newDeserializationError(
1182
+ {III}fmt.Sprintf(
1183
+ {IIII}"Expected a start element with local name %s, "+
1184
+ {IIIII}"but got a start element with local name %s",
1185
+ {IIII}expectedLocal, local,
1186
+ {III}),
1187
+ {II})
1188
+ {II}return
1189
+ {I}}}
1190
+
1191
+ {I}current, err = readNext(decoder, current)
1192
+ {I}if err != nil {{
1193
+ {II}return
1194
+ {I}}}
1195
+
1196
+ {I}instance, current, err = {read_as_sequence_name}(
1197
+ {II}decoder,
1198
+ {II}current,
1199
+ )
1200
+ {I}if err != nil {{
1201
+ {II}return
1202
+ {I}}}
1203
+
1204
+ {I}err = checkEndElement(current, local)
1205
+ {I}return
1206
+ }}"""
1207
+ )
1208
+
1209
+
1210
+ @require(
1211
+ lambda cls: len(cls.concrete_descendants) > 0,
1212
+ "The class must have one or more concrete descendants; "
1213
+ "otherwise the dispatch makes no sense",
1214
+ )
1215
+ def _generate_read_with_lookahead_with_dispatch(
1216
+ cls: intermediate.ClassUnion,
1217
+ ) -> Stripped:
1218
+ interface_name = golang_naming.interface_name(cls.name)
1219
+ function_name = golang_naming.private_function_name(
1220
+ Identifier(f"read_{cls.name}_with_lookahead")
1221
+ )
1222
+
1223
+ case_blocks = [] # type: List[Stripped]
1224
+
1225
+ for descendant_cls in cls.concrete_descendants:
1226
+ xml_class_name_literal = golang_common.string_literal(
1227
+ naming.xml_class_name(descendant_cls.name)
1228
+ )
1229
+ read_as_sequence = golang_naming.private_function_name(
1230
+ Identifier(f"read_{descendant_cls.name}_as_sequence")
1231
+ )
1232
+ case_blocks.append(
1233
+ Stripped(
1234
+ f"""\
1235
+ case {xml_class_name_literal}:
1236
+ {I}instance, current, err = {read_as_sequence}(
1237
+ {II}decoder, current,
1238
+ {I})"""
1239
+ )
1240
+ )
1241
+
1242
+ if isinstance(cls, intermediate.ConcreteClass):
1243
+ xml_class_name_literal = golang_common.string_literal(
1244
+ naming.xml_class_name(cls.name)
1245
+ )
1246
+ read_as_sequence = golang_naming.private_function_name(
1247
+ Identifier(f"read_{cls.name}_as_sequence")
1248
+ )
1249
+ case_blocks.append(
1250
+ Stripped(
1251
+ f"""\
1252
+ case {xml_class_name_literal}:
1253
+ {I}instance, current, err = {read_as_sequence}(
1254
+ {II}decoder, current,
1255
+ {I})"""
1256
+ )
1257
+ )
1258
+
1259
+ case_blocks.append(
1260
+ Stripped(
1261
+ f"""\
1262
+ default:
1263
+ {I}err = newDeserializationError(
1264
+ {II}fmt.Sprintf(
1265
+ {III}"Unexpected start element %s as discriminator "+
1266
+ {IIII}"for {interface_name}",
1267
+ {III}local,
1268
+ {II}),
1269
+ {I})"""
1270
+ )
1271
+ )
1272
+
1273
+ case_blocks_joined = "\n".join(case_blocks)
1274
+
1275
+ switch_stmt = Stripped(
1276
+ f"""\
1277
+ switch local {{
1278
+ {case_blocks_joined}
1279
+ }}"""
1280
+ )
1281
+
1282
+ return Stripped(
1283
+ f"""\
1284
+ // De-serialize an instance of [aastypes.{interface_name}]
1285
+ // as an XML element where the start element is expected to have been already read
1286
+ // as `current` token.
1287
+ //
1288
+ // The de-serialization stops by consuming the final end element. The next call to
1289
+ // the `decoder.Token()` will return the element just after the end element.
1290
+ func {function_name}(
1291
+ {I}decoder *xml.Decoder,
1292
+ {I}current xml.Token,
1293
+ ) (instance aastypes.{interface_name},
1294
+ {I}err error,
1295
+ ) {{
1296
+ {I}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
1297
+ {I}if err != nil {{
1298
+ {II}return
1299
+ {I}}}
1300
+
1301
+ {I}var local string
1302
+ {I}local, err = parseAsStartElementAndExtractLocalName(
1303
+ {II}current,
1304
+ {I})
1305
+ {I}if err != nil {{
1306
+ {II}return
1307
+ {I}}}
1308
+
1309
+ {I}// Move the current to the properties of the instance
1310
+ {I}current, err = readNext(decoder, current)
1311
+ {I}if err != nil {{
1312
+ {II}return
1313
+ {I}}}
1314
+
1315
+ {I}{indent_but_first_line(switch_stmt, I)}
1316
+ {I}if err != nil {{
1317
+ {II}return
1318
+ {I}}}
1319
+
1320
+ {I}err = checkEndElement(current, local)
1321
+ {I}return
1322
+ }}"""
1323
+ )
1324
+
1325
+
1326
+ def _generate_unmarshal(symbol_table: intermediate.SymbolTable) -> Stripped:
1327
+ case_blocks = [] # type: List[Stripped]
1328
+ for cls in symbol_table.concrete_classes:
1329
+ read_as_sequence = golang_naming.private_function_name(
1330
+ Identifier(f"read_{cls.name}_as_sequence")
1331
+ )
1332
+
1333
+ xml_class_name_literal = golang_common.string_literal(
1334
+ naming.xml_class_name(cls.name)
1335
+ )
1336
+
1337
+ case_blocks.append(
1338
+ Stripped(
1339
+ f"""\
1340
+ case {xml_class_name_literal}:
1341
+ {I}instance, current, err = {read_as_sequence}(
1342
+ {II}decoder, current,
1343
+ {I})"""
1344
+ )
1345
+ )
1346
+
1347
+ case_blocks.append(
1348
+ Stripped(
1349
+ f"""\
1350
+ default:
1351
+ {II}err = newDeserializationError(
1352
+ {III}fmt.Sprintf(
1353
+ {IIII}"Unexpected XML element name %s as class discriminator",
1354
+ {IIII}local,
1355
+ {III}),
1356
+ {II})"""
1357
+ )
1358
+ )
1359
+
1360
+ case_blocks_joined = "\n".join(case_blocks)
1361
+
1362
+ return Stripped(
1363
+ f"""\
1364
+ // Unmarshal an instance of [aastypes.IClass] serialized as an XML element.
1365
+ //
1366
+ // The XML element must live in the [Namespace] space.
1367
+ func Unmarshal(
1368
+ {I}decoder *xml.Decoder,
1369
+ ) (instance aastypes.IClass, err error) {{
1370
+ {I}var current xml.Token
1371
+ {I}current, err = readNext(decoder, nil)
1372
+ {I}if err != nil {{
1373
+ {II}return
1374
+ {I}}}
1375
+
1376
+ {I}current, err = skipEmptyTextWhitespaceAndComments(decoder, current)
1377
+ {I}if err != nil {{
1378
+ {II}return
1379
+ {I}}}
1380
+
1381
+ {I}var local string
1382
+ {I}local, err = parseAsStartElementAndExtractLocalName(
1383
+ {II}current,
1384
+ {I})
1385
+ {I}if err != nil {{
1386
+ {II}return
1387
+ {I}}}
1388
+
1389
+ {I}// Move the current to the properties of the instance
1390
+ {I}current, err = readNext(decoder, current)
1391
+ {I}if err != nil {{
1392
+ {II}return
1393
+ {I}}}
1394
+
1395
+ {I}switch local {{
1396
+ {II}{indent_but_first_line(case_blocks_joined, II)}
1397
+ {I}}}
1398
+ {I}if err != nil {{
1399
+ {II}return
1400
+ {I}}}
1401
+
1402
+ {I}err = checkEndElement(current, local)
1403
+ {I}return
1404
+ }}"""
1405
+ )
1406
+
1407
+
1408
+ # endregion
1409
+
1410
+ # region Serialization
1411
+
1412
+
1413
+ def _generate_serialization_error() -> List[Stripped]:
1414
+ return [
1415
+ Stripped(
1416
+ f"""\
1417
+ // Represent an error during the serialization.
1418
+ //
1419
+ // Implements `error`.
1420
+ type SerializationError struct {{
1421
+ {I}Path *aasreporting.Path
1422
+ {I}Message string
1423
+ }}"""
1424
+ ),
1425
+ Stripped(
1426
+ f"""\
1427
+ func newSerializationError(message string) *SerializationError {{
1428
+ {I}return &SerializationError{{
1429
+ {II}Path: &aasreporting.Path{{}},
1430
+ {II}Message: message,
1431
+ {I}}}
1432
+ }}"""
1433
+ ),
1434
+ Stripped(
1435
+ f"""\
1436
+ func (se *SerializationError) Error() string {{
1437
+ {I}return fmt.Sprintf(
1438
+ {II}"%s: %s",
1439
+ {II}se.PathString(),
1440
+ {II}se.Message,
1441
+ {I})
1442
+ }}"""
1443
+ ),
1444
+ Stripped(
1445
+ f"""\
1446
+ // Render the path as a string.
1447
+ func (se *SerializationError) PathString() string {{
1448
+ {I}return aasreporting.ToGolangPath(se.Path)
1449
+ }}"""
1450
+ ),
1451
+ ]
1452
+
1453
+
1454
+ def _generate_write_start_element() -> Stripped:
1455
+ return Stripped(
1456
+ f"""\
1457
+ // Write the start element with the given `local` name to the encoder.
1458
+ //
1459
+ // Do not flush.
1460
+ //
1461
+ // If the `withNamespace` is set, set the [xml.Name.Space] property in the element
1462
+ // accordingly.
1463
+ func writeStartElement(
1464
+ {I}encoder *xml.Encoder,
1465
+ {I}local string,
1466
+ {I}withNamespace bool,
1467
+ ) (err error) {{
1468
+ {I}startElement := xml.StartElement{{Name: xml.Name{{Local: local}}}}
1469
+ {I}if withNamespace {{
1470
+ {II}startElement.Name.Space = Namespace
1471
+ {I}}}
1472
+
1473
+ {I}err = encoder.EncodeToken(startElement)
1474
+ {I}return
1475
+ }}"""
1476
+ )
1477
+
1478
+
1479
+ def _generate_write_end_element() -> Stripped:
1480
+ return Stripped(
1481
+ f"""\
1482
+ // Write the end element with the given `local` name to the encoder.
1483
+ //
1484
+ // Do not flush.
1485
+ //
1486
+ // If the `withNamespace` is set, set the [xml.Name.Space] property in the element
1487
+ // accordingly.
1488
+ func writeEndElement(
1489
+ {I}encoder *xml.Encoder,
1490
+ {I}local string,
1491
+ {I}withNamespace bool,
1492
+ ) (err error) {{
1493
+ {I}endElement := xml.EndElement{{Name: xml.Name{{Local: local}}}}
1494
+ {I}if withNamespace {{
1495
+ {II}endElement.Name.Space = Namespace
1496
+ {I}}}
1497
+
1498
+ {I}err = encoder.EncodeToken(endElement)
1499
+ {I}return
1500
+ }}"""
1501
+ )
1502
+
1503
+
1504
+ def _generate_write_text() -> Stripped:
1505
+ return Stripped(
1506
+ f"""\
1507
+ // Write the `text` to the encoder.
1508
+ //
1509
+ // Do not flush.
1510
+ //
1511
+ // If `text` is empty, do nothing.
1512
+ func writeText(
1513
+ {I}encoder *xml.Encoder,
1514
+ {I}text string,
1515
+ ) (err error) {{
1516
+ {I}if len(text) > 0 {{
1517
+ {II}err = encoder.EncodeToken(
1518
+ {III}xml.CharData([]byte(text)),
1519
+ {II})
1520
+ {I}}}
1521
+ {I}return
1522
+ }}"""
1523
+ )
1524
+
1525
+
1526
+ def _generate_write_boolean_property() -> Stripped:
1527
+ return Stripped(
1528
+ f"""\
1529
+ // Write the `value` of a property as `xs:boolean` enclosed in an XML element.
1530
+ //
1531
+ // Do not flush.
1532
+ //
1533
+ // The XML namespace is expected to have been defined outside of the resulting XML
1534
+ // element.
1535
+ func writeBooleanProperty(
1536
+ {I}encoder *xml.Encoder,
1537
+ {I}local string,
1538
+ {I}value bool,
1539
+ ) (err error) {{
1540
+ {I}err = writeStartElement(
1541
+ {II}encoder,
1542
+ {II}local,
1543
+ {II}false,
1544
+ {I})
1545
+ {I}if err != nil {{
1546
+ {II}return
1547
+ {I}}}
1548
+
1549
+ {I}text := "true"
1550
+ {I}if !value {{
1551
+ {II}text = "false"
1552
+ {I}}}
1553
+ {I}err = writeText(encoder, text)
1554
+ {I}if err != nil {{
1555
+ {II}return
1556
+ {I}}}
1557
+
1558
+ {I}err = writeEndElement(
1559
+ {II}encoder,
1560
+ {II}local,
1561
+ {II}false,
1562
+ {I})
1563
+ {I}if err != nil {{
1564
+ {II}return
1565
+ {I}}}
1566
+
1567
+ {I}return
1568
+ }}"""
1569
+ )
1570
+
1571
+
1572
+ def _generate_write_long_property() -> Stripped:
1573
+ return Stripped(
1574
+ f"""\
1575
+ // Write the `value` of a property as `xs:long` enclosed in an XML element.
1576
+ //
1577
+ // Do not flush.
1578
+ //
1579
+ // The XML namespace is expected to have been defined outside of the resulting XML
1580
+ // element.
1581
+ func writeLongProperty(
1582
+ {I}encoder *xml.Encoder,
1583
+ {I}local string,
1584
+ {I}value int64,
1585
+ {I}withNamespace bool,
1586
+ ) (err error) {{
1587
+ {I}err = writeStartElement(
1588
+ {II}encoder,
1589
+ {II}local,
1590
+ {II}false,
1591
+ {I})
1592
+ {I}if err != nil {{
1593
+ {II}return
1594
+ {I}}}
1595
+
1596
+ {I}text := strconv.FormatInt(value, 10)
1597
+ {I}err = writeText(encoder, text)
1598
+ {I}if err != nil {{
1599
+ {II}return
1600
+ {I}}}
1601
+
1602
+ {I}err = writeEndElement(
1603
+ {II}encoder,
1604
+ {II}local,
1605
+ {II}false,
1606
+ {I})
1607
+ {I}if err != nil {{
1608
+ {II}return
1609
+ {I}}}
1610
+
1611
+ {I}return
1612
+ }}"""
1613
+ )
1614
+
1615
+
1616
+ def _generate_write_double_property() -> Stripped:
1617
+ return Stripped(
1618
+ f"""\
1619
+ // Write the `value` of a property as `xs:double` enclosed in an XML element.
1620
+ //
1621
+ // Do not flush.
1622
+ //
1623
+ // The XML namespace is expected to have been defined outside of the resulting XML
1624
+ // element.
1625
+ func writeDoubleProperty(
1626
+ {I}encoder *xml.Encoder,
1627
+ {I}local string,
1628
+ {I}value float64,
1629
+ ) (err error) {{
1630
+ {I}err = writeStartElement(
1631
+ {II}encoder,
1632
+ {II}local,
1633
+ {II}false,
1634
+ {I})
1635
+ {I}if err != nil {{
1636
+ {II}return
1637
+ {I}}}
1638
+
1639
+ {I}var text string
1640
+
1641
+ {I}// See: https://www.w3.org/TR/xmlschema-2/#double
1642
+ {I}// for the exact literals.
1643
+ {I}if math.IsInf(value, 0) {{
1644
+ {II}if value < 0 {{
1645
+ {III}text = "-INF"
1646
+ {II}}} else {{
1647
+ {III}text = "INF"
1648
+ {II}}}
1649
+ {I}}} else if math.IsNaN(value) {{
1650
+ {II}text = "NaN"
1651
+ {I}}} else {{
1652
+ {II}text = strconv.FormatFloat(value, 'g', -1, 64)
1653
+ {I}}}
1654
+
1655
+ {I}err = writeText(encoder, text)
1656
+ {I}if err != nil {{
1657
+ {II}return
1658
+ {I}}}
1659
+
1660
+ {I}err = writeEndElement(
1661
+ {II}encoder,
1662
+ {II}local,
1663
+ {II}false,
1664
+ {I})
1665
+ {I}if err != nil {{
1666
+ {II}return
1667
+ {I}}}
1668
+
1669
+ {I}return
1670
+ }}"""
1671
+ )
1672
+
1673
+
1674
+ def _generate_write_string_property() -> Stripped:
1675
+ return Stripped(
1676
+ f"""\
1677
+ // Write the `value` of a property as `xs:string` enclosed in an XML element.
1678
+ //
1679
+ // Do not flush.
1680
+ //
1681
+ // The XML namespace is expected to have been defined outside of the resulting XML
1682
+ // element.
1683
+ func writeStringProperty(
1684
+ {I}encoder *xml.Encoder,
1685
+ {I}local string,
1686
+ {I}value string,
1687
+ ) (err error) {{
1688
+ {I}err = writeStartElement(
1689
+ {II}encoder,
1690
+ {II}local,
1691
+ {II}false,
1692
+ {I})
1693
+ {I}if err != nil {{
1694
+ {II}return
1695
+ {I}}}
1696
+
1697
+ {I}err = writeText(encoder, value)
1698
+ {I}if err != nil {{
1699
+ {II}return
1700
+ {I}}}
1701
+
1702
+ {I}err = writeEndElement(
1703
+ {II}encoder,
1704
+ {II}local,
1705
+ {II}false,
1706
+ {I})
1707
+ {I}if err != nil {{
1708
+ {II}return
1709
+ {I}}}
1710
+
1711
+ {I}return
1712
+ }}"""
1713
+ )
1714
+
1715
+
1716
+ def _generate_write_bytes_property() -> Stripped:
1717
+ return Stripped(
1718
+ f"""\
1719
+ // Write the `value` of a property as base64-encoded bytes.
1720
+ //
1721
+ // Do not flush.
1722
+ //
1723
+ // The XML namespace is expected to have been defined outside of the resulting XML
1724
+ // element.
1725
+ func writeBytesProperty(
1726
+ {I}encoder *xml.Encoder,
1727
+ {I}local string,
1728
+ {I}value []byte,
1729
+ ) (err error) {{
1730
+ {I}err = writeStartElement(
1731
+ {II}encoder,
1732
+ {II}local,
1733
+ {II}false,
1734
+ {I})
1735
+ {I}if err != nil {{
1736
+ {II}return
1737
+ {I}}}
1738
+
1739
+ {I}text := b64.StdEncoding.EncodeToString(
1740
+ {II}value,
1741
+ {I})
1742
+
1743
+ {I}err = writeText(encoder, text)
1744
+ {I}if err != nil {{
1745
+ {II}return
1746
+ {I}}}
1747
+
1748
+ {I}err = writeEndElement(
1749
+ {II}encoder,
1750
+ {II}local,
1751
+ {II}false,
1752
+ {I})
1753
+ {I}if err != nil {{
1754
+ {II}return
1755
+ {I}}}
1756
+
1757
+ {I}return
1758
+ }}"""
1759
+ )
1760
+
1761
+
1762
+ def _generate_write_list_as_sequence() -> Stripped:
1763
+ return Stripped(
1764
+ f"""\
1765
+ // Serialize the list of instances as a sequence of XML elements enclosed in a parent
1766
+ // XML element with the `local` name.
1767
+ func writeListProperty[T aastypes.IClass](
1768
+ {I}encoder *xml.Encoder,
1769
+ {I}local string,
1770
+ {I}list []T,
1771
+ ) (err error) {{
1772
+ {I}err = writeStartElement(
1773
+ {II}encoder,
1774
+ {II}local,
1775
+ {II}false,
1776
+ {I})
1777
+ {I}if err != nil {{
1778
+ {II}return
1779
+ {I}}}
1780
+
1781
+ {I}for i, item := range list {{
1782
+ {II}err = Marshal(
1783
+ {III}encoder,
1784
+ {III}item,
1785
+ {III}false,
1786
+ {II})
1787
+ {II}if err != nil {{
1788
+ {III}if seriaErr, ok := err.(*SerializationError); ok {{
1789
+ {IIII}seriaErr.Path.PrependIndex(
1790
+ {IIIII}&aasreporting.IndexSegment{{
1791
+ {IIIIII}Index: i,
1792
+ {IIIII}}},
1793
+ {IIII})
1794
+ {III}}}
1795
+ {III}return
1796
+ {II}}}
1797
+ {I}}}
1798
+
1799
+ {I}err = writeEndElement(
1800
+ {II}encoder,
1801
+ {II}local,
1802
+ {II}false,
1803
+ {I})
1804
+ {I}if err != nil {{
1805
+ {II}return
1806
+ {I}}}
1807
+
1808
+ {I}return
1809
+ }}"""
1810
+ )
1811
+
1812
+
1813
+ def _generate_write_enumeration_property(
1814
+ enumeration: intermediate.Enumeration,
1815
+ ) -> Stripped:
1816
+ enum_name = golang_naming.enum_name(enumeration.name)
1817
+ function_name = golang_naming.private_function_name(
1818
+ Identifier(f"write_{enumeration.name}_property")
1819
+ )
1820
+ to_string_name = golang_naming.function_name(
1821
+ Identifier(f"{enumeration.name}_to_string")
1822
+ )
1823
+
1824
+ return Stripped(
1825
+ f"""\
1826
+ // Write the `value` of a property as string representation
1827
+ // of [aastypes.{enum_name}]
1828
+ // enclosed in an XML element.
1829
+ //
1830
+ // Do not flush.
1831
+ func {function_name}(
1832
+ {I}encoder *xml.Encoder,
1833
+ {I}local string,
1834
+ {I}value aastypes.{enum_name},
1835
+ ) (err error) {{
1836
+ {I}text, ok := aasstringification.{to_string_name}(
1837
+ {II}value,
1838
+ {I})
1839
+ {I}if !ok {{
1840
+ {II}err = newSerializationError(
1841
+ {III}fmt.Sprintf(
1842
+ {IIII}"Unexpected literal of {enum_name}: %v",
1843
+ {IIII}value,
1844
+ {III}),
1845
+ {II})
1846
+ {II}return
1847
+ {I}}}
1848
+
1849
+ {I}err = writeStringProperty(encoder, local, text)
1850
+ {I}return
1851
+ }}"""
1852
+ )
1853
+
1854
+
1855
+ _WRITE_FUNCTION_BY_PRIMITIVE_TYPE = {
1856
+ intermediate.PrimitiveType.BOOL: "writeBooleanProperty",
1857
+ intermediate.PrimitiveType.INT: "writeLongProperty",
1858
+ intermediate.PrimitiveType.FLOAT: "writeDoubleProperty",
1859
+ intermediate.PrimitiveType.STR: "writeStringProperty",
1860
+ intermediate.PrimitiveType.BYTEARRAY: "writeBytesProperty",
1861
+ }
1862
+ assert all(
1863
+ literal in _WRITE_FUNCTION_BY_PRIMITIVE_TYPE
1864
+ for literal in intermediate.PrimitiveType
1865
+ )
1866
+
1867
+
1868
+ def _generate_snippet_to_serialize_property(prop: intermediate.Property) -> Stripped:
1869
+ blocks = [] # type: List[Stripped]
1870
+
1871
+ local_literal = golang_common.string_literal(naming.xml_property(prop.name))
1872
+
1873
+ segment_name_literal = golang_common.string_literal(
1874
+ f"{golang_naming.getter_name(prop.name)}()"
1875
+ )
1876
+
1877
+ type_anno = intermediate.beneath_optional(prop.type_annotation)
1878
+
1879
+ getter_name = golang_naming.getter_name(prop.name)
1880
+ access_expr = f"that.{getter_name}()"
1881
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
1882
+ prop_var = golang_naming.variable_name(Identifier(f"the_{prop.name}"))
1883
+ access_expr = prop_var
1884
+
1885
+ blocks.append(
1886
+ Stripped(
1887
+ f"""\
1888
+ {prop_var} := that.{getter_name}()"""
1889
+ )
1890
+ )
1891
+
1892
+ write_block = None # type: Optional[Stripped]
1893
+
1894
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation) or (
1895
+ isinstance(type_anno, intermediate.OurTypeAnnotation)
1896
+ and isinstance(
1897
+ type_anno.our_type,
1898
+ (intermediate.ConstrainedPrimitive, intermediate.Enumeration),
1899
+ )
1900
+ ):
1901
+ primitive_type = intermediate.try_primitive_type(type_anno)
1902
+
1903
+ if primitive_type is not None:
1904
+ write_function = _WRITE_FUNCTION_BY_PRIMITIVE_TYPE[primitive_type]
1905
+ else:
1906
+ assert isinstance(type_anno, intermediate.OurTypeAnnotation) and isinstance(
1907
+ type_anno.our_type, intermediate.Enumeration
1908
+ )
1909
+ write_function = golang_naming.private_function_name(
1910
+ Identifier(f"write_{type_anno.our_type.name}_property")
1911
+ )
1912
+
1913
+ pointer = golang_pointering.is_pointer_type(prop.type_annotation)
1914
+
1915
+ if_err_nil_prepend_name_if_serialization_error = Stripped(
1916
+ f"""\
1917
+ if err != nil {{
1918
+ {I}if seriaErr, ok := err.(*SerializationError); ok {{
1919
+ {II}seriaErr.Path.PrependName(
1920
+ {III}&aasreporting.NameSegment{{
1921
+ {IIII}Name: {segment_name_literal},
1922
+ {III}}},
1923
+ {II})
1924
+ {I}}}
1925
+ {I}return
1926
+ }}"""
1927
+ )
1928
+
1929
+ if pointer:
1930
+ write_block = Stripped(
1931
+ f"""\
1932
+ err = {write_function}(
1933
+ {I}encoder,
1934
+ {I}{local_literal},
1935
+ {I}*{access_expr},
1936
+ )
1937
+ {if_err_nil_prepend_name_if_serialization_error}"""
1938
+ )
1939
+ else:
1940
+ write_block = Stripped(
1941
+ f"""\
1942
+ err = {write_function}(
1943
+ {I}encoder,
1944
+ {I}{local_literal},
1945
+ {I}{access_expr},
1946
+ )
1947
+ {if_err_nil_prepend_name_if_serialization_error}"""
1948
+ )
1949
+
1950
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
1951
+ our_type = type_anno.our_type
1952
+
1953
+ if isinstance(our_type, intermediate.Enumeration):
1954
+ raise AssertionError("Must have been handled before")
1955
+
1956
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1957
+ raise AssertionError("Must have been handled before")
1958
+
1959
+ elif isinstance(
1960
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
1961
+ ):
1962
+ if (
1963
+ isinstance(our_type, intermediate.ConcreteClass)
1964
+ and len(our_type.concrete_descendants) == 0
1965
+ ):
1966
+ write_as_sequence_name = golang_naming.private_function_name(
1967
+ Identifier(f"write_{our_type.name}_as_sequence")
1968
+ )
1969
+ write_block = Stripped(
1970
+ f"""\
1971
+ err = writeStartElement(
1972
+ {I}encoder,
1973
+ {I}{local_literal},
1974
+ {I}false,
1975
+ )
1976
+ if err != nil {{
1977
+ {I}return
1978
+ }}
1979
+ err = {write_as_sequence_name}(
1980
+ {I}encoder,
1981
+ {I}{access_expr},
1982
+ )
1983
+ if err != nil {{
1984
+ {I}if seriaErr, ok := err.(*SerializationError); ok {{
1985
+ {II}seriaErr.Path.PrependName(
1986
+ {III}&aasreporting.NameSegment{{
1987
+ {IIII}Name: {segment_name_literal},
1988
+ {III}}},
1989
+ {II})
1990
+ {I}}}
1991
+ {I}return
1992
+ }}
1993
+ err = writeEndElement(
1994
+ {I}encoder,
1995
+ {I}{local_literal},
1996
+ {I}false,
1997
+ )
1998
+ if err != nil {{
1999
+ {I}return
2000
+ }}"""
2001
+ )
2002
+ else:
2003
+ write_block = Stripped(
2004
+ f"""\
2005
+ err = writeStartElement(
2006
+ {I}encoder,
2007
+ {I}{local_literal},
2008
+ false,
2009
+ )
2010
+ if err != nil {{
2011
+ {I}return
2012
+ }}
2013
+ err = Marshal(
2014
+ {I}encoder,
2015
+ {I}{access_expr},
2016
+ {I}false,
2017
+ )
2018
+ if err != nil {{
2019
+ {I}if seriaErr, ok := err.(*SerializationError); ok {{
2020
+ {II}seriaErr.Path.PrependName(
2021
+ {III}&aasreporting.NameSegment{{
2022
+ {IIII}Name: {segment_name_literal},
2023
+ {III}}},
2024
+ {II})
2025
+ {I}}}
2026
+ {I}return
2027
+ }}
2028
+ err = writeEndElement(
2029
+ {I}encoder,
2030
+ {I}{local_literal},
2031
+ false,
2032
+ )
2033
+ if err != nil {{
2034
+ {I}return
2035
+ }}"""
2036
+ )
2037
+
2038
+ else:
2039
+ assert_never(our_type)
2040
+
2041
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
2042
+ assert isinstance(
2043
+ type_anno.items, intermediate.OurTypeAnnotation
2044
+ ) and isinstance(
2045
+ type_anno.items.our_type,
2046
+ (intermediate.AbstractClass, intermediate.ConcreteClass),
2047
+ ), (
2048
+ f"NOTE (mristin, 2023-06-20): We expect only lists of classes "
2049
+ f"at the moment, but you specified {type_anno}. "
2050
+ f"Please contact the developers if you need this feature."
2051
+ )
2052
+
2053
+ write_block = Stripped(
2054
+ f"""\
2055
+ err = writeListProperty(
2056
+ {I}encoder,
2057
+ {I}{local_literal},
2058
+ {I}{access_expr},
2059
+ )
2060
+ if err != nil {{
2061
+ {I}if seriaErr, ok := err.(*SerializationError); ok {{
2062
+ {II}seriaErr.Path.PrependName(
2063
+ {III}&aasreporting.NameSegment{{
2064
+ {IIII}Name: {segment_name_literal},
2065
+ {III}}},
2066
+ {II})
2067
+ {I}}}
2068
+ {I}return
2069
+ }}"""
2070
+ )
2071
+
2072
+ else:
2073
+ assert_never(type_anno)
2074
+
2075
+ assert write_block is not None
2076
+
2077
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
2078
+ blocks.append(
2079
+ Stripped(
2080
+ f"""\
2081
+ if {access_expr} != nil {{
2082
+ {I}{indent_but_first_line(write_block, I)}
2083
+ }}"""
2084
+ )
2085
+ )
2086
+ else:
2087
+ blocks.append(write_block)
2088
+
2089
+ blocks.append(
2090
+ Stripped(
2091
+ f"""\
2092
+ err = encoder.Flush()
2093
+ if err != nil {{
2094
+ {I}return err
2095
+ }}"""
2096
+ )
2097
+ )
2098
+
2099
+ blocks.insert(0, Stripped(f"// region {getter_name}"))
2100
+ blocks.append(Stripped("// endregion"))
2101
+
2102
+ return Stripped("\n\n".join(blocks))
2103
+
2104
+
2105
+ def _generate_write_as_sequence(cls: intermediate.ConcreteClass) -> Stripped:
2106
+ function_name = golang_naming.private_function_name(
2107
+ Identifier(f"write_{cls.name}_as_sequence")
2108
+ )
2109
+
2110
+ interface_name = golang_naming.interface_name(cls.name)
2111
+
2112
+ prop_blocks = [] # type: List[Stripped]
2113
+
2114
+ for prop in cls.properties:
2115
+ prop_blocks.append(_generate_snippet_to_serialize_property(prop=prop))
2116
+
2117
+ if len(prop_blocks) == 0:
2118
+ prop_blocks.append(Stripped("// Intentionally empty."))
2119
+
2120
+ prop_blocks_joined = "\n\n".join(prop_blocks)
2121
+
2122
+ return Stripped(
2123
+ f"""\
2124
+ // Serialize the instance
2125
+ // of [aastypes.{interface_name}]
2126
+ // as a sequence of properties, each represented as an XML element.
2127
+ //
2128
+ // The XML namespace is expected to be set in the one of the parent elements
2129
+ // enclosing the sequence.
2130
+ //
2131
+ // Flush at the end element of each property.
2132
+ func {function_name}(
2133
+ {I}encoder *xml.Encoder,
2134
+ {I}that aastypes.{interface_name},
2135
+ ) (err error) {{
2136
+ {I}{indent_but_first_line(prop_blocks_joined, I)}
2137
+
2138
+ {I}return
2139
+ }}"""
2140
+ )
2141
+
2142
+
2143
+ def _generate_write_for(cls: intermediate.ConcreteClass) -> Stripped:
2144
+ interface_name = golang_naming.interface_name(cls.name)
2145
+
2146
+ if len(cls.concrete_descendants) == 0:
2147
+ function_name = golang_naming.private_function_name(
2148
+ Identifier(f"write_{cls.name}")
2149
+ )
2150
+ doc_comment = Stripped(
2151
+ f"""\
2152
+ // Serialize the instance of [aastypes.{interface_name}]
2153
+ // enclosed in an XML element which represents the model type.
2154
+ //
2155
+ // If `withNamespace` is set, the `xmlns` attribute is set in the outer XML element.
2156
+ //
2157
+ // Flush once the closing end element has been written."""
2158
+ )
2159
+ else:
2160
+ model_type_literal = golang_naming.enum_literal_name(
2161
+ enumeration_name=Identifier("Model_type"), literal_name=cls.name
2162
+ )
2163
+
2164
+ doc_comment = Stripped(
2165
+ f"""\
2166
+ // Serialize the instance of [aastypes.{interface_name}]
2167
+ // enclosed in an XML element which represents the model type.
2168
+ //
2169
+ // Do not dispatch on the runtime model type, *i.e.*, assume that the runtime model type
2170
+ // is exactly [aastypes.{model_type_literal}]. If you need dispatch,
2171
+ // call [Marshal].
2172
+ //
2173
+ // If `withNamespace` is set, the `xmlns` attribute is set in the outer XML element.
2174
+ //
2175
+ // Flush once the closing end element has been written."""
2176
+ )
2177
+
2178
+ function_name = golang_naming.private_function_name(
2179
+ Identifier(f"write_{cls.name}_without_dispatch")
2180
+ )
2181
+
2182
+ xml_class_name_literal = golang_common.string_literal(
2183
+ naming.xml_class_name(cls.name)
2184
+ )
2185
+
2186
+ write_as_sequence_name = golang_naming.private_function_name(
2187
+ Identifier(f"write_{cls.name}_as_sequence")
2188
+ )
2189
+
2190
+ return Stripped(
2191
+ f"""\
2192
+ {doc_comment}
2193
+ func {function_name}(
2194
+ {I}encoder *xml.Encoder,
2195
+ {I}that aastypes.{interface_name},
2196
+ {I}withNamespace bool,
2197
+ ) (err error) {{
2198
+ {I}local := {xml_class_name_literal}
2199
+ {I}
2200
+ {I}err = writeStartElement(
2201
+ {II}encoder,
2202
+ {II}local,
2203
+ {II}withNamespace,
2204
+ {I})
2205
+ {I}if err != nil {{
2206
+ {II}return
2207
+ {I}}}
2208
+
2209
+ {I}err = {write_as_sequence_name}(
2210
+ {II}encoder,
2211
+ {II}that,
2212
+ {I})
2213
+ {I}if err != nil {{
2214
+ {II}return
2215
+ {I}}}
2216
+ {I}
2217
+ {I}err = writeEndElement(
2218
+ {II}encoder,
2219
+ {II}local,
2220
+ {II}withNamespace,
2221
+ {I})
2222
+ {I}if err != nil {{
2223
+ {II}return
2224
+ {I}}}
2225
+
2226
+ {I}err = encoder.Flush()
2227
+ {I}return
2228
+ }}"""
2229
+ )
2230
+
2231
+
2232
+ def _generate_marshal(symbol_table: intermediate.SymbolTable) -> Stripped:
2233
+ case_blocks = [] # type: List[Stripped]
2234
+ for cls in symbol_table.concrete_classes:
2235
+ model_type_literal = golang_naming.enum_literal_name(
2236
+ enumeration_name=Identifier("Model_type"), literal_name=cls.name
2237
+ )
2238
+
2239
+ interface_name = golang_naming.interface_name(cls.name)
2240
+
2241
+ if len(cls.concrete_descendants) == 0:
2242
+ write_function = golang_naming.private_function_name(
2243
+ Identifier(f"write_{cls.name}")
2244
+ )
2245
+ else:
2246
+ write_function = golang_naming.private_function_name(
2247
+ Identifier(f"write_{cls.name}_without_dispatch")
2248
+ )
2249
+
2250
+ case_blocks.append(
2251
+ Stripped(
2252
+ f"""\
2253
+ case aastypes.{model_type_literal}:
2254
+ {I}err = {write_function}(
2255
+ {II}encoder,
2256
+ {II}that.(aastypes.{interface_name}),
2257
+ {II}withNamespace,
2258
+ {I})"""
2259
+ )
2260
+ )
2261
+
2262
+ case_blocks.append(
2263
+ Stripped(
2264
+ f"""\
2265
+ default:
2266
+ {I}err = newSerializationError(
2267
+ {II}fmt.Sprintf(
2268
+ {III}"Unexpected model type: %v",
2269
+ {III}that.ModelType(),
2270
+ {II}),
2271
+ {I})"""
2272
+ )
2273
+ )
2274
+
2275
+ case_blocks_joined = "\n".join(case_blocks)
2276
+ model_type_getter = golang_naming.getter_name(Identifier("model_type"))
2277
+
2278
+ return Stripped(
2279
+ f"""\
2280
+ // Serialize `that` instance as an XML element.
2281
+ //
2282
+ // If `withNamespace` is set, the `xmlns` attribute is set in the XML element
2283
+ // to [Namespace].
2284
+ func Marshal(
2285
+ {I}encoder *xml.Encoder,
2286
+ {I}that aastypes.IClass,
2287
+ {I}withNamespace bool,
2288
+ ) (err error) {{
2289
+ {I}switch that.{model_type_getter}() {{
2290
+ {I}{indent_but_first_line(case_blocks_joined, I)}
2291
+ {I}}}
2292
+ {I}return
2293
+ }}"""
2294
+ )
2295
+
2296
+
2297
+ # endregion
2298
+
2299
+ # fmt: off
2300
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
2301
+ @ensure(
2302
+ lambda result:
2303
+ not (result[0] is not None) or result[0].endswith('\n'),
2304
+ "Trailing newline mandatory for valid end-of-files"
2305
+ )
2306
+ # fmt: on
2307
+ def generate(
2308
+ symbol_table: intermediate.SymbolTable,
2309
+ spec_impls: specific_implementations.SpecificImplementations,
2310
+ repo_url: Stripped,
2311
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
2312
+ """Generate the Golang code for the general de/serialization."""
2313
+ aastypes_url_literal = golang_common.string_literal(f"{repo_url}/types")
2314
+
2315
+ aasreporting_url_literal = golang_common.string_literal(f"{repo_url}/reporting")
2316
+
2317
+ aasstringification_url_literal = golang_common.string_literal(
2318
+ f"{repo_url}/stringification"
2319
+ )
2320
+
2321
+ aasverification_url_literal = golang_common.string_literal(
2322
+ f"{repo_url}/verification"
2323
+ )
2324
+
2325
+ namespace_literal = golang_common.string_literal(
2326
+ symbol_table.meta_model.xml_namespace
2327
+ )
2328
+
2329
+ blocks = [
2330
+ Stripped(
2331
+ """\
2332
+ // Package xmlization de/serializes model instances to and from XML.
2333
+ //
2334
+ // To de-serialize, call one of the `Unmarshal*` functions.
2335
+ //
2336
+ // To serialize, call the [Marshal] function.
2337
+ package xmlization"""
2338
+ ),
2339
+ golang_common.WARNING,
2340
+ Stripped(
2341
+ f"""\
2342
+ import (
2343
+ {I}b64 "encoding/base64"
2344
+ {I}"encoding/xml"
2345
+ {I}"fmt"
2346
+ {I}"io"
2347
+ {I}"math"
2348
+ {I}"strconv"
2349
+ {I}"strings"
2350
+ {I}"unicode"
2351
+ {I}aasreporting {aasreporting_url_literal}
2352
+ {I}aasstringification {aasstringification_url_literal}
2353
+ {I}aastypes {aastypes_url_literal}
2354
+ {I}aasverification {aasverification_url_literal}
2355
+ )"""
2356
+ ),
2357
+ Stripped("// region De-serialization"),
2358
+ ]
2359
+
2360
+ blocks.extend(_generate_deserialization_error_and_its_methods())
2361
+
2362
+ blocks.extend(
2363
+ [
2364
+ Stripped(
2365
+ """\
2366
+ // This is class for a sentinel token to signal the end-of-file.
2367
+ type eof struct{}"""
2368
+ ),
2369
+ _generate_is_whitespace(),
2370
+ _generate_read_next(),
2371
+ _generate_skip_empty_text_whitespace_and_comments(),
2372
+ _generate_read_text(),
2373
+ _generate_read_text_as_boolean(),
2374
+ _generate_read_text_as_long(),
2375
+ _generate_read_text_as_double(),
2376
+ _generate_read_text_as_base64_encoded_bytes(),
2377
+ Stripped(
2378
+ f"""\
2379
+ const Namespace = {namespace_literal}"""
2380
+ ),
2381
+ _generate_check_start_element(),
2382
+ _generate_extract_local_name_from_start_element(),
2383
+ _generate_parse_as_start_element_and_extract_local_name(),
2384
+ _generate_check_end_element(),
2385
+ _generate_read_list(),
2386
+ ]
2387
+ )
2388
+
2389
+ errors = [] # type: List[Error]
2390
+
2391
+ for our_type in symbol_table.our_types:
2392
+ if isinstance(our_type, intermediate.Enumeration):
2393
+ blocks.append(_generate_read_text_as_enumeration(enumeration=our_type))
2394
+
2395
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
2396
+ pass
2397
+ elif isinstance(our_type, intermediate.AbstractClass):
2398
+ blocks.append(_generate_read_with_lookahead_with_dispatch(cls=our_type))
2399
+
2400
+ elif isinstance(our_type, intermediate.ConcreteClass):
2401
+ if our_type.is_implementation_specific:
2402
+ implementation_key = specific_implementations.ImplementationKey(
2403
+ f"Xmlization/read_{our_type.name}_as_sequence.go"
2404
+ )
2405
+
2406
+ implementation = spec_impls.get(implementation_key, None)
2407
+ if implementation is None:
2408
+ errors.append(
2409
+ Error(
2410
+ our_type.parsed.node,
2411
+ f"The xmlization snippet is missing "
2412
+ f"for the implementation-specific "
2413
+ f"class {our_type.name}: {implementation_key}",
2414
+ )
2415
+ )
2416
+ continue
2417
+ else:
2418
+ blocks.append(_generate_read_as_sequence(cls=our_type))
2419
+
2420
+ if len(our_type.concrete_descendants) > 0:
2421
+ blocks.append(_generate_read_with_lookahead_with_dispatch(cls=our_type))
2422
+ else:
2423
+ blocks.append(
2424
+ _generate_read_with_lookahead_without_dispatch(cls=our_type)
2425
+ )
2426
+ else:
2427
+ assert_never(our_type)
2428
+
2429
+ blocks.append(_generate_unmarshal(symbol_table=symbol_table))
2430
+
2431
+ blocks.append(Stripped("// endregion"))
2432
+
2433
+ blocks.append(Stripped("// region Serialization"))
2434
+
2435
+ blocks.extend(_generate_serialization_error())
2436
+
2437
+ blocks.extend(
2438
+ [
2439
+ _generate_write_start_element(),
2440
+ _generate_write_end_element(),
2441
+ _generate_write_text(),
2442
+ _generate_write_boolean_property(),
2443
+ _generate_write_long_property(),
2444
+ _generate_write_double_property(),
2445
+ _generate_write_string_property(),
2446
+ _generate_write_bytes_property(),
2447
+ _generate_write_list_as_sequence(),
2448
+ ]
2449
+ )
2450
+
2451
+ for our_type in symbol_table.our_types:
2452
+ if isinstance(our_type, intermediate.Enumeration):
2453
+ blocks.append(_generate_write_enumeration_property(enumeration=our_type))
2454
+
2455
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
2456
+ # NOTE (mristin, 2023-06-18):
2457
+ # We will serialize constrained primitives as primitives.
2458
+ pass
2459
+
2460
+ elif isinstance(our_type, intermediate.AbstractClass):
2461
+ # NOTE (mristin, 2023-06-18):
2462
+ # We will use general ``write`` function.
2463
+ pass
2464
+
2465
+ elif isinstance(our_type, intermediate.ConcreteClass):
2466
+ if our_type.is_implementation_specific:
2467
+ implementation_key = specific_implementations.ImplementationKey(
2468
+ f"Xmlization/write_{our_type.name}_as_sequence.go"
2469
+ )
2470
+
2471
+ implementation = spec_impls.get(implementation_key, None)
2472
+ if implementation is None:
2473
+ errors.append(
2474
+ Error(
2475
+ our_type.parsed.node,
2476
+ f"The xmlization snippet is missing "
2477
+ f"for the implementation-specific "
2478
+ f"class {our_type.name}: {implementation_key}",
2479
+ )
2480
+ )
2481
+ continue
2482
+ else:
2483
+ blocks.append(_generate_write_as_sequence(cls=our_type))
2484
+
2485
+ blocks.append(_generate_write_for(cls=our_type))
2486
+ else:
2487
+ assert_never(our_type)
2488
+
2489
+ blocks.append(_generate_marshal(symbol_table=symbol_table))
2490
+
2491
+ blocks.append(Stripped("// endregion"))
2492
+
2493
+ if len(errors) > 0:
2494
+ return None, errors
2495
+
2496
+ blocks.append(golang_common.WARNING)
2497
+
2498
+ writer = io.StringIO()
2499
+ for i, block in enumerate(blocks):
2500
+ if i > 0:
2501
+ writer.write("\n\n")
2502
+
2503
+ writer.write(block)
2504
+
2505
+ writer.write("\n")
2506
+
2507
+ return writer.getvalue(), None