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.
- aas_core_codegen/__init__.py +6 -0
- aas_core_codegen/__main__.py +8 -0
- aas_core_codegen/common.py +500 -0
- aas_core_codegen/cpp/__init__.py +1 -0
- aas_core_codegen/cpp/aas_common/__init__.py +6 -0
- aas_core_codegen/cpp/aas_common/_generate.py +713 -0
- aas_core_codegen/cpp/common.py +681 -0
- aas_core_codegen/cpp/constants/__init__.py +6 -0
- aas_core_codegen/cpp/constants/_generate.py +568 -0
- aas_core_codegen/cpp/description.py +654 -0
- aas_core_codegen/cpp/enhancing/__init__.py +4 -0
- aas_core_codegen/cpp/enhancing/_generate.py +993 -0
- aas_core_codegen/cpp/iteration/__init__.py +6 -0
- aas_core_codegen/cpp/iteration/_generate.py +2332 -0
- aas_core_codegen/cpp/jsonization/__init__.py +6 -0
- aas_core_codegen/cpp/jsonization/_generate.py +2619 -0
- aas_core_codegen/cpp/main.py +694 -0
- aas_core_codegen/cpp/naming.py +170 -0
- aas_core_codegen/cpp/optionaling.py +557 -0
- aas_core_codegen/cpp/pattern/__init__.py +6 -0
- aas_core_codegen/cpp/pattern/_generate.py +508 -0
- aas_core_codegen/cpp/revm/__init__.py +6 -0
- aas_core_codegen/cpp/revm/_generate.py +1149 -0
- aas_core_codegen/cpp/stringification/__init__.py +5 -0
- aas_core_codegen/cpp/stringification/_generate.py +955 -0
- aas_core_codegen/cpp/structure/__init__.py +7 -0
- aas_core_codegen/cpp/structure/_generate.py +1503 -0
- aas_core_codegen/cpp/transpilation.py +1383 -0
- aas_core_codegen/cpp/unrolling.py +159 -0
- aas_core_codegen/cpp/verification/__init__.py +6 -0
- aas_core_codegen/cpp/verification/_generate.py +3073 -0
- aas_core_codegen/cpp/visitation/__init__.py +6 -0
- aas_core_codegen/cpp/visitation/_generate.py +521 -0
- aas_core_codegen/cpp/wstringification/__init__.py +5 -0
- aas_core_codegen/cpp/wstringification/_generate.py +586 -0
- aas_core_codegen/cpp/xmlization/__init__.py +6 -0
- aas_core_codegen/cpp/xmlization/_generate.py +5373 -0
- aas_core_codegen/cpp/yielding.py +201 -0
- aas_core_codegen/csharp/__init__.py +1 -0
- aas_core_codegen/csharp/common.py +224 -0
- aas_core_codegen/csharp/constants/__init__.py +5 -0
- aas_core_codegen/csharp/constants/_generate.py +409 -0
- aas_core_codegen/csharp/copying/__init__.py +4 -0
- aas_core_codegen/csharp/copying/_generate.py +498 -0
- aas_core_codegen/csharp/description.py +1103 -0
- aas_core_codegen/csharp/enhancing/__init__.py +4 -0
- aas_core_codegen/csharp/enhancing/_generate.py +667 -0
- aas_core_codegen/csharp/jsonization/__init__.py +4 -0
- aas_core_codegen/csharp/jsonization/_generate.py +1630 -0
- aas_core_codegen/csharp/main.py +421 -0
- aas_core_codegen/csharp/naming.py +157 -0
- aas_core_codegen/csharp/reporting/__init__.py +4 -0
- aas_core_codegen/csharp/reporting/_generate.py +266 -0
- aas_core_codegen/csharp/stringification/__init__.py +4 -0
- aas_core_codegen/csharp/stringification/_generate.py +243 -0
- aas_core_codegen/csharp/structure/__init__.py +6 -0
- aas_core_codegen/csharp/structure/_generate.py +1341 -0
- aas_core_codegen/csharp/transpilation.py +990 -0
- aas_core_codegen/csharp/unrolling.py +211 -0
- aas_core_codegen/csharp/verification/__init__.py +6 -0
- aas_core_codegen/csharp/verification/_generate.py +1457 -0
- aas_core_codegen/csharp/visitation/__init__.py +5 -0
- aas_core_codegen/csharp/visitation/_generate.py +579 -0
- aas_core_codegen/csharp/xmlization/__init__.py +4 -0
- aas_core_codegen/csharp/xmlization/_generate.py +1980 -0
- aas_core_codegen/golang/__init__.py +1 -0
- aas_core_codegen/golang/aas_common/__init__.py +4 -0
- aas_core_codegen/golang/aas_common/_generate.py +152 -0
- aas_core_codegen/golang/common.py +303 -0
- aas_core_codegen/golang/constants/__init__.py +5 -0
- aas_core_codegen/golang/constants/_generate.py +339 -0
- aas_core_codegen/golang/description.py +501 -0
- aas_core_codegen/golang/enhancing/__init__.py +4 -0
- aas_core_codegen/golang/enhancing/_generate.py +527 -0
- aas_core_codegen/golang/jsonization/__init__.py +4 -0
- aas_core_codegen/golang/jsonization/_generate.py +1740 -0
- aas_core_codegen/golang/main.py +368 -0
- aas_core_codegen/golang/naming.py +412 -0
- aas_core_codegen/golang/pointering.py +631 -0
- aas_core_codegen/golang/reporting/__init__.py +4 -0
- aas_core_codegen/golang/reporting/_generate.py +218 -0
- aas_core_codegen/golang/stringification/__init__.py +4 -0
- aas_core_codegen/golang/stringification/_generate.py +394 -0
- aas_core_codegen/golang/structure/__init__.py +6 -0
- aas_core_codegen/golang/structure/_generate.py +1493 -0
- aas_core_codegen/golang/transpilation.py +1191 -0
- aas_core_codegen/golang/unrolling.py +159 -0
- aas_core_codegen/golang/verification/__init__.py +6 -0
- aas_core_codegen/golang/verification/_generate.py +1513 -0
- aas_core_codegen/golang/xmlization/__init__.py +4 -0
- aas_core_codegen/golang/xmlization/_generate.py +2507 -0
- aas_core_codegen/infer_for_schema/__init__.py +21 -0
- aas_core_codegen/infer_for_schema/_inline.py +693 -0
- aas_core_codegen/infer_for_schema/_len.py +527 -0
- aas_core_codegen/infer_for_schema/_pattern.py +311 -0
- aas_core_codegen/infer_for_schema/_set.py +394 -0
- aas_core_codegen/infer_for_schema/_stringify.py +201 -0
- aas_core_codegen/infer_for_schema/_types.py +135 -0
- aas_core_codegen/infer_for_schema/match.py +122 -0
- aas_core_codegen/intermediate/__init__.py +78 -0
- aas_core_codegen/intermediate/_hierarchy.py +397 -0
- aas_core_codegen/intermediate/_stringify.py +989 -0
- aas_core_codegen/intermediate/_translate.py +5128 -0
- aas_core_codegen/intermediate/_types.py +2901 -0
- aas_core_codegen/intermediate/construction.py +750 -0
- aas_core_codegen/intermediate/doc.py +344 -0
- aas_core_codegen/intermediate/pattern_verification.py +428 -0
- aas_core_codegen/intermediate/revm.py +985 -0
- aas_core_codegen/intermediate/type_inference.py +2266 -0
- aas_core_codegen/java/__init__.py +1 -0
- aas_core_codegen/java/common.py +197 -0
- aas_core_codegen/java/constants/__init__.py +5 -0
- aas_core_codegen/java/constants/_generate.py +334 -0
- aas_core_codegen/java/copying/__init__.py +4 -0
- aas_core_codegen/java/copying/_generate.py +502 -0
- aas_core_codegen/java/description.py +774 -0
- aas_core_codegen/java/enhancing/__init__.py +4 -0
- aas_core_codegen/java/enhancing/_generate.py +820 -0
- aas_core_codegen/java/generation/__init__.py +5 -0
- aas_core_codegen/java/generation/_generate.py +285 -0
- aas_core_codegen/java/jsonization/__init__.py +4 -0
- aas_core_codegen/java/jsonization/_generate.py +1472 -0
- aas_core_codegen/java/main.py +438 -0
- aas_core_codegen/java/naming.py +187 -0
- aas_core_codegen/java/optional.py +514 -0
- aas_core_codegen/java/reporting/__init__.py +4 -0
- aas_core_codegen/java/reporting/_generate.py +248 -0
- aas_core_codegen/java/stringification/__init__.py +4 -0
- aas_core_codegen/java/stringification/_generate.py +212 -0
- aas_core_codegen/java/structure/__init__.py +6 -0
- aas_core_codegen/java/structure/_generate.py +1767 -0
- aas_core_codegen/java/transpilation.py +1111 -0
- aas_core_codegen/java/verification/__init__.py +6 -0
- aas_core_codegen/java/verification/_generate.py +1536 -0
- aas_core_codegen/java/visitation/__init__.py +5 -0
- aas_core_codegen/java/visitation/_generate.py +689 -0
- aas_core_codegen/java/xmlization/__init__.py +4 -0
- aas_core_codegen/java/xmlization/_generate.py +2274 -0
- aas_core_codegen/jsonld/__init__.py +1 -0
- aas_core_codegen/jsonld/main.py +455 -0
- aas_core_codegen/jsonschema/__init__.py +1 -0
- aas_core_codegen/jsonschema/main.py +982 -0
- aas_core_codegen/main.py +245 -0
- aas_core_codegen/naming.py +133 -0
- aas_core_codegen/opcua/__init__.py +1 -0
- aas_core_codegen/opcua/main.py +1525 -0
- aas_core_codegen/opcua/naming.py +126 -0
- aas_core_codegen/parse/__init__.py +46 -0
- aas_core_codegen/parse/_rules.py +796 -0
- aas_core_codegen/parse/_stringify.py +532 -0
- aas_core_codegen/parse/_translate.py +3940 -0
- aas_core_codegen/parse/_types.py +973 -0
- aas_core_codegen/parse/retree/__init__.py +46 -0
- aas_core_codegen/parse/retree/_fix.py +434 -0
- aas_core_codegen/parse/retree/_parse.py +1143 -0
- aas_core_codegen/parse/retree/_render.py +298 -0
- aas_core_codegen/parse/retree/_stringify.py +199 -0
- aas_core_codegen/parse/retree/_types.py +362 -0
- aas_core_codegen/parse/retree/_visitor.py +70 -0
- aas_core_codegen/parse/tree.py +1303 -0
- aas_core_codegen/protobuf/__init__.py +1 -0
- aas_core_codegen/protobuf/common.py +225 -0
- aas_core_codegen/protobuf/description.py +1102 -0
- aas_core_codegen/protobuf/main.py +115 -0
- aas_core_codegen/protobuf/naming.py +143 -0
- aas_core_codegen/protobuf/structure/__init__.py +6 -0
- aas_core_codegen/protobuf/structure/_generate.py +502 -0
- aas_core_codegen/py.typed +1 -0
- aas_core_codegen/python/__init__.py +1 -0
- aas_core_codegen/python/aas_common/__init__.py +4 -0
- aas_core_codegen/python/aas_common/_generate.py +63 -0
- aas_core_codegen/python/common.py +406 -0
- aas_core_codegen/python/constants/__init__.py +5 -0
- aas_core_codegen/python/constants/_generate.py +377 -0
- aas_core_codegen/python/description.py +508 -0
- aas_core_codegen/python/jsonization/__init__.py +4 -0
- aas_core_codegen/python/jsonization/_generate.py +1391 -0
- aas_core_codegen/python/main.py +323 -0
- aas_core_codegen/python/naming.py +255 -0
- aas_core_codegen/python/stringification/__init__.py +4 -0
- aas_core_codegen/python/stringification/_generate.py +129 -0
- aas_core_codegen/python/structure/__init__.py +6 -0
- aas_core_codegen/python/structure/_generate.py +1801 -0
- aas_core_codegen/python/transpilation.py +958 -0
- aas_core_codegen/python/unrolling.py +156 -0
- aas_core_codegen/python/verification/__init__.py +6 -0
- aas_core_codegen/python/verification/_generate.py +1471 -0
- aas_core_codegen/python/xmlization/__init__.py +4 -0
- aas_core_codegen/python/xmlization/_generate.py +3003 -0
- aas_core_codegen/python_protobuf/__init__.py +1 -0
- aas_core_codegen/python_protobuf/main.py +1424 -0
- aas_core_codegen/python_protobuf/naming.py +85 -0
- aas_core_codegen/rdf_shacl/__init__.py +1 -0
- aas_core_codegen/rdf_shacl/_description.py +351 -0
- aas_core_codegen/rdf_shacl/common.py +206 -0
- aas_core_codegen/rdf_shacl/main.py +114 -0
- aas_core_codegen/rdf_shacl/naming.py +145 -0
- aas_core_codegen/rdf_shacl/rdf.py +435 -0
- aas_core_codegen/rdf_shacl/shacl.py +453 -0
- aas_core_codegen/run.py +124 -0
- aas_core_codegen/smoke/__init__.py +1 -0
- aas_core_codegen/smoke/main.py +219 -0
- aas_core_codegen/specific_implementations.py +72 -0
- aas_core_codegen/stringify.py +333 -0
- aas_core_codegen/typescript/__init__.py +1 -0
- aas_core_codegen/typescript/aas_common/__init__.py +4 -0
- aas_core_codegen/typescript/aas_common/_generate.py +472 -0
- aas_core_codegen/typescript/common.py +340 -0
- aas_core_codegen/typescript/constants/__init__.py +5 -0
- aas_core_codegen/typescript/constants/_generate.py +347 -0
- aas_core_codegen/typescript/description.py +530 -0
- aas_core_codegen/typescript/jsonization/__init__.py +4 -0
- aas_core_codegen/typescript/jsonization/_generate.py +1510 -0
- aas_core_codegen/typescript/main.py +258 -0
- aas_core_codegen/typescript/naming.py +189 -0
- aas_core_codegen/typescript/stringification/__init__.py +4 -0
- aas_core_codegen/typescript/stringification/_generate.py +367 -0
- aas_core_codegen/typescript/structure/__init__.py +6 -0
- aas_core_codegen/typescript/structure/_generate.py +2500 -0
- aas_core_codegen/typescript/transpilation.py +1051 -0
- aas_core_codegen/typescript/unrolling.py +159 -0
- aas_core_codegen/typescript/verification/__init__.py +6 -0
- aas_core_codegen/typescript/verification/_generate.py +1578 -0
- aas_core_codegen/xsd/__init__.py +1 -0
- aas_core_codegen/xsd/main.py +1187 -0
- aas_core_codegen/xsd/naming.py +83 -0
- aas_core_codegen/yielding/__init__.py +1 -0
- aas_core_codegen/yielding/flow.py +139 -0
- aas_core_codegen/yielding/linear.py +754 -0
- aas_core_codegen-0.0.16.dist-info/METADATA +211 -0
- aas_core_codegen-0.0.16.dist-info/RECORD +604 -0
- aas_core_codegen-0.0.16.dist-info/WHEEL +5 -0
- aas_core_codegen-0.0.16.dist-info/entry_points.txt +3 -0
- aas_core_codegen-0.0.16.dist-info/licenses/AUTHORS +9 -0
- aas_core_codegen-0.0.16.dist-info/licenses/LICENSE +23 -0
- aas_core_codegen-0.0.16.dist-info/top_level.txt +2 -0
- dev/continuous_integration/__init__.py +1 -0
- dev/continuous_integration/check_help_in_readme.py +208 -0
- dev/continuous_integration/check_init_and_pyproject_consistent.py +154 -0
- dev/continuous_integration/precommit.py +400 -0
- dev/dev_scripts/__init__.py +1 -0
- dev/dev_scripts/compare_rendered_regexes_against_source_py.py +42 -0
- dev/dev_scripts/copy_to_aas_core3_cpp.py +100 -0
- dev/dev_scripts/copy_to_aas_core3_java.py +90 -0
- dev/dev_scripts/download_latest_aas_core_meta_v3.py +114 -0
- dev/dev_scripts/draw_bipartite_graph_based_on_lines.py +37 -0
- dev/dev_scripts/run_tests_with_rerecord.py +69 -0
- dev/dev_scripts/update_to_aas_core_meta.py +174 -0
- dev/integration_tests/input/jsonschema/boilerplate/main.py +55 -0
- dev/integration_tests/input/meta_model.py +38 -0
- dev/integration_tests/input/python/boilerplate/main.py +153 -0
- dev/integration_tests/main.py +258 -0
- dev/test_data/csharp/test_structure/concrete_class_with_descendants/meta_model.py +15 -0
- dev/test_data/csharp/test_structure/constructor_without_arguments/all_properties_optional/meta_model.py +9 -0
- dev/test_data/csharp/test_structure/constructor_without_arguments/no_properties/meta_model.py +6 -0
- dev/test_data/csharp/test_verification/builtin_functions/len/on_list/meta_model.py +20 -0
- dev/test_data/csharp/test_verification/builtin_functions/len/on_str/meta_model.py +16 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_prefix/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_suffix/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_group_with_quantifier/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_the_middle/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_union/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/single_utf32_literal/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_within_group/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_without_group/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_beginning/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_end/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/in_the_middle/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/multiple/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single_with_quantifier/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/mixed_with_non_utf32/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/more_than_two_high_surrogates/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges/meta_model.py +8 -0
- 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
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate_with_quantifier/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/two_high_surrogates/meta_model.py +8 -0
- dev/test_data/intermediate/expected/class/empty/meta_model.py +6 -0
- dev/test_data/intermediate/expected/class/implementation_specific_method/meta_model.py +8 -0
- dev/test_data/intermediate/expected/class/inheritance/meta_model.py +41 -0
- dev/test_data/intermediate/expected/class/methods_with_contracts/meta_model.py +15 -0
- dev/test_data/intermediate/expected/class/only_method_no_property/meta_model.py +7 -0
- dev/test_data/intermediate/expected/class/only_property_no_method/meta_model.py +9 -0
- dev/test_data/intermediate/expected/constant/constant_set/of_enum/meta_model.py +12 -0
- dev/test_data/intermediate/expected/constant/constant_set/of_str/meta_model.py +4 -0
- dev/test_data/intermediate/expected/constant/constant_set/with_description/meta_model.py +6 -0
- dev/test_data/intermediate/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
- dev/test_data/intermediate/expected/constant/constant_str/only_value/meta_model.py +7 -0
- dev/test_data/intermediate/expected/constant/constant_str/with_description/meta_model.py +5 -0
- dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_in_literal/meta_model.py +20 -0
- dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_outside_literal/meta_model.py +20 -0
- dev/test_data/intermediate/expected/empty/meta_model.py +2 -0
- dev/test_data/intermediate/expected/enumeration/meta_model.py +9 -0
- dev/test_data/intermediate/expected/interface/basic/meta_model.py +14 -0
- dev/test_data/intermediate/expected/interface/empty/meta_model.py +7 -0
- dev/test_data/intermediate/expected/interface/inheritance/meta_model.py +27 -0
- dev/test_data/intermediate/expected/interface/method_signature/meta_model.py +10 -0
- dev/test_data/intermediate/expected/interface/only_constructor/meta_model.py +11 -0
- dev/test_data/intermediate/expected/method/non_mutating/implementation_specific/meta_model.py +12 -0
- dev/test_data/intermediate/expected/method/non_mutating/understood/meta_model.py +11 -0
- dev/test_data/intermediate/expected/type_annotation/atomic/meta_model.py +9 -0
- dev/test_data/intermediate/expected/type_annotation/subscripted/class/meta_model.py +13 -0
- dev/test_data/intermediate/expected/type_annotation/subscripted/primitive/meta_model.py +9 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/enumeration_literals_in_subset_outside_of_superset/meta_model.py +20 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/invalid_literal/meta_model.py +11 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_between_enumeration_and_literal/meta_model.py +30 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_in_enumerations_between_subset_and_superset/meta_model.py +21 -0
- dev/test_data/intermediate/unexpected/constant_set/of_str/literals_in_subset_outside_of_superset/meta_model.py +18 -0
- dev/test_data/intermediate/unexpected/constant_set/of_str/mismatch_between_type_annotation_and_literals/meta_model.py +10 -0
- dev/test_data/intermediate/unexpected/constant_set/of_str/superset_and_subset_mismatch_in_type/meta_model.py +12 -0
- dev/test_data/intermediate/unexpected/constraints/dangling_constraintref/meta_model.py +18 -0
- dev/test_data/intermediate/unexpected/constraints/duplicate_constraints/meta_model.py +20 -0
- dev/test_data/intermediate/unexpected/documentation/unexpected_documentation_elements/meta_model.py +34 -0
- dev/test_data/intermediate/unexpected/invariant/class_invariant_uses_re/meta_model.py +10 -0
- dev/test_data/intermediate/unexpected/invariant/invariant_of_constrained_primitive_uses_re/meta_model.py +7 -0
- dev/test_data/intermediate/unexpected/invariant/unexpected_argument_count_to_len/meta_model.py +20 -0
- dev/test_data/intermediate/unexpected/invariant/unhandled_built_in_function/meta_model.py +16 -0
- dev/test_data/intermediate/unexpected/method_definitions/non_constant_default/meta_model.py +7 -0
- dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/default_non_none/meta_model.py +16 -0
- dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/no_default/meta_model.py +16 -0
- dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/after_inheritance/meta_model.py +58 -0
- dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/type_missmatch/meta_model.py +9 -0
- dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/within_class/meta_model.py +22 -0
- dev/test_data/jsonschema/test_main/regression_when_len_constraints_on_inherited_property/meta_model.py +28 -0
- dev/test_data/opcua/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
- dev/test_data/opcua/test_main/classes_with_invariants/meta_model.py +21 -0
- dev/test_data/opcua/test_main/concrete_class_with_descendant/meta_model.py +27 -0
- dev/test_data/opcua/test_main/concrete_class_with_enum/meta_model.py +21 -0
- dev/test_data/opcua/test_main/concrete_class_with_list_of_instances/meta_model.py +21 -0
- dev/test_data/opcua/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
- dev/test_data/opcua/test_main/concrete_class_with_string/meta_model.py +13 -0
- dev/test_data/opcua/test_main/constrained_primitive/meta_model.py +20 -0
- dev/test_data/opcua/test_main/multiple_inheritance/meta_model.py +25 -0
- dev/test_data/parse/expected/constant/constant_set/of_enum/meta_model.py +12 -0
- dev/test_data/parse/expected/constant/constant_set/of_str/meta_model.py +4 -0
- dev/test_data/parse/expected/constant/constant_set/with_description/meta_model.py +6 -0
- dev/test_data/parse/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
- dev/test_data/parse/expected/constant/constant_str/only_value/meta_model.py +7 -0
- dev/test_data/parse/expected/constant/constant_str/with_description/meta_model.py +5 -0
- dev/test_data/parse/expected/enum/ok/meta_model.py +15 -0
- dev/test_data/parse/expected/implementation_specific_class/properties_and_methods_in_implementation_specific_class/meta_model.py +17 -0
- dev/test_data/parse/expected/inheritance/basic/meta_model.py +11 -0
- dev/test_data/parse/expected/inheritance/diamond/meta_model.py +26 -0
- dev/test_data/parse/expected/inheritance/inheritance_from_concrete_class/meta_model.py +10 -0
- dev/test_data/parse/expected/invariants/in_relation/meta_model.py +16 -0
- dev/test_data/parse/expected/method/arguments/meta_model.py +7 -0
- dev/test_data/parse/expected/method/basic/meta_model.py +7 -0
- dev/test_data/parse/expected/method/contracts/condition_as_keyword_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/condition_as_positional_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/description_as_keyword_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/description_as_positional_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/multiple_contracts_in_order/meta_model.py +17 -0
- dev/test_data/parse/expected/method/contracts/postcondition/basic/meta_model.py +10 -0
- dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_keyword_arguments/meta_model.py +9 -0
- dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_positional_arguments/meta_model.py +9 -0
- dev/test_data/parse/expected/method/default/meta_model.py +9 -0
- dev/test_data/parse/expected/method/description/meta_model.py +8 -0
- dev/test_data/parse/expected/method/is_implementation_specific/meta_model.py +8 -0
- dev/test_data/parse/expected/method/non_mutating/meta_model.py +11 -0
- dev/test_data/parse/expected/method/returns_none/meta_model.py +7 -0
- dev/test_data/parse/expected/method/returns_something/meta_model.py +7 -0
- dev/test_data/parse/expected/single_class/description/meta_model.py +12 -0
- dev/test_data/parse/expected/single_class/empty/meta_model.py +6 -0
- dev/test_data/parse/expected/single_class/property/description/meta_model.py +14 -0
- dev/test_data/parse/expected/single_class/property/mandatory/meta_model.py +6 -0
- dev/test_data/parse/expected/single_class/property/optional/meta_model.py +6 -0
- dev/test_data/parse/expected/single_class/property/recursion_to_entity/meta_model.py +6 -0
- dev/test_data/parse/unexpected/class_decorators/non_name_decorator/meta_model.py +7 -0
- dev/test_data/parse/unexpected/class_decorators/unknown_decorator/meta_model.py +7 -0
- dev/test_data/parse/unexpected/class_definitions/is_abstract_and_implementation_specific/meta_model.py +8 -0
- dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_before_a_method/meta_model.py +11 -0
- dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_for_a_pass/meta_model.py +9 -0
- dev/test_data/parse/unexpected/class_definitions/unexpected_double_description_for_a_property/meta_model.py +10 -0
- dev/test_data/parse/unexpected/class_inheritances/inheriting_from_implementation_specific_parent/meta_model.py +20 -0
- dev/test_data/parse/unexpected/class_inheritances/non_name_super_class/meta_model.py +6 -0
- dev/test_data/parse/unexpected/enum/expression_as_assignment_value/meta_model.py +6 -0
- dev/test_data/parse/unexpected/enum/non_assignment/meta_model.py +8 -0
- dev/test_data/parse/unexpected/enum/non_string_literal/meta_model.py +6 -0
- dev/test_data/parse/unexpected/enum/unexpected_inheritance/meta_model.py +6 -0
- dev/test_data/parse/unexpected/method_contracts/contract/non_lambda_condition/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/contract/non_string_literal_description/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/contract/without_any_arguments/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/contract/without_condition/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/postcondition/OLD_in_postcondition_without_snapshot/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/postcondition/argument_missing_in_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/precondition/argument_missing_in_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/argument_missing_in_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/capture_not_a_lambda/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/invalid_name/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/name_not_a_string_literal/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_capture/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_name/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_constructor/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_verification_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/non_name_decorator/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/unknown_call_decorator/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/unknown_name_decorator/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_definitions/argument_with_final/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/argument_without_a_type_annotation/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/default_for_self/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/dunder/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/init_with_return_type/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_keyword_only_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_positional_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_type_annotation_for_self/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_variable_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_variable_keyword_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/without_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/without_self/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/without_type_annotation_for_result/meta_model.py +7 -0
- dev/test_data/parse/unexpected/property_definitions/final_without_subscript/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/nested_final/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/non_simple/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/unexpected_assignment/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/unexpected_non_name_property/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/without_type_annotation/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/constant_set_with_a_non_set_subset/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_inheritance/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_a_property/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_an_argument/meta_model.py +7 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_constant_set/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_subset_in_constant_set/meta_model.py +4 -0
- dev/test_data/parse/unexpected/symbol_table/inheritance_from_non_class/meta_model.py +10 -0
- dev/test_data/parse_retree/expected/character_set/common_escaping/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/complementing/double_caret/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/complementing/multiple_ranges/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/complementing/suffix_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/escape_first_caret/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/literals_which_need_no_escaping_in_characters_set_but_need_escaping_outside/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/multiple_ranges/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/single_literal/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/single_range/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/unescaped_dash/only_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/unescaped_dash/prefix_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/unescaped_dash/suffix_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/dot/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/group/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/group_in_a_group/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/group_of_union_of_empty_concatenations/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/regex/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/union_of_empty_concatenations/source.py +1 -0
- dev/test_data/parse_retree/expected/escaped_literals/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/at_the_beginning/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/at_the_end/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/in_the_middle/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/single_formatted_value/source.py +1 -0
- dev/test_data/parse_retree/expected/literal/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/at_least_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/at_least_one/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/at_most_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/exactly_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/maybe/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/zero_or_more/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_one/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/at_most_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/exactly_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/maybe/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/zero_or_more/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_character_set/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_formatted_value/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_group/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_literal/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/double_end_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/double_start_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/end_symbol_in_the_middle/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/only_start_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/only_stop_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_at_the_beginning/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_in_the_middle/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/stop_symbol_at_the_end/source.py +1 -0
- dev/test_data/parse_retree/expected/union/of_character_sets/source.py +1 -0
- dev/test_data/parse_retree/expected/union/of_groups/source.py +1 -0
- dev/test_data/parse_retree/expected/union/of_string_literals/source.py +1 -0
- dev/test_data/parse_retree/expected/union/within_group/source.py +1 -0
- dev/test_data/parse_retree/expected/whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/Uxxxxxxxx_out_of_range/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/only_backslash/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_Uxxxxxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_uxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unexpected_escaping/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/Uxxxxxxxx_out_of_range/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/only_backslash/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_Uxxxxxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_uxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unexpected_escaping/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_character_range/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_quantifier/at_least_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_quantifier/between_3_and_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_quantifier/exactly_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unhandled_group_directives/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/character_set/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/group/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/group_of_union_of_empty_concatenations/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/quantifier/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_comma/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_number_and_comma/source.py +1 -0
- dev/test_data/proto/test_main/expected/abstract_and_concrete_classes/meta_model.py +37 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_descendants/meta_model.py +30 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_enum/meta_model.py +21 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_list_of_instances/meta_model.py +21 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_primitive_attributes/meta_model.py +41 -0
- dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/expected_output/pbization.py +532 -0
- dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/expected_output/pbization.py +527 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/meta_model.py +27 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_enum/expected_output/pbization.py +290 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_enum/meta_model.py +21 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/expected_output/pbization.py +328 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/meta_model.py +23 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/expected_output/pbization.py +274 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
- dev/test_data/rdf_shacl/test_main/expected/regression_when_lang_string_class_is_missing/meta_model.py +29 -0
- dev/test_data/rdf_shacl/test_main/expected/regression_when_len_constraints_on_inherited_property/meta_model.py +27 -0
- dev/test_data/rdf_shacl/test_main/unexpected/regression_len_constraint_on_class_property/meta_model.py +61 -0
- dev/test_data/real_meta_models/aas_core_meta.v3.py +5721 -0
- dev/test_data/smoke/test_main/unexpected/infer_for_schema_error/meta_model.py +12 -0
- dev/test_data/smoke/test_main/unexpected/intermediate_error/meta_model.py +18 -0
- dev/test_data/smoke/test_main/unexpected/parse_error/meta_model.py +5 -0
- dev/test_data/smoke/test_main/unexpected/pattern_verification_unparsable_regex/direct_match/meta_model.py +8 -0
- dev/test_data/smoke/test_main/unexpected/type_error/meta_model.py +18 -0
- dev/tests/__init__.py +1 -0
- dev/tests/common.py +197 -0
- dev/tests/cpp/__init__.py +0 -0
- dev/tests/cpp/test_common.py +32 -0
- dev/tests/cpp/test_main.py +144 -0
- dev/tests/cpp/test_pattern.py +188 -0
- dev/tests/cpp/test_verification.py +189 -0
- dev/tests/cpp/test_yielding.py +225 -0
- dev/tests/csharp/__init__.py +0 -0
- dev/tests/csharp/live_test_main.py +109 -0
- dev/tests/csharp/test_common.py +28 -0
- dev/tests/csharp/test_description.py +684 -0
- dev/tests/csharp/test_main.py +129 -0
- dev/tests/csharp/test_structure.py +93 -0
- dev/tests/csharp/test_verification.py +82 -0
- dev/tests/description.py +29 -0
- dev/tests/golang/__init__.py +0 -0
- dev/tests/golang/test_common.py +78 -0
- dev/tests/golang/test_main.py +128 -0
- dev/tests/infer_for_schema/__init__.py +0 -0
- dev/tests/infer_for_schema/common.py +47 -0
- dev/tests/infer_for_schema/test_len_on_properties.py +955 -0
- dev/tests/infer_for_schema/test_len_on_self.py +580 -0
- dev/tests/infer_for_schema/test_patterns_on_properties.py +686 -0
- dev/tests/infer_for_schema/test_patterns_on_self.py +258 -0
- dev/tests/infer_for_schema/test_property_in_set_of_enumeration_literals.py +600 -0
- dev/tests/infer_for_schema/test_property_in_set_of_primitives.py +549 -0
- dev/tests/intermediate/__init__.py +0 -0
- dev/tests/intermediate/test_constructor.py +719 -0
- dev/tests/intermediate/test_hierarchy.py +221 -0
- dev/tests/intermediate/test_revm.py +134 -0
- dev/tests/intermediate/test_translate.py +337 -0
- dev/tests/intermediate/test_type_inference.py +333 -0
- dev/tests/intermediate/test_types.py +169 -0
- dev/tests/java/__init__.py +0 -0
- dev/tests/java/test_common.py +20 -0
- dev/tests/java/test_description.py +128 -0
- dev/tests/java/test_main.py +234 -0
- dev/tests/jsonld_context/test_main.py +79 -0
- dev/tests/opcua/__init__.py +3 -0
- dev/tests/opcua/test_main.py +110 -0
- dev/tests/our_jsonschema/__init__.py +3 -0
- dev/tests/our_jsonschema/test_main.py +232 -0
- dev/tests/parse/__init__.py +0 -0
- dev/tests/parse/test_parse.py +503 -0
- dev/tests/parse/test_retree.py +272 -0
- dev/tests/proto/__init__.py +0 -0
- dev/tests/proto/test_main.py +112 -0
- dev/tests/python/__init__.py +0 -0
- dev/tests/python/test_common.py +124 -0
- dev/tests/python/test_main.py +126 -0
- dev/tests/python/test_xml_playground.py +254 -0
- dev/tests/python_protobuf/__init__.py +0 -0
- dev/tests/python_protobuf/test_main.py +111 -0
- dev/tests/rdf_shacl/__init__.py +0 -0
- dev/tests/rdf_shacl/test_common.py +32 -0
- dev/tests/rdf_shacl/test_description.py +223 -0
- dev/tests/rdf_shacl/test_main.py +194 -0
- dev/tests/smoke/__init__.py +0 -0
- dev/tests/smoke/test_main.py +83 -0
- dev/tests/test_common.py +94 -0
- dev/tests/typescript/__init__.py +0 -0
- dev/tests/typescript/test_common.py +108 -0
- dev/tests/typescript/test_main.py +125 -0
- dev/tests/xsd/__init__.py +0 -0
- dev/tests/xsd/test_main.py +227 -0
- dev/tests/yielding/__init__.py +0 -0
- 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
|