blob: b3c3a6b2e7d26e865e41cfed107af0bb22ca1b96 [file] [log] [blame]
{%- macro encode_value(source, encodable, depth) -%}
{%- if encodable.is_nullable -%}
@Nullable {{encode_value(source, encodable.without_nullable(), depth + 1)}}
{%- elif encodable.is_optional -%}
Optional<{{encode_value(source, encodable.without_optional(), depth + 1)}}>
{%- elif encodable.is_list -%}
ArrayList<{{encode_value(source, encodable.without_list(), depth + 1)}}>
{%- elif encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() -%}
ChipStructs.{{source.name}}Cluster{{struct.name}}
{%- else -%}
{{encodable.boxed_java_type}}
{%- endif -%}
{%- endmacro -%}
{%- macro encode_value_remove_generic(source, encodable, depth) -%}
{%- if encodable.is_optional -%}
Optional
{%- elif encodable.is_list -%}
ArrayList
{%- elif encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() -%}
ChipStructs.{{source.name}}Cluster{{struct.name}}
{%- else -%}
{{encodable.boxed_java_type}}
{%- endif -%}
{%- endmacro -%}
{%- macro encode_value_remove_generic_optional(source, encodable, depth) -%}
{%- if encodable.is_list -%}
ArrayList
{%- elif encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() -%}
ChipStructs.{{source.name}}Cluster{{struct.name}}
{%- else -%}
{{encodable.boxed_java_type}}
{%- endif -%}
{%- endmacro -%}
{%- macro encode_value_without_optional(source, encodable, depth) -%}
{%- if encodable.is_nullable -%}
@Nullable {{encode_value_without_optional(source, encodable.without_nullable(), depth + 1)}}
{%- elif encodable.is_list -%}
List<{{encode_value_without_optional(source, encodable.without_list(), depth + 1)}}>
{%- elif encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() -%}
ChipStructs.{{source.name}}Cluster{{struct.name}}
{%- else -%}
{{encodable.boxed_java_type}}
{%- endif -%}
{%- endmacro -%}
{%- macro encode_value_without_nullable_arraylist(source, encodable, depth) -%}
{%- if encodable.is_optional -%}
Optional<{{encode_value_without_nullable_arraylist(source, encodable.without_optional(), depth + 1)}}>
{%- elif encodable.is_list -%}
ArrayList<{{encode_value_without_nullable_arraylist(source, encodable.without_list(), depth + 1)}}>
{%- elif encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() -%}
ChipStructs.{{source.name}}Cluster{{struct.name}}
{%- else -%}
{{encodable.boxed_java_type}}
{%- endif -%}
{%- endmacro -%}
{%- macro encode_value_without_optional_nullable(source, encodable, depth) -%}
{%- if encodable.is_list -%}
List<{{encode_value_without_optional_nullable(source, encodable.without_list(), depth + 1)}}>
{%- elif encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() -%}
ChipStructs.{{source.name}}Cluster{{struct.name}}
{%- else -%}
{{encodable.boxed_java_type}}
{%- endif -%}
{%- endmacro -%}
/*
*
* Copyright (c) 2023 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package chip.devicecontroller;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import chip.clusterinfo.ClusterInfo;
import chip.clusterinfo.InteractionInfo;
import chip.clusterinfo.CommandParameterInfo;
import chip.clusterinfo.DelegatedClusterCallback;
import chip.clusterinfo.ClusterCommandCallback;
import chip.clusterinfo.CommandResponseInfo;
import chip.devicecontroller.ChipClusters.DefaultClusterCallback;
import chip.devicecontroller.ClusterReadMapping;
import chip.devicecontroller.ClusterWriteMapping;
public class ClusterInfoMapping {
public static class DelegatedCharStringAttributeCallback implements ChipClusters.CharStringAttributeCallback, DelegatedClusterCallback {
/** Indicates a successful read for a CHAR_STRING attribute. */
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(String value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "String");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedOctetStringAttributeCallback implements ChipClusters.OctetStringAttributeCallback, DelegatedClusterCallback {
/** Indicates a successful read for an OCTET_STRING attribute. */
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(byte[] value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "byte[]");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedIntegerAttributeCallback implements ChipClusters.IntegerAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(int value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "int");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedLongAttributeCallback implements ChipClusters.LongAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(long value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "long");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedBooleanAttributeCallback implements ChipClusters.BooleanAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(boolean value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "boolean");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedFloatAttributeCallback implements ChipClusters.FloatAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(float value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "float");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedDoubleAttributeCallback implements ChipClusters.DoubleAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(double value) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo setupPINResponseValue = new CommandResponseInfo("value", "double");
responseValues.put(setupPINResponseValue, value);
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
public static class DelegatedDefaultClusterCallback implements DefaultClusterCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
// Parameters and list-adds here should be generated - refer to the template code that creates each callback interface.
@Override
public void onSuccess() {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception e) {
callback.onFailure(e);
}
}
{% for cluster in clientClusters | sort(attribute='code') -%}
{%- set typeLookup = idl | createLookupContext(cluster) -%}
{%- set already_handled_command = [] -%}
{% for command in cluster.commands | sort(attribute='code') -%}
{% if command | isCommandNotDefaultCallback() -%}
{% set callbackName = command | javaCommandCallbackName() -%}
{%- if callbackName not in already_handled_command %}
public static class Delegated{{cluster.name}}Cluster{{callbackName}}Callback implements ChipClusters.{{cluster.name}}Cluster.{{callbackName}}Callback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
@Override
public void onSuccess(
{%- for field in (cluster.structs | named(command.output_param)).fields -%}
{%- set encodable = field | asEncodable(typeLookup) -%}
{{encode_value(cluster, encodable, 0)}} {{field.name}}
{%- if loop.index0 < loop.length - 1 -%}{{", "}}{%- endif -%}
{%- endfor -%}) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
{% for field in (cluster.structs | named(command.output_param)).fields -%}
{%- set encodable = field | asEncodable(typeLookup) -%}
{% if encodable.is_list %}
// {{field.name}}: {{encodable.data_type.name}}
// Conversion from this type to Java is not properly implemented yet
{% else -%}
{%- if encodable.is_struct -%}
{%- set struct = encodable.get_underlying_struct() %}
// {{field.name}}: Struct {{struct.name}}
// Conversion from this type to Java is not properly implemented yet
{%- else %}
CommandResponseInfo {{field.name}}ResponseValue = new CommandResponseInfo("{{field.name}}", "{{encode_value_without_nullable_arraylist(cluster, encodable, 0)}}");
responseValues.put({{field.name}}ResponseValue, {{field.name}});
{%- endif -%}
{%- endif -%}
{% endfor %}
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception error) {
callback.onFailure(error);
}
}
{%- if already_handled_command.append(callbackName) -%}
{# This block does nothing, it only exists to append to already_handled_command. #}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{% endfor %}
{%- set already_handled_attribute = [] -%}
{%- for attribute in cluster.attributes | rejectattr('definition', 'is_field_global_name', typeLookup) -%}
{%- set encodable = attribute.definition | asEncodable(typeLookup) -%}
{%- set encodable2 = attribute.definition | asEncodable(typeLookup) -%}
{%- set encodable_check = attribute.definition | asEncodable(typeLookup) -%}
{%- set interfaceName = attribute | javaAttributeCallbackName(typeLookup) -%}
{%- if interfaceName not in already_handled_attribute %}
public static class Delegated{{cluster.name}}Cluster{{attribute.definition.name | upfirst}}AttributeCallback implements ChipClusters.{{cluster.name}}Cluster.{{attribute.definition.name | upfirst}}AttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
public void setCallbackDelegate(ClusterCommandCallback callback) {
this.callback = callback;
}
{# NOTE: asJavaType ends up sniffing for isArray on the context. Since we want the type of our _entry_, force isArray to false. -#}
@Override
public void onSuccess({{encode_value_without_optional(cluster, encodable, 0)}} {% if encodable_check.is_list -%}valueList{%- else -%}value{%- endif -%}) {
Map<CommandResponseInfo, Object> responseValues = new LinkedHashMap<>();
CommandResponseInfo commandResponseInfo = new CommandResponseInfo("{%- if encodable_check.is_list -%}valueList{%- else -%}value{%- endif -%}", "{{encode_value_without_optional_nullable(cluster, encodable2, 0)}}");
responseValues.put(commandResponseInfo, {% if encodable_check.is_list -%}valueList{%- else -%}value{%- endif -%});
callback.onSuccess(responseValues);
}
@Override
public void onError(Exception ex) {
callback.onFailure(ex);
}
}
{% if already_handled_attribute.append(interfaceName) -%}
{# This block does nothing, it only exists to append to already_handled_attribute. #}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endfor %}
public Map<String, ClusterInfo> getClusterMap() {
Map<String, ClusterInfo> clusterMap = initializeClusterMap();
Map<String, Map<String, InteractionInfo>> commandMap = getCommandMap();
combineCommand(clusterMap, commandMap);
Map<String, Map<String, InteractionInfo>> readAttributeMap = new ClusterReadMapping().getReadAttributeMap();
combineCommand(clusterMap, readAttributeMap);
Map<String, Map<String, InteractionInfo>> writeAttributeMap = new ClusterWriteMapping().getWriteAttributeMap();
combineCommand(clusterMap, writeAttributeMap);
return clusterMap;
}
public Map<String, ClusterInfo> initializeClusterMap() {
Map<String, ClusterInfo> clusterMap = new HashMap<>();
{% for cluster in clientClusters | sort(attribute='code') %}
ClusterInfo {{cluster.name | lowfirst}}ClusterInfo = new ClusterInfo(
(ptr, endpointId) -> new ChipClusters.{{cluster.name}}Cluster(ptr, endpointId), new HashMap<>());
clusterMap.put("{{cluster.name | lowfirst}}", {{cluster.name | lowfirst}}ClusterInfo);
{% endfor %}
return clusterMap;
}
public void combineCommand(Map<String, ClusterInfo> destination, Map<String, Map<String, InteractionInfo>> source) {
{%- for cluster in clientClusters | sort(attribute='code') %}
destination.get("{{cluster.name | lowfirst}}").combineCommands(source.get("{{cluster.name | lowfirst}}"));
{%- endfor %}
}
@SuppressWarnings("unchecked")
public Map<String, Map<String, InteractionInfo>> getCommandMap() {
Map<String, Map<String, InteractionInfo>> commandMap = new HashMap<>();
{% for cluster in clientClusters | sort(attribute='code') -%}
{%- set typeLookup = idl | createLookupContext(cluster) %}
Map<String, InteractionInfo> {{cluster.name | lowfirst}}ClusterInteractionInfoMap = new LinkedHashMap<>();
{% for command in cluster.commands | sort(attribute='code') -%}
{%- set callbackName = command | javaCommandCallbackName() %}
Map<String, CommandParameterInfo> {{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}CommandParams = new LinkedHashMap<String, CommandParameterInfo>();
{#- TODO: fill out parameter types -#}
{%- if command.input_param -%}
{%- for field in (cluster.structs | named(command.input_param)).fields -%}
{%- set encodable = field | asEncodable(typeLookup) %}
{% if not encodable.is_struct %}
CommandParameterInfo {{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}{{field.name | lowfirst_except_acronym}}CommandParameterInfo = new CommandParameterInfo("{{field.name | lowfirst_except_acronym}}", {{encode_value_remove_generic(cluster, encodable, 0)}}.class, {{encode_value_remove_generic_optional(cluster, encodable, 0)}}.class);
{{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}CommandParams.put("{{field.name | lowfirst_except_acronym}}",{{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}{{field.name | lowfirst_except_acronym}}CommandParameterInfo);
{%- endif -%}
{% endfor -%}
{%- endif -%}
{% if command | isCommandNotDefaultCallback() %}
InteractionInfo {{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}InteractionInfo = new InteractionInfo(
(cluster, callback, commandArguments) -> {
((ChipClusters.{{cluster.name}}Cluster) cluster)
.{{command.name | lowfirst_except_acronym}}((ChipClusters.{{cluster.name}}Cluster.{{callbackName}}Callback) callback
{%- if command.input_param -%}
{% for field in (cluster.structs | named(command.input_param)).fields -%}
{%- set encodable = field | asEncodable(typeLookup) %}
, ({{encode_value_without_nullable_arraylist(cluster, encodable, 0)}})
commandArguments.get("{{field.name | lowfirst_except_acronym}}")
{% endfor -%}
{%- endif %}
{# TODO: Allow timeout to be passed from client for this and timed write. -#}
{%- if command.is_timed_invoke -%}, 10000{%- endif -%}
);
},
() -> new Delegated{{cluster.name}}Cluster{{callbackName}}Callback(),
{{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}CommandParams
);
{%- else %}
InteractionInfo {{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}InteractionInfo = new InteractionInfo(
(cluster, callback, commandArguments) -> {
((ChipClusters.{{cluster.name}}Cluster) cluster)
.{{command.name | lowfirst_except_acronym}}((DefaultClusterCallback) callback
{%- if command.input_param %}
{%- for field in (cluster.structs | named(command.input_param)).fields -%}
{%- set encodable = field | asEncodable(typeLookup) %}
, ({{encode_value_without_nullable_arraylist(cluster, encodable, 0)}})
commandArguments.get("{{field.name | lowfirst_except_acronym}}")
{%- endfor -%}
{%- endif -%}
{#- TODO: Allow timeout to be passed from client for this and timed write. -#}
{% if command.is_timed_invoke %}, 10000{%- endif %}
);
},
() -> new DelegatedDefaultClusterCallback(),
{{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}CommandParams
);
{%- endif %}
{{cluster.name | lowfirst}}ClusterInteractionInfoMap.put("{{command.name | lowfirst_except_acronym}}", {{cluster.name | lowfirst}}{{command.name | lowfirst_except_acronym}}InteractionInfo);
{% endfor %}
commandMap.put("{{cluster.name | lowfirst}}", {{cluster.name | lowfirst}}ClusterInteractionInfoMap);
{% endfor %}
return commandMap;
}
}