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