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