Skip to content

Commit 1672092

Browse files
yufengwangcapull[bot]
authored andcommitted
[Kotlin] Add template to generate cluster structs & events (#30139)
1 parent 73b7f24 commit 1672092

File tree

240 files changed

+11924
-736
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

240 files changed

+11924
-736
lines changed

scripts/py_matter_idl/matter_idl/generators/kotlin/MatterClusters.jinja

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
{%- elif encodable.is_optional -%}
77
{{encode_value(source, encodable.without_optional(), depth + 1)}}?
88
{%- elif encodable.is_list -%}
9-
ArrayList<{{encode_value(source, encodable.without_list(), depth + 1)}}>
9+
List<{{encode_value(source, encodable.without_list(), depth + 1)}}>
1010
{%- elif encodable.is_struct -%}
1111
{%- set struct = encodable.get_underlying_struct() -%}
12-
ChipStructs.{{source.name}}Cluster{{struct.name}}
12+
{{source.name}}Cluster{{struct.name}}
1313
{%- else -%}
1414
{{encodable.kotlin_type}}
1515
{%- endif -%}
@@ -22,18 +22,18 @@
2222
List<{{encode_value_without_optional(source, encodable.without_list(), depth + 1)}}>
2323
{%- elif encodable.is_struct -%}
2424
{%- set struct = encodable.get_underlying_struct() -%}
25-
ChipStructs.{{source.name}}Cluster{{struct.name}}
25+
{{source.name}}Cluster{{struct.name}}
2626
{%- else -%}
2727
{{encodable.kotlin_type}}
2828
{%- endif -%}
2929
{%- endmacro -%}
3030

3131
{%- macro encode_value_without_optional_nullable(source, encodable, depth) -%}
3232
{%- if encodable.is_list -%}
33-
ArrayList<{{encode_value_without_optional_nullable(source, encodable.without_list(), depth + 1)}}>
33+
List<{{encode_value_without_optional_nullable(source, encodable.without_list(), depth + 1)}}>
3434
{%- elif encodable.is_struct -%}
3535
{%- set struct = encodable.get_underlying_struct() -%}
36-
ChipStructs.{{source.name}}Cluster{{struct.name}}
36+
{{source.name}}Cluster{{struct.name}}
3737
{%- else -%}
3838
{{encodable.kotlin_type}}
3939
{%- endif -%}
@@ -58,7 +58,7 @@
5858

5959
package matter.devicecontroller.cluster.clusters
6060

61-
import java.util.ArrayList
61+
import matter.devicecontroller.cluster.structs.*
6262
{% set typeLookup = idl | createLookupContext(cluster) %}
6363
class {{cluster.name}}Cluster(private val endpointId: UShort) {
6464

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
{%- macro encode_value(source, encodable, depth) -%}
2+
{%- if encodable.is_nullable -%}
3+
{{encode_value(source, encodable.without_nullable(), depth + 1)}}?
4+
{%- elif encodable.is_optional -%}
5+
Optional<{{encode_value(source, encodable.without_optional(), depth + 1)}}>
6+
{%- elif encodable.is_list -%}
7+
List<{{encode_value(source, encodable.without_list(), depth + 1)}}>
8+
{%- elif encodable.is_struct -%}
9+
{%- set struct = encodable.get_underlying_struct() -%}
10+
matter.devicecontroller.cluster.structs.{{source.name}}Cluster{{struct.name}}
11+
{%- else -%}
12+
{{encodable.kotlin_type}}
13+
{%- endif -%}
14+
{%- endmacro -%}
15+
16+
{%- macro encode_tlv(encodable, tag, name, depth) %}
17+
{%- if encodable.is_nullable -%}
18+
if ({{name}} != null) {
19+
{{encode_tlv(encodable.without_nullable(), tag, name, depth + 1)}}
20+
} else {
21+
putNull({{tag}})
22+
}
23+
{%- elif encodable.is_optional -%}
24+
if ({{name}}.isPresent) {
25+
val opt{{name}} = {{name}}.get()
26+
{{encode_tlv(encodable.without_optional(), tag, "opt" + name, depth + 1)}}
27+
}
28+
{%- elif encodable.is_list -%}
29+
startArray({{tag}})
30+
for (item in {{name}}.iterator()) {
31+
{{encode_tlv(encodable.without_list(), "AnonymousTag", "item", depth + 1)}}
32+
}
33+
endArray()
34+
{%- elif encodable.is_struct -%}
35+
{{name}}.toTlv({{tag}}, this)
36+
{%- else -%}
37+
put({{tag}}, {{name}})
38+
{%- endif -%}
39+
{%- endmacro -%}
40+
41+
{%- macro decode_tlv(source, encodable, tag, depth) %}
42+
{%- if encodable.is_nullable -%}
43+
if (!tlvReader.isNull()) {
44+
{{decode_tlv(source, encodable.without_nullable(), tag, depth + 1)}}
45+
} else {
46+
tlvReader.getNull({{tag}})
47+
null
48+
}
49+
{%- elif encodable.is_optional -%}
50+
if (tlvReader.isNextTag({{tag}})) {
51+
Optional.of({{decode_tlv(source, encodable.without_optional(), tag, depth + 1)}})
52+
} else {
53+
Optional.empty()
54+
}
55+
{%- elif encodable.is_list -%}
56+
{%- set encodablewithoutlist = encodable.without_list() -%}
57+
buildList <{{encode_value(source, encodablewithoutlist, depth + 1)}}> {
58+
tlvReader.enterArray({{tag}})
59+
while(!tlvReader.isEndOfContainer()) {
60+
this.add({{decode_tlv(source, encodablewithoutlist, "AnonymousTag", depth + 1)}})
61+
}
62+
tlvReader.exitContainer()
63+
}
64+
{%- elif encodable.is_struct -%}
65+
{%- set struct = encodable.get_underlying_struct() -%}
66+
matter.devicecontroller.cluster.structs.{{source.name}}Cluster{{struct.name}}.fromTlv({{tag}}, tlvReader)
67+
{%- else -%}
68+
tlvReader.get{{encodable.kotlin_type}}({{tag}})
69+
{%- endif -%}
70+
{%- endmacro -%}
71+
72+
{%- macro contextSpecificTag(field) -%}
73+
ContextSpecificTag(TAG_{{field.name | constcase}})
74+
{%- endmacro -%}
75+
76+
/*
77+
*
78+
* Copyright (c) 2023 Project CHIP Authors
79+
*
80+
* Licensed under the Apache License, Version 2.0 (the "License");
81+
* you may not use this file except in compliance with the License.
82+
* You may obtain a copy of the License at
83+
*
84+
* http://www.apache.org/licenses/LICENSE-2.0
85+
*
86+
* Unless required by applicable law or agreed to in writing, software
87+
* distributed under the License is distributed on an "AS IS" BASIS,
88+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89+
* See the License for the specific language governing permissions and
90+
* limitations under the License.
91+
*/
92+
package matter.devicecontroller.cluster.eventstructs
93+
94+
import matter.devicecontroller.cluster.*
95+
import matter.tlv.AnonymousTag
96+
import matter.tlv.ContextSpecificTag
97+
import matter.tlv.Tag
98+
import matter.tlv.TlvParsingException
99+
import matter.tlv.TlvReader
100+
import matter.tlv.TlvWriter
101+
102+
import java.util.Optional
103+
104+
class {{cluster.name}}Cluster{{event.name}}Event (
105+
{%- for field in event.fields -%}
106+
{%- set encodable = field | asEncodable(typeLookup) %}
107+
val {{field.name}}: {{encode_value(cluster, encodable, 0)}}
108+
{%- if loop.index0 < loop.length - 1 -%}{{","}}{%- endif -%}
109+
{%- endfor -%}) {
110+
override fun toString(): String = buildString {
111+
append("{{cluster.name}}Cluster{{event.name}}Event {\n")
112+
{%- for field in event.fields %}
113+
append("\t{{field.name}} : ${{field.name}}\n")
114+
{%- endfor %}
115+
append("}\n")
116+
}
117+
118+
fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) {
119+
tlvWriter.apply {
120+
startStructure(tlvTag)
121+
{% for field in event.fields %}
122+
{%- set encodable = field | asEncodable(typeLookup) %}
123+
{%- set tag = contextSpecificTag(field) -%}
124+
{{encode_tlv(encodable, tag, field.name, 0)}}
125+
{% endfor -%}
126+
endStructure()
127+
}
128+
}
129+
130+
companion object {
131+
{%- for field in event.fields %}
132+
private const val TAG_{{field.name | constcase}} = {{field.code}}
133+
{%- endfor %}
134+
135+
fun fromTlv(tlvTag: Tag, tlvReader: TlvReader) : {{cluster.name}}Cluster{{event.name}}Event {
136+
tlvReader.enterStructure(tlvTag)
137+
{% for field in event.fields %}
138+
{%- set decodable = field | asEncodable(typeLookup) %}
139+
{%- set tag = contextSpecificTag(field) -%}
140+
val {{field.name}} = {{decode_tlv(cluster, decodable, tag, 0)}}
141+
{% endfor %}
142+
tlvReader.exitContainer()
143+
144+
return {{cluster.name}}Cluster{{event.name}}Event(
145+
{%- for field in event.fields -%}
146+
{%- set encodable = field | asEncodable(typeLookup) -%}
147+
{{field.name}}
148+
{%- if loop.index0 < loop.length - 1 -%}{{", "}}{%- endif -%}
149+
{%- endfor -%}
150+
)
151+
}
152+
}
153+
}

scripts/py_matter_idl/matter_idl/generators/kotlin/MatterFiles_gni.jinja

+22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
import("//build_overrides/build.gni")
22
import("//build_overrides/chip.gni")
33

4+
matter_structs_sources = [
5+
{%- for cluster in clientClusters | sort(attribute='name') %}
6+
{%- set typeLookup = idl | createLookupContext(cluster) %}
7+
{%- for struct in cluster.structs | sort(attribute='name') %}
8+
{%- if not struct.tag %}
9+
"${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/{{cluster.name}}Cluster{{struct.name}}.kt",
10+
{%- endif %}
11+
{%- endfor %}
12+
{%- endfor %}
13+
]
14+
15+
matter_eventstructs_sources = [
16+
{%- for cluster in clientClusters | sort(attribute='name') %}
17+
{%- set typeLookup = idl | createLookupContext(cluster) %}
18+
{%- for event in cluster.events | sort(attribute='name') %}
19+
{%- if event.fields %}
20+
"${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/{{cluster.name}}Cluster{{event.name}}Event.kt",
21+
{%- endif %}
22+
{%- endfor %}
23+
{%- endfor %}
24+
]
25+
426
matter_clusters_sources = [
527
{%- for cluster in clientClusters | sort(attribute='name') %}
628
{%- set typeLookup = idl | createLookupContext(cluster) %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
{%- macro encode_value(source, encodable, depth) -%}
2+
{%- if encodable.is_nullable -%}
3+
{{encode_value(source, encodable.without_nullable(), depth + 1)}}?
4+
{%- elif encodable.is_optional -%}
5+
Optional<{{encode_value(source, encodable.without_optional(), depth + 1)}}>
6+
{%- elif encodable.is_list -%}
7+
List<{{encode_value(source, encodable.without_list(), depth + 1)}}>
8+
{%- elif encodable.is_struct -%}
9+
{%- set struct = encodable.get_underlying_struct() -%}
10+
{{source.name}}Cluster{{struct.name}}
11+
{%- else -%}
12+
{{encodable.kotlin_type}}
13+
{%- endif -%}
14+
{%- endmacro -%}
15+
16+
{%- macro encode_tlv(encodable, tag, name, depth) %}
17+
{%- if encodable.is_nullable -%}
18+
if ({{name}} != null) {
19+
{{encode_tlv(encodable.without_nullable(), tag, name, depth + 1)}}
20+
} else {
21+
putNull({{tag}})
22+
}
23+
{%- elif encodable.is_optional -%}
24+
if ({{name}}.isPresent) {
25+
val opt{{name}} = {{name}}.get()
26+
{{encode_tlv(encodable.without_optional(), tag, "opt" + name, depth + 1)}}
27+
}
28+
{%- elif encodable.is_list -%}
29+
startArray({{tag}})
30+
for (item in {{name}}.iterator()) {
31+
{{encode_tlv(encodable.without_list(), "AnonymousTag", "item", depth + 1)}}
32+
}
33+
endArray()
34+
{%- elif encodable.is_struct -%}
35+
{{name}}.toTlv({{tag}}, this)
36+
{%- else -%}
37+
put({{tag}}, {{name}})
38+
{%- endif -%}
39+
{%- endmacro -%}
40+
41+
{%- macro decode_tlv(source, encodable, tag, depth) %}
42+
{%- if encodable.is_nullable -%}
43+
if (!tlvReader.isNull()) {
44+
{{decode_tlv(source, encodable.without_nullable(), tag, depth + 1)}}
45+
} else {
46+
tlvReader.getNull({{tag}})
47+
null
48+
}
49+
{%- elif encodable.is_optional -%}
50+
if (tlvReader.isNextTag({{tag}})) {
51+
Optional.of({{decode_tlv(source, encodable.without_optional(), tag, depth + 1)}})
52+
} else {
53+
Optional.empty()
54+
}
55+
{%- elif encodable.is_list -%}
56+
{%- set encodablewithoutlist = encodable.without_list() -%}
57+
buildList<{{encode_value(source, encodablewithoutlist, depth + 1)}}> {
58+
tlvReader.enterArray({{tag}})
59+
while(!tlvReader.isEndOfContainer()) {
60+
add({{decode_tlv(source, encodablewithoutlist, "AnonymousTag", depth + 1)}})
61+
}
62+
tlvReader.exitContainer()
63+
}
64+
{%- elif encodable.is_struct -%}
65+
{%- set struct = encodable.get_underlying_struct() -%}
66+
{{source.name}}Cluster{{struct.name}}.fromTlv({{tag}}, tlvReader)
67+
{%- else -%}
68+
tlvReader.get{{encodable.kotlin_type}}({{tag}})
69+
{%- endif -%}
70+
{%- endmacro -%}
71+
72+
{%- macro contextSpecificTag(field) -%}
73+
ContextSpecificTag(TAG_{{field.name | constcase}})
74+
{%- endmacro -%}
75+
76+
/*
77+
*
78+
* Copyright (c) 2023 Project CHIP Authors
79+
*
80+
* Licensed under the Apache License, Version 2.0 (the "License");
81+
* you may not use this file except in compliance with the License.
82+
* You may obtain a copy of the License at
83+
*
84+
* http://www.apache.org/licenses/LICENSE-2.0
85+
*
86+
* Unless required by applicable law or agreed to in writing, software
87+
* distributed under the License is distributed on an "AS IS" BASIS,
88+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89+
* See the License for the specific language governing permissions and
90+
* limitations under the License.
91+
*/
92+
package matter.devicecontroller.cluster.structs
93+
94+
import matter.devicecontroller.cluster.*
95+
import matter.tlv.AnonymousTag
96+
import matter.tlv.ContextSpecificTag
97+
import matter.tlv.Tag
98+
import matter.tlv.TlvParsingException
99+
import matter.tlv.TlvReader
100+
import matter.tlv.TlvWriter
101+
102+
import java.util.Optional
103+
104+
class {{cluster.name}}Cluster{{struct.name}} (
105+
{%- for field in struct.fields %}
106+
{%- set encodable = field | asEncodable(typeLookup) %}
107+
val {{field.name}}: {{encode_value(cluster, encodable, 0)}}
108+
{%- if loop.index0 < loop.length - 1 -%}{{","}}{%- endif -%}
109+
{%- endfor -%}) {
110+
override fun toString(): String = buildString {
111+
append("{{cluster.name}}Cluster{{struct.name}} {\n")
112+
{%- for field in struct.fields %}
113+
append("\t{{field.name}} : ${{field.name}}\n")
114+
{%- endfor %}
115+
append("}\n")
116+
}
117+
118+
fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) {
119+
tlvWriter.apply {
120+
startStructure(tlvTag)
121+
{% for field in struct.fields %}
122+
{%- set encodable = field | asEncodable(typeLookup) %}
123+
{%- set tag = contextSpecificTag(field) -%}
124+
{{encode_tlv(encodable, tag, field.name, 0)}}
125+
{% endfor -%}
126+
endStructure()
127+
}
128+
}
129+
130+
companion object {
131+
{%- for field in struct.fields %}
132+
private const val TAG_{{field.name | constcase}} = {{field.code}}
133+
{%- endfor %}
134+
135+
fun fromTlv(tlvTag: Tag, tlvReader: TlvReader) : {{cluster.name}}Cluster{{struct.name}} {
136+
tlvReader.enterStructure(tlvTag)
137+
{% for field in struct.fields %}
138+
{%- set decodable = field | asEncodable(typeLookup) %}
139+
{%- set tag = contextSpecificTag(field) -%}
140+
val {{field.name}} = {{decode_tlv(cluster, decodable, tag, 0)}}
141+
{% endfor %}
142+
tlvReader.exitContainer()
143+
144+
return {{cluster.name}}Cluster{{struct.name}}(
145+
{%- for field in struct.fields -%}
146+
{%- set encodable = field | asEncodable(typeLookup) -%}
147+
{{field.name}}
148+
{%- if loop.index0 < loop.length - 1 -%}{{", "}}{%- endif -%}
149+
{%- endfor -%}
150+
)
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)