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,1980 @@
|
|
|
1
|
+
"""Generate C# code for XML-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, require
|
|
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_skip_whitespace_and_comments() -> Stripped:
|
|
31
|
+
"""Generate the function to skip whitespace text and XML comments."""
|
|
32
|
+
return Stripped(
|
|
33
|
+
f"""\
|
|
34
|
+
internal static void SkipNoneWhitespaceAndComments(
|
|
35
|
+
{I}Xml.XmlReader reader)
|
|
36
|
+
{{
|
|
37
|
+
{I}while (
|
|
38
|
+
{II}!reader.EOF
|
|
39
|
+
{II}&& (
|
|
40
|
+
{III}reader.NodeType == Xml.XmlNodeType.None
|
|
41
|
+
{III}|| reader.NodeType == Xml.XmlNodeType.Whitespace
|
|
42
|
+
{III}|| reader.NodeType == Xml.XmlNodeType.Comment))
|
|
43
|
+
{I}{{
|
|
44
|
+
{II}reader.Read();
|
|
45
|
+
{I}}}
|
|
46
|
+
}}"""
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _generate_read_whole_content_as_base_64() -> Stripped:
|
|
51
|
+
"""Generate the function to read the whole of element's content as bytes."""
|
|
52
|
+
return Stripped(
|
|
53
|
+
f"""\
|
|
54
|
+
/// <summary>
|
|
55
|
+
/// Read the whole content of an element into memory.
|
|
56
|
+
/// </summary>
|
|
57
|
+
private static byte[] ReadWholeContentAsBase64(
|
|
58
|
+
{I}Xml.XmlReader reader)
|
|
59
|
+
{{
|
|
60
|
+
{I}// The capacity of 1024 bytes is an arbitrary,
|
|
61
|
+
{I}// but plausible default capacity.
|
|
62
|
+
{I}byte[] buffer = new byte[1024];
|
|
63
|
+
{I}using System.IO.MemoryStream stream = (
|
|
64
|
+
{II}new System.IO.MemoryStream(1024));
|
|
65
|
+
{I}int readBytes;
|
|
66
|
+
{I}while ((readBytes = reader.ReadContentAsBase64(buffer, 0, 1024)) > 0)
|
|
67
|
+
{I}{{
|
|
68
|
+
{II}stream.Write(buffer, 0, readBytes);
|
|
69
|
+
{I}}}
|
|
70
|
+
{I}return stream.ToArray();
|
|
71
|
+
}}"""
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _generate_extract_element_name() -> Stripped:
|
|
76
|
+
"""Generate the function to strip the prefix and check the namespace."""
|
|
77
|
+
return Stripped(
|
|
78
|
+
f"""\
|
|
79
|
+
/// <summary>
|
|
80
|
+
/// Check the namespace and extract the element's name.
|
|
81
|
+
/// </summary>
|
|
82
|
+
private static string TryElementName(
|
|
83
|
+
{I}Xml.XmlReader reader,
|
|
84
|
+
{I}out Reporting.Error? error
|
|
85
|
+
{I})
|
|
86
|
+
{{
|
|
87
|
+
{I}// Pre-condition
|
|
88
|
+
{I}if (reader.NodeType != Xml.XmlNodeType.Element
|
|
89
|
+
{II}&& reader.NodeType != Xml.XmlNodeType.EndElement)
|
|
90
|
+
{I}{{
|
|
91
|
+
{II}throw new System.InvalidOperationException(
|
|
92
|
+
{III}"Expected to be at a start or an end element " +
|
|
93
|
+
{III}$"in {{nameof(TryElementName)}}, " +
|
|
94
|
+
{III}$"but got: {{reader.NodeType}}");
|
|
95
|
+
{I}}}
|
|
96
|
+
|
|
97
|
+
{I}error = null;
|
|
98
|
+
{I}if (reader.NamespaceURI != NS)
|
|
99
|
+
{I}{{
|
|
100
|
+
{II}error = new Reporting.Error(
|
|
101
|
+
{III}$"Expected an element within a namespace {{NS}}, " +
|
|
102
|
+
{III}$"but got: {{reader.NamespaceURI}}");
|
|
103
|
+
{III}return "";
|
|
104
|
+
{I}}}
|
|
105
|
+
|
|
106
|
+
{I}return reader.LocalName;
|
|
107
|
+
}}"""
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _generate_deserialize_primitive_property(
|
|
112
|
+
prop: intermediate.Property, cls: intermediate.ConcreteClass
|
|
113
|
+
) -> Stripped:
|
|
114
|
+
"""Generate the snippet to deserialize a property ``prop`` of primitive type."""
|
|
115
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
116
|
+
|
|
117
|
+
a_type = intermediate.try_primitive_type(type_anno)
|
|
118
|
+
assert a_type is not None, f"Unexpected type annotation: {prop.type_annotation}"
|
|
119
|
+
|
|
120
|
+
deserialization_expr: str
|
|
121
|
+
if a_type is intermediate.PrimitiveType.BOOL:
|
|
122
|
+
deserialization_expr = "reader.ReadContentAsBoolean()"
|
|
123
|
+
elif a_type is intermediate.PrimitiveType.INT:
|
|
124
|
+
deserialization_expr = "reader.ReadContentAsLong()"
|
|
125
|
+
elif a_type is intermediate.PrimitiveType.FLOAT:
|
|
126
|
+
deserialization_expr = "reader.ReadContentAsDouble()"
|
|
127
|
+
elif a_type is intermediate.PrimitiveType.STR:
|
|
128
|
+
deserialization_expr = "reader.ReadContentAsString()"
|
|
129
|
+
elif a_type is intermediate.PrimitiveType.BYTEARRAY:
|
|
130
|
+
deserialization_expr = f"""\
|
|
131
|
+
DeserializeImplementation.ReadWholeContentAsBase64(
|
|
132
|
+
{I}reader)"""
|
|
133
|
+
else:
|
|
134
|
+
assert_never(a_type)
|
|
135
|
+
|
|
136
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
137
|
+
|
|
138
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
139
|
+
cls_name = csharp_naming.class_name(cls.name)
|
|
140
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
141
|
+
|
|
142
|
+
if a_type is intermediate.PrimitiveType.STR:
|
|
143
|
+
empty_handling_body = Stripped(f'{target_var} = "";')
|
|
144
|
+
else:
|
|
145
|
+
empty_handling_body = Stripped(
|
|
146
|
+
f"""\
|
|
147
|
+
error = new Reporting.Error(
|
|
148
|
+
{I}"The property {prop_name} of an instance of class {cls_name} " +
|
|
149
|
+
{I}"can not be de-serialized from a self-closing element " +
|
|
150
|
+
{I}"since it needs content");
|
|
151
|
+
error.PrependSegment(
|
|
152
|
+
{I}new Reporting.NameSegment(
|
|
153
|
+
{II}{xml_prop_name_literal}));
|
|
154
|
+
return null;"""
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return Stripped(
|
|
158
|
+
f"""\
|
|
159
|
+
if (isEmptyProperty)
|
|
160
|
+
{{
|
|
161
|
+
{I}{indent_but_first_line(empty_handling_body, I)}
|
|
162
|
+
}}
|
|
163
|
+
else
|
|
164
|
+
{{
|
|
165
|
+
{I}if (reader.EOF)
|
|
166
|
+
{I}{{
|
|
167
|
+
{II}error = new Reporting.Error(
|
|
168
|
+
{III}"Expected an XML content representing " +
|
|
169
|
+
{III}"the property {prop_name} of an instance of class {cls_name}, " +
|
|
170
|
+
{III}"but reached the end-of-file");
|
|
171
|
+
{II}return null;
|
|
172
|
+
{I}}}
|
|
173
|
+
|
|
174
|
+
{I}try
|
|
175
|
+
{I}{{
|
|
176
|
+
{II}{target_var} = {indent_but_first_line(deserialization_expr, I)};
|
|
177
|
+
{I}}}
|
|
178
|
+
{I}catch (System.Exception exception)
|
|
179
|
+
{I}{{
|
|
180
|
+
{II}if (exception is System.FormatException
|
|
181
|
+
{III}|| exception is System.Xml.XmlException)
|
|
182
|
+
{II}{{
|
|
183
|
+
{III}error = new Reporting.Error(
|
|
184
|
+
{IIII}"The property {prop_name} of an instance of class {cls_name} " +
|
|
185
|
+
{IIII}$"could not be de-serialized: {{exception.Message}}");
|
|
186
|
+
{III}error.PrependSegment(
|
|
187
|
+
{IIII}new Reporting.NameSegment(
|
|
188
|
+
{IIIII}{xml_prop_name_literal}));
|
|
189
|
+
{III}return null;
|
|
190
|
+
{II}}}
|
|
191
|
+
|
|
192
|
+
{II}throw;
|
|
193
|
+
{I}}}
|
|
194
|
+
}}"""
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _generate_deserialize_enumeration_property(
|
|
199
|
+
prop: intermediate.Property, cls: intermediate.ConcreteClass
|
|
200
|
+
) -> Stripped:
|
|
201
|
+
"""Generate the snippet to deserialize a property ``prop`` as an enum."""
|
|
202
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
203
|
+
|
|
204
|
+
assert isinstance(type_anno, intermediate.OurTypeAnnotation)
|
|
205
|
+
|
|
206
|
+
our_type = type_anno.our_type
|
|
207
|
+
assert isinstance(our_type, intermediate.Enumeration)
|
|
208
|
+
|
|
209
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
210
|
+
text_var = csharp_naming.variable_name(Identifier(f"text_{prop.name}"))
|
|
211
|
+
|
|
212
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
213
|
+
cls_name = csharp_naming.class_name(cls.name)
|
|
214
|
+
enum_name = csharp_naming.enum_name(our_type.name)
|
|
215
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
216
|
+
|
|
217
|
+
return Stripped(
|
|
218
|
+
f"""\
|
|
219
|
+
if (isEmptyProperty)
|
|
220
|
+
{{
|
|
221
|
+
{I}error = new Reporting.Error(
|
|
222
|
+
{II}"The property {prop_name} of an instance of class {cls_name} " +
|
|
223
|
+
{II}"can not be de-serialized from a self-closing element " +
|
|
224
|
+
{II}"since it needs content");
|
|
225
|
+
{I}error.PrependSegment(
|
|
226
|
+
{II}new Reporting.NameSegment(
|
|
227
|
+
{III}{xml_prop_name_literal}));
|
|
228
|
+
{I}return null;
|
|
229
|
+
}}
|
|
230
|
+
|
|
231
|
+
{I}if (reader.EOF)
|
|
232
|
+
{{
|
|
233
|
+
{II}error = new Reporting.Error(
|
|
234
|
+
{III}"Expected an XML content representing " +
|
|
235
|
+
{III}"the property {prop_name} of an instance of class {cls_name}, " +
|
|
236
|
+
{III}"but reached the end-of-file");
|
|
237
|
+
{II}return null;
|
|
238
|
+
}}
|
|
239
|
+
|
|
240
|
+
string {text_var};
|
|
241
|
+
try
|
|
242
|
+
{{
|
|
243
|
+
{I}{text_var} = reader.ReadContentAsString();
|
|
244
|
+
}}
|
|
245
|
+
catch (System.FormatException exception)
|
|
246
|
+
{{
|
|
247
|
+
{I}error = new Reporting.Error(
|
|
248
|
+
{II}"The property {prop_name} of an instance of class {cls_name} " +
|
|
249
|
+
{II}$"could not be de-serialized as a string: {{exception}}");
|
|
250
|
+
{I}error.PrependSegment(
|
|
251
|
+
{II}new Reporting.NameSegment(
|
|
252
|
+
{III}{xml_prop_name_literal}));
|
|
253
|
+
{I}return null;
|
|
254
|
+
}}
|
|
255
|
+
|
|
256
|
+
{target_var} = Stringification.{enum_name}FromString(
|
|
257
|
+
{I}{text_var});
|
|
258
|
+
|
|
259
|
+
if ({target_var} == null)
|
|
260
|
+
{{
|
|
261
|
+
{I}error = new Reporting.Error(
|
|
262
|
+
{II}"The property {prop_name} of an instance of class {cls_name} " +
|
|
263
|
+
{II}"could not be de-serialized from an unexpected enumeration literal: " +
|
|
264
|
+
{II}{text_var});
|
|
265
|
+
{I}error.PrependSegment(
|
|
266
|
+
{II}new Reporting.NameSegment(
|
|
267
|
+
{III}{xml_prop_name_literal}));
|
|
268
|
+
{I}return null;
|
|
269
|
+
}}"""
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def _generate_deserialize_interface_property(
|
|
274
|
+
prop: intermediate.Property,
|
|
275
|
+
cls: intermediate.ConcreteClass,
|
|
276
|
+
) -> Stripped:
|
|
277
|
+
"""Generate the snippet to deserialize a property ``prop`` as an interface."""
|
|
278
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
279
|
+
|
|
280
|
+
assert isinstance(type_anno, intermediate.OurTypeAnnotation)
|
|
281
|
+
|
|
282
|
+
our_type = type_anno.our_type
|
|
283
|
+
assert isinstance(
|
|
284
|
+
our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
285
|
+
)
|
|
286
|
+
assert our_type.interface is not None
|
|
287
|
+
|
|
288
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
289
|
+
cls_name = csharp_naming.class_name(cls.name)
|
|
290
|
+
|
|
291
|
+
interface_name = csharp_naming.interface_name(our_type.interface.name)
|
|
292
|
+
|
|
293
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
294
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
295
|
+
|
|
296
|
+
return Stripped(
|
|
297
|
+
f"""\
|
|
298
|
+
if (isEmptyProperty)
|
|
299
|
+
{{
|
|
300
|
+
{I}error = new Reporting.Error(
|
|
301
|
+
{II}$"Expected an XML element within the element {{elementName}} representing " +
|
|
302
|
+
{II}"the property {prop_name} of an instance of class {cls_name}, " +
|
|
303
|
+
{II}"but encountered a self-closing element {{elementName}}");
|
|
304
|
+
{I}return null;
|
|
305
|
+
}}
|
|
306
|
+
|
|
307
|
+
// We need to skip the whitespace here in order to be able to look ahead
|
|
308
|
+
// the discriminator element shortly.
|
|
309
|
+
SkipNoneWhitespaceAndComments(reader);
|
|
310
|
+
|
|
311
|
+
if (reader.EOF)
|
|
312
|
+
{{
|
|
313
|
+
{I}error = new Reporting.Error(
|
|
314
|
+
{II}$"Expected an XML element within the element {{elementName}} representing " +
|
|
315
|
+
{II}"the property {prop_name} of an instance of class {cls_name}, " +
|
|
316
|
+
{II}"but reached the end-of-file");
|
|
317
|
+
{I}return null;
|
|
318
|
+
}}
|
|
319
|
+
|
|
320
|
+
// Try to look ahead the discriminator name;
|
|
321
|
+
// we need this name only for the error reporting below.
|
|
322
|
+
// {interface_name}FromElement will perform more sophisticated
|
|
323
|
+
// checks.
|
|
324
|
+
string? discriminatorElementName = null;
|
|
325
|
+
if (reader.NodeType == Xml.XmlNodeType.Element)
|
|
326
|
+
{{
|
|
327
|
+
{I}discriminatorElementName = reader.LocalName;
|
|
328
|
+
}}
|
|
329
|
+
|
|
330
|
+
{target_var} = {interface_name}FromElement(
|
|
331
|
+
{I}reader, out error);
|
|
332
|
+
|
|
333
|
+
if (error != null)
|
|
334
|
+
{{
|
|
335
|
+
{I}if (discriminatorElementName != null)
|
|
336
|
+
{I}{{
|
|
337
|
+
{II}error.PrependSegment(
|
|
338
|
+
{III}new Reporting.NameSegment(
|
|
339
|
+
{IIII}discriminatorElementName));
|
|
340
|
+
{I}}}
|
|
341
|
+
|
|
342
|
+
{I}error.PrependSegment(
|
|
343
|
+
{II}new Reporting.NameSegment(
|
|
344
|
+
{III}{xml_prop_name_literal}));
|
|
345
|
+
{I}return null;
|
|
346
|
+
}}"""
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _generate_deserialize_cls_property(prop: intermediate.Property) -> Stripped:
|
|
351
|
+
"""Generate the snippet to deserialize a property ``prop`` as a concrete class."""
|
|
352
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
353
|
+
|
|
354
|
+
assert isinstance(type_anno, intermediate.OurTypeAnnotation)
|
|
355
|
+
|
|
356
|
+
our_type = type_anno.our_type
|
|
357
|
+
assert isinstance(our_type, intermediate.ConcreteClass)
|
|
358
|
+
|
|
359
|
+
target_cls_name = csharp_naming.class_name(our_type.name)
|
|
360
|
+
|
|
361
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
362
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
363
|
+
|
|
364
|
+
return Stripped(
|
|
365
|
+
f"""\
|
|
366
|
+
{target_var} = {target_cls_name}FromSequence(
|
|
367
|
+
{I}reader, isEmptyProperty, out error);
|
|
368
|
+
|
|
369
|
+
if (error != null)
|
|
370
|
+
{{
|
|
371
|
+
{I}error.PrependSegment(
|
|
372
|
+
{II}new Reporting.NameSegment(
|
|
373
|
+
{III}{xml_prop_name_literal}));
|
|
374
|
+
{I}return null;
|
|
375
|
+
}}"""
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def _generate_deserialize_list_property(prop: intermediate.Property) -> Stripped:
|
|
380
|
+
"""Generate the code to de-serialize a property ``prop`` as a list."""
|
|
381
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
382
|
+
|
|
383
|
+
# fmt: off
|
|
384
|
+
assert (
|
|
385
|
+
isinstance(type_anno, intermediate.ListTypeAnnotation)
|
|
386
|
+
and isinstance(type_anno.items, intermediate.OurTypeAnnotation)
|
|
387
|
+
and isinstance(
|
|
388
|
+
type_anno.items.our_type,
|
|
389
|
+
(intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
390
|
+
)
|
|
391
|
+
), "See intermediate._translate._verify_only_simple_type_patterns"
|
|
392
|
+
# fmt: on
|
|
393
|
+
|
|
394
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
395
|
+
index_var = csharp_naming.variable_name(Identifier(f"index_{prop.name}"))
|
|
396
|
+
|
|
397
|
+
item_our_type = type_anno.items.our_type
|
|
398
|
+
if (
|
|
399
|
+
isinstance(item_our_type, intermediate.AbstractClass)
|
|
400
|
+
or len(item_our_type.concrete_descendants) > 0
|
|
401
|
+
):
|
|
402
|
+
deserialize_method = (
|
|
403
|
+
f"{csharp_naming.interface_name(type_anno.items.our_type.name)}FromElement"
|
|
404
|
+
)
|
|
405
|
+
else:
|
|
406
|
+
deserialize_method = (
|
|
407
|
+
f"{csharp_naming.class_name(type_anno.items.our_type.name)}FromElement"
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
item_type = csharp_common.generate_type(type_anno.items)
|
|
411
|
+
|
|
412
|
+
xml_prop_name = naming.xml_property(prop.name)
|
|
413
|
+
xml_prop_name_literal = csharp_common.string_literal(xml_prop_name)
|
|
414
|
+
|
|
415
|
+
body_for_non_empty_property = Stripped(
|
|
416
|
+
f"""\
|
|
417
|
+
SkipNoneWhitespaceAndComments(reader);
|
|
418
|
+
|
|
419
|
+
int {index_var} = 0;
|
|
420
|
+
while (reader.NodeType == Xml.XmlNodeType.Element)
|
|
421
|
+
{{
|
|
422
|
+
{I}{item_type}? item = {deserialize_method}(
|
|
423
|
+
{II}reader, out error);
|
|
424
|
+
|
|
425
|
+
{I}if (error != null)
|
|
426
|
+
{I}{{
|
|
427
|
+
{II}error.PrependSegment(
|
|
428
|
+
{III}new Reporting.IndexSegment(
|
|
429
|
+
{IIII}{index_var}));
|
|
430
|
+
error.PrependSegment(
|
|
431
|
+
{I}new Reporting.NameSegment(
|
|
432
|
+
{II}{xml_prop_name_literal}));
|
|
433
|
+
{II}return null;
|
|
434
|
+
{I}}}
|
|
435
|
+
|
|
436
|
+
{I}{target_var}.Add(
|
|
437
|
+
{II}item
|
|
438
|
+
{III}?? throw new System.InvalidOperationException(
|
|
439
|
+
{IIII}"Unexpected item null when error null"));
|
|
440
|
+
|
|
441
|
+
{I}{index_var}++;
|
|
442
|
+
{I}SkipNoneWhitespaceAndComments(reader);
|
|
443
|
+
}}"""
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
return Stripped(
|
|
447
|
+
f"""\
|
|
448
|
+
{target_var} = new List<{item_type}>();
|
|
449
|
+
|
|
450
|
+
if (!isEmptyProperty)
|
|
451
|
+
{{
|
|
452
|
+
{I}{indent_but_first_line(body_for_non_empty_property, I)}
|
|
453
|
+
}}"""
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
@require(lambda prop, cls: id(prop) in cls.property_id_set)
|
|
458
|
+
def _generate_deserialize_property(
|
|
459
|
+
prop: intermediate.Property, cls: intermediate.ConcreteClass
|
|
460
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
461
|
+
"""Generate the snippet to deserialize the property ``prop`` from the content."""
|
|
462
|
+
blocks = [] # type: List[Stripped]
|
|
463
|
+
|
|
464
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
465
|
+
|
|
466
|
+
if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
|
|
467
|
+
blocks.append(_generate_deserialize_primitive_property(prop=prop, cls=cls))
|
|
468
|
+
elif isinstance(type_anno, intermediate.OurTypeAnnotation):
|
|
469
|
+
our_type = type_anno.our_type
|
|
470
|
+
if isinstance(our_type, intermediate.Enumeration):
|
|
471
|
+
blocks.append(
|
|
472
|
+
_generate_deserialize_enumeration_property(prop=prop, cls=cls)
|
|
473
|
+
)
|
|
474
|
+
elif isinstance(our_type, intermediate.ConstrainedPrimitive):
|
|
475
|
+
# NOTE (mristin, 2022-04-13):
|
|
476
|
+
# The constrained primitives are only verified, but not represented as
|
|
477
|
+
# separate classes in the XSD.
|
|
478
|
+
blocks.append(_generate_deserialize_primitive_property(prop=prop, cls=cls))
|
|
479
|
+
elif isinstance(
|
|
480
|
+
our_type, (intermediate.ConcreteClass, intermediate.AbstractClass)
|
|
481
|
+
):
|
|
482
|
+
if (
|
|
483
|
+
isinstance(our_type, intermediate.AbstractClass)
|
|
484
|
+
or len(our_type.concrete_descendants) > 0
|
|
485
|
+
):
|
|
486
|
+
blocks.append(
|
|
487
|
+
_generate_deserialize_interface_property(prop=prop, cls=cls)
|
|
488
|
+
)
|
|
489
|
+
else:
|
|
490
|
+
blocks.append(_generate_deserialize_cls_property(prop=prop))
|
|
491
|
+
else:
|
|
492
|
+
assert_never(our_type)
|
|
493
|
+
|
|
494
|
+
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
|
|
495
|
+
blocks.append(_generate_deserialize_list_property(prop=prop))
|
|
496
|
+
|
|
497
|
+
else:
|
|
498
|
+
assert_never(type_anno)
|
|
499
|
+
|
|
500
|
+
return Stripped("\n\n".join(blocks)), None
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
def _generate_deserialize_impl_cls_from_sequence(
|
|
504
|
+
cls: intermediate.ConcreteClass,
|
|
505
|
+
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
|
|
506
|
+
"""Generate the function to de-serialize the ``cls`` from an XML sequence."""
|
|
507
|
+
name = csharp_naming.class_name(identifier=cls.name)
|
|
508
|
+
|
|
509
|
+
description = Stripped(
|
|
510
|
+
f"""\
|
|
511
|
+
/// <summary>
|
|
512
|
+
/// Deserialize an instance of class {name} from a sequence of XML elements.
|
|
513
|
+
/// </summary>
|
|
514
|
+
/// <remarks>
|
|
515
|
+
/// If <paramref name="isEmptySequence" /> is set, we should try to deserialize
|
|
516
|
+
/// the instance from an empty sequence. That is, the parent element
|
|
517
|
+
/// was a self-closing element.
|
|
518
|
+
/// </remarks>"""
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
# NOTE (mristin, 2022-06-21):
|
|
522
|
+
# Hard-wire for the case when no sequence is read
|
|
523
|
+
if len(cls.constructor.arguments) == 0:
|
|
524
|
+
return (
|
|
525
|
+
Stripped(
|
|
526
|
+
f"""\
|
|
527
|
+
{description}
|
|
528
|
+
internal static Aas.{name} {name}FromSequence(
|
|
529
|
+
{I}Xml.XmlReader reader,
|
|
530
|
+
{I}bool isEmptySequence,
|
|
531
|
+
{I}out Reporting.Error? error)
|
|
532
|
+
{{
|
|
533
|
+
{I}error = null;
|
|
534
|
+
{I}return new Aas.{name}();
|
|
535
|
+
}} // internal static Aas.{name}? {name}FromSequence"""
|
|
536
|
+
),
|
|
537
|
+
None,
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
errors = [] # type: List[Error]
|
|
541
|
+
|
|
542
|
+
blocks = [
|
|
543
|
+
Stripped("error = null;"),
|
|
544
|
+
] # type: List[Stripped]
|
|
545
|
+
|
|
546
|
+
assert len(cls.constructor.arguments) > 0, "Otherwise expected hard-wiring above"
|
|
547
|
+
init_target_var_stmts = [] # type: List[Stripped]
|
|
548
|
+
for prop in cls.properties:
|
|
549
|
+
target_type = csharp_common.generate_type(prop.type_annotation)
|
|
550
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
551
|
+
|
|
552
|
+
# NOTE (mristin, 2022-04-13):
|
|
553
|
+
# This is a poor man's trick to make all temporary variables optional.
|
|
554
|
+
# The required constructor arguments / properties will be checked just
|
|
555
|
+
# before the constructor as we can not predict in advance which properties
|
|
556
|
+
# were actually provided without any lookahead in XML reading.
|
|
557
|
+
if not target_type.endswith("?"):
|
|
558
|
+
target_type = Stripped(f"{target_type}?")
|
|
559
|
+
|
|
560
|
+
init_target_var_stmts.append(Stripped(f"{target_type} {target_var} = null;"))
|
|
561
|
+
blocks.append(Stripped("\n".join(init_target_var_stmts)))
|
|
562
|
+
|
|
563
|
+
# noinspection PyListCreation
|
|
564
|
+
blocks_for_non_empty = [] # type: List[Stripped]
|
|
565
|
+
|
|
566
|
+
blocks_for_non_empty.append(
|
|
567
|
+
Stripped(
|
|
568
|
+
f"""\
|
|
569
|
+
SkipNoneWhitespaceAndComments(reader);
|
|
570
|
+
if (reader.EOF)
|
|
571
|
+
{{
|
|
572
|
+
{I}error = new Reporting.Error(
|
|
573
|
+
{II}"Expected an XML element representing " +
|
|
574
|
+
{II}"a property of an instance of class {name}, " +
|
|
575
|
+
{II}"but reached the end-of-file");
|
|
576
|
+
{I}return null;
|
|
577
|
+
}}"""
|
|
578
|
+
)
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
case_blocks = [] # type: List[Stripped]
|
|
582
|
+
for prop in cls.properties:
|
|
583
|
+
case_body, error = _generate_deserialize_property(prop=prop, cls=cls)
|
|
584
|
+
if error is not None:
|
|
585
|
+
errors.append(error)
|
|
586
|
+
continue
|
|
587
|
+
|
|
588
|
+
assert case_body is not None
|
|
589
|
+
|
|
590
|
+
xml_prop_name = naming.xml_property(prop.name)
|
|
591
|
+
xml_prop_name_literal = csharp_common.string_literal(xml_prop_name)
|
|
592
|
+
case_blocks.append(
|
|
593
|
+
Stripped(
|
|
594
|
+
f"""\
|
|
595
|
+
case {xml_prop_name_literal}:
|
|
596
|
+
{{
|
|
597
|
+
{I}{indent_but_first_line(case_body, I)}
|
|
598
|
+
{I}break;
|
|
599
|
+
}}"""
|
|
600
|
+
)
|
|
601
|
+
)
|
|
602
|
+
|
|
603
|
+
if len(errors) > 0:
|
|
604
|
+
return None, errors
|
|
605
|
+
|
|
606
|
+
case_blocks.append(
|
|
607
|
+
Stripped(
|
|
608
|
+
f"""\
|
|
609
|
+
default:
|
|
610
|
+
{I}error = new Reporting.Error(
|
|
611
|
+
{II}"We expected properties of the class {name}, " +
|
|
612
|
+
{II}"but got an unexpected element " +
|
|
613
|
+
{II}$"with the name {{elementName}}");
|
|
614
|
+
{I}return null;"""
|
|
615
|
+
)
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
switch_body = "\n".join(case_blocks)
|
|
619
|
+
|
|
620
|
+
blocks_for_non_empty.append(
|
|
621
|
+
Stripped(
|
|
622
|
+
f"""\
|
|
623
|
+
while (true)
|
|
624
|
+
{{
|
|
625
|
+
{I}SkipNoneWhitespaceAndComments(reader);
|
|
626
|
+
|
|
627
|
+
{I}if (reader.NodeType == Xml.XmlNodeType.EndElement || reader.EOF)
|
|
628
|
+
{I}{{
|
|
629
|
+
{II}break;
|
|
630
|
+
{I}}}
|
|
631
|
+
|
|
632
|
+
{I}if (reader.NodeType != Xml.XmlNodeType.Element)
|
|
633
|
+
{I}{{
|
|
634
|
+
{II}error = new Reporting.Error(
|
|
635
|
+
{III}"Expected an XML start element representing " +
|
|
636
|
+
{III}"a property of an instance of class {name}, " +
|
|
637
|
+
{III}$"but got the node of type {{reader.NodeType}} " +
|
|
638
|
+
{III}$"with the value {{reader.Value}}");
|
|
639
|
+
{II}return null;
|
|
640
|
+
{I}}}
|
|
641
|
+
|
|
642
|
+
{I}string elementName = TryElementName(
|
|
643
|
+
{II}reader, out error);
|
|
644
|
+
{I}if (error != null)
|
|
645
|
+
{I}{{
|
|
646
|
+
{II}return null;
|
|
647
|
+
{I}}}
|
|
648
|
+
|
|
649
|
+
{I}bool isEmptyProperty = reader.IsEmptyElement;
|
|
650
|
+
|
|
651
|
+
{I}// Skip the expected element
|
|
652
|
+
{I}reader.Read();
|
|
653
|
+
|
|
654
|
+
{I}switch (elementName)
|
|
655
|
+
{I}{{
|
|
656
|
+
{II}{indent_but_first_line(switch_body, II)}
|
|
657
|
+
{I}}}
|
|
658
|
+
|
|
659
|
+
{I}SkipNoneWhitespaceAndComments(reader);
|
|
660
|
+
|
|
661
|
+
{I}if (!isEmptyProperty)
|
|
662
|
+
{I}{{
|
|
663
|
+
{II}// Read the end element
|
|
664
|
+
|
|
665
|
+
{II}if (reader.EOF)
|
|
666
|
+
{II}{{
|
|
667
|
+
{III}error = new Reporting.Error(
|
|
668
|
+
{IIII}"Expected an XML end element to conclude a property of class {name} " +
|
|
669
|
+
{IIII}$"with the element name {{elementName}}, " +
|
|
670
|
+
{IIII}"but got the end-of-file.");
|
|
671
|
+
{III}return null;
|
|
672
|
+
{II}}}
|
|
673
|
+
{II}if (reader.NodeType != Xml.XmlNodeType.EndElement)
|
|
674
|
+
{II}{{
|
|
675
|
+
{III}error = new Reporting.Error(
|
|
676
|
+
{IIII}"Expected an XML end element to conclude a property of class {name} " +
|
|
677
|
+
{IIII}$"with the element name {{elementName}}, " +
|
|
678
|
+
{IIII}$"but got the node of type {{reader.NodeType}} " +
|
|
679
|
+
{IIII}$"with the value {{reader.Value}}");
|
|
680
|
+
{III}return null;
|
|
681
|
+
{II}}}
|
|
682
|
+
|
|
683
|
+
{II}string endElementName = TryElementName(
|
|
684
|
+
{III}reader, out error);
|
|
685
|
+
{II}if (error != null)
|
|
686
|
+
{II}{{
|
|
687
|
+
{III}return null;
|
|
688
|
+
{II}}}
|
|
689
|
+
|
|
690
|
+
{II}if (endElementName != elementName)
|
|
691
|
+
{II}{{
|
|
692
|
+
{III}error = new Reporting.Error(
|
|
693
|
+
{IIII}"Expected an XML end element to conclude a property of class {name} " +
|
|
694
|
+
{IIII}$"with the element name {{elementName}}, " +
|
|
695
|
+
{IIII}$"but got the end element with the name {{reader.Name}}");
|
|
696
|
+
{III}return null;
|
|
697
|
+
{II}}}
|
|
698
|
+
{II}// Skip the expected end element
|
|
699
|
+
{II}reader.Read();
|
|
700
|
+
{I}}}
|
|
701
|
+
}}"""
|
|
702
|
+
)
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
body_for_non_empty_sequence = "\n".join(blocks_for_non_empty)
|
|
706
|
+
blocks.append(
|
|
707
|
+
Stripped(
|
|
708
|
+
f"""\
|
|
709
|
+
if (!isEmptySequence)
|
|
710
|
+
{{
|
|
711
|
+
{I}{indent_but_first_line(body_for_non_empty_sequence, I)}
|
|
712
|
+
}}"""
|
|
713
|
+
)
|
|
714
|
+
)
|
|
715
|
+
|
|
716
|
+
# region Check that the mandatory properties have been set
|
|
717
|
+
|
|
718
|
+
for prop in cls.properties:
|
|
719
|
+
prop_csharp = csharp_naming.property_name(prop.name)
|
|
720
|
+
target_var = csharp_naming.variable_name(Identifier(f"the_{prop.name}"))
|
|
721
|
+
|
|
722
|
+
if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
723
|
+
blocks.append(
|
|
724
|
+
Stripped(
|
|
725
|
+
f"""\
|
|
726
|
+
if ({target_var} == null)
|
|
727
|
+
{{
|
|
728
|
+
{I}error = new Reporting.Error(
|
|
729
|
+
{II}"The required property {prop_csharp} has not been given " +
|
|
730
|
+
{II}"in the XML representation of an instance of class {name}");
|
|
731
|
+
{I}return null;
|
|
732
|
+
}}"""
|
|
733
|
+
)
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
# endregion
|
|
737
|
+
|
|
738
|
+
# region Pass in properties as arguments to the constructor
|
|
739
|
+
|
|
740
|
+
property_names = [prop.name for prop in cls.properties]
|
|
741
|
+
constructor_argument_names = [arg.name for arg in cls.constructor.arguments]
|
|
742
|
+
|
|
743
|
+
# fmt: off
|
|
744
|
+
assert (
|
|
745
|
+
set(prop.name for prop in cls.properties)
|
|
746
|
+
== set(arg.name for arg in cls.constructor.arguments)
|
|
747
|
+
), (
|
|
748
|
+
f"Expected the properties to coincide with constructor arguments, "
|
|
749
|
+
f"but they do not for {cls.name!r}:"
|
|
750
|
+
f"{property_names=}, {constructor_argument_names=}"
|
|
751
|
+
)
|
|
752
|
+
# fmt: on
|
|
753
|
+
|
|
754
|
+
init_writer = io.StringIO()
|
|
755
|
+
init_writer.write(f"return new Aas.{name}(\n")
|
|
756
|
+
|
|
757
|
+
for i, arg in enumerate(cls.constructor.arguments):
|
|
758
|
+
prop = cls.properties_by_name[arg.name]
|
|
759
|
+
|
|
760
|
+
# NOTE (mristin, 2022-04-13):
|
|
761
|
+
# The argument to the constructor may be optional while the property might
|
|
762
|
+
# be required, since we can set the default value in the body of the
|
|
763
|
+
# constructor. However, we can not have an optional property and a required
|
|
764
|
+
# constructor argument as we then would not know how to create the instance.
|
|
765
|
+
|
|
766
|
+
if not (
|
|
767
|
+
intermediate.type_annotations_equal(
|
|
768
|
+
arg.type_annotation, prop.type_annotation
|
|
769
|
+
)
|
|
770
|
+
or intermediate.type_annotations_equal(
|
|
771
|
+
intermediate.beneath_optional(arg.type_annotation),
|
|
772
|
+
prop.type_annotation,
|
|
773
|
+
)
|
|
774
|
+
):
|
|
775
|
+
errors.append(
|
|
776
|
+
Error(
|
|
777
|
+
arg.parsed.node,
|
|
778
|
+
f"Expected type annotation for property {prop.name!r} "
|
|
779
|
+
f"and constructor argument {arg.name!r} "
|
|
780
|
+
f"of the class {cls.name!r} to have matching types, "
|
|
781
|
+
f"but they do not: "
|
|
782
|
+
f"property type is {prop.type_annotation} "
|
|
783
|
+
f"and argument type is {arg.type_annotation}. "
|
|
784
|
+
f"Hence we do not know how to generate the call "
|
|
785
|
+
f"to the constructor in the JSON de-serialization.",
|
|
786
|
+
)
|
|
787
|
+
)
|
|
788
|
+
continue
|
|
789
|
+
|
|
790
|
+
arg_var = csharp_naming.variable_name(Identifier(f"the_{arg.name}"))
|
|
791
|
+
|
|
792
|
+
init_writer.write(f"{I}{arg_var}")
|
|
793
|
+
if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
794
|
+
init_writer.write("\n")
|
|
795
|
+
|
|
796
|
+
# Dedention could not work here due to prefix indention at the very
|
|
797
|
+
# beginning.
|
|
798
|
+
init_writer.write(
|
|
799
|
+
f"""\
|
|
800
|
+
{II} ?? throw new System.InvalidOperationException(
|
|
801
|
+
{III}"Unexpected null, had to be handled before")"""
|
|
802
|
+
)
|
|
803
|
+
|
|
804
|
+
if i < len(cls.constructor.arguments) - 1:
|
|
805
|
+
init_writer.write(",\n")
|
|
806
|
+
else:
|
|
807
|
+
init_writer.write(");")
|
|
808
|
+
|
|
809
|
+
if len(errors) > 0:
|
|
810
|
+
return None, errors
|
|
811
|
+
|
|
812
|
+
# endregion
|
|
813
|
+
|
|
814
|
+
blocks.append(Stripped(init_writer.getvalue()))
|
|
815
|
+
|
|
816
|
+
writer = io.StringIO()
|
|
817
|
+
writer.write(
|
|
818
|
+
f"""\
|
|
819
|
+
{description}
|
|
820
|
+
internal static Aas.{name}? {name}FromSequence(
|
|
821
|
+
{I}Xml.XmlReader reader,
|
|
822
|
+
{I}bool isEmptySequence,
|
|
823
|
+
{I}out Reporting.Error? error)
|
|
824
|
+
{{
|
|
825
|
+
"""
|
|
826
|
+
)
|
|
827
|
+
|
|
828
|
+
for i, block in enumerate(blocks):
|
|
829
|
+
if i > 0:
|
|
830
|
+
writer.write("\n\n")
|
|
831
|
+
writer.write(textwrap.indent(block, I))
|
|
832
|
+
|
|
833
|
+
writer.write(f"\n}} // internal static Aas.{name}? {name}FromSequence")
|
|
834
|
+
|
|
835
|
+
return Stripped(writer.getvalue()), None
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def _generate_deserialize_impl_concrete_cls_from_element(
|
|
839
|
+
cls: intermediate.ConcreteClass,
|
|
840
|
+
) -> Stripped:
|
|
841
|
+
"""Generate the function to de-serialize a concrete ``cls`` from an XML element."""
|
|
842
|
+
name = csharp_naming.class_name(cls.name)
|
|
843
|
+
xml_name = naming.xml_class_name(cls.name)
|
|
844
|
+
xml_name_literal = csharp_common.string_literal(xml_name)
|
|
845
|
+
|
|
846
|
+
# NOTE (mristin, 2022-06-21):
|
|
847
|
+
# We need to propagate nullability. Otherwise, InspectCode complains.
|
|
848
|
+
result_nullability = "?" if len(cls.constructor.arguments) > 0 else ""
|
|
849
|
+
|
|
850
|
+
body = Stripped(
|
|
851
|
+
f"""\
|
|
852
|
+
error = null;
|
|
853
|
+
|
|
854
|
+
SkipNoneWhitespaceAndComments(reader);
|
|
855
|
+
|
|
856
|
+
if (reader.EOF)
|
|
857
|
+
{{
|
|
858
|
+
{I}error = new Reporting.Error(
|
|
859
|
+
{II}"Expected an XML element representing an instance of class {name}, " +
|
|
860
|
+
{II}"but reached the end-of-file");
|
|
861
|
+
{I}return null;
|
|
862
|
+
}}
|
|
863
|
+
|
|
864
|
+
if (reader.NodeType != Xml.XmlNodeType.Element)
|
|
865
|
+
{{
|
|
866
|
+
{I}error = new Reporting.Error(
|
|
867
|
+
{II}"Expected an XML element representing an instance of class {name}, " +
|
|
868
|
+
{II}$"but got a node of type {{reader.NodeType}} " +
|
|
869
|
+
{II}$"with value {{reader.Value}}");
|
|
870
|
+
{I}return null;
|
|
871
|
+
}}
|
|
872
|
+
|
|
873
|
+
string elementName = TryElementName(
|
|
874
|
+
reader, out error);
|
|
875
|
+
if (error != null)
|
|
876
|
+
{{
|
|
877
|
+
{I}return null;
|
|
878
|
+
}}
|
|
879
|
+
|
|
880
|
+
if (elementName != {xml_name_literal})
|
|
881
|
+
{{
|
|
882
|
+
{I}error = new Reporting.Error(
|
|
883
|
+
{II}"Expected an element representing an instance of class {name} " +
|
|
884
|
+
{II}$"with element name {xml_name}, but got: {{elementName}}");
|
|
885
|
+
{I}return null;
|
|
886
|
+
}}
|
|
887
|
+
|
|
888
|
+
bool isEmptyElement = reader.IsEmptyElement;
|
|
889
|
+
|
|
890
|
+
// Skip the element node and go to the content
|
|
891
|
+
reader.Read();
|
|
892
|
+
|
|
893
|
+
Aas.{name}{result_nullability} result = (
|
|
894
|
+
{I}{name}FromSequence(
|
|
895
|
+
{II}reader, isEmptyElement, out error));
|
|
896
|
+
if (error != null)
|
|
897
|
+
{{
|
|
898
|
+
{I}return null;
|
|
899
|
+
}}
|
|
900
|
+
|
|
901
|
+
SkipNoneWhitespaceAndComments(reader);
|
|
902
|
+
|
|
903
|
+
if (!isEmptyElement)
|
|
904
|
+
{{
|
|
905
|
+
{I}if (reader.EOF)
|
|
906
|
+
{I}{{
|
|
907
|
+
{II}error = new Reporting.Error(
|
|
908
|
+
{III}"Expected an XML end element concluding an instance of class {name}, " +
|
|
909
|
+
{III}"but reached the end-of-file");
|
|
910
|
+
{II}return null;
|
|
911
|
+
{I}}}
|
|
912
|
+
|
|
913
|
+
{I}if (reader.NodeType != Xml.XmlNodeType.EndElement)
|
|
914
|
+
{I}{{
|
|
915
|
+
{II}error = new Reporting.Error(
|
|
916
|
+
{III}"Expected an XML end element concluding an instance of class {name}, " +
|
|
917
|
+
{III}$"but got a node of type {{reader.NodeType}} " +
|
|
918
|
+
{III}$"with value {{reader.Value}}");
|
|
919
|
+
{II}return null;
|
|
920
|
+
{I}}}
|
|
921
|
+
|
|
922
|
+
{I}string endElementName = TryElementName(
|
|
923
|
+
{II}reader, out error);
|
|
924
|
+
{I}if (error != null)
|
|
925
|
+
{I}{{
|
|
926
|
+
{II}return null;
|
|
927
|
+
{I}}}
|
|
928
|
+
|
|
929
|
+
{I}if (endElementName != elementName)
|
|
930
|
+
{I}{{
|
|
931
|
+
{II}error = new Reporting.Error(
|
|
932
|
+
{III}$"Expected an XML end element with an name {{elementName}}, " +
|
|
933
|
+
{III}$"but got: {{endElementName}}");
|
|
934
|
+
{II}return null;
|
|
935
|
+
{I}}}
|
|
936
|
+
|
|
937
|
+
{I}// Skip the end element
|
|
938
|
+
{I}reader.Read();
|
|
939
|
+
}}
|
|
940
|
+
|
|
941
|
+
return result;"""
|
|
942
|
+
)
|
|
943
|
+
|
|
944
|
+
return Stripped(
|
|
945
|
+
f"""\
|
|
946
|
+
/// <summary>
|
|
947
|
+
/// Deserialize an instance of class {name} from an XML element.
|
|
948
|
+
/// </summary>
|
|
949
|
+
internal static Aas.{name}? {name}FromElement(
|
|
950
|
+
{I}Xml.XmlReader reader,
|
|
951
|
+
{I}out Reporting.Error? error)
|
|
952
|
+
{{
|
|
953
|
+
{I}{indent_but_first_line(body, I)}
|
|
954
|
+
}} // internal static Aas.{name}? {name}FromElement"""
|
|
955
|
+
)
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
def _generate_deserialize_impl_interface_from_element(
|
|
959
|
+
interface: intermediate.Interface,
|
|
960
|
+
) -> Stripped:
|
|
961
|
+
"""Generate the function to de-serialize an ``interface`` from an XML element."""
|
|
962
|
+
name = csharp_naming.interface_name(interface.name)
|
|
963
|
+
|
|
964
|
+
blocks = [
|
|
965
|
+
Stripped(
|
|
966
|
+
f"""\
|
|
967
|
+
error = null;
|
|
968
|
+
|
|
969
|
+
SkipNoneWhitespaceAndComments(reader);
|
|
970
|
+
|
|
971
|
+
if (reader.EOF)
|
|
972
|
+
{{
|
|
973
|
+
{I}error = new Reporting.Error(
|
|
974
|
+
{II}"Expected an XML element, but reached end-of-file");
|
|
975
|
+
{I}return null;
|
|
976
|
+
}}
|
|
977
|
+
|
|
978
|
+
if (reader.NodeType != Xml.XmlNodeType.Element)
|
|
979
|
+
{{
|
|
980
|
+
{I}error = new Reporting.Error(
|
|
981
|
+
{II}"Expected an XML element, " +
|
|
982
|
+
{II}$"but got a node of type {{reader.NodeType}} " +
|
|
983
|
+
{II}$"with value {{reader.Value}}");
|
|
984
|
+
{I}return null;
|
|
985
|
+
}}"""
|
|
986
|
+
)
|
|
987
|
+
] # type: List[Stripped]
|
|
988
|
+
|
|
989
|
+
case_stmts = [] # type: List[Stripped]
|
|
990
|
+
for implementer in interface.implementers:
|
|
991
|
+
implementer_xml_name_literal = csharp_common.string_literal(
|
|
992
|
+
naming.xml_class_name(implementer.name)
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
implementer_name = csharp_naming.class_name(implementer.name)
|
|
996
|
+
|
|
997
|
+
case_stmts.append(
|
|
998
|
+
Stripped(
|
|
999
|
+
f"""\
|
|
1000
|
+
case {implementer_xml_name_literal}:
|
|
1001
|
+
{I}return {implementer_name}FromElement(
|
|
1002
|
+
{II}reader, out error);"""
|
|
1003
|
+
)
|
|
1004
|
+
)
|
|
1005
|
+
|
|
1006
|
+
case_stmts.append(
|
|
1007
|
+
Stripped(
|
|
1008
|
+
f"""\
|
|
1009
|
+
default:
|
|
1010
|
+
{I}error = new Reporting.Error(
|
|
1011
|
+
{II}$"Unexpected element with the name {{elementName}}");
|
|
1012
|
+
{I}return null;"""
|
|
1013
|
+
)
|
|
1014
|
+
)
|
|
1015
|
+
|
|
1016
|
+
switch_writer = io.StringIO()
|
|
1017
|
+
switch_writer.write(
|
|
1018
|
+
f"""\
|
|
1019
|
+
string elementName = TryElementName(
|
|
1020
|
+
{I}reader, out error);
|
|
1021
|
+
if (error != null)
|
|
1022
|
+
{{
|
|
1023
|
+
{I}return null;
|
|
1024
|
+
}}
|
|
1025
|
+
|
|
1026
|
+
switch (elementName)
|
|
1027
|
+
{{
|
|
1028
|
+
"""
|
|
1029
|
+
)
|
|
1030
|
+
for i, case_stmt in enumerate(case_stmts):
|
|
1031
|
+
if i > 0:
|
|
1032
|
+
switch_writer.write("\n")
|
|
1033
|
+
switch_writer.write(textwrap.indent(case_stmt, I))
|
|
1034
|
+
|
|
1035
|
+
switch_writer.write("\n}")
|
|
1036
|
+
|
|
1037
|
+
blocks.append(Stripped(switch_writer.getvalue()))
|
|
1038
|
+
|
|
1039
|
+
writer = io.StringIO()
|
|
1040
|
+
writer.write(
|
|
1041
|
+
f"""\
|
|
1042
|
+
/// <summary>
|
|
1043
|
+
/// Deserialize an instance of {name} from an XML element.
|
|
1044
|
+
/// </summary>
|
|
1045
|
+
[CodeAnalysis.SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
1046
|
+
internal static Aas.{name}? {name}FromElement(
|
|
1047
|
+
{I}Xml.XmlReader reader,
|
|
1048
|
+
{I}out Reporting.Error? error)
|
|
1049
|
+
{{
|
|
1050
|
+
"""
|
|
1051
|
+
)
|
|
1052
|
+
|
|
1053
|
+
for i, block in enumerate(blocks):
|
|
1054
|
+
if i > 0:
|
|
1055
|
+
writer.write("\n\n")
|
|
1056
|
+
writer.write(textwrap.indent(block, I))
|
|
1057
|
+
|
|
1058
|
+
writer.write(f"\n}} // internal static Aas.{name}? {name}FromElement")
|
|
1059
|
+
|
|
1060
|
+
return Stripped(writer.getvalue())
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
def _generate_deserialize_impl(
|
|
1064
|
+
symbol_table: intermediate.SymbolTable,
|
|
1065
|
+
spec_impls: specific_implementations.SpecificImplementations,
|
|
1066
|
+
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
|
|
1067
|
+
"""Generate the implementation for deserialization functions."""
|
|
1068
|
+
blocks = [
|
|
1069
|
+
_generate_skip_whitespace_and_comments(),
|
|
1070
|
+
_generate_read_whole_content_as_base_64(),
|
|
1071
|
+
_generate_extract_element_name(),
|
|
1072
|
+
] # type: List[Stripped]
|
|
1073
|
+
|
|
1074
|
+
errors = [] # type: List[Error]
|
|
1075
|
+
|
|
1076
|
+
# NOTE (mristin, 2022-04-13):
|
|
1077
|
+
# Enumerations are going to be directly deserialized using
|
|
1078
|
+
# ``Stringification``.
|
|
1079
|
+
|
|
1080
|
+
# NOTE (mristin, 2022-04-13):
|
|
1081
|
+
# Constrained primitives are only verified, but do not represent a C# type.
|
|
1082
|
+
|
|
1083
|
+
for cls in symbol_table.classes:
|
|
1084
|
+
if cls.is_implementation_specific:
|
|
1085
|
+
implementation_keys = [
|
|
1086
|
+
specific_implementations.ImplementationKey(
|
|
1087
|
+
f"Xmlization/DeserializeImplementation/"
|
|
1088
|
+
f"{cls.name}_from_element.cs"
|
|
1089
|
+
),
|
|
1090
|
+
specific_implementations.ImplementationKey(
|
|
1091
|
+
f"Xmlization/DeserializeImplementation/"
|
|
1092
|
+
f"{cls.name}_from_sequence.cs"
|
|
1093
|
+
),
|
|
1094
|
+
]
|
|
1095
|
+
|
|
1096
|
+
for implementation_key in implementation_keys:
|
|
1097
|
+
implementation = spec_impls.get(implementation_key, None)
|
|
1098
|
+
if implementation is None:
|
|
1099
|
+
errors.append(
|
|
1100
|
+
Error(
|
|
1101
|
+
cls.parsed.node,
|
|
1102
|
+
f"The xmlization snippet is missing "
|
|
1103
|
+
f"for the implementation-specific "
|
|
1104
|
+
f"class {cls.name}: {implementation_key}",
|
|
1105
|
+
)
|
|
1106
|
+
)
|
|
1107
|
+
continue
|
|
1108
|
+
else:
|
|
1109
|
+
blocks.append(spec_impls[implementation_key])
|
|
1110
|
+
else:
|
|
1111
|
+
if isinstance(cls, intermediate.ConcreteClass):
|
|
1112
|
+
(
|
|
1113
|
+
block,
|
|
1114
|
+
generation_errors,
|
|
1115
|
+
) = _generate_deserialize_impl_cls_from_sequence(cls=cls)
|
|
1116
|
+
if generation_errors is not None:
|
|
1117
|
+
errors.append(
|
|
1118
|
+
Error(
|
|
1119
|
+
cls.parsed.node,
|
|
1120
|
+
f"Failed to generate the XML deserialization code "
|
|
1121
|
+
f"for the class {cls.name}",
|
|
1122
|
+
generation_errors,
|
|
1123
|
+
)
|
|
1124
|
+
)
|
|
1125
|
+
else:
|
|
1126
|
+
assert block is not None
|
|
1127
|
+
blocks.append(block)
|
|
1128
|
+
|
|
1129
|
+
if cls.interface is not None:
|
|
1130
|
+
blocks.append(
|
|
1131
|
+
_generate_deserialize_impl_interface_from_element(
|
|
1132
|
+
interface=cls.interface
|
|
1133
|
+
)
|
|
1134
|
+
)
|
|
1135
|
+
|
|
1136
|
+
if isinstance(cls, intermediate.ConcreteClass):
|
|
1137
|
+
blocks.append(
|
|
1138
|
+
_generate_deserialize_impl_concrete_cls_from_element(cls=cls)
|
|
1139
|
+
)
|
|
1140
|
+
|
|
1141
|
+
if len(errors) > 0:
|
|
1142
|
+
return None, errors
|
|
1143
|
+
|
|
1144
|
+
writer = io.StringIO()
|
|
1145
|
+
|
|
1146
|
+
writer.write(
|
|
1147
|
+
"""\
|
|
1148
|
+
/// <summary>
|
|
1149
|
+
/// Implement the deserialization of meta-model classes from XML.
|
|
1150
|
+
/// </summary>
|
|
1151
|
+
/// <remarks>
|
|
1152
|
+
/// The implementation propagates an <see cref="Reporting.Error" /> instead of
|
|
1153
|
+
/// relying on exceptions. Under the assumption that incorrect data is much less
|
|
1154
|
+
/// frequent than correct data, this makes the deserialization more
|
|
1155
|
+
/// efficient.
|
|
1156
|
+
///
|
|
1157
|
+
/// However, we do not want to force the client to deal with
|
|
1158
|
+
/// the <see cref="Reporting.Error" /> class as this is not intuitive.
|
|
1159
|
+
/// Therefore we distinguish the implementation, realized in
|
|
1160
|
+
/// <see cref="DeserializeImplementation" />, and the facade given in
|
|
1161
|
+
/// <see cref="Deserialize" /> class.
|
|
1162
|
+
/// </remarks>
|
|
1163
|
+
internal static class DeserializeImplementation
|
|
1164
|
+
{
|
|
1165
|
+
"""
|
|
1166
|
+
)
|
|
1167
|
+
|
|
1168
|
+
for i, block in enumerate(blocks):
|
|
1169
|
+
if i > 0:
|
|
1170
|
+
writer.write("\n\n")
|
|
1171
|
+
writer.write(textwrap.indent(block, I))
|
|
1172
|
+
|
|
1173
|
+
writer.write("\n} // internal static class DeserializeImplementation")
|
|
1174
|
+
|
|
1175
|
+
return Stripped(writer.getvalue()), None
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
def _generate_deserialize_from(name: Identifier) -> Stripped:
|
|
1179
|
+
"""Generate the facade method for deserialization of the class or interface."""
|
|
1180
|
+
writer = io.StringIO()
|
|
1181
|
+
|
|
1182
|
+
writer.write(
|
|
1183
|
+
f"""\
|
|
1184
|
+
/// <summary>
|
|
1185
|
+
/// Deserialize an instance of {name} from <paramref name="reader" />.
|
|
1186
|
+
/// </summary>
|
|
1187
|
+
/// <param name="reader">Initialized XML reader with cursor set to the element</param>
|
|
1188
|
+
/// <exception cref="Xmlization.Exception">
|
|
1189
|
+
/// Thrown when the element is not a valid XML
|
|
1190
|
+
/// representation of {name}.
|
|
1191
|
+
/// </exception>
|
|
1192
|
+
"""
|
|
1193
|
+
)
|
|
1194
|
+
|
|
1195
|
+
if name.startswith("I"):
|
|
1196
|
+
writer.write(
|
|
1197
|
+
"""\
|
|
1198
|
+
[CodeAnalysis.SuppressMessage("ReSharper", "InconsistentNaming")]"""
|
|
1199
|
+
)
|
|
1200
|
+
|
|
1201
|
+
writer.write(
|
|
1202
|
+
f"""\
|
|
1203
|
+
public static Aas.{name} {name}From(
|
|
1204
|
+
{I}Xml.XmlReader reader)
|
|
1205
|
+
{{
|
|
1206
|
+
{I}DeserializeImplementation.SkipNoneWhitespaceAndComments(reader);
|
|
1207
|
+
|
|
1208
|
+
{I}if (!reader.EOF && reader.NodeType == Xml.XmlNodeType.XmlDeclaration)
|
|
1209
|
+
{I}{{
|
|
1210
|
+
{II}throw new Xmlization.Exception(
|
|
1211
|
+
{III}"",
|
|
1212
|
+
{III}"Unexpected XML declaration when reading an instance " +
|
|
1213
|
+
{III}"of class {name}, as we expect the reader " +
|
|
1214
|
+
{III}"to be set at content with MoveToContent");
|
|
1215
|
+
{I}}}
|
|
1216
|
+
|
|
1217
|
+
{I}Aas.{name}? result = (
|
|
1218
|
+
{II}DeserializeImplementation.{name}FromElement(
|
|
1219
|
+
{III}reader,
|
|
1220
|
+
{III}out Reporting.Error? error));
|
|
1221
|
+
{I}if (error != null)
|
|
1222
|
+
{I}{{
|
|
1223
|
+
{II}throw new Xmlization.Exception(
|
|
1224
|
+
{III}Reporting.GenerateRelativeXPath(error.PathSegments),
|
|
1225
|
+
{III}error.Cause);
|
|
1226
|
+
{I}}}
|
|
1227
|
+
{I}return result
|
|
1228
|
+
{II}?? throw new System.InvalidOperationException(
|
|
1229
|
+
{III}"Unexpected output null when error is null");
|
|
1230
|
+
}}"""
|
|
1231
|
+
)
|
|
1232
|
+
|
|
1233
|
+
return Stripped(writer.getvalue())
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
def _generate_deserialize(symbol_table: intermediate.SymbolTable) -> Stripped:
|
|
1237
|
+
"""Generate the public class ``Deserialize``."""
|
|
1238
|
+
blocks = [] # type: List[Stripped]
|
|
1239
|
+
|
|
1240
|
+
# NOTE (mristin, 2022-04-13):
|
|
1241
|
+
# We use stringification for de-serialization of enumerations.
|
|
1242
|
+
|
|
1243
|
+
# NOTE (mristin, 2022-04-13):
|
|
1244
|
+
# Constrained primitives are not handled as separate classes, but as
|
|
1245
|
+
# primitives, and only verified in the verification.
|
|
1246
|
+
|
|
1247
|
+
for cls in symbol_table.classes:
|
|
1248
|
+
if cls.interface is not None:
|
|
1249
|
+
blocks.append(
|
|
1250
|
+
_generate_deserialize_from(
|
|
1251
|
+
name=csharp_naming.interface_name(cls.interface.name)
|
|
1252
|
+
)
|
|
1253
|
+
)
|
|
1254
|
+
|
|
1255
|
+
if isinstance(cls, intermediate.ConcreteClass):
|
|
1256
|
+
blocks.append(
|
|
1257
|
+
_generate_deserialize_from(name=csharp_naming.class_name(cls.name))
|
|
1258
|
+
)
|
|
1259
|
+
|
|
1260
|
+
writer = io.StringIO()
|
|
1261
|
+
writer.write(
|
|
1262
|
+
"""\
|
|
1263
|
+
/// <summary>
|
|
1264
|
+
/// Deserialize instances of meta-model classes from XML.
|
|
1265
|
+
/// </summary>
|
|
1266
|
+
"""
|
|
1267
|
+
)
|
|
1268
|
+
|
|
1269
|
+
first_cls = symbol_table.classes[0] if len(symbol_table.classes) > 0 else None
|
|
1270
|
+
|
|
1271
|
+
if first_cls is not None:
|
|
1272
|
+
cls_name: str
|
|
1273
|
+
if isinstance(first_cls, intermediate.AbstractClass):
|
|
1274
|
+
cls_name = csharp_naming.interface_name(first_cls.name)
|
|
1275
|
+
elif isinstance(first_cls, intermediate.ConcreteClass):
|
|
1276
|
+
cls_name = csharp_naming.class_name(first_cls.name)
|
|
1277
|
+
else:
|
|
1278
|
+
assert_never(first_cls)
|
|
1279
|
+
|
|
1280
|
+
an_instance_variable = csharp_naming.variable_name(Identifier("an_instance"))
|
|
1281
|
+
|
|
1282
|
+
writer.write(
|
|
1283
|
+
f"""\
|
|
1284
|
+
/// <example>
|
|
1285
|
+
/// Here is an example how to parse an instance of class {cls_name}:
|
|
1286
|
+
/// <code>
|
|
1287
|
+
/// var reader = new System.Xml.XmlReader(/* some arguments */);
|
|
1288
|
+
/// Aas.{cls_name} {an_instance_variable} = Deserialize.{cls_name}From(
|
|
1289
|
+
/// {I}reader);
|
|
1290
|
+
/// </code>
|
|
1291
|
+
/// </example>
|
|
1292
|
+
///
|
|
1293
|
+
/// <example>
|
|
1294
|
+
/// If the elements live in a namespace, you have to supply it. For example:
|
|
1295
|
+
/// <code>
|
|
1296
|
+
/// var reader = new System.Xml.XmlReader(/* some arguments */);
|
|
1297
|
+
/// Aas.{cls_name} {an_instance_variable} = Deserialize.{cls_name}From(
|
|
1298
|
+
/// {I}reader,
|
|
1299
|
+
/// {I}"http://www.example.com/5/12");
|
|
1300
|
+
/// </code>
|
|
1301
|
+
/// </example>
|
|
1302
|
+
"""
|
|
1303
|
+
)
|
|
1304
|
+
|
|
1305
|
+
writer.write(
|
|
1306
|
+
"""\
|
|
1307
|
+
public static class Deserialize
|
|
1308
|
+
{
|
|
1309
|
+
"""
|
|
1310
|
+
)
|
|
1311
|
+
|
|
1312
|
+
for i, block in enumerate(blocks):
|
|
1313
|
+
if i > 0:
|
|
1314
|
+
writer.write("\n\n")
|
|
1315
|
+
writer.write(textwrap.indent(block, I))
|
|
1316
|
+
|
|
1317
|
+
writer.write("\n} // public static class Deserialize")
|
|
1318
|
+
|
|
1319
|
+
return Stripped(writer.getvalue())
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
def _generate_serialize_primitive_property_as_content(
|
|
1323
|
+
prop: intermediate.Property,
|
|
1324
|
+
) -> Stripped:
|
|
1325
|
+
"""Generate the serialization of the primitive-type ``prop`` as XML content."""
|
|
1326
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
1327
|
+
|
|
1328
|
+
a_type = intermediate.try_primitive_type(type_anno)
|
|
1329
|
+
assert (
|
|
1330
|
+
a_type is not None
|
|
1331
|
+
), f"Unexpected non-primitive type of the property {prop.name!r}: {type_anno}"
|
|
1332
|
+
|
|
1333
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
1334
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
1335
|
+
|
|
1336
|
+
write_value_block: Stripped
|
|
1337
|
+
|
|
1338
|
+
if (
|
|
1339
|
+
a_type is intermediate.PrimitiveType.BOOL
|
|
1340
|
+
or a_type is intermediate.PrimitiveType.INT
|
|
1341
|
+
or a_type is intermediate.PrimitiveType.FLOAT
|
|
1342
|
+
or a_type is intermediate.PrimitiveType.STR
|
|
1343
|
+
):
|
|
1344
|
+
write_value_block = Stripped(
|
|
1345
|
+
f"""\
|
|
1346
|
+
writer.WriteValue(
|
|
1347
|
+
{I}that.{prop_name});"""
|
|
1348
|
+
)
|
|
1349
|
+
elif a_type is intermediate.PrimitiveType.BYTEARRAY:
|
|
1350
|
+
write_value_block = Stripped(
|
|
1351
|
+
f"""\
|
|
1352
|
+
writer.WriteBase64(
|
|
1353
|
+
{I}that.{prop_name},
|
|
1354
|
+
{I}0,
|
|
1355
|
+
{I}that.{prop_name}.Length);"""
|
|
1356
|
+
)
|
|
1357
|
+
else:
|
|
1358
|
+
assert_never(a_type)
|
|
1359
|
+
|
|
1360
|
+
# NOTE (mristin, 2022-06-21):
|
|
1361
|
+
# Wrap the write_value_block with property even if we discard it below
|
|
1362
|
+
write_value_block = Stripped(
|
|
1363
|
+
f"""\
|
|
1364
|
+
writer.WriteStartElement(
|
|
1365
|
+
{I}{xml_prop_name_literal},
|
|
1366
|
+
{I}NS);
|
|
1367
|
+
|
|
1368
|
+
{write_value_block}
|
|
1369
|
+
|
|
1370
|
+
writer.WriteEndElement();"""
|
|
1371
|
+
)
|
|
1372
|
+
|
|
1373
|
+
if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
1374
|
+
if a_type in (
|
|
1375
|
+
intermediate.PrimitiveType.BOOL,
|
|
1376
|
+
intermediate.PrimitiveType.INT,
|
|
1377
|
+
intermediate.PrimitiveType.FLOAT,
|
|
1378
|
+
):
|
|
1379
|
+
write_value_block = Stripped(
|
|
1380
|
+
f"""\
|
|
1381
|
+
if (that.{prop_name}.HasValue)
|
|
1382
|
+
{{
|
|
1383
|
+
{I}writer.WriteStartElement(
|
|
1384
|
+
{II}{xml_prop_name_literal},
|
|
1385
|
+
{II}NS);
|
|
1386
|
+
|
|
1387
|
+
{I}writer.WriteValue(
|
|
1388
|
+
{II}that.{prop_name}.Value);
|
|
1389
|
+
|
|
1390
|
+
{I}writer.WriteEndElement();
|
|
1391
|
+
}}"""
|
|
1392
|
+
)
|
|
1393
|
+
else:
|
|
1394
|
+
write_value_block = Stripped(
|
|
1395
|
+
f"""\
|
|
1396
|
+
if (that.{prop_name} != null)
|
|
1397
|
+
{{
|
|
1398
|
+
{I}{indent_but_first_line(write_value_block, I)}
|
|
1399
|
+
}}"""
|
|
1400
|
+
)
|
|
1401
|
+
|
|
1402
|
+
return write_value_block
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
def _generate_serialize_enumeration_property_as_content(
|
|
1406
|
+
prop: intermediate.Property,
|
|
1407
|
+
) -> Stripped:
|
|
1408
|
+
"""Generate the serialization of an enumeration ``prop`` as XML content."""
|
|
1409
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
1410
|
+
assert isinstance(type_anno, intermediate.OurTypeAnnotation) and isinstance(
|
|
1411
|
+
type_anno.our_type, intermediate.Enumeration
|
|
1412
|
+
), "See intermediate._translate._verify_only_simple_type_patterns"
|
|
1413
|
+
|
|
1414
|
+
enumeration = type_anno.our_type
|
|
1415
|
+
|
|
1416
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
1417
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
1418
|
+
|
|
1419
|
+
enum_name = csharp_naming.enum_name(enumeration.name)
|
|
1420
|
+
|
|
1421
|
+
text_var = csharp_naming.variable_name(Identifier(f"text_{prop.name}"))
|
|
1422
|
+
write_value_block = Stripped(
|
|
1423
|
+
f"""\
|
|
1424
|
+
writer.WriteStartElement(
|
|
1425
|
+
{I}{xml_prop_name_literal},
|
|
1426
|
+
{I}NS);
|
|
1427
|
+
|
|
1428
|
+
string? {text_var} = Stringification.ToString(
|
|
1429
|
+
{I}that.{prop_name});
|
|
1430
|
+
writer.WriteValue(
|
|
1431
|
+
{I}{text_var}
|
|
1432
|
+
{II}?? throw new System.ArgumentException(
|
|
1433
|
+
{III}"Invalid literal for the enumeration {enum_name}: " +
|
|
1434
|
+
{III}that.{prop_name}.ToString()));
|
|
1435
|
+
|
|
1436
|
+
writer.WriteEndElement();"""
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
1440
|
+
write_value_block = Stripped(
|
|
1441
|
+
f"""\
|
|
1442
|
+
if (that.{prop_name} != null)
|
|
1443
|
+
{{
|
|
1444
|
+
{I}{indent_but_first_line(write_value_block, I)}
|
|
1445
|
+
}}"""
|
|
1446
|
+
)
|
|
1447
|
+
|
|
1448
|
+
return write_value_block
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
def _generate_serialize_interface_property_as_content(
|
|
1452
|
+
prop: intermediate.Property,
|
|
1453
|
+
) -> Stripped:
|
|
1454
|
+
"""Generate the serialization of an interface as XML content."""
|
|
1455
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
1456
|
+
|
|
1457
|
+
# fmt: off
|
|
1458
|
+
assert (
|
|
1459
|
+
isinstance(type_anno, intermediate.OurTypeAnnotation)
|
|
1460
|
+
and (
|
|
1461
|
+
isinstance(type_anno.our_type, intermediate.AbstractClass)
|
|
1462
|
+
or (
|
|
1463
|
+
isinstance(type_anno.our_type, intermediate.ConcreteClass)
|
|
1464
|
+
and len(type_anno.our_type.concrete_descendants) > 0
|
|
1465
|
+
)
|
|
1466
|
+
)
|
|
1467
|
+
), "See intermediate._translate._verify_only_simple_type_patterns"
|
|
1468
|
+
# fmt: on
|
|
1469
|
+
|
|
1470
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
1471
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
1472
|
+
|
|
1473
|
+
result = Stripped(
|
|
1474
|
+
f"""\
|
|
1475
|
+
writer.WriteStartElement(
|
|
1476
|
+
{I}{xml_prop_name_literal},
|
|
1477
|
+
{I}NS);
|
|
1478
|
+
|
|
1479
|
+
this.Visit(
|
|
1480
|
+
{I}that.{prop_name},
|
|
1481
|
+
{I}writer);
|
|
1482
|
+
|
|
1483
|
+
writer.WriteEndElement();"""
|
|
1484
|
+
)
|
|
1485
|
+
|
|
1486
|
+
if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
1487
|
+
result = Stripped(
|
|
1488
|
+
f"""\
|
|
1489
|
+
if (that.{prop_name} != null)
|
|
1490
|
+
{{
|
|
1491
|
+
{I}{indent_but_first_line(result, I)}
|
|
1492
|
+
}}"""
|
|
1493
|
+
)
|
|
1494
|
+
|
|
1495
|
+
return result
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
def _generate_serialize_concrete_class_property_as_sequence(
|
|
1499
|
+
prop: intermediate.Property,
|
|
1500
|
+
) -> Stripped:
|
|
1501
|
+
"""Generate the serialization of the class ``prop`` as a sequence of properties."""
|
|
1502
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
1503
|
+
assert isinstance(type_anno, intermediate.OurTypeAnnotation)
|
|
1504
|
+
assert isinstance(type_anno.our_type, intermediate.ConcreteClass)
|
|
1505
|
+
|
|
1506
|
+
cls_to_sequence = csharp_naming.method_name(
|
|
1507
|
+
Identifier(f"{type_anno.our_type.name}_to_sequence")
|
|
1508
|
+
)
|
|
1509
|
+
|
|
1510
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
1511
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
1512
|
+
|
|
1513
|
+
result = Stripped(
|
|
1514
|
+
f"""\
|
|
1515
|
+
writer.WriteStartElement(
|
|
1516
|
+
{I}{xml_prop_name_literal},
|
|
1517
|
+
{I}NS);
|
|
1518
|
+
|
|
1519
|
+
this.{cls_to_sequence}(
|
|
1520
|
+
{I}that.{prop_name},
|
|
1521
|
+
{I}writer);
|
|
1522
|
+
|
|
1523
|
+
writer.WriteEndElement();"""
|
|
1524
|
+
)
|
|
1525
|
+
|
|
1526
|
+
if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
1527
|
+
result = Stripped(
|
|
1528
|
+
f"""\
|
|
1529
|
+
if (that.{prop_name} != null)
|
|
1530
|
+
{{
|
|
1531
|
+
{I}{indent_but_first_line(result, I)}
|
|
1532
|
+
}}"""
|
|
1533
|
+
)
|
|
1534
|
+
|
|
1535
|
+
return result
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
def _generate_serialize_list_property_as_content(
|
|
1539
|
+
prop: intermediate.Property,
|
|
1540
|
+
) -> Stripped:
|
|
1541
|
+
"""Generate the serialization of a list ``prop`` as a sequence of elements."""
|
|
1542
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
1543
|
+
|
|
1544
|
+
# fmt: off
|
|
1545
|
+
assert (
|
|
1546
|
+
isinstance(type_anno, intermediate.ListTypeAnnotation)
|
|
1547
|
+
and isinstance(type_anno.items, intermediate.OurTypeAnnotation)
|
|
1548
|
+
and isinstance(
|
|
1549
|
+
type_anno.items.our_type,
|
|
1550
|
+
(intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
1551
|
+
)
|
|
1552
|
+
), "See intermediate._translate._verify_only_simple_type_patterns"
|
|
1553
|
+
# fmt: on
|
|
1554
|
+
|
|
1555
|
+
prop_name = csharp_naming.property_name(prop.name)
|
|
1556
|
+
xml_prop_name_literal = csharp_common.string_literal(naming.xml_property(prop.name))
|
|
1557
|
+
|
|
1558
|
+
result = Stripped(
|
|
1559
|
+
f"""\
|
|
1560
|
+
writer.WriteStartElement(
|
|
1561
|
+
{I}{xml_prop_name_literal},
|
|
1562
|
+
{I}NS);
|
|
1563
|
+
|
|
1564
|
+
foreach (var item in that.{prop_name})
|
|
1565
|
+
{{
|
|
1566
|
+
{I}this.Visit(
|
|
1567
|
+
{II}item,
|
|
1568
|
+
{II}writer);
|
|
1569
|
+
}}
|
|
1570
|
+
|
|
1571
|
+
writer.WriteEndElement();"""
|
|
1572
|
+
)
|
|
1573
|
+
|
|
1574
|
+
if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
|
|
1575
|
+
result = Stripped(
|
|
1576
|
+
f"""\
|
|
1577
|
+
if (that.{prop_name} != null)
|
|
1578
|
+
{{
|
|
1579
|
+
{I}{indent_but_first_line(result, I)}
|
|
1580
|
+
}}"""
|
|
1581
|
+
)
|
|
1582
|
+
|
|
1583
|
+
return result
|
|
1584
|
+
|
|
1585
|
+
|
|
1586
|
+
def _generate_serialize_property_as_content(prop: intermediate.Property) -> Stripped:
|
|
1587
|
+
"""Generate the code to serialize the ``prop`` as content of an XML element."""
|
|
1588
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
1589
|
+
|
|
1590
|
+
body = None # type: Optional[Stripped]
|
|
1591
|
+
|
|
1592
|
+
if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
|
|
1593
|
+
body = _generate_serialize_primitive_property_as_content(prop=prop)
|
|
1594
|
+
elif isinstance(type_anno, intermediate.OurTypeAnnotation):
|
|
1595
|
+
our_type = type_anno.our_type
|
|
1596
|
+
|
|
1597
|
+
if isinstance(our_type, intermediate.Enumeration):
|
|
1598
|
+
body = _generate_serialize_enumeration_property_as_content(prop=prop)
|
|
1599
|
+
|
|
1600
|
+
elif isinstance(our_type, intermediate.ConstrainedPrimitive):
|
|
1601
|
+
body = _generate_serialize_primitive_property_as_content(prop=prop)
|
|
1602
|
+
|
|
1603
|
+
elif isinstance(
|
|
1604
|
+
our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
1605
|
+
):
|
|
1606
|
+
if (
|
|
1607
|
+
isinstance(our_type, intermediate.AbstractClass)
|
|
1608
|
+
or len(our_type.concrete_descendants) > 0
|
|
1609
|
+
):
|
|
1610
|
+
body = _generate_serialize_interface_property_as_content(prop=prop)
|
|
1611
|
+
else:
|
|
1612
|
+
body = _generate_serialize_concrete_class_property_as_sequence(
|
|
1613
|
+
prop=prop
|
|
1614
|
+
)
|
|
1615
|
+
|
|
1616
|
+
else:
|
|
1617
|
+
assert_never(our_type)
|
|
1618
|
+
|
|
1619
|
+
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
|
|
1620
|
+
body = _generate_serialize_list_property_as_content(prop=prop)
|
|
1621
|
+
|
|
1622
|
+
else:
|
|
1623
|
+
assert_never(type_anno)
|
|
1624
|
+
|
|
1625
|
+
return body
|
|
1626
|
+
|
|
1627
|
+
|
|
1628
|
+
def _generate_class_to_sequence(cls: intermediate.ConcreteClass) -> Stripped:
|
|
1629
|
+
"""Generate the method to write ``cls`` as a sequence of properties as XML."""
|
|
1630
|
+
blocks = [] # type: List[Stripped]
|
|
1631
|
+
|
|
1632
|
+
for prop in cls.properties:
|
|
1633
|
+
body = _generate_serialize_property_as_content(prop=prop)
|
|
1634
|
+
blocks.append(body)
|
|
1635
|
+
|
|
1636
|
+
interface_name = csharp_naming.interface_name(cls.name)
|
|
1637
|
+
method_name = csharp_naming.method_name(Identifier(f"{cls.name}_to_sequence"))
|
|
1638
|
+
|
|
1639
|
+
writer = io.StringIO()
|
|
1640
|
+
|
|
1641
|
+
if len(cls.properties) == 0:
|
|
1642
|
+
blocks.append(Stripped("// Intentionally empty."))
|
|
1643
|
+
|
|
1644
|
+
writer.write(
|
|
1645
|
+
'[CodeAnalysis.SuppressMessage("ReSharper", "UnusedParameter.Local")]\n'
|
|
1646
|
+
)
|
|
1647
|
+
|
|
1648
|
+
writer.write(
|
|
1649
|
+
f"""\
|
|
1650
|
+
private void {method_name}(
|
|
1651
|
+
{I}Aas.{interface_name} that,
|
|
1652
|
+
{I}Xml.XmlWriter writer)
|
|
1653
|
+
{{
|
|
1654
|
+
"""
|
|
1655
|
+
)
|
|
1656
|
+
|
|
1657
|
+
for i, block in enumerate(blocks):
|
|
1658
|
+
if i > 0:
|
|
1659
|
+
writer.write("\n\n")
|
|
1660
|
+
writer.write(textwrap.indent(block, I))
|
|
1661
|
+
|
|
1662
|
+
writer.write(f"\n}} // private void {method_name}")
|
|
1663
|
+
|
|
1664
|
+
return Stripped(writer.getvalue())
|
|
1665
|
+
|
|
1666
|
+
|
|
1667
|
+
def _generate_visit_for_class(cls: intermediate.ConcreteClass) -> Stripped:
|
|
1668
|
+
"""Generate the method to write the ``cls`` as an XML element."""
|
|
1669
|
+
interface_name = csharp_naming.interface_name(cls.name)
|
|
1670
|
+
visit_name = csharp_naming.method_name(Identifier(f"visit_{cls.name}"))
|
|
1671
|
+
|
|
1672
|
+
cls_to_sequence_name = csharp_naming.method_name(
|
|
1673
|
+
Identifier(f"{cls.name}_to_sequence")
|
|
1674
|
+
)
|
|
1675
|
+
|
|
1676
|
+
xml_cls_name_literal = csharp_common.string_literal(naming.xml_class_name(cls.name))
|
|
1677
|
+
|
|
1678
|
+
return Stripped(
|
|
1679
|
+
f"""\
|
|
1680
|
+
public override void {visit_name}(
|
|
1681
|
+
{I}Aas.{interface_name} that,
|
|
1682
|
+
{I}Xml.XmlWriter writer)
|
|
1683
|
+
{{
|
|
1684
|
+
{I}writer.WriteStartElement(
|
|
1685
|
+
{II}{xml_cls_name_literal},
|
|
1686
|
+
{II}NS);
|
|
1687
|
+
{I}this.{cls_to_sequence_name}(
|
|
1688
|
+
{II}that,
|
|
1689
|
+
{II}writer);
|
|
1690
|
+
{I}writer.WriteEndElement();
|
|
1691
|
+
}}"""
|
|
1692
|
+
)
|
|
1693
|
+
|
|
1694
|
+
|
|
1695
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
1696
|
+
def _generate_visitor(
|
|
1697
|
+
symbol_table: intermediate.SymbolTable,
|
|
1698
|
+
spec_impls: specific_implementations.SpecificImplementations,
|
|
1699
|
+
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
|
|
1700
|
+
"""Generate a visitor which serializes instances of the meta-model to XML."""
|
|
1701
|
+
errors = [] # type: List[Error]
|
|
1702
|
+
|
|
1703
|
+
blocks = [] # type: List[Stripped]
|
|
1704
|
+
|
|
1705
|
+
# The abstract classes are directly dispatched by the transformer,
|
|
1706
|
+
# so we do not need to handle them separately.
|
|
1707
|
+
|
|
1708
|
+
for cls in symbol_table.concrete_classes:
|
|
1709
|
+
if cls.is_implementation_specific:
|
|
1710
|
+
implementation_keys = [
|
|
1711
|
+
specific_implementations.ImplementationKey(
|
|
1712
|
+
f"Xmlization/VisitorWithWriter/visit_{cls.name}.cs"
|
|
1713
|
+
),
|
|
1714
|
+
specific_implementations.ImplementationKey(
|
|
1715
|
+
f"Xmlization/VisitorWithWriter/{cls.name}_to_sequence.cs"
|
|
1716
|
+
),
|
|
1717
|
+
]
|
|
1718
|
+
|
|
1719
|
+
for implementation_key in implementation_keys:
|
|
1720
|
+
implementation = spec_impls.get(implementation_key, None)
|
|
1721
|
+
if implementation is None:
|
|
1722
|
+
errors.append(
|
|
1723
|
+
Error(
|
|
1724
|
+
cls.parsed.node,
|
|
1725
|
+
f"The xmlization snippet is missing "
|
|
1726
|
+
f"for the implementation-specific "
|
|
1727
|
+
f"class {cls.name}: {implementation_key}",
|
|
1728
|
+
)
|
|
1729
|
+
)
|
|
1730
|
+
continue
|
|
1731
|
+
|
|
1732
|
+
blocks.append(spec_impls[implementation_key])
|
|
1733
|
+
else:
|
|
1734
|
+
blocks.append(_generate_class_to_sequence(cls=cls))
|
|
1735
|
+
|
|
1736
|
+
blocks.append(_generate_visit_for_class(cls=cls))
|
|
1737
|
+
|
|
1738
|
+
if len(errors) > 0:
|
|
1739
|
+
return None, errors
|
|
1740
|
+
|
|
1741
|
+
writer = io.StringIO()
|
|
1742
|
+
writer.write(
|
|
1743
|
+
f"""\
|
|
1744
|
+
/// <summary>
|
|
1745
|
+
/// Serialize recursively the instances as XML elements.
|
|
1746
|
+
/// </summary>
|
|
1747
|
+
internal class VisitorWithWriter
|
|
1748
|
+
{I}: Visitation.AbstractVisitorWithContext<Xml.XmlWriter>
|
|
1749
|
+
{{
|
|
1750
|
+
"""
|
|
1751
|
+
)
|
|
1752
|
+
|
|
1753
|
+
for i, block in enumerate(blocks):
|
|
1754
|
+
if i > 0:
|
|
1755
|
+
writer.write("\n\n")
|
|
1756
|
+
writer.write(textwrap.indent(block, I))
|
|
1757
|
+
|
|
1758
|
+
writer.write("\n} // internal class VisitorWithWriter")
|
|
1759
|
+
|
|
1760
|
+
return Stripped(writer.getvalue()), None
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
def _generate_serialize(
|
|
1764
|
+
symbol_table: intermediate.SymbolTable,
|
|
1765
|
+
) -> Stripped:
|
|
1766
|
+
"""Generate the static serializer."""
|
|
1767
|
+
blocks = [
|
|
1768
|
+
Stripped(
|
|
1769
|
+
f"""\
|
|
1770
|
+
[CodeAnalysis.SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
1771
|
+
private static readonly VisitorWithWriter _visitorWithWriter = (
|
|
1772
|
+
{I}new VisitorWithWriter());"""
|
|
1773
|
+
),
|
|
1774
|
+
Stripped(
|
|
1775
|
+
f"""\
|
|
1776
|
+
/// <summary>
|
|
1777
|
+
/// Serialize an instance of the meta-model to XML.
|
|
1778
|
+
/// </summary>
|
|
1779
|
+
public static void To(
|
|
1780
|
+
{I}Aas.IClass that,
|
|
1781
|
+
{I}Xml.XmlWriter writer)
|
|
1782
|
+
{{
|
|
1783
|
+
{I}Serialize._visitorWithWriter.Visit(
|
|
1784
|
+
{II}that, writer);
|
|
1785
|
+
}}"""
|
|
1786
|
+
),
|
|
1787
|
+
] # type: List[Stripped]
|
|
1788
|
+
|
|
1789
|
+
writer = io.StringIO()
|
|
1790
|
+
writer.write(
|
|
1791
|
+
"""\
|
|
1792
|
+
/// <summary>
|
|
1793
|
+
/// Serialize instances of meta-model classes to XML.
|
|
1794
|
+
/// </summary>
|
|
1795
|
+
"""
|
|
1796
|
+
)
|
|
1797
|
+
|
|
1798
|
+
first_cls = (
|
|
1799
|
+
symbol_table.classes[0] if len(symbol_table.classes) > 0 else None
|
|
1800
|
+
) # type: Optional[intermediate.ClassUnion]
|
|
1801
|
+
|
|
1802
|
+
if first_cls is not None:
|
|
1803
|
+
cls_name: str
|
|
1804
|
+
if isinstance(first_cls, intermediate.AbstractClass):
|
|
1805
|
+
cls_name = csharp_naming.interface_name(first_cls.name)
|
|
1806
|
+
elif isinstance(first_cls, intermediate.ConcreteClass):
|
|
1807
|
+
cls_name = csharp_naming.class_name(first_cls.name)
|
|
1808
|
+
else:
|
|
1809
|
+
assert_never(first_cls)
|
|
1810
|
+
|
|
1811
|
+
an_instance_variable = csharp_naming.variable_name(Identifier("an_instance"))
|
|
1812
|
+
|
|
1813
|
+
writer.write(
|
|
1814
|
+
f"""\
|
|
1815
|
+
/// <example>
|
|
1816
|
+
/// Here is an example how to serialize an instance of {cls_name}:
|
|
1817
|
+
/// <code>
|
|
1818
|
+
/// var {an_instance_variable} = new Aas.{cls_name}(
|
|
1819
|
+
/// /* ... some constructor arguments ... */
|
|
1820
|
+
/// );
|
|
1821
|
+
/// var writer = new System.Xml.XmlWriter( /* some arguments */ );
|
|
1822
|
+
/// Serialize.To(
|
|
1823
|
+
/// {I}{an_instance_variable},
|
|
1824
|
+
/// {I}writer);
|
|
1825
|
+
/// </code>
|
|
1826
|
+
/// </example>
|
|
1827
|
+
"""
|
|
1828
|
+
)
|
|
1829
|
+
|
|
1830
|
+
writer.write(
|
|
1831
|
+
"""\
|
|
1832
|
+
public static class Serialize
|
|
1833
|
+
{
|
|
1834
|
+
"""
|
|
1835
|
+
)
|
|
1836
|
+
|
|
1837
|
+
for i, block in enumerate(blocks):
|
|
1838
|
+
if i > 0:
|
|
1839
|
+
writer.write("\n\n")
|
|
1840
|
+
writer.write(textwrap.indent(block, I))
|
|
1841
|
+
|
|
1842
|
+
writer.write("\n} // public static class Serialize")
|
|
1843
|
+
|
|
1844
|
+
return Stripped(writer.getvalue())
|
|
1845
|
+
|
|
1846
|
+
|
|
1847
|
+
# fmt: off
|
|
1848
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
1849
|
+
@ensure(
|
|
1850
|
+
lambda result:
|
|
1851
|
+
not (result[0] is not None) or result[0].endswith('\n'),
|
|
1852
|
+
"Trailing newline mandatory for valid end-of-files"
|
|
1853
|
+
)
|
|
1854
|
+
# fmt: on
|
|
1855
|
+
def generate(
|
|
1856
|
+
symbol_table: intermediate.SymbolTable,
|
|
1857
|
+
namespace: csharp_common.NamespaceIdentifier,
|
|
1858
|
+
spec_impls: specific_implementations.SpecificImplementations,
|
|
1859
|
+
) -> Tuple[Optional[str], Optional[List[Error]]]:
|
|
1860
|
+
"""
|
|
1861
|
+
Generate the C# code for the general serialization.
|
|
1862
|
+
|
|
1863
|
+
The ``namespace`` defines the AAS C# namespace.
|
|
1864
|
+
"""
|
|
1865
|
+
xmlization_blocks = [] # type: List[Stripped]
|
|
1866
|
+
|
|
1867
|
+
errors = [] # type: List[Error]
|
|
1868
|
+
|
|
1869
|
+
deserialize_impl_block, deserialize_impl_errors = _generate_deserialize_impl(
|
|
1870
|
+
symbol_table=symbol_table, spec_impls=spec_impls
|
|
1871
|
+
)
|
|
1872
|
+
if deserialize_impl_errors is not None:
|
|
1873
|
+
errors.extend(deserialize_impl_errors)
|
|
1874
|
+
else:
|
|
1875
|
+
assert deserialize_impl_block is not None
|
|
1876
|
+
xmlization_blocks.append(deserialize_impl_block)
|
|
1877
|
+
|
|
1878
|
+
xmlization_blocks.append(
|
|
1879
|
+
Stripped(
|
|
1880
|
+
f"""\
|
|
1881
|
+
/// <summary>
|
|
1882
|
+
/// Represent a critical error during the deserialization.
|
|
1883
|
+
/// </summary>
|
|
1884
|
+
public class Exception : System.Exception
|
|
1885
|
+
{{
|
|
1886
|
+
{I}public readonly string Path;
|
|
1887
|
+
{I}public readonly string Cause;
|
|
1888
|
+
{I}public Exception(string path, string cause)
|
|
1889
|
+
{II}: base($"{{cause}} at: {{(path == "" ? "the beginning" : path)}}")
|
|
1890
|
+
{I}{{
|
|
1891
|
+
{II}Path = path;
|
|
1892
|
+
{II}Cause = cause;
|
|
1893
|
+
{I}}}
|
|
1894
|
+
}}"""
|
|
1895
|
+
)
|
|
1896
|
+
)
|
|
1897
|
+
|
|
1898
|
+
xmlization_blocks.append(_generate_deserialize(symbol_table=symbol_table))
|
|
1899
|
+
|
|
1900
|
+
visitor_block, visitor_errors = _generate_visitor(
|
|
1901
|
+
symbol_table=symbol_table, spec_impls=spec_impls
|
|
1902
|
+
)
|
|
1903
|
+
if visitor_errors is not None:
|
|
1904
|
+
errors.extend(visitor_errors)
|
|
1905
|
+
else:
|
|
1906
|
+
assert visitor_block is not None
|
|
1907
|
+
xmlization_blocks.append(visitor_block)
|
|
1908
|
+
|
|
1909
|
+
if len(errors) > 0:
|
|
1910
|
+
return None, errors
|
|
1911
|
+
|
|
1912
|
+
xmlization_blocks.append(_generate_serialize(symbol_table=symbol_table))
|
|
1913
|
+
|
|
1914
|
+
xmlization_writer = io.StringIO()
|
|
1915
|
+
|
|
1916
|
+
xml_namespace_literal = csharp_common.string_literal(
|
|
1917
|
+
symbol_table.meta_model.xml_namespace
|
|
1918
|
+
)
|
|
1919
|
+
|
|
1920
|
+
xmlization_writer.write(
|
|
1921
|
+
f"""\
|
|
1922
|
+
namespace {namespace}
|
|
1923
|
+
{{
|
|
1924
|
+
{I}/// <summary>
|
|
1925
|
+
{I}/// Provide de/serialization of meta-model classes to/from XML.
|
|
1926
|
+
{I}/// </summary>
|
|
1927
|
+
{I}public static class Xmlization
|
|
1928
|
+
{I}{{
|
|
1929
|
+
{II}/// The XML namespace of the meta-model
|
|
1930
|
+
{II}[CodeAnalysis.SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
1931
|
+
{II}public static readonly string NS = (
|
|
1932
|
+
{III}{xml_namespace_literal});
|
|
1933
|
+
|
|
1934
|
+
"""
|
|
1935
|
+
)
|
|
1936
|
+
|
|
1937
|
+
for i, xmlization_block in enumerate(xmlization_blocks):
|
|
1938
|
+
if i > 0:
|
|
1939
|
+
xmlization_writer.write("\n\n")
|
|
1940
|
+
|
|
1941
|
+
xmlization_writer.write(textwrap.indent(xmlization_block, II))
|
|
1942
|
+
|
|
1943
|
+
xmlization_writer.write(f"\n{I}}} // public static class Xmlization")
|
|
1944
|
+
xmlization_writer.write(f"\n}} // namespace {namespace}")
|
|
1945
|
+
|
|
1946
|
+
using_directives = [] # type: List[Stripped]
|
|
1947
|
+
using_directives.extend(
|
|
1948
|
+
csharp_common.generate_using_aas_directive_if_necessary(namespace)
|
|
1949
|
+
)
|
|
1950
|
+
|
|
1951
|
+
using_directives.append(
|
|
1952
|
+
Stripped(
|
|
1953
|
+
"""\
|
|
1954
|
+
using CodeAnalysis = System.Diagnostics.CodeAnalysis;
|
|
1955
|
+
using Xml = System.Xml;
|
|
1956
|
+
|
|
1957
|
+
using System.Collections.Generic; // can't alias"""
|
|
1958
|
+
)
|
|
1959
|
+
)
|
|
1960
|
+
|
|
1961
|
+
# pylint: disable=line-too-long
|
|
1962
|
+
blocks = [
|
|
1963
|
+
csharp_common.WARNING,
|
|
1964
|
+
Stripped("\n".join(using_directives)),
|
|
1965
|
+
Stripped(xmlization_writer.getvalue()),
|
|
1966
|
+
csharp_common.WARNING,
|
|
1967
|
+
]
|
|
1968
|
+
|
|
1969
|
+
writer = io.StringIO()
|
|
1970
|
+
for i, block in enumerate(blocks):
|
|
1971
|
+
if i > 0:
|
|
1972
|
+
writer.write("\n\n")
|
|
1973
|
+
|
|
1974
|
+
assert not block.startswith("\n")
|
|
1975
|
+
assert not block.endswith("\n")
|
|
1976
|
+
writer.write(block)
|
|
1977
|
+
|
|
1978
|
+
writer.write("\n")
|
|
1979
|
+
|
|
1980
|
+
return writer.getvalue(), None
|