Skip to content

Commit

Permalink
Support list in dm xml (#29950)
Browse files Browse the repository at this point in the history
* Add parse support for list types in data model xml

* Restyle

* Fix unused type

* Fix a typo in data types ... may as well fix here since python change

---------

Co-authored-by: Andrei Litvin <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Apr 24, 2024
1 parent b6d3871 commit 2261538
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import logging
import re
from dataclasses import dataclass
from typing import Optional

from matter_idl.generators.types import GetDataTypeSizeInBits, IsSignedDataType
Expand All @@ -22,6 +23,12 @@
LOGGER = logging.getLogger('data-model-xml-data-parsing')


@dataclass
class ParsedType:
name: str
is_list: bool = False


def ParseInt(value: str, data_type: Optional[DataType] = None) -> int:
"""
Convert a string that is a known integer into an actual number.
Expand Down Expand Up @@ -61,15 +68,15 @@ def ParseOptionalInt(value: str) -> Optional[int]:
"uint32": "int32u",
"uint48": "int48u",
"uint52": "int52u",
"uint64": "int54u",
"uint64": "int64u",
# signed
"sint8": "int8s",
"sint16": "int16s",
"sint24": "int24s",
"sint32": "int32s",
"sint48": "int48s",
"sint52": "int52s",
"sint64": "int54s",
"sint64": "int64s",
# other
"bool": "boolean",
"string": "char_string",
Expand All @@ -82,6 +89,23 @@ def NormalizeDataType(t: str) -> str:
return _TYPE_REMAP.get(t.lower(), t.replace("-", "_"))


def ParseType(t: str) -> ParsedType:
"""Parse a data type entry.
Specifically parses a name like "list[Foo Type]".
"""
# very rough matcher ...
is_list = False
if t.startswith("list[") and t.endswith("]"):
is_list = True
t = t[5:-1]

if t.endswith(" Type"):
t = t[:-5]

return ParsedType(name=NormalizeDataType(t), is_list=is_list)


def NormalizeName(name: str) -> str:
"""Convert a free form name from the spec into a programming language
name that is appropriate for matter IDL.
Expand Down Expand Up @@ -126,10 +150,13 @@ def AttributesToField(attrs) -> Field:
assert "id" in attrs
assert "type" in attrs

t = ParseType(attrs["type"])

return Field(
name=FieldName(attrs["name"]),
code=ParseInt(attrs["id"]),
data_type=DataType(name=NormalizeDataType(attrs["type"]))
is_list=t.is_list,
data_type=DataType(name=t.name),
)


Expand All @@ -154,11 +181,14 @@ def AttributesToAttribute(attrs) -> Attribute:
LOGGER.error(f"Attribute {attrs['name']} has no type")
attr_type = "sint32"

t = ParseType(attr_type)

return Attribute(
definition=Field(
code=ParseInt(attrs["id"]),
name=FieldName(attrs["name"]),
data_type=DataType(name=attr_type),
is_list=t.is_list,
data_type=DataType(name=t.name),
)
)

Expand Down
42 changes: 42 additions & 0 deletions scripts/py_matter_idl/matter_idl/test_data_model_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,48 @@ def testBasicInput(self):

self.assertEqual(xml_idl, expected_idl)

def testAttributes(self):
# Validate an attribute with a type list
# This is a very stripped down version from the original AudioOutput.xml

xml_idl = XmlToIdl('''
<cluster id="123" name="Test" revision="1">
<dataTypes>
<struct name="OutputInfoStruct">
<field id="0" name="Index" type="uint8">
<access read="true" write="true"/>
<mandatoryConform/>
</field>
</struct>
</dataTypes>
<attributes>
<attribute id="0x0000" name="OutputList" type="list[OutputInfoStruct Type]">
<access read="true" readPrivilege="view"/>
<mandatoryConform/>
</attribute>
</attributes>
</cluster>
''')

expected_idl = IdlTextToIdl('''
client cluster Test = 123 {
struct OutputInfoStruct {
int8u index = 0;
}
readonly attribute OutputInfoStruct outputList[] = 0;
readonly attribute attrib_id attributeList[] = 65531;
readonly attribute event_id eventList[] = 65530;
readonly attribute command_id acceptedCommandList[] = 65529;
readonly attribute command_id generatedCommandList[] = 65528;
readonly attribute bitmap32 featureMap = 65532;
readonly attribute int16u clusterRevision = 65533;
}
''')

self.assertEqual(xml_idl, expected_idl)

def testComplexInput(self):
# This parses a known copy of Switch.xml which happens to be fully
# spec-conformant (so assuming it as a good input)
Expand Down

0 comments on commit 2261538

Please sign in to comment.