Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List of Primitives #527

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions aas_core_codegen/cpp/enhancing/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,12 @@ def _generate_wrap_snippet_for_required_property(
else:
assert_never(type_anno.our_type)
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation) or (
isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-07-07): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
Expand Down
24 changes: 14 additions & 10 deletions aas_core_codegen/cpp/iteration/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,11 +782,13 @@ def __init__(self, cls: intermediate.ConcreteClass) -> None:
relevant_properties.append(prop)

elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-09-27): We expect only lists of classes "
f"at the moment, but you specified {prop.type_annotation} "
Expand Down Expand Up @@ -947,11 +949,13 @@ def _generate_iterator_over_cls_execute_implementation(
flow.append(yielding_flow.Yield())

elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-09-27): We expect only lists of classes "
f"at the moment, but you specified {prop.type_annotation} "
Expand Down
63 changes: 43 additions & 20 deletions aas_core_codegen/cpp/jsonization/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,18 @@ def _generate_deserialize_bytearray() -> Stripped:
for primitive_type in intermediate.PrimitiveType
)

_PRIMITIVE_TYPE_TO_NATIVE_TYPE = {
intermediate.PrimitiveType.BOOL: "bool",
intermediate.PrimitiveType.INT: "int64_t",
intermediate.PrimitiveType.FLOAT: "double",
intermediate.PrimitiveType.STR: "std::wstring",
intermediate.PrimitiveType.BYTEARRAY: "std::vector<std::uint8_t>",
}
assert all(
primitive_type in _PRIMITIVE_TYPE_TO_NATIVE_TYPE
for primitive_type in intermediate.PrimitiveType
)


def _generate_get_model_type() -> Stripped:
"""Generate the getter of the model type from JSON object for dispatches."""
Expand Down Expand Up @@ -1158,20 +1170,27 @@ def _generate_deserialize_list_property(
"""
type_anno = intermediate.beneath_optional(prop.type_annotation)
assert isinstance(type_anno, intermediate.ListTypeAnnotation)
assert isinstance(type_anno.items, intermediate.OurTypeAnnotation) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-11-10): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
f"Please contact the developers if you need this feature."
)

cls = type_anno.items.our_type

interface_name = cpp_naming.interface_name(cls.name)

deserialize_function = _determine_deserialize_function_to_call(cls=cls)
if isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation):
primitive_type = intermediate.try_primitive_type(type_anno.items)
interface_name = _PRIMITIVE_TYPE_TO_NATIVE_TYPE[primitive_type]
deserialize_function = _PRIMITIVE_TYPE_TO_DESERIALIZE[primitive_type]
else:
cls = type_anno.items.our_type
interface_name = f"types::{cpp_naming.interface_name(cls.name)}"
deserialize_function = _determine_deserialize_function_to_call(cls=cls)

var_name = cpp_naming.variable_name(Identifier(f"the_{prop.name}"))
json_prop_name = naming.json_property(prop.name)
Expand Down Expand Up @@ -1211,7 +1230,7 @@ def _generate_deserialize_list_property(

{var_name} = common::make_optional<
{I}std::vector<
{II}std::shared_ptr<types::{interface_name}>
{II}std::shared_ptr<{interface_name}>
{I}>
>();

Expand All @@ -1224,7 +1243,7 @@ def _generate_deserialize_list_property(
{I}: {var_json}
) {{
{I}common::optional<
{II}std::shared_ptr<types::{interface_name}>
{II}std::shared_ptr<{interface_name}>
{I}> deserialized;

{I}std::tie(
Expand Down Expand Up @@ -1300,11 +1319,13 @@ def _generate_deserialize_property(
else:
assert_never(type_anno.our_type)
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-11-10): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
Expand Down Expand Up @@ -2192,11 +2213,13 @@ def _generate_serialize_property(prop: intermediate.Property) -> Stripped:
else:
assert_never(type_anno.our_type)
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-11-21): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
Expand Down
12 changes: 7 additions & 5 deletions aas_core_codegen/cpp/verification/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -842,11 +842,13 @@ def _collect_constrained_primitive_properties(
assert_never(type_anno.our_type)

elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-03-29): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
Expand Down
12 changes: 7 additions & 5 deletions aas_core_codegen/cpp/visitation/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,13 @@ def _generate_recursive_visit_for_property(
else:
assert_never(type_anno.our_type)
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
assert isinstance(
type_anno.items, intermediate.OurTypeAnnotation
) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-03-29): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
Expand Down
75 changes: 50 additions & 25 deletions aas_core_codegen/cpp/xmlization/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3022,23 +3022,30 @@ def _generate_deserialize_list_property(
type_anno = intermediate.beneath_optional(prop.type_annotation)
assert isinstance(type_anno, intermediate.ListTypeAnnotation)

assert isinstance(type_anno.items, intermediate.OurTypeAnnotation) and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation)
or isinstance(type_anno.items, intermediate.OurTypeAnnotation)
and isinstance(
type_anno.items.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-12-10): We expect only lists of classes "
f"at the moment, but you specified {type_anno}. "
f"Please contact the developers if you need this feature."
)

item_type = cpp_common.generate_type(
type_annotation=type_anno.items, types_namespace=cpp_common.TYPES_NAMESPACE
)

from_element_name = cpp_naming.function_name(
Identifier(f"{type_anno.items.our_type.name}_from_element")
)

if isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation):
primitive_type = intermediate.try_primitive_type(type_anno.items)
item_type = _PRIMITIVE_TYPE_TO_NATIVE_TYPE[primitive_type]
from_element_name = _PRIMITIVE_TYPE_TO_DESERIALIZE[primitive_type]
else:
item_type = cpp_common.generate_type(
type_annotation=type_anno.items, types_namespace=cpp_common.TYPES_NAMESPACE
)
from_element_name = cpp_naming.function_name(
Identifier(f"{type_anno.items.our_type.name}_from_element")
)
var_name = cpp_naming.variable_name(Identifier(f"the_{prop.name}"))

# NOTE (mristin, 2023-12-12):
Expand Down Expand Up @@ -4418,6 +4425,18 @@ class SelfClosingWriter {{
for primitive_type in intermediate.PrimitiveType
)

_PRIMITIVE_TYPE_TO_NATIVE_TYPE = {
intermediate.PrimitiveType.BOOL: "bool",
intermediate.PrimitiveType.INT: "int64_t",
intermediate.PrimitiveType.FLOAT: "double",
intermediate.PrimitiveType.STR: "std::wstring",
intermediate.PrimitiveType.BYTEARRAY: "std::vector<std::uint8_t>",
}
assert all(
primitive_type in _PRIMITIVE_TYPE_TO_NATIVE_TYPE
for primitive_type in intermediate.PrimitiveType
)


def _generate_serialize_primitive_value(
primitive_type: intermediate.PrimitiveType, var_name: Identifier
Expand Down Expand Up @@ -4462,26 +4481,32 @@ def _generate_serialize_list(
item_type_annotation: intermediate.TypeAnnotationUnion, var_name: Identifier
) -> Stripped:
"""Serialize the list at ``var_name``."""
assert isinstance(
item_type_annotation, intermediate.OurTypeAnnotation
) and isinstance(
item_type_annotation.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
assert (
isinstance(item_type_annotation, intermediate.PrimitiveTypeAnnotation)
or isinstance(item_type_annotation, intermediate.OurTypeAnnotation)
and isinstance(
item_type_annotation.our_type,
(intermediate.AbstractClass, intermediate.ConcreteClass),
)
), (
f"NOTE (mristin, 2023-12-20): We expect only lists of classes "
f"at the moment, but you specified a list of {item_type_annotation}. "
f"Please contact the developers if you need this feature."
)

item_cls = item_type_annotation.our_type

item_serialize_function = cpp_naming.function_name(
Identifier(f"serialize_{item_cls.name}_as_element")
)

item_type = cpp_common.generate_type_with_const_ref_if_applicable(
type_annotation=item_type_annotation, types_namespace=cpp_common.TYPES_NAMESPACE
)
if isinstance(item_type_annotation, intermediate.PrimitiveTypeAnnotation):
primitive_type = intermediate.try_primitive_type(item_type_annotation)
item_type = _PRIMITIVE_TYPE_TO_NATIVE_TYPE[primitive_type]
item_serialize_function = _PRIMITIVE_TYPE_TO_DESERIALIZE[primitive_type]
else:
item_cls = item_type_annotation.our_type
item_serialize_function = cpp_naming.function_name(
Identifier(f"serialize_{item_cls.name}_as_element")
)
item_type = cpp_common.generate_type_with_const_ref_if_applicable(
type_annotation=item_type_annotation,
types_namespace=cpp_common.TYPES_NAMESPACE,
)

return Stripped(
f"""\
Expand Down
11 changes: 7 additions & 4 deletions aas_core_codegen/intermediate/_translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4415,17 +4415,20 @@ def _verify_only_simple_type_patterns(symbol_table: SymbolTable) -> List[Error]:
type_anno = beneath_optional(prop.type_annotation)
if isinstance(type_anno, ListTypeAnnotation):
if not (
isinstance(type_anno.items, OurTypeAnnotation)
and isinstance(
type_anno.items.our_type, (AbstractClass, ConcreteClass)
isinstance(type_anno.items, PrimitiveTypeAnnotation)
or (
isinstance(type_anno.items, OurTypeAnnotation)
and isinstance(
type_anno.items.our_type, (AbstractClass, ConcreteClass)
)
)
):
errors.append(
Error(
prop.parsed.node,
f"We currently support only a limited set of "
f"type annotation patterns. At the moment, we handle "
f"only lists of classes (both concrete or abstract), "
f"only lists of classes (both concrete or abstract) or primitive types, "
f"but the property {prop.name!r} "
f"of the class {cls.name!r} "
f"has type: {prop.type_annotation}. "
Expand Down
20 changes: 20 additions & 0 deletions aas_core_codegen/xsd/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,26 @@ def _generate_xs_element_for_a_list_property(
)
else:
assert_never(our_type)
elif isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation):
xs_element_inner = ET.Element(
"xs:element",
{
"name": "v",
"type": _PRIMITIVE_MAP[type_anno.items.a_type],
"minOccurs": min_occurs,
"maxOccurs": max_occurs,
},
)
xs_sequence = ET.Element("xs:sequence")
xs_sequence.append(xs_element_inner)

xs_complex_type = ET.Element("xs:complexType")
xs_complex_type.append(xs_sequence)

xs_element = ET.Element(
"xs:element", {"name": naming.xml_property(prop.name)}
)
xs_element.append(xs_complex_type)
else:
return None, Error(
prop.parsed.node,
Expand Down
Loading