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