From 608aef87f01566b9988eed0428a7fa15ec94f624 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 18 Oct 2022 14:00:46 -0400 Subject: [PATCH 01/23] Compile time code generation. Picked PluginApplicationCallbacks because it is simple and added it to a compile-time generated list. The main exercise for this is to make sure we can inject the appropriate calls to compile time generation to all examples. It is not yet perfect as it only involves include directories, however it does a "if it compiles it works, otherwise it fails to compile" approach. Uses codegen.py rather than ZAP for this particular file. For other files, we may chose to use ZAP however for that we have to: - ensure it is stand-alone runnable (likely as an installable app) - figure out any multi-processing conflicts as cmake/gn WILL run build steps in parallel and zap shares a common DB. --- build/chip/chip_codegen.cmake | 70 +++++++++++++++ build/chip/esp32/esp32_codegen.cmake | 45 ++++++++++ .../esp32/main/CMakeLists.txt | 8 +- .../esp32/main/CMakeLists.txt | 8 +- examples/bridge-app/esp32/main/CMakeLists.txt | 6 ++ examples/chef/esp32/main/CMakeLists.txt | 7 +- .../dynamic-bridge-app/bridge-common/BUILD.gn | 2 + .../esp32/main/CMakeLists.txt | 7 +- .../light-switch-app/telink/CMakeLists.txt | 15 ++++ .../lighting-app/esp32/main/CMakeLists.txt | 8 +- examples/lighting-app/telink/CMakeLists.txt | 15 ++++ examples/lock-app/esp32/main/CMakeLists.txt | 13 ++- .../esp32/main/CMakeLists.txt | 6 +- .../esp32/main/CMakeLists.txt | 8 +- .../ota-requestor-app/telink/CMakeLists.txt | 15 ++++ .../pigweed-app/esp32/main/CMakeLists.txt | 4 +- .../esp32/main/CMakeLists.txt | 9 +- scripts/codegen.py | 5 ++ scripts/idl/generators/cpp/__init__.py | 0 .../PluginApplicationCallbacksHeader.jinja | 9 ++ .../generators/cpp/application/__init__.py | 61 +++++++++++++ scripts/idl/test_generators.py | 5 +- scripts/idl/tests/available_tests.yaml | 5 ++ .../cpp-app/PluginApplicationCallbacks.h | 9 ++ src/app/chip_data_model.cmake | 31 ++++++- src/app/chip_data_model.gni | 24 +++++ src/app/util/util.cpp | 4 +- src/app/zap-templates/app-templates.json | 5 -- .../PluginApplicationCallbacks.h | 88 ------------------ .../PluginApplicationCallbacks.h | 83 ----------------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 51 ----------- .../PluginApplicationCallbacks.h | 45 ---------- .../PluginApplicationCallbacks.h | 49 ---------- .../PluginApplicationCallbacks.h | 52 ----------- .../PluginApplicationCallbacks.h | 51 ----------- .../PluginApplicationCallbacks.h | 52 ----------- .../PluginApplicationCallbacks.h | 48 ---------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 53 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 51 ----------- .../PluginApplicationCallbacks.h | 52 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 55 ------------ .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 48 ---------- .../PluginApplicationCallbacks.h | 89 ------------------- .../PluginApplicationCallbacks.h | 50 ----------- .../PluginApplicationCallbacks.h | 52 ----------- .../PluginApplicationCallbacks.h | 41 --------- .../PluginApplicationCallbacks.h | 51 ----------- .../PluginApplicationCallbacks.h | 49 ---------- .../PluginApplicationCallbacks.h | 30 ------- .../PluginApplicationCallbacks.h | 38 -------- .../PluginApplicationCallbacks.h | 42 --------- .../PluginApplicationCallbacks.h | 71 --------------- .../PluginApplicationCallbacks.h | 71 --------------- .../PluginApplicationCallbacks.h | 45 ---------- .../PluginApplicationCallbacks.h | 43 --------- .../PluginApplicationCallbacks.h | 43 --------- .../PluginApplicationCallbacks.h | 51 ----------- .../PluginApplicationCallbacks.h | 64 ------------- .../PluginApplicationCallbacks.h | 67 -------------- .../PluginApplicationCallbacks.h | 49 ---------- 70 files changed, 376 insertions(+), 2252 deletions(-) create mode 100644 build/chip/chip_codegen.cmake create mode 100644 build/chip/esp32/esp32_codegen.cmake create mode 100644 scripts/idl/generators/cpp/__init__.py create mode 100644 scripts/idl/generators/cpp/application/PluginApplicationCallbacksHeader.jinja create mode 100644 scripts/idl/generators/cpp/application/__init__.py create mode 100644 scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/all-clusters-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/all-clusters-minimal-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/bridge-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-noip_rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_colortemperaturelight_hbUnzYVeyn/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_contactsensor_lFAGG1bfRO/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_doorlock_aNKYAreMXE/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_extendedcolorlight_8lcaaYJVAa/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_fan_7N2TobIlOX/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_flowsensor_1zVxHedlaV/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_heatingcoolingunit_ncdGai1E5a/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_humiditysensor_Xyj4gda6Hb/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_lightsensor_lZQycTFcJK/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_occupancysensor_iHyVgifZuo/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_onofflight_bbs1b7IaOV/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_onofflightswitch_FsPlMr090Q/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_onoffpluginunit_Wtf8ss5EBY/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_pressuresensor_s0qC9wLH4k/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_speaker_RpzeXdimqA/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_temperaturesensor_Qy1zkNW7c3/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_thermostat_bm3fb8dhYi/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/chef-rootnode_windowcovering_RLCxaGi9Yx/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/controller-clusters/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/dynamic-bridge-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/lighting-app/nxp/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/lock-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/log-source-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/ota-provider-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/ota-requestor-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/placeholder/app1/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/placeholder/app2/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/pump-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/temperature-measurement-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/thermostat/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/tv-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/tv-casting-app/zap-generated/PluginApplicationCallbacks.h delete mode 100644 zzz_generated/window-app/zap-generated/PluginApplicationCallbacks.h diff --git a/build/chip/chip_codegen.cmake b/build/chip/chip_codegen.cmake new file mode 100644 index 00000000000000..d0c20c0bd99976 --- /dev/null +++ b/build/chip/chip_codegen.cmake @@ -0,0 +1,70 @@ +# Run chip code generation. +# +# Example usage: +# chip_codegen("app" +# INPUT "some_file.matter" +# GENERATOR "bridge" +# OUTPUTS +# "bridge/OnOff.h" +# "bridge/LevelControl.h" +# "bridge/Switch.h" +# # ... more outputs +# OUTPUT_PATH DIR_NAME_VAR +# OUTPUT_FILES FILE_NAMES_VAR +# ) +# +# Arguments: +# INPUT - the name of the ".matter" file to use for generation +# GENERATOR - generator to use for codegen.py +# OUTPUTS - EXPECTED output names. MUST match actual outputs +# +# OUTPUT_PATH - [OUT] output variable will contain the directory where the +# files will be generated +# OUTPUT_FILES - [OUT] output variable will contain the path of generated files. +# suitable to be added within a build target +# +function(chip_codegen TARGET_NAME) + cmake_parse_arguments(ARG + "" + "INPUT;GENERATOR;OUTPUT_PATH;OUTPUT_FILES" + "OUTPUTS" + ${ARGN} + ) + + set(GEN_FOLDER "${CMAKE_BINARY_DIR}/gen/${TARGET_NAME}/${ARG_GENERATOR}") + + string(REPLACE ";" "\n" OUTPUT_AS_NEWLINES "${ARG_OUTPUTS}") + + file(MAKE_DIRECTORY "${GEN_FOLDER}") + file(GENERATE + OUTPUT "${GEN_FOLDER}/expected.outputs" + CONTENT "${OUTPUT_AS_NEWLINES}" + ) + + + set(OUT_NAMES) + foreach(NAME IN LISTS ARG_OUTPUTS) + list(APPEND OUT_NAMES "${GEN_FOLDER}/${NAME}") + endforeach() + + # Python is expected to be in the path + # + # find_package(Python3 REQUIRED) + add_custom_command( + OUTPUT "${OUT_NAMES}" + COMMAND "${CHIP_ROOT}/scripts/codegen.py" + ARGS "--generator" "${ARG_GENERATOR}" + "--output-dir" "${GEN_FOLDER}" + "--expected-outputs" "${GEN_FOLDER}/expected.outputs" + "${ARG_INPUT}" + DEPENDS + "${ARG_INPUT}" + VERBATIM + ) + + add_custom_target(${TARGET_NAME} DEPENDS "${OUT_NAMES}") + + # Forward outputs to the parent + set(${ARG_OUTPUT_FILES} "${OUT_NAMES}" PARENT_SCOPE) + set(${ARG_OUTPUT_PATH} "${GEN_FOLDER}" PARENT_SCOPE) +endfunction() diff --git a/build/chip/esp32/esp32_codegen.cmake b/build/chip/esp32/esp32_codegen.cmake new file mode 100644 index 00000000000000..8d454e369dc75c --- /dev/null +++ b/build/chip/esp32/esp32_codegen.cmake @@ -0,0 +1,45 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# 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. +# + + + +macro(chip_app_component_codegen IDL_NAME) + include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") + + # The IDF build system performs a two-pass expansion to determine + # component expansion. The first pass runs in script-mode + # to determine idf_component_register REQUIRES and PRIV_REQUIRES. + # + # We can only set up code generation during the 2nd pass + # + # see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html + if (NOT CMAKE_BUILD_EARLY_EXPANSION) + + chip_codegen(app-codegen + INPUT "${IDL_NAME}" + GENERATOR "cpp-app" + OUTPUTS + "app/PluginApplicationCallbacks.h" + OUTPUT_PATH APP_GEN_DIR + OUTPUT_FILES APP_GEN_FILES + ) + + target_include_directories(${COMPONENT_LIB} PUBLIC "${APP_GEN_DIR}") + + add_dependencies(${COMPONENT_LIB} app-codegen) + endif() +endmacro() diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index f25a2b351094d5..11445b48bd0df4 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) # The list of src and include dirs must be in sync with that in all-clusters-app/esp32/main/component.mk set(PRIV_INCLUDE_DIRS_LIST @@ -137,6 +136,12 @@ idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} EXCLUDE_SRCS ${EXCLUDE_SRCS_LIST} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter") + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC @@ -145,7 +150,6 @@ target_compile_options(${COMPONENT_LIB} PUBLIC if (CONFIG_ENABLE_PW_RPC) -get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt index 2ae36b439e00a1..376f85bc368378 100644 --- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt @@ -128,6 +128,12 @@ idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter") + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC @@ -136,8 +142,6 @@ target_compile_options(${COMPONENT_LIB} PUBLIC if (CONFIG_ENABLE_PW_RPC) -get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) - set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) include(${PIGWEED_ROOT}/pw_protobuf_compiler/proto.cmake) diff --git a/examples/bridge-app/esp32/main/CMakeLists.txt b/examples/bridge-app/esp32/main/CMakeLists.txt index 81eae85be11da9..9ed6f0f1410c68 100644 --- a/examples/bridge-app/esp32/main/CMakeLists.txt +++ b/examples/bridge-app/esp32/main/CMakeLists.txt @@ -54,6 +54,12 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" PRIV_REQUIRES chip QRCode bt) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/bridge-app/bridge-common/bridge-app.matter") + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 14) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC diff --git a/examples/chef/esp32/main/CMakeLists.txt b/examples/chef/esp32/main/CMakeLists.txt index e7def1a4efb05f..2f02250d10ab76 100644 --- a/examples/chef/esp32/main/CMakeLists.txt +++ b/examples/chef/esp32/main/CMakeLists.txt @@ -16,7 +16,7 @@ # # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../../.. REALPATH) +get_filename_component(CHIP_ROOT ../third_party/connectedhomeip REALPATH) get_filename_component(CHEF ${CMAKE_CURRENT_SOURCE_DIR}/../../ REALPATH) get_filename_component(GEN_DIR ${CHEF}/out/${SAMPLE_NAME}/zap-generated REALPATH) @@ -107,6 +107,9 @@ idf_component_register(PRIV_INCLUDE_DIRS PRIV_REQUIRES chip nvs_flash bt console esp32_mbedtls QRCode tft screen-framework spidriver SRC_DIRS ${SRC_DIRS_LIST}) +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") +chip_app_component_codegen("${CHEF}/devices/${SAMPLE_NAME}.matter") + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC @@ -115,8 +118,6 @@ target_compile_options(${COMPONENT_LIB} PUBLIC if (CONFIG_ENABLE_PW_RPC) -get_filename_component(CHIP_ROOT ../third_party/connectedhomeip REALPATH) - set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) include(${PIGWEED_ROOT}/pw_protobuf_compiler/proto.cmake) diff --git a/examples/dynamic-bridge-app/bridge-common/BUILD.gn b/examples/dynamic-bridge-app/bridge-common/BUILD.gn index 22fc176dcd69d6..1507e54b130dc3 100644 --- a/examples/dynamic-bridge-app/bridge-common/BUILD.gn +++ b/examples/dynamic-bridge-app/bridge-common/BUILD.gn @@ -22,6 +22,8 @@ chip_data_model("dynamic-bridge-common") { zap_pregenerated_dir = "${chip_root}/zzz_generated/dynamic-bridge-app/zap-generated" + + is_server = true # TODO: the definition of DYNAMIC_ENDPOINT_COUNT needs find a common home! diff --git a/examples/light-switch-app/esp32/main/CMakeLists.txt b/examples/light-switch-app/esp32/main/CMakeLists.txt index 8402283ee623e2..5d4e4dbdce2f08 100644 --- a/examples/light-switch-app/esp32/main/CMakeLists.txt +++ b/examples/light-switch-app/esp32/main/CMakeLists.txt @@ -14,8 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/light-switch-app" "${CMAKE_CURRENT_LIST_DIR}/include" @@ -61,6 +61,11 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/groups-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/group-key-mgmt-server" PRIV_REQUIRES chip QRCode bt app_update) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/light-switch-app/light-switch-common/light-switch-app.matter") set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") diff --git a/examples/light-switch-app/telink/CMakeLists.txt b/examples/light-switch-app/telink/CMakeLists.txt index 36a2970bc76371..af24506644349d 100755 --- a/examples/light-switch-app/telink/CMakeLists.txt +++ b/examples/light-switch-app/telink/CMakeLists.txt @@ -24,6 +24,19 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) +include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") + +# TODO: this CMakeFile should use src/app/chip_data_model.cmake +# and then codegen would be inherited +chip_codegen(app-codegen + INPUT "${CHIP_ROOT}/examples/light-switch-app/light-switch-common/light-switch-app.matter" + GENERATOR "cpp-app" + OUTPUTS + "app/PluginApplicationCallbacks.h" + OUTPUT_PATH APP_GEN_DIR + OUTPUT_FILES APP_GEN_FILES +) + # Load NCS/Zephyr build system list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -36,11 +49,13 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include + ${APP_GEN_DIR} ${GEN_DIR}/app-common ${GEN_DIR}/light-switch-app ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) +add_dependencies(app app-codegen) add_definitions( "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index ff9fac181e2e5d..61953e1c2a0d34 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -17,12 +17,13 @@ # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) set(PRIV_INCLUDE_DIRS_LIST + "${APP_GEN_DIR}" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/lighting-app" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/lighting-app/lighting-common/include" "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" -) +) set(SRC_DIRS_LIST "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" @@ -90,6 +91,11 @@ endif (CONFIG_ENABLE_PW_RPC) idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/lighting-app/lighting-common/lighting-app.matter") set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index bad40aedef8a8e..ed87f292eb05c5 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -24,6 +24,19 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) +include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") + +# TODO: this CMakeFile should use src/app/chip_data_model.cmake +# and then codegen would be inherited +chip_codegen(app-codegen + INPUT "${CHIP_ROOT}/examples/lighting-app/lighting-common/lighting-app.matter" + GENERATOR "cpp-app" + OUTPUTS + "app/PluginApplicationCallbacks.h" + OUTPUT_PATH APP_GEN_DIR + OUTPUT_FILES APP_GEN_FILES +) + # Load NCS/Zephyr build system list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -36,11 +49,13 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include + ${APP_GEN_DIR} ${GEN_DIR}/app-common ${GEN_DIR}/lighting-app ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) +add_dependencies(app app-codegen) add_definitions( "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" diff --git a/examples/lock-app/esp32/main/CMakeLists.txt b/examples/lock-app/esp32/main/CMakeLists.txt index 189014129af2bd..eee6f6926d5d32 100644 --- a/examples/lock-app/esp32/main/CMakeLists.txt +++ b/examples/lock-app/esp32/main/CMakeLists.txt @@ -16,6 +16,8 @@ # # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + if (CONFIG_ENABLE_PW_RPC) idf_component_register(INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}" @@ -67,8 +69,7 @@ idf_component_register(INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/identify-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/groups-server" PRIV_REQUIRES bt chip QRCode) - -get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +add_dependencies(${COMPONENT_LIB} app-codegen) set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) @@ -186,6 +187,8 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/groups-server" PRIV_REQUIRES chip QRCode bt) +add_dependencies(${COMPONENT_LIB} app-codegen) + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC @@ -193,3 +196,9 @@ target_compile_options(${COMPONENT_LIB} PUBLIC ) endif (CONFIG_ENABLE_PW_RPC) + +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") + +chip_app_component_codegen("${CHIP_ROOT}/examples/lock-app/lock-common/lock-app.matter") diff --git a/examples/ota-provider-app/esp32/main/CMakeLists.txt b/examples/ota-provider-app/esp32/main/CMakeLists.txt index 468fdce04c0f46..e5a6cf7327fcd6 100644 --- a/examples/ota-provider-app/esp32/main/CMakeLists.txt +++ b/examples/ota-provider-app/esp32/main/CMakeLists.txt @@ -16,7 +16,7 @@ # # # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -idf_component_register(PRIV_INCLUDE_DIRS +idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/ota-provider-app/" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/ota-provider-app" @@ -59,6 +59,10 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp" PRIV_REQUIRES chip QRCode bt console spiffs) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") +chip_app_component_codegen("${CHIP_ROOT}/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter") + spiffs_create_partition_image(img_storage ${CMAKE_SOURCE_DIR}/spiffs_image FLASH_IN_PROJECT) set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 14) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") diff --git a/examples/ota-requestor-app/esp32/main/CMakeLists.txt b/examples/ota-requestor-app/esp32/main/CMakeLists.txt index 1ab96247f242e8..5939f42f6f4f66 100644 --- a/examples/ota-requestor-app/esp32/main/CMakeLists.txt +++ b/examples/ota-requestor-app/esp32/main/CMakeLists.txt @@ -16,6 +16,8 @@ # # # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src" @@ -86,6 +88,9 @@ idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") +chip_app_component_codegen("${CHIP_ROOT}/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter") + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC @@ -94,9 +99,8 @@ target_compile_options(${COMPONENT_LIB} PUBLIC if (CONFIG_ENABLE_PW_RPC) -get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) -set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") +set(PIGWEED_ROOT "${cHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) include(${PIGWEED_ROOT}/pw_protobuf_compiler/proto.cmake) set(dir_pw_third_party_nanopb "${CHIP_ROOT}/third_party/nanopb/repo" CACHE STRING "" FORCE) diff --git a/examples/ota-requestor-app/telink/CMakeLists.txt b/examples/ota-requestor-app/telink/CMakeLists.txt index c602b75b7bffb7..a36efb780741c4 100644 --- a/examples/ota-requestor-app/telink/CMakeLists.txt +++ b/examples/ota-requestor-app/telink/CMakeLists.txt @@ -24,6 +24,19 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) +include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") + +# TODO: this CMakeFile should use src/app/chip_data_model.cmake +# and then codegen would be inherited +chip_codegen(app-codegen + INPUT "${CHIP_ROOT}/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter" + GENERATOR "cpp-app" + OUTPUTS + "app/PluginApplicationCallbacks.h" + OUTPUT_PATH APP_GEN_DIR + OUTPUT_FILES APP_GEN_FILES +) + # Load NCS/Zephyr build system list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -36,11 +49,13 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include + ${APP_GEN_DIR} ${GEN_DIR}/app-common ${GEN_DIR}/ota-requestor-app ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) +add_dependencies(app app-codegen) add_definitions( "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" diff --git a/examples/pigweed-app/esp32/main/CMakeLists.txt b/examples/pigweed-app/esp32/main/CMakeLists.txt index 4e89e02e117101..c23dfe3a8de84c 100644 --- a/examples/pigweed-app/esp32/main/CMakeLists.txt +++ b/examples/pigweed-app/esp32/main/CMakeLists.txt @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -idf_component_register(INCLUDE_DIRS +idf_component_register(INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/pw_sys_io/public" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" @@ -22,7 +22,7 @@ idf_component_register(INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common/pigweed/esp32" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/lib/support" "${IDF_PATH}/components/freertos/include/freertos" - + SRC_DIRS "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" diff --git a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt index d2d1826b8d5d78..dce457d2448346 100644 --- a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt +++ b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt @@ -15,7 +15,9 @@ # limitations under the License. # # -# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + +get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) + set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/temperature-measurement-app/" "${CMAKE_CURRENT_LIST_DIR}/include" @@ -78,6 +80,9 @@ idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) +include("${CHIP_ROOT}/build/chip/esp32/esp32_codegen.cmake") +chip_app_component_codegen("${CHIP_ROOT}/examples/temperature-measurement-app/esp32/main/temperature-measurement.matter") + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC @@ -86,8 +91,6 @@ target_compile_options(${COMPONENT_LIB} PUBLIC if (CONFIG_ENABLE_PW_RPC) -get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) - set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) include(${PIGWEED_ROOT}/pw_protobuf_compiler/proto.cmake) diff --git a/scripts/codegen.py b/scripts/codegen.py index bcbba6833a49b4..a43676f138469f 100755 --- a/scripts/codegen.py +++ b/scripts/codegen.py @@ -29,6 +29,7 @@ from idl.generators import FileSystemGeneratorStorage, GeneratorStorage from idl.generators.java import JavaGenerator from idl.generators.bridge import BridgeGenerator +from idl.generators.cpp.application import CppApplicationGenerator class CodeGeneratorTypes(enum.Enum): @@ -39,12 +40,15 @@ class CodeGeneratorTypes(enum.Enum): """ JAVA = enum.auto() BRIDGE = enum.auto() + CPP_APPLICATION = enum.auto() def CreateGenerator(self, *args, **kargs): if self == CodeGeneratorTypes.JAVA: return JavaGenerator(*args, **kargs) elif self == CodeGeneratorTypes.BRIDGE: return BridgeGenerator(*args, **kargs) + elif self == CodeGeneratorTypes.CPP_APPLICATION: + return CppApplicationGenerator(*args, **kargs) else: raise Error("Unknown code generator type") @@ -76,6 +80,7 @@ def write_new_data(self, relative_path: str, content: str): __GENERATORS__ = { 'java': CodeGeneratorTypes.JAVA, 'bridge': CodeGeneratorTypes.BRIDGE, + 'cpp-app': CodeGeneratorTypes.CPP_APPLICATION, } diff --git a/scripts/idl/generators/cpp/__init__.py b/scripts/idl/generators/cpp/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/scripts/idl/generators/cpp/application/PluginApplicationCallbacksHeader.jinja b/scripts/idl/generators/cpp/application/PluginApplicationCallbacksHeader.jinja new file mode 100644 index 00000000000000..83e3dbf4c15a8a --- /dev/null +++ b/scripts/idl/generators/cpp/application/PluginApplicationCallbacksHeader.jinja @@ -0,0 +1,9 @@ +#pragma once + +#include + +#define MATTER_PLUGINS_INIT \ +{%- for cluster in clusters | sort(attribute='name') %} + Matter{{ cluster.name }}Plugin{{ cluster.side | clusterSideString }}InitCallback();{{ " \\" if not loop.last else ""}} +{%- endfor %} + diff --git a/scripts/idl/generators/cpp/application/__init__.py b/scripts/idl/generators/cpp/application/__init__.py new file mode 100644 index 00000000000000..40a4bb26b0b34b --- /dev/null +++ b/scripts/idl/generators/cpp/application/__init__.py @@ -0,0 +1,61 @@ +# Copyright (c) 2022 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. + +from idl.generators import CodeGenerator, GeneratorStorage +from idl.matter_idl_types import Idl, ClusterSide, Field, Attribute, Cluster, FieldQuality, Command, DataType +from idl import matter_idl_types +from idl.generators.types import ParseDataType, BasicString, BasicInteger, FundamentalType, IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext +from typing import Union, List, Set +from stringcase import capitalcase + +import enum +import logging + + +def clusterSideString(side: ClusterSide): + if side == ClusterSide.CLIENT: + return "Client" + elif side == ClusterSide.SERVER: + return "Server" + else: + raise Exception("Unknown cluster side %r" % (side, )) + + +class CppApplicationGenerator(CodeGenerator): + """ + Generation of cpp code for application implementation for matter. + """ + + def __init__(self, storage: GeneratorStorage, idl: Idl): + """ + Inintialization is specific for java generation and will add + filters as required by the java .jinja templates to function. + """ + super().__init__(storage, idl) + + self.jinja_env.filters['clusterSideString'] = clusterSideString + + def internal_render_all(self): + """ + Renders the cpp and header files required for applications + """ + + # Header containing a macro to initialize all cluster plugins + self.internal_render_one_output( + template_path="cpp/application/PluginApplicationCallbacksHeader.jinja", + output_file_name="app/PluginApplicationCallbacks.h", + vars={ + 'clusters': self.idl.clusters, + } + ) diff --git a/scripts/idl/test_generators.py b/scripts/idl/test_generators.py index 88b929e0fcbe5d..bd7dfc7c232987 100755 --- a/scripts/idl/test_generators.py +++ b/scripts/idl/test_generators.py @@ -33,6 +33,7 @@ from idl.matter_idl_types import Idl from idl.generators.java import JavaGenerator from idl.generators.bridge import BridgeGenerator +from idl.generators.cpp.application import CppApplicationGenerator from idl.generators import GeneratorStorage @@ -96,7 +97,7 @@ def write_new_data(self, relative_path: str, content: str): # This will display actual diffs in the output files self.checker.assertEqual( - self.get_existing_data(relative_path), content) + self.get_existing_data(relative_path), content, "Content of %s" % relative_path) # Even if no diff, to be build system friendly, we do NOT expect any # actual data writes. @@ -119,6 +120,8 @@ def _create_generator(self, storage: GeneratorStorage, idl: Idl): return JavaGenerator(storage, idl) if self.generator_name.lower() == 'bridge': return BridgeGenerator(storage, idl) + if self.generator_name.lower() == 'cpp-app': + return CppApplicationGenerator(storage, idl) else: raise Exception("Unknown generator for testing: %s", self.generator_name.lower()) diff --git a/scripts/idl/tests/available_tests.yaml b/scripts/idl/tests/available_tests.yaml index 3fb20e2a482b87..7563d2454d708d 100644 --- a/scripts/idl/tests/available_tests.yaml +++ b/scripts/idl/tests/available_tests.yaml @@ -57,3 +57,8 @@ bridge: bridge/First.h: outputs/several_clusters/bridge/First.h bridge/Second.h: outputs/several_clusters/bridge/Second.h bridge/Third.h: outputs/several_clusters/bridge/Third.h + +cpp-app: + inputs/several_clusters.matter: + app/PluginApplicationCallbacks.h: outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h + diff --git a/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h b/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h new file mode 100644 index 00000000000000..1cb70f041e620d --- /dev/null +++ b/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#define MATTER_PLUGINS_INIT \ + MatterFirstPluginClientInitCallback(); \ + MatterSecondPluginClientInitCallback(); \ + MatterThirdPluginClientInitCallback(); + diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake index 72a62b3b2d9e26..355eaf27a5babc 100644 --- a/src/app/chip_data_model.cmake +++ b/src/app/chip_data_model.cmake @@ -16,7 +16,15 @@ set(CHIP_APP_BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) -# +if (NOT CHIP_ROOT) + # TODO: these are WORKAROUNDS and should be removed + if(DEFINED ameba_matter_root) + SET(CHIP_ROOT "${ameba_matter_root}") + endif() +endif() + +include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") + # Configure ${APP_TARGET} with source files associated with ${CLUSTER} cluster # function(chip_configure_cluster APP_TARGET CLUSTER) @@ -52,9 +60,11 @@ endfunction() # INCLUDE_SERVER Include source files from src/app/server directory # ZAP_FILE Path to the ZAP file, used to determine the list of clusters # supported by the application. +# IDL .matter IDL file to use for codegen. Inferred from ZAP_FILE +# if not provided # function(chip_configure_data_model APP_TARGET) - cmake_parse_arguments(ARG "INCLUDE_SERVER" "ZAP_FILE;GEN_DIR" "" ${ARGN}) + cmake_parse_arguments(ARG "INCLUDE_SERVER" "ZAP_FILE;GEN_DIR;IDL" "" ${ARGN}) if (ARG_INCLUDE_SERVER) target_sources(${APP_TARGET} PRIVATE @@ -72,6 +82,23 @@ function(chip_configure_data_model APP_TARGET) if (ARG_ZAP_FILE) chip_configure_zap_file(${APP_TARGET} ${ARG_ZAP_FILE}) + if (NOT ARG_IDL) + string(REPLACE ".zap" ".matter" ARG_IDL ${ARG_ZAP_FILE}) + endif() + endif() + + if (ARG_IDL) + chip_codegen(${APP_TARGET}-codegen + INPUT "${ARG_IDL}" + GENERATOR "cpp-app" + OUTPUTS + "app/PluginApplicationCallbacks.h" + OUTPUT_PATH APP_GEN_DIR + OUTPUT_FILES APP_GEN_FILES + ) + + target_include_directories(${APP_TARGET} PRIVATE "${APP_GEN_DIR}") + add_dependencies(${APP_TARGET} ${APP_TARGET}-codegen) endif() target_sources(${APP_TARGET} PRIVATE diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index b2b50687503dc5..4c065d8e7298f9 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("${chip_root}/build/chip/chip_codegen.gni") import("${chip_root}/src/platform/python.gni") import("${chip_root}/src/lib/core/core.gni") @@ -31,11 +32,31 @@ _zap_cluster_list_script = get_path_info("zap_cluster_list.py", "abspath") # zap_file # Path to the ZAP input file. # +# idl +# Path to the .matter IDL corresponding to the zap file. This is for +# dependencies on build-time code generation. +# # Forwards all the remaining variables to the source_set. # template("chip_data_model") { _data_model_name = target_name + if (defined(invoker.idl)) { + _idl = invoker.idl + } else { + # Assume that IDL name is the same as the zap file name, but instead of + # '.zap' use '.matter' as extension. This is currently the case in the + # sample apps, but may change in the future + print("AUTO-DETECTING input matter IDL file.") + _idl = string_replace(invoker.zap_file, ".zap", ".matter") + } + + chip_codegen("${_data_model_name}_codegen") { + input = _idl + generator = "cpp-app" + outputs = [ "app/PluginApplicationCallbacks.h" ] + } + config("${_data_model_name}_config") { include_dirs = [] @@ -60,6 +81,8 @@ template("chip_data_model") { sources = [] } + sources += get_target_outputs(":${_data_model_name}_codegen") + sources += [ "${_app_root}/clusters/barrier-control-server/barrier-control-server.h", "${_app_root}/clusters/basic/basic.h", @@ -163,6 +186,7 @@ template("chip_data_model") { } public_deps += [ + ":${_data_model_name}_codegen", "${chip_root}/src/app", "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/controller", diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index aa8d3cade68113..1ba17a0e935967 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -25,7 +25,9 @@ #include #include #include -#include + +// TODO: figure out a clear path for compile-time codegen +#include #ifdef EMBER_AF_PLUGIN_GROUPS_SERVER #include diff --git a/src/app/zap-templates/app-templates.json b/src/app/zap-templates/app-templates.json index b79bb4f13e7266..ecc7aa080c9066 100644 --- a/src/app/zap-templates/app-templates.json +++ b/src/app/zap-templates/app-templates.json @@ -41,11 +41,6 @@ } ], "templates": [ - { - "path": "templates/app/callbacks/PluginApplicationCallbacks.zapt", - "name": "Matter Application Callbacks header", - "output": "PluginApplicationCallbacks.h" - }, { "path": "templates/app/callback-stub-src.zapt", "name": "ZCL callback-stub source", diff --git a/zzz_generated/all-clusters-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/all-clusters-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 841c63fdb69b0e..00000000000000 --- a/zzz_generated/all-clusters-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterOnOffSwitchConfigurationPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterBinaryInputBasicPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterActionsPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterPowerSourceConfigurationPluginServerInitCallback(); \ - MatterPowerSourcePluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterBooleanStatePluginServerInitCallback(); \ - MatterModeSelectPluginServerInitCallback(); \ - MatterDoorLockPluginServerInitCallback(); \ - MatterWindowCoveringPluginServerInitCallback(); \ - MatterBarrierControlPluginServerInitCallback(); \ - MatterPumpConfigurationAndControlPluginServerInitCallback(); \ - MatterThermostatPluginServerInitCallback(); \ - MatterFanControlPluginServerInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); \ - MatterIlluminanceMeasurementPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); \ - MatterPressureMeasurementPluginServerInitCallback(); \ - MatterFlowMeasurementPluginServerInitCallback(); \ - MatterRelativeHumidityMeasurementPluginServerInitCallback(); \ - MatterOccupancySensingPluginServerInitCallback(); \ - MatterWakeOnLanPluginServerInitCallback(); \ - MatterChannelPluginServerInitCallback(); \ - MatterTargetNavigatorPluginServerInitCallback(); \ - MatterMediaPlaybackPluginServerInitCallback(); \ - MatterMediaInputPluginServerInitCallback(); \ - MatterLowPowerPluginServerInitCallback(); \ - MatterKeypadInputPluginServerInitCallback(); \ - MatterContentLauncherPluginServerInitCallback(); \ - MatterAudioOutputPluginServerInitCallback(); \ - MatterApplicationLauncherPluginServerInitCallback(); \ - MatterApplicationBasicPluginServerInitCallback(); \ - MatterAccountLoginPluginServerInitCallback(); \ - MatterElectricalMeasurementPluginServerInitCallback(); \ - MatterTestClusterPluginServerInitCallback(); \ - MatterFaultInjectionPluginServerInitCallback(); diff --git a/zzz_generated/all-clusters-minimal-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/all-clusters-minimal-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 67219dcd814857..00000000000000 --- a/zzz_generated/all-clusters-minimal-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterActionsPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterPowerSourceConfigurationPluginServerInitCallback(); \ - MatterPowerSourcePluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterBooleanStatePluginServerInitCallback(); \ - MatterModeSelectPluginServerInitCallback(); \ - MatterDoorLockPluginServerInitCallback(); \ - MatterWindowCoveringPluginServerInitCallback(); \ - MatterPumpConfigurationAndControlPluginServerInitCallback(); \ - MatterThermostatPluginServerInitCallback(); \ - MatterFanControlPluginServerInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); \ - MatterIlluminanceMeasurementPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); \ - MatterPressureMeasurementPluginServerInitCallback(); \ - MatterFlowMeasurementPluginServerInitCallback(); \ - MatterRelativeHumidityMeasurementPluginServerInitCallback(); \ - MatterOccupancySensingPluginServerInitCallback(); \ - MatterWakeOnLanPluginServerInitCallback(); \ - MatterChannelPluginServerInitCallback(); \ - MatterTargetNavigatorPluginServerInitCallback(); \ - MatterMediaPlaybackPluginServerInitCallback(); \ - MatterMediaInputPluginServerInitCallback(); \ - MatterLowPowerPluginServerInitCallback(); \ - MatterKeypadInputPluginServerInitCallback(); \ - MatterContentLauncherPluginServerInitCallback(); \ - MatterAudioOutputPluginServerInitCallback(); \ - MatterApplicationLauncherPluginServerInitCallback(); \ - MatterApplicationBasicPluginServerInitCallback(); \ - MatterAccountLoginPluginServerInitCallback(); \ - MatterTestClusterPluginServerInitCallback(); diff --git a/zzz_generated/bridge-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/bridge-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index f0368e6a64bb30..00000000000000 --- a/zzz_generated/bridge-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterActionsPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/chef-noip_rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-noip_rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 849a9383fbb82a..00000000000000 --- a/zzz_generated/chef-noip_rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterOccupancySensingPluginClientInitCallback(); diff --git a/zzz_generated/chef-rootnode_colortemperaturelight_hbUnzYVeyn/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_colortemperaturelight_hbUnzYVeyn/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index c5040d9a82f202..00000000000000 --- a/zzz_generated/chef-rootnode_colortemperaturelight_hbUnzYVeyn/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_contactsensor_lFAGG1bfRO/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_contactsensor_lFAGG1bfRO/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 7cb20885eb6939..00000000000000 --- a/zzz_generated/chef-rootnode_contactsensor_lFAGG1bfRO/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterBooleanStatePluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 8e4985e7e7ffe2..00000000000000 --- a/zzz_generated/chef-rootnode_dimmablelight_bCwGYSDpoe/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterOccupancySensingPluginClientInitCallback(); diff --git a/zzz_generated/chef-rootnode_doorlock_aNKYAreMXE/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_doorlock_aNKYAreMXE/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index abae6af8e5565f..00000000000000 --- a/zzz_generated/chef-rootnode_doorlock_aNKYAreMXE/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginClientInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterDoorLockPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_extendedcolorlight_8lcaaYJVAa/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_extendedcolorlight_8lcaaYJVAa/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index bf63aaa09358f9..00000000000000 --- a/zzz_generated/chef-rootnode_extendedcolorlight_8lcaaYJVAa/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_fan_7N2TobIlOX/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_fan_7N2TobIlOX/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index af43a6aa723484..00000000000000 --- a/zzz_generated/chef-rootnode_fan_7N2TobIlOX/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterFanControlPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_flowsensor_1zVxHedlaV/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_flowsensor_1zVxHedlaV/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 42b72ac388d102..00000000000000 --- a/zzz_generated/chef-rootnode_flowsensor_1zVxHedlaV/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterFlowMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_heatingcoolingunit_ncdGai1E5a/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_heatingcoolingunit_ncdGai1E5a/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 3b886f35afccba..00000000000000 --- a/zzz_generated/chef-rootnode_heatingcoolingunit_ncdGai1E5a/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterThermostatPluginClientInitCallback(); \ - MatterFanControlPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_humiditysensor_Xyj4gda6Hb/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_humiditysensor_Xyj4gda6Hb/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 1e97ffe07f4f74..00000000000000 --- a/zzz_generated/chef-rootnode_humiditysensor_Xyj4gda6Hb/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterRelativeHumidityMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_lightsensor_lZQycTFcJK/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_lightsensor_lZQycTFcJK/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index b1e270d7769ea5..00000000000000 --- a/zzz_generated/chef-rootnode_lightsensor_lZQycTFcJK/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterIlluminanceMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_occupancysensor_iHyVgifZuo/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_occupancysensor_iHyVgifZuo/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index e505e9f530832f..00000000000000 --- a/zzz_generated/chef-rootnode_occupancysensor_iHyVgifZuo/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterOccupancySensingPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_onofflight_bbs1b7IaOV/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_onofflight_bbs1b7IaOV/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 0f24b2860e7f91..00000000000000 --- a/zzz_generated/chef-rootnode_onofflight_bbs1b7IaOV/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_onofflightswitch_FsPlMr090Q/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_onofflightswitch_FsPlMr090Q/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 3edd89a53f2702..00000000000000 --- a/zzz_generated/chef-rootnode_onofflightswitch_FsPlMr090Q/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginClientInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_onoffpluginunit_Wtf8ss5EBY/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_onoffpluginunit_Wtf8ss5EBY/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index e3d4c729a40830..00000000000000 --- a/zzz_generated/chef-rootnode_onoffpluginunit_Wtf8ss5EBY/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_pressuresensor_s0qC9wLH4k/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_pressuresensor_s0qC9wLH4k/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index d636a4c8114913..00000000000000 --- a/zzz_generated/chef-rootnode_pressuresensor_s0qC9wLH4k/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterPressureMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_speaker_RpzeXdimqA/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_speaker_RpzeXdimqA/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index a2d936c47deef9..00000000000000 --- a/zzz_generated/chef-rootnode_speaker_RpzeXdimqA/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_temperaturesensor_Qy1zkNW7c3/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_temperaturesensor_Qy1zkNW7c3/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index f1ee9047b7ee0e..00000000000000 --- a/zzz_generated/chef-rootnode_temperaturesensor_Qy1zkNW7c3/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/chef-rootnode_thermostat_bm3fb8dhYi/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_thermostat_bm3fb8dhYi/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index f487ddad4445ef..00000000000000 --- a/zzz_generated/chef-rootnode_thermostat_bm3fb8dhYi/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterThermostatPluginServerInitCallback(); \ - MatterFanControlPluginClientInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginClientInitCallback(); \ - MatterRelativeHumidityMeasurementPluginClientInitCallback(); \ - MatterOccupancySensingPluginClientInitCallback(); diff --git a/zzz_generated/chef-rootnode_windowcovering_RLCxaGi9Yx/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/chef-rootnode_windowcovering_RLCxaGi9Yx/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index ad47ce921a578f..00000000000000 --- a/zzz_generated/chef-rootnode_windowcovering_RLCxaGi9Yx/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterWindowCoveringPluginServerInitCallback(); diff --git a/zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 70685cfb3b2ee4..00000000000000 --- a/zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterBooleanStatePluginServerInitCallback(); \ - MatterOccupancySensingPluginServerInitCallback(); diff --git a/zzz_generated/controller-clusters/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/controller-clusters/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 0b55a4004fc6ec..00000000000000 --- a/zzz_generated/controller-clusters/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginClientInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ - MatterScenesPluginClientInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterOnOffSwitchConfigurationPluginClientInitCallback(); \ - MatterLevelControlPluginClientInitCallback(); \ - MatterBinaryInputBasicPluginClientInitCallback(); \ - MatterDescriptorPluginClientInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginClientInitCallback(); \ - MatterActionsPluginClientInitCallback(); \ - MatterBasicPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginClientInitCallback(); \ - MatterLocalizationConfigurationPluginClientInitCallback(); \ - MatterTimeFormatLocalizationPluginClientInitCallback(); \ - MatterUnitLocalizationPluginClientInitCallback(); \ - MatterPowerSourceConfigurationPluginClientInitCallback(); \ - MatterPowerSourcePluginClientInitCallback(); \ - MatterGeneralCommissioningPluginClientInitCallback(); \ - MatterNetworkCommissioningPluginClientInitCallback(); \ - MatterDiagnosticLogsPluginClientInitCallback(); \ - MatterGeneralDiagnosticsPluginClientInitCallback(); \ - MatterSoftwareDiagnosticsPluginClientInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginClientInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginClientInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginClientInitCallback(); \ - MatterBridgedDeviceBasicPluginClientInitCallback(); \ - MatterSwitchPluginClientInitCallback(); \ - MatterAdministratorCommissioningPluginClientInitCallback(); \ - MatterOperationalCredentialsPluginClientInitCallback(); \ - MatterGroupKeyManagementPluginClientInitCallback(); \ - MatterFixedLabelPluginClientInitCallback(); \ - MatterUserLabelPluginClientInitCallback(); \ - MatterBooleanStatePluginClientInitCallback(); \ - MatterModeSelectPluginClientInitCallback(); \ - MatterDoorLockPluginClientInitCallback(); \ - MatterWindowCoveringPluginClientInitCallback(); \ - MatterBarrierControlPluginClientInitCallback(); \ - MatterPumpConfigurationAndControlPluginClientInitCallback(); \ - MatterThermostatPluginClientInitCallback(); \ - MatterFanControlPluginClientInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginClientInitCallback(); \ - MatterColorControlPluginClientInitCallback(); \ - MatterBallastConfigurationPluginClientInitCallback(); \ - MatterIlluminanceMeasurementPluginClientInitCallback(); \ - MatterTemperatureMeasurementPluginClientInitCallback(); \ - MatterPressureMeasurementPluginClientInitCallback(); \ - MatterFlowMeasurementPluginClientInitCallback(); \ - MatterRelativeHumidityMeasurementPluginClientInitCallback(); \ - MatterOccupancySensingPluginClientInitCallback(); \ - MatterWakeOnLanPluginClientInitCallback(); \ - MatterChannelPluginClientInitCallback(); \ - MatterTargetNavigatorPluginClientInitCallback(); \ - MatterMediaPlaybackPluginClientInitCallback(); \ - MatterMediaInputPluginClientInitCallback(); \ - MatterLowPowerPluginClientInitCallback(); \ - MatterKeypadInputPluginClientInitCallback(); \ - MatterContentLauncherPluginClientInitCallback(); \ - MatterAudioOutputPluginClientInitCallback(); \ - MatterApplicationLauncherPluginClientInitCallback(); \ - MatterApplicationBasicPluginClientInitCallback(); \ - MatterAccountLoginPluginClientInitCallback(); \ - MatterElectricalMeasurementPluginClientInitCallback(); \ - MatterTestClusterPluginClientInitCallback(); diff --git a/zzz_generated/dynamic-bridge-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/dynamic-bridge-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index f0368e6a64bb30..00000000000000 --- a/zzz_generated/dynamic-bridge-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterAccessControlPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterActionsPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 856d83e27c638e..00000000000000 --- a/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginClientInitCallback(); \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginClientInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterColorControlPluginClientInitCallback(); diff --git a/zzz_generated/lighting-app/nxp/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/lighting-app/nxp/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 0cfb01937c9d9f..00000000000000 --- a/zzz_generated/lighting-app/nxp/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); diff --git a/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index fddb4d6e6cb042..00000000000000 --- a/zzz_generated/lighting-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); \ - MatterOccupancySensingPluginServerInitCallback(); diff --git a/zzz_generated/lock-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/lock-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 529bd99d404d59..00000000000000 --- a/zzz_generated/lock-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterPowerSourceConfigurationPluginServerInitCallback(); \ - MatterPowerSourcePluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterDoorLockPluginServerInitCallback(); diff --git a/zzz_generated/log-source-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/log-source-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 6ba8ead67775f7..00000000000000 --- a/zzz_generated/log-source-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterAccessControlPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginClientInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); diff --git a/zzz_generated/ota-provider-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/ota-provider-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index ab1922e3b8547b..00000000000000 --- a/zzz_generated/ota-provider-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterAccessControlPluginClientInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); diff --git a/zzz_generated/ota-requestor-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/ota-requestor-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 33a985a874c373..00000000000000 --- a/zzz_generated/ota-requestor-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); diff --git a/zzz_generated/placeholder/app1/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/placeholder/app1/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index aa0b14313ab21e..00000000000000 --- a/zzz_generated/placeholder/app1/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterActionsPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterPowerSourceConfigurationPluginServerInitCallback(); \ - MatterPowerSourcePluginServerInitCallback(); \ - MatterGeneralCommissioningPluginClientInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginClientInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginClientInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterBooleanStatePluginServerInitCallback(); \ - MatterModeSelectPluginClientInitCallback(); \ - MatterModeSelectPluginServerInitCallback(); \ - MatterWindowCoveringPluginServerInitCallback(); \ - MatterPumpConfigurationAndControlPluginServerInitCallback(); \ - MatterThermostatPluginServerInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginClientInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); \ - MatterIlluminanceMeasurementPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginClientInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); \ - MatterPressureMeasurementPluginServerInitCallback(); \ - MatterFlowMeasurementPluginServerInitCallback(); \ - MatterRelativeHumidityMeasurementPluginClientInitCallback(); \ - MatterRelativeHumidityMeasurementPluginServerInitCallback(); \ - MatterTargetNavigatorPluginClientInitCallback(); \ - MatterTargetNavigatorPluginServerInitCallback(); \ - MatterKeypadInputPluginClientInitCallback(); \ - MatterKeypadInputPluginServerInitCallback(); \ - MatterContentLauncherPluginClientInitCallback(); \ - MatterContentLauncherPluginServerInitCallback(); \ - MatterApplicationBasicPluginClientInitCallback(); \ - MatterApplicationBasicPluginServerInitCallback(); diff --git a/zzz_generated/placeholder/app2/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/placeholder/app2/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index aa0b14313ab21e..00000000000000 --- a/zzz_generated/placeholder/app2/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterActionsPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterPowerSourceConfigurationPluginServerInitCallback(); \ - MatterPowerSourcePluginServerInitCallback(); \ - MatterGeneralCommissioningPluginClientInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginClientInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginClientInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterBooleanStatePluginServerInitCallback(); \ - MatterModeSelectPluginClientInitCallback(); \ - MatterModeSelectPluginServerInitCallback(); \ - MatterWindowCoveringPluginServerInitCallback(); \ - MatterPumpConfigurationAndControlPluginServerInitCallback(); \ - MatterThermostatPluginServerInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginClientInitCallback(); \ - MatterThermostatUserInterfaceConfigurationPluginServerInitCallback(); \ - MatterColorControlPluginServerInitCallback(); \ - MatterIlluminanceMeasurementPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginClientInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); \ - MatterPressureMeasurementPluginServerInitCallback(); \ - MatterFlowMeasurementPluginServerInitCallback(); \ - MatterRelativeHumidityMeasurementPluginClientInitCallback(); \ - MatterRelativeHumidityMeasurementPluginServerInitCallback(); \ - MatterTargetNavigatorPluginClientInitCallback(); \ - MatterTargetNavigatorPluginServerInitCallback(); \ - MatterKeypadInputPluginClientInitCallback(); \ - MatterKeypadInputPluginServerInitCallback(); \ - MatterContentLauncherPluginClientInitCallback(); \ - MatterContentLauncherPluginServerInitCallback(); \ - MatterApplicationBasicPluginClientInitCallback(); \ - MatterApplicationBasicPluginServerInitCallback(); diff --git a/zzz_generated/pump-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/pump-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 3e61d2b69546fa..00000000000000 --- a/zzz_generated/pump-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterPumpConfigurationAndControlPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); \ - MatterPressureMeasurementPluginServerInitCallback(); \ - MatterFlowMeasurementPluginServerInitCallback(); \ - MatterOccupancySensingPluginClientInitCallback(); diff --git a/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index a8bc9fe9f3b492..00000000000000 --- a/zzz_generated/pump-controller-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterPumpConfigurationAndControlPluginClientInitCallback(); \ - MatterTemperatureMeasurementPluginClientInitCallback(); \ - MatterPressureMeasurementPluginClientInitCallback(); \ - MatterFlowMeasurementPluginClientInitCallback(); diff --git a/zzz_generated/temperature-measurement-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/temperature-measurement-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 8392297e883ed4..00000000000000 --- a/zzz_generated/temperature-measurement-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterTemperatureMeasurementPluginServerInitCallback(); diff --git a/zzz_generated/thermostat/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/thermostat/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index fc1f15a7696df2..00000000000000 --- a/zzz_generated/thermostat/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginClientInitCallback(); \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterThermostatPluginServerInitCallback(); diff --git a/zzz_generated/tv-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/tv-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 638b057baa7436..00000000000000 --- a/zzz_generated/tv-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginClientInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginClientInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginClientInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginClientInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterRelativeHumidityMeasurementPluginServerInitCallback(); \ - MatterWakeOnLanPluginServerInitCallback(); \ - MatterChannelPluginServerInitCallback(); \ - MatterTargetNavigatorPluginServerInitCallback(); \ - MatterMediaPlaybackPluginServerInitCallback(); \ - MatterMediaInputPluginServerInitCallback(); \ - MatterLowPowerPluginServerInitCallback(); \ - MatterKeypadInputPluginServerInitCallback(); \ - MatterContentLauncherPluginServerInitCallback(); \ - MatterAudioOutputPluginServerInitCallback(); \ - MatterApplicationLauncherPluginServerInitCallback(); \ - MatterApplicationBasicPluginServerInitCallback(); \ - MatterAccountLoginPluginServerInitCallback(); diff --git a/zzz_generated/tv-casting-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/tv-casting-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index d7963d5e5abad2..00000000000000 --- a/zzz_generated/tv-casting-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterOnOffPluginClientInitCallback(); \ - MatterOnOffPluginServerInitCallback(); \ - MatterLevelControlPluginClientInitCallback(); \ - MatterLevelControlPluginServerInitCallback(); \ - MatterBinaryInputBasicPluginServerInitCallback(); \ - MatterDescriptorPluginClientInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterBindingPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterDiagnosticLogsPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterSwitchPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterBarrierControlPluginServerInitCallback(); \ - MatterWakeOnLanPluginServerInitCallback(); \ - MatterChannelPluginClientInitCallback(); \ - MatterTargetNavigatorPluginClientInitCallback(); \ - MatterMediaPlaybackPluginClientInitCallback(); \ - MatterMediaInputPluginClientInitCallback(); \ - MatterKeypadInputPluginClientInitCallback(); \ - MatterContentLauncherPluginClientInitCallback(); \ - MatterAudioOutputPluginClientInitCallback(); \ - MatterApplicationLauncherPluginClientInitCallback(); \ - MatterApplicationBasicPluginClientInitCallback(); \ - MatterAccountLoginPluginClientInitCallback(); diff --git a/zzz_generated/window-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/window-app/zap-generated/PluginApplicationCallbacks.h deleted file mode 100644 index 15053dcb75be49..00000000000000 --- a/zzz_generated/window-app/zap-generated/PluginApplicationCallbacks.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -// THIS FILE IS GENERATED BY ZAP - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT \ - MatterIdentifyPluginServerInitCallback(); \ - MatterGroupsPluginServerInitCallback(); \ - MatterScenesPluginServerInitCallback(); \ - MatterDescriptorPluginServerInitCallback(); \ - MatterAccessControlPluginServerInitCallback(); \ - MatterBasicPluginServerInitCallback(); \ - MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ - MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ - MatterLocalizationConfigurationPluginServerInitCallback(); \ - MatterTimeFormatLocalizationPluginServerInitCallback(); \ - MatterUnitLocalizationPluginServerInitCallback(); \ - MatterPowerSourcePluginServerInitCallback(); \ - MatterGeneralCommissioningPluginServerInitCallback(); \ - MatterNetworkCommissioningPluginServerInitCallback(); \ - MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterSoftwareDiagnosticsPluginServerInitCallback(); \ - MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ - MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ - MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ - MatterAdministratorCommissioningPluginServerInitCallback(); \ - MatterOperationalCredentialsPluginServerInitCallback(); \ - MatterGroupKeyManagementPluginServerInitCallback(); \ - MatterFixedLabelPluginServerInitCallback(); \ - MatterUserLabelPluginServerInitCallback(); \ - MatterWindowCoveringPluginServerInitCallback(); From 1cae09520506dbb3465b489bf27e87c84c896a54 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 18 Oct 2022 14:31:36 -0400 Subject: [PATCH 02/23] Remove PluginApplicationCallbacks.zapt --- .../app/callbacks/PluginApplicationCallbacks.zapt | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/app/zap-templates/templates/app/callbacks/PluginApplicationCallbacks.zapt diff --git a/src/app/zap-templates/templates/app/callbacks/PluginApplicationCallbacks.zapt b/src/app/zap-templates/templates/app/callbacks/PluginApplicationCallbacks.zapt deleted file mode 100644 index 68e471da9a4e32..00000000000000 --- a/src/app/zap-templates/templates/app/callbacks/PluginApplicationCallbacks.zapt +++ /dev/null @@ -1,8 +0,0 @@ -{{> header}} - -#pragma once - -#include - -#define MATTER_PLUGINS_INIT {{#all_user_clusters}}Matter{{asUpperCamelCase name}}Plugin{{asUpperCamelCase side}}InitCallback(); {{/all_user_clusters}} - From 6c2b5b03d08f8e02e1a61843d80f752b65dc0f5c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 18 Oct 2022 14:32:25 -0400 Subject: [PATCH 03/23] Restyle --- examples/dynamic-bridge-app/bridge-common/BUILD.gn | 1 - scripts/idl/tests/available_tests.yaml | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/dynamic-bridge-app/bridge-common/BUILD.gn b/examples/dynamic-bridge-app/bridge-common/BUILD.gn index 1507e54b130dc3..0482fed92cc782 100644 --- a/examples/dynamic-bridge-app/bridge-common/BUILD.gn +++ b/examples/dynamic-bridge-app/bridge-common/BUILD.gn @@ -23,7 +23,6 @@ chip_data_model("dynamic-bridge-common") { zap_pregenerated_dir = "${chip_root}/zzz_generated/dynamic-bridge-app/zap-generated" - is_server = true # TODO: the definition of DYNAMIC_ENDPOINT_COUNT needs find a common home! diff --git a/scripts/idl/tests/available_tests.yaml b/scripts/idl/tests/available_tests.yaml index 7563d2454d708d..0cd859af001681 100644 --- a/scripts/idl/tests/available_tests.yaml +++ b/scripts/idl/tests/available_tests.yaml @@ -59,6 +59,5 @@ bridge: bridge/Third.h: outputs/several_clusters/bridge/Third.h cpp-app: - inputs/several_clusters.matter: + inputs/several_clusters.matter: app/PluginApplicationCallbacks.h: outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h - From 7d49af5662309123c80c1c99b81505fea3f1e4ee Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 18 Oct 2022 14:53:38 -0400 Subject: [PATCH 04/23] Add idl to build instructions --- scripts/idl/BUILD.gn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/idl/BUILD.gn b/scripts/idl/BUILD.gn index 1903aa573be359..5729b488fa452d 100644 --- a/scripts/idl/BUILD.gn +++ b/scripts/idl/BUILD.gn @@ -30,6 +30,7 @@ pw_python_package("idl") { "generators/bridge/BridgeClustersGlobalStructs.jinja", "generators/java/ChipClustersCpp.jinja", "generators/java/ChipClustersRead.jinja", + "generators/cpp/application/PluginApplicationCallbacksHeader.jinja", # Unit test data "tests/available_tests.yaml", @@ -72,6 +73,8 @@ pw_python_package("idl") { "__init__.py", "generators/__init__.py", "generators/bridge/__init__.py", + "generators/cpp/__init__.py", + "generators/cpp/application/__init__.py", "generators/filters.py", "generators/java/__init__.py", "generators/types.py", From c410d7d1e3d7cf9d2927e715dc73dfe6b1aefa02 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 18 Oct 2022 15:02:26 -0400 Subject: [PATCH 05/23] Disable pylint for now. It looks like pylint is a lot more strict than expected and this was triggered only if we have dependencies --- scripts/idl/BUILD.gn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/idl/BUILD.gn b/scripts/idl/BUILD.gn index 5729b488fa452d..741b22ec45aff1 100644 --- a/scripts/idl/BUILD.gn +++ b/scripts/idl/BUILD.gn @@ -94,4 +94,8 @@ pw_python_package("idl") { "test_generators.py", "test_xml_parser.py", ] + + # TODO: at a future time consider enabling all (* or missing) here to get + # pylint checking these files + static_analysis = [] } From 1aad352f8f18f7c95e3049a46ae04493a8f7620d Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 18 Oct 2022 16:42:59 -0400 Subject: [PATCH 06/23] Ensure we run codegen so sanitizer can find generated files --- .github/workflows/build.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a2cbe7d1fbfdf7..bc90573a14152f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -210,6 +210,11 @@ jobs: BUILD_TYPE=sanitizers scripts/build/gn_gen.sh --args="$GN_ARGS" --export-compile-commands BUILD_TYPE=sanitizers scripts/tests/gn_tests.sh done + - name: Ensure codegen is done for sanitize + timeout-minutes: 45 + run: | + ./scripts/run_in_build_env.sh \ + "ninja -C out/sanitizers src/controller/data_model:data_model_codegen" - name: Clang-tidy validation timeout-minutes: 45 run: | @@ -401,6 +406,11 @@ jobs: scripts/run_in_build_env.sh "ninja -C ./out/$BUILD_TYPE" BUILD_TYPE=$BUILD_TYPE scripts/tests/gn_tests.sh done + - name: Ensure codegen is done for sanitize + timeout-minutes: 45 + run: | + ./scripts/run_in_build_env.sh \ + "ninja -C out/default src/controller/data_model:data_model_codegen" - name: Clang-tidy validation timeout-minutes: 45 run: | From bc5a25d584315976812ede758dc7474c20280313 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 11:40:27 -0400 Subject: [PATCH 07/23] Revert telink changes after master merge: no need for separate codegen anymore as telink now uses standard data model methods --- examples/light-switch-app/telink/CMakeLists.txt | 15 --------------- examples/lighting-app/telink/CMakeLists.txt | 15 --------------- examples/ota-requestor-app/telink/CMakeLists.txt | 15 --------------- 3 files changed, 45 deletions(-) diff --git a/examples/light-switch-app/telink/CMakeLists.txt b/examples/light-switch-app/telink/CMakeLists.txt index 46b1ae1549bedb..f47a79987c50b2 100755 --- a/examples/light-switch-app/telink/CMakeLists.txt +++ b/examples/light-switch-app/telink/CMakeLists.txt @@ -24,19 +24,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) -include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") - -# TODO: this CMakeFile should use src/app/chip_data_model.cmake -# and then codegen would be inherited -chip_codegen(app-codegen - INPUT "${CHIP_ROOT}/examples/light-switch-app/light-switch-common/light-switch-app.matter" - GENERATOR "cpp-app" - OUTPUTS - "app/PluginApplicationCallbacks.h" - OUTPUT_PATH APP_GEN_DIR - OUTPUT_FILES APP_GEN_FILES -) - # Load NCS/Zephyr build system list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -50,13 +37,11 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include - ${APP_GEN_DIR} ${GEN_DIR}/app-common ${GEN_DIR}/light-switch-app ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) -add_dependencies(app app-codegen) add_definitions( "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index a9bbc4be952471..e1e5c38f48d9ea 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -24,19 +24,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) -include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") - -# TODO: this CMakeFile should use src/app/chip_data_model.cmake -# and then codegen would be inherited -chip_codegen(app-codegen - INPUT "${CHIP_ROOT}/examples/lighting-app/lighting-common/lighting-app.matter" - GENERATOR "cpp-app" - OUTPUTS - "app/PluginApplicationCallbacks.h" - OUTPUT_PATH APP_GEN_DIR - OUTPUT_FILES APP_GEN_FILES -) - # Load NCS/Zephyr build system list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -50,13 +37,11 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include - ${APP_GEN_DIR} ${GEN_DIR}/app-common ${GEN_DIR}/lighting-app ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) -add_dependencies(app app-codegen) add_definitions( "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" diff --git a/examples/ota-requestor-app/telink/CMakeLists.txt b/examples/ota-requestor-app/telink/CMakeLists.txt index 28a2744a96f0ea..6efbc5ec434465 100644 --- a/examples/ota-requestor-app/telink/CMakeLists.txt +++ b/examples/ota-requestor-app/telink/CMakeLists.txt @@ -24,19 +24,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) -include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") - -# TODO: this CMakeFile should use src/app/chip_data_model.cmake -# and then codegen would be inherited -chip_codegen(app-codegen - INPUT "${CHIP_ROOT}/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter" - GENERATOR "cpp-app" - OUTPUTS - "app/PluginApplicationCallbacks.h" - OUTPUT_PATH APP_GEN_DIR - OUTPUT_FILES APP_GEN_FILES -) - # Load NCS/Zephyr build system list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -50,13 +37,11 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include - ${APP_GEN_DIR} ${GEN_DIR}/app-common ${GEN_DIR}/ota-requestor-app ${NLIO_ROOT} ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) -add_dependencies(app app-codegen) add_definitions( "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" From 5527a0e6da1389cfc5f5188fdc4517c5904b1336 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 12:13:02 -0400 Subject: [PATCH 08/23] Ensure all needed codegen is done (for clang tidy at least). Tested in linux, may need to adjust darwin --- .github/workflows/build.yaml | 6 ++-- scripts/run_codegen_targets.sh | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) create mode 100755 scripts/run_codegen_targets.sh diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bc90573a14152f..1f375a3148360f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -213,8 +213,7 @@ jobs: - name: Ensure codegen is done for sanitize timeout-minutes: 45 run: | - ./scripts/run_in_build_env.sh \ - "ninja -C out/sanitizers src/controller/data_model:data_model_codegen" + ./scripts/run_in_build_env.sh "./scripts/run_codegen_targets.sh out/sanitizers" - name: Clang-tidy validation timeout-minutes: 45 run: | @@ -409,8 +408,7 @@ jobs: - name: Ensure codegen is done for sanitize timeout-minutes: 45 run: | - ./scripts/run_in_build_env.sh \ - "ninja -C out/default src/controller/data_model:data_model_codegen" + ./scripts/run_in_build_env.sh "./scripts/run_codegen_targets.sh out/sanitizers" - name: Clang-tidy validation timeout-minutes: 45 run: | diff --git a/scripts/run_codegen_targets.sh b/scripts/run_codegen_targets.sh new file mode 100755 index 00000000000000..f3fc871371ecf0 --- /dev/null +++ b/scripts/run_codegen_targets.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2022 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. +# + +# This script runs all targets taht are generating code +# in the given output directory +# CHIP_ROOT with a build environment activated. + +set -e + +OUT_DIR="$1" + +if [ ! -d "$OUT_DIR" ]; then + echo "Input directory '${OUT_DIR}' does not exist. " + echo "USAGE: $0 " + exit 1 +fi + +# Code generation for build config files (via buildconfig_header) +for name in $(ninja -C "${OUT_DIR}" -t targets | grep -E '^gen_.*_buildconfig:' | sed 's/: .*//'); do + echo "Generating $name ..." + ninja -C "${OUT_DIR}" $name +done + +# Code generation (based on zap/matter) +for name in $(ninja -C "${OUT_DIR}" -t targets | grep -E '_codegen:' | sed 's/: .*//'); do + echo "Generating $name ..." + ninja -C "${OUT_DIR}" $name +done + +# Linus targets: dbus generate hdeaders +for name in $(ninja -C "${OUT_DIR}" -t targets | grep -E 'dbus.*codegen:' | sed 's/: .*//'); do + echo "Generating $name ..." + ninja -C "${OUT_DIR}" $name +done + +# ASN1 has no specific rule +ninja -C "${OUT_DIR}" gen_asn1oid From 24a36d1e3f8ab0a1d1f81ca2c87f33fcf815cc5b Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 12:35:27 -0400 Subject: [PATCH 09/23] Code review comment: centralize the generator/string for known generators --- scripts/codegen.py | 36 +- scripts/idl/build/lib/generators/__init__.py | 171 +++++ .../build/lib/generators/bridge/__init__.py | 193 ++++++ .../idl/build/lib/generators/cpp/__init__.py | 0 .../generators/cpp/application/__init__.py | 61 ++ scripts/idl/build/lib/generators/filters.py | 34 + .../idl/build/lib/generators/java/__init__.py | 394 +++++++++++ scripts/idl/build/lib/generators/registry.py | 58 ++ scripts/idl/build/lib/generators/types.py | 407 ++++++++++++ scripts/idl/build/lib/lint/__init__.py | 15 + .../idl/build/lib/lint/lint_rules_parser.py | 309 +++++++++ scripts/idl/build/lib/lint/types.py | 259 ++++++++ scripts/idl/build/lib/zapxml/__init__.py | 118 ++++ .../idl/build/lib/zapxml/handlers/__init__.py | 36 + scripts/idl/build/lib/zapxml/handlers/base.py | 62 ++ .../idl/build/lib/zapxml/handlers/context.py | 124 ++++ .../idl/build/lib/zapxml/handlers/handlers.py | 614 ++++++++++++++++++ .../idl/build/lib/zapxml/handlers/parsing.py | 96 +++ scripts/idl/generators/registry.py | 59 ++ scripts/run_codegen_targets.sh | 22 +- 20 files changed, 3024 insertions(+), 44 deletions(-) create mode 100644 scripts/idl/build/lib/generators/__init__.py create mode 100644 scripts/idl/build/lib/generators/bridge/__init__.py create mode 100644 scripts/idl/build/lib/generators/cpp/__init__.py create mode 100644 scripts/idl/build/lib/generators/cpp/application/__init__.py create mode 100644 scripts/idl/build/lib/generators/filters.py create mode 100644 scripts/idl/build/lib/generators/java/__init__.py create mode 100644 scripts/idl/build/lib/generators/registry.py create mode 100644 scripts/idl/build/lib/generators/types.py create mode 100644 scripts/idl/build/lib/lint/__init__.py create mode 100644 scripts/idl/build/lib/lint/lint_rules_parser.py create mode 100644 scripts/idl/build/lib/lint/types.py create mode 100644 scripts/idl/build/lib/zapxml/__init__.py create mode 100644 scripts/idl/build/lib/zapxml/handlers/__init__.py create mode 100644 scripts/idl/build/lib/zapxml/handlers/base.py create mode 100644 scripts/idl/build/lib/zapxml/handlers/context.py create mode 100644 scripts/idl/build/lib/zapxml/handlers/handlers.py create mode 100644 scripts/idl/build/lib/zapxml/handlers/parsing.py create mode 100644 scripts/idl/generators/registry.py diff --git a/scripts/codegen.py b/scripts/codegen.py index a43676f138469f..da81b06210d933 100755 --- a/scripts/codegen.py +++ b/scripts/codegen.py @@ -27,30 +27,7 @@ from idl.matter_idl_parser import CreateParser from idl.generators import FileSystemGeneratorStorage, GeneratorStorage -from idl.generators.java import JavaGenerator -from idl.generators.bridge import BridgeGenerator -from idl.generators.cpp.application import CppApplicationGenerator - - -class CodeGeneratorTypes(enum.Enum): - """ - Represents every generator type supported by codegen and maps - the simple enum value (user friendly and can be a command line input) - into underlying generators. - """ - JAVA = enum.auto() - BRIDGE = enum.auto() - CPP_APPLICATION = enum.auto() - - def CreateGenerator(self, *args, **kargs): - if self == CodeGeneratorTypes.JAVA: - return JavaGenerator(*args, **kargs) - elif self == CodeGeneratorTypes.BRIDGE: - return BridgeGenerator(*args, **kargs) - elif self == CodeGeneratorTypes.CPP_APPLICATION: - return CppApplicationGenerator(*args, **kargs) - else: - raise Error("Unknown code generator type") +from idl.generators.registry import CodeGenerator, GENERATORS class ListGeneratedFilesStorage(GeneratorStorage): @@ -77,12 +54,6 @@ def write_new_data(self, relative_path: str, content: str): 'fatal': logging.FATAL, } -__GENERATORS__ = { - 'java': CodeGeneratorTypes.JAVA, - 'bridge': CodeGeneratorTypes.BRIDGE, - 'cpp-app': CodeGeneratorTypes.CPP_APPLICATION, -} - @click.command() @click.option( @@ -93,7 +64,7 @@ def write_new_data(self, relative_path: str, content: str): @click.option( '--generator', default='JAVA', - type=click.Choice(__GENERATORS__.keys(), case_sensitive=False), + type=click.Choice(GENERATORS.keys(), case_sensitive=False), help='What code generator to run') @click.option( '--output-dir', @@ -134,8 +105,7 @@ def main(log_level, generator, output_dir, dry_run, name_only, expected_outputs, storage = FileSystemGeneratorStorage(output_dir) logging.info("Running code generator %s" % generator) - generator = __GENERATORS__[ - generator].CreateGenerator(storage, idl=idl_tree) + generator = CodeGenerator.FromString(generator).Create(storage, idl=idl_tree) generator.render(dry_run) if expected_outputs: diff --git a/scripts/idl/build/lib/generators/__init__.py b/scripts/idl/build/lib/generators/__init__.py new file mode 100644 index 00000000000000..1adbb6d4d0071b --- /dev/null +++ b/scripts/idl/build/lib/generators/__init__.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# Copyright (c) 2022 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. + +import os +import logging +import jinja2 + +from typing import Dict +from idl.matter_idl_types import Idl + +from .filters import RegisterCommonFilters + + +class GeneratorStorage: + """ + Handles file operations for generator output. Specifically can create + required files for output. + + Is overriden for unit tests. + """ + + def __init__(self): + self._generated_paths = set() + + @property + def generated_paths(self): + return self._generated_paths + + def report_output_file(self, relative_path: str): + self._generated_paths.add(relative_path) + + def get_existing_data(self, relative_path: str): + """Gets the existing data at the given path. + If such data does not exist, will return None. + """ + raise NotImplementedError() + + def write_new_data(self, relative_path: str, content: str): + """Write new data to the given path.""" + raise NotImplementedError() + + +class FileSystemGeneratorStorage(GeneratorStorage): + """ + A storage generator which will physically write files to disk into + a given output folder. + """ + + def __init__(self, output_dir: str): + super().__init__() + self.output_dir = output_dir + + def get_existing_data(self, relative_path: str): + """Gets the existing data at the given path. + If such data does not exist, will return None. + """ + target = os.path.join(self.output_dir, relative_path) + + if not os.path.exists(target): + return None + + logging.info("Checking existing data in %s" % target) + with open(target, 'rt') as existing: + return existing.read() + + def write_new_data(self, relative_path: str, content: str): + """Write new data to the given path.""" + + target = os.path.join(self.output_dir, relative_path) + target_dir = os.path.dirname(target) + if not os.path.exists(target_dir): + logging.info("Creating output directory: %s" % target_dir) + os.makedirs(target_dir) + + logging.info("Writing new data to: %s" % target) + with open(target, "wt") as out: + out.write(content) + + +class CodeGenerator: + """ + Defines the general interface for things that can generate code output. + + A CodeGenerator takes a AST as input (a `Idl` type) and generates files + as output (like java/cpp/mm/other). + + Its public interface surface is reasonably small: + 'storage' init argument specifies where generated code goes + 'idl' is the input AST to generate + 'render' will perform a rendering of all files. + + As special optimizations, CodeGenerators generally will try to read + existing data and will not re-write content if not changed (so that + write time of files do not change and rebuilds are not triggered). + """ + + def __init__(self, storage: GeneratorStorage, idl: Idl): + """ + A code generator will render a parsed IDL (a AST) into a given storage. + """ + self.storage = storage + self.idl = idl + self.jinja_env = jinja2.Environment( + loader=jinja2.FileSystemLoader(searchpath=os.path.dirname(__file__)), + keep_trailing_newline=True) + self.dry_run = False + + RegisterCommonFilters(self.jinja_env.filters) + + def render(self, dry_run=False): + """ + Renders all required files given the idl contained in the code generator. + Reset the list of generated outputs. + + Args: + dry_run: if true, outputs are not actually written to disk. + if false, outputs are actually written to disk. + """ + self.dry_run = dry_run + self.internal_render_all() + + def internal_render_all(self): + """This method is to be implemented by subclasses to run all generation + as needed. + """ + raise NotImplementedError("Method should be implemented by subclasses") + + def internal_render_one_output(self, template_path: str, output_file_name: str, vars: Dict): + """ + Method to be called by subclasses to mark that a template is to be generated. + + File will either actually do a jinja2 generation or just log things + if dry-run was requested during `render`. + + NOTE: to make this method suitable for rebuilds, this file will NOT alter + the timestamp of the output file if the file content would not + change (i.e. no write will be invoked in that case.) + + Args: + template_path - the path to the template to be loaded for file generation. + Template MUST be a jinja2 template. + output_file_name - File name that the template is to be generated to. + vars - variables used for template generation + """ + logging.info("File to be generated: %s" % output_file_name) + if self.dry_run: + return + + rendered = self.jinja_env.get_template(template_path).render(vars) + + # Report regardless if it has changed or not. This is because even if + # files are unchanged, validation of what the correct output is should + # still be done. + self.storage.report_output_file(output_file_name) + + if rendered == self.storage.get_existing_data(output_file_name): + logging.info("File content not changed") + else: + self.storage.write_new_data(output_file_name, rendered) diff --git a/scripts/idl/build/lib/generators/bridge/__init__.py b/scripts/idl/build/lib/generators/bridge/__init__.py new file mode 100644 index 00000000000000..5d0bace9faf431 --- /dev/null +++ b/scripts/idl/build/lib/generators/bridge/__init__.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +# Copyright (c) 2022 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. + +import enum +import logging +import re + +from idl.generators import CodeGenerator, GeneratorStorage +from idl.matter_idl_types import (Idl, Field, Attribute, Cluster) +from idl import matter_idl_types +from idl.generators.types import (ParseDataType, BasicString, BasicInteger, FundamentalType, + IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext) +from typing import Union, List, Set + + +def camel_to_const(s): + return re.sub("([a-z])([A-Z])", lambda y: y.group(1) + "_" + y.group(2), s).upper() + + +def create_lookup_context(idl: Idl, cluster: Cluster) -> TypeLookupContext: + """ + A filter to mark a lookup context to be within a specific cluster. + + This is used to specify how structure/enum/other names are looked up. + Generally one looks up within the specific cluster then if cluster does + not contain a definition, we loop at global namespacing. + """ + return TypeLookupContext(idl, cluster) + + +def get_field_info(definition: Field, cluster: Cluster, idl: Idl): + context = create_lookup_context(idl, cluster) + actual = ParseDataType(definition.data_type, context) + + orig = actual + is_enum = type(actual) == IdlEnumType + + if type(actual) == IdlEnumType: + actual = actual.base_type + elif type(actual) == IdlBitmapType: + actual = actual.base_type + + if type(actual) == BasicString: + return 'OctetString', 'char', actual.max_length, \ + 'ZCL_%s_ATTRIBUTE_TYPE' % orig.idl_name.upper() + + if type(actual) == BasicInteger: + name = orig.idl_name.upper() + if is_enum: + name = actual.idl_name.upper() + ty = "int%d_t" % actual.power_of_two_bits + if not actual.is_signed: + ty = "u" + ty + return "", ty, actual.byte_count, "ZCL_%s_ATTRIBUTE_TYPE" % name + if type(actual) == FundamentalType: + if actual == FundamentalType.BOOL: + return "", "bool", 1, "ZCL_BOOLEAN_ATTRIBUTE_TYPE" + if actual == FundamentalType.FLOAT: + return "", "float", 4, "ZCL_SINGLE_ATTRIBUTE_TYPE" + if actual == FundamentalType.DOUBLE: + return "", "double", 8, "ZCL_DOUBLE_ATTRIBUTE_TYPE" + logging.warn('Unknown fundamental type: %r' % actual) + return None + if type(actual) == IdlType: + return '', actual.idl_name, 'sizeof(%s)' % actual.idl_name, \ + 'ZCL_STRUCT_ATTRIBUTE_TYPE' + logging.warn('Unknown type: %r' % actual) + return None + + +def get_raw_size_and_type(attr: Attribute, cluster: Cluster, idl: Idl): + container, cType, size, matterType = get_field_info(attr.definition, cluster, idl) + if attr.definition.is_list: + return 'ZCL_ARRAY_ATTRIBUTE_TYPE, {}'.format(size) + return '{}, {}'.format(matterType, size) + + +def get_field_type(definition: Field, cluster: Cluster, idl: Idl): + container, cType, size, matterType = get_field_info(definition, cluster, idl) + if container == 'OctetString': + return 'std::string' + if definition.is_list: + cType = 'std::vector<{}>'.format(cType) + if definition.is_nullable: + cType = '::chip::app::DataModel::Nullable<{}>'.format(cType) + if definition.is_nullable: + cType = '::chip::Optional<{}>'.format(cType) + return cType + + +def get_attr_type(attr: Attribute, cluster: Cluster, idl: Idl): + return get_field_type(attr.definition, cluster, idl) + + +def get_attr_init(attr: Attribute, cluster: Cluster, idl: Idl): + if attr.definition.name == 'clusterRevision': + return ', ZCL_' + camel_to_const(cluster.name) + '_CLUSTER_REVISION' + return '' + + +def get_attr_mask(attr: Attribute, cluster: Cluster, idl: Idl): + masks = [] + if attr.is_writable: + masks.append('ATTRIBUTE_MASK_WRITABLE') + if masks: + return ' | '.join(masks) + return '0' + + +def get_dynamic_endpoint(idl: Idl): + for ep in idl.endpoints: + if ep.number == 2: + return ep + + +def is_dynamic_cluster(cluster: Cluster, idl: Idl): + ep = get_dynamic_endpoint(idl) + if not ep: + return True + for c in ep.server_clusters: + if cluster.name == c.name: + return True + return False + + +class BridgeGenerator(CodeGenerator): + """ + Generation of bridge cpp code for matter. + """ + + def __init__(self, storage: GeneratorStorage, idl: Idl): + """ + Inintialization is specific for cpp generation and will add + filters as required by the cpp .jinja templates to function. + """ + super().__init__(storage, idl) + + self.jinja_env.filters['getType'] = get_attr_type + self.jinja_env.filters['getRawSizeAndType'] = get_raw_size_and_type + self.jinja_env.filters['getField'] = get_field_type + self.jinja_env.filters['getMask'] = get_attr_mask + self.jinja_env.filters['getInit'] = get_attr_init + self.jinja_env.filters['dynamicCluster'] = is_dynamic_cluster + # constcase will transform ID to I_D which is not what we want + # instead make the requirement a transition from lower to upper + self.jinja_env.filters['cameltoconst'] = camel_to_const + + def internal_render_all(self): + """ + Renders C++ + """ + for cluster in self.idl.clusters: + if not is_dynamic_cluster(cluster, self.idl): + continue + + self.internal_render_one_output( + template_path="bridge/BridgeClustersCpp.jinja", + output_file_name="bridge/%s.h" % cluster.name, + vars={ + 'cluster': cluster, + 'idl': self.idl, + } + ) + + self.internal_render_one_output( + template_path="bridge/BridgeClustersCommon.jinja", + output_file_name="bridge/BridgeClustersImpl.h", + vars={ + 'clusters': self.idl.clusters, + 'idl': self.idl, + } + ) + + self.internal_render_one_output( + template_path="bridge/BridgeClustersGlobalStructs.jinja", + output_file_name="bridge/BridgeGlobalStructs.h", + vars={ + 'idl': self.idl, + 'structs': self.idl.structs, + } + ) diff --git a/scripts/idl/build/lib/generators/cpp/__init__.py b/scripts/idl/build/lib/generators/cpp/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/scripts/idl/build/lib/generators/cpp/application/__init__.py b/scripts/idl/build/lib/generators/cpp/application/__init__.py new file mode 100644 index 00000000000000..40a4bb26b0b34b --- /dev/null +++ b/scripts/idl/build/lib/generators/cpp/application/__init__.py @@ -0,0 +1,61 @@ +# Copyright (c) 2022 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. + +from idl.generators import CodeGenerator, GeneratorStorage +from idl.matter_idl_types import Idl, ClusterSide, Field, Attribute, Cluster, FieldQuality, Command, DataType +from idl import matter_idl_types +from idl.generators.types import ParseDataType, BasicString, BasicInteger, FundamentalType, IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext +from typing import Union, List, Set +from stringcase import capitalcase + +import enum +import logging + + +def clusterSideString(side: ClusterSide): + if side == ClusterSide.CLIENT: + return "Client" + elif side == ClusterSide.SERVER: + return "Server" + else: + raise Exception("Unknown cluster side %r" % (side, )) + + +class CppApplicationGenerator(CodeGenerator): + """ + Generation of cpp code for application implementation for matter. + """ + + def __init__(self, storage: GeneratorStorage, idl: Idl): + """ + Inintialization is specific for java generation and will add + filters as required by the java .jinja templates to function. + """ + super().__init__(storage, idl) + + self.jinja_env.filters['clusterSideString'] = clusterSideString + + def internal_render_all(self): + """ + Renders the cpp and header files required for applications + """ + + # Header containing a macro to initialize all cluster plugins + self.internal_render_one_output( + template_path="cpp/application/PluginApplicationCallbacksHeader.jinja", + output_file_name="app/PluginApplicationCallbacks.h", + vars={ + 'clusters': self.idl.clusters, + } + ) diff --git a/scripts/idl/build/lib/generators/filters.py b/scripts/idl/build/lib/generators/filters.py new file mode 100644 index 00000000000000..13e84d37233be1 --- /dev/null +++ b/scripts/idl/build/lib/generators/filters.py @@ -0,0 +1,34 @@ +# Copyright (c) 2022 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. + +import logging +import stringcase + + +def RegisterCommonFilters(filtermap): + """ + Register filters that are NOT considered platform-generator specific. + + Codegen often needs standardized names, like "method names are CamelCase" + or "command names need-to-be-spinal-case" so these filters are often + generally registered on all generators. + """ + + # General casing for output naming + filtermap['camelcase'] = stringcase.camelcase + filtermap['capitalcase'] = stringcase.capitalcase + filtermap['constcase'] = stringcase.constcase + filtermap['pascalcase'] = stringcase.pascalcase + filtermap['snakecase'] = stringcase.snakecase + filtermap['spinalcase'] = stringcase.spinalcase diff --git a/scripts/idl/build/lib/generators/java/__init__.py b/scripts/idl/build/lib/generators/java/__init__.py new file mode 100644 index 00000000000000..6f18e9629304e5 --- /dev/null +++ b/scripts/idl/build/lib/generators/java/__init__.py @@ -0,0 +1,394 @@ +#!/usr/bin/env python +# Copyright (c) 2022 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. + +from idl.generators import CodeGenerator, GeneratorStorage +from idl.matter_idl_types import Idl, ClusterSide, Field, Attribute, Cluster, FieldQuality, Command, DataType +from idl import matter_idl_types +from idl.generators.types import ParseDataType, BasicString, BasicInteger, FundamentalType, IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext +from typing import Union, List, Set +from stringcase import capitalcase + +import enum +import logging + + +def FieldToGlobalName(field: Field, context: TypeLookupContext) -> Union[str, None]: + """Global names are used for generic callbacks shared across + all clusters (e.g. for bool/float/uint32 and similar) + """ + if field.is_list: + return None # lists are always specific per cluster + + if FieldQuality.NULLABLE & field.qualities: + return None + + if FieldQuality.OPTIONAL & field.qualities: + return None + + actual = ParseDataType(field.data_type, context) + if type(actual) == IdlEnumType: + actual = actual.base_type + elif type(actual) == IdlBitmapType: + actual = actual.base_type + + if type(actual) == BasicString: + if actual.is_binary: + return 'OctetString' + else: + return 'CharString' + elif type(actual) == BasicInteger: + # TODO: unclear why this, but tries to match zap: + if actual.idl_name.lower() in ['vendor_id', 'fabric_idx']: + return None + + if actual.is_signed: + return "Int{}s".format(actual.power_of_two_bits) + else: + return "Int{}u".format(actual.power_of_two_bits) + elif type(actual) == FundamentalType: + if actual == FundamentalType.BOOL: + return 'Boolean' + elif actual == FundamentalType.FLOAT: + return 'Float' + elif actual == FundamentalType.DOUBLE: + return 'Double' + else: + logging.warn('Unknown fundamental type: %r' % actual) + + return None + + +def CallbackName(attr: Attribute, cluster: Cluster, context: TypeLookupContext) -> str: + """ + Figure out what callback name to use when a variable requires a read callback. + + These are split into native types, like Boolean/Float/Double/CharString, where + one callback type can support anything. + + For specific types (e.g. A struct) codegen will generate its own callback name + specific to that type. + """ + global_name = FieldToGlobalName(attr.definition, context) + + if global_name: + return 'CHIP{}AttributeCallback'.format(capitalcase(global_name)) + + return 'CHIP{}{}AttributeCallback'.format( + capitalcase(cluster.name), + capitalcase(attr.definition.name) + ) + + +def CommandCallbackName(command: Command, cluster: Cluster): + if command.output_param.lower() == 'defaultsuccess': + return 'DefaultSuccess' + return '{}Cluster{}'.format(cluster.name, command.output_param) + + +def attributesWithSupportedCallback(attrs, context: TypeLookupContext): + for attr in attrs: + # Attributes will be generated for all types + # except non-list structures + if not attr.definition.is_list: + underlying = ParseDataType(attr.definition.data_type, context) + if type(underlying) == IdlType: + continue + + yield attr + + +def NamedFilter(choices: List, name: str): + for choice in choices: + if choice.name == name: + return choice + raise Exception("No item named %s in %r" % (name, choices)) + + +def ToBoxedJavaType(field: Field): + if field.is_optional: + return 'jobject' + elif field.data_type.name.lower() in ['octet_string', 'long_octet_string']: + return 'jbyteArray' + elif field.data_type.name.lower() in ['char_string', 'long_char_string']: + return 'jstring' + else: + return 'jobject' + + +def LowercaseFirst(name: str) -> str: + """ + Change the first letter of a string to lowercase as long as the 2nd + letter is not uppercase. + + Can be used for variable naming, eg insider structures, codegen will + call things "Foo foo" (notice variable name is lowercase). + """ + if len(name) > 1 and name[1].lower() != name[1]: + # Odd workaround: PAKEVerifier should not become pAKEVerifier + return name + return name[0].lower() + name[1:] + + +class EncodableValueAttr(enum.Enum): + LIST = enum.auto() + NULLABLE = enum.auto() + OPTIONAL = enum.auto() + + +class EncodableValue: + """ + Contains helpers for encoding values, specifically lookups + for optionality, lists and recursive data type lookups within + the IDL and cluster + + Intended use is to be able to: + - derive types (see clone and without_* methods) such that codegen + can implement things like 'if x != null { treat non-null x}' + - Java specific conversions: get boxed types and JNI string signautes + for the underlying types. + """ + + def __init__(self, context: TypeLookupContext, data_type: DataType, attrs: Set[EncodableValueAttr]): + self.context = context + self.data_type = data_type + self.attrs = attrs + + @property + def is_nullable(self): + return EncodableValueAttr.NULLABLE in self.attrs + + @property + def is_optional(self): + return EncodableValueAttr.OPTIONAL in self.attrs + + @property + def is_list(self): + return EncodableValueAttr.LIST in self.attrs + + @property + def is_octet_string(self): + return self.data_type.name.lower() in ['octet_string', 'long_octet_string'] + + @property + def is_char_string(self): + return self.data_type.name.lower() in ['char_string', 'long_char_string'] + + @property + def is_struct(self): + return self.context.is_struct_type(self.data_type.name) + + @property + def is_enum(self): + return self.context.is_enum_type(self.data_type.name) + + @property + def is_bitmap(self): + self.context.is_bitmap_type(self.data_type.name) + + def clone(self): + return EncodableValue(self.context, self.data_type, self.attrs) + + def without_nullable(self): + result = self.clone() + result.attrs.remove(EncodableValueAttr.NULLABLE) + return result + + def without_optional(self): + result = self.clone() + result.attrs.remove(EncodableValueAttr.OPTIONAL) + return result + + def without_list(self): + result = self.clone() + result.attrs.remove(EncodableValueAttr.LIST) + return result + + def get_underlying_struct(self): + s = self.context.find_struct(self.data_type.name) + if not s: + raise Exception("Struct %s not found" % self.data_type.name) + return s + + def get_underlying_enum(self): + e = self.context.find_enum(self.data_type.name) + if not e: + raise Exception("Enum %s not found" % self.data_type.name) + return e + + @property + def boxed_java_type(self): + t = ParseDataType(self.data_type, self.context) + + if type(t) == FundamentalType: + if t == FundamentalType.BOOL: + return "Boolean" + elif t == FundamentalType.FLOAT: + return "Float" + elif t == FundamentalType.DOUBLE: + return "Double" + else: + raise Error("Unknown fundamental type") + elif type(t) == BasicInteger: + if t.byte_count >= 4: + return "Long" + else: + return "Integer" + elif type(t) == BasicString: + if t.is_binary: + return "byte[]" + else: + return "String" + elif type(t) == IdlEnumType: + return "Integer" + elif type(t) == IdlBitmapType: + return "Integer" + else: + return "Object" + + @property + def boxed_java_signature(self): + # Optional takes precedence over list - Optional compiles down to just java.util.Optional. + if self.is_optional: + return "Ljava/util/Optional;" + + if self.is_list: + return "Ljava/util/ArrayList;" + + t = ParseDataType(self.data_type, self.context) + + if type(t) == FundamentalType: + if t == FundamentalType.BOOL: + return "Ljava/lang/Boolean;" + elif t == FundamentalType.FLOAT: + return "Ljava/lang/Float;" + elif t == FundamentalType.DOUBLE: + return "Ljava/lang/Double;" + else: + raise Error("Unknown fundamental type") + elif type(t) == BasicInteger: + if t.byte_count >= 4: + return "Ljava/lang/Long;" + else: + return "Ljava/lang/Integer;" + elif type(t) == BasicString: + if t.is_binary: + return "[B" + else: + return "Ljava/lang/String;" + elif type(t) == IdlEnumType: + return "Ljava/lang/Integer;" + elif type(t) == IdlBitmapType: + return "Ljava/lang/Integer;" + else: + return "Lchip/devicecontroller/ChipStructs${}Cluster{};".format(self.context.cluster.name, self.data_type.name) + + +def EncodableValueFrom(field: Field, context: TypeLookupContext) -> EncodableValue: + """ + Filter to convert a standard field to an EncodableValue. + + This converts the AST information (field name/info + lookup context) into + a java-generator specific wrapper that can be manipulated and + queried for properties like java native name or JNI string signature. + """ + attrs = set() + + if field.is_optional: + attrs.add(EncodableValueAttr.OPTIONAL) + + if field.is_nullable: + attrs.add(EncodableValueAttr.NULLABLE) + + if field.is_list: + attrs.add(EncodableValueAttr.LIST) + + return EncodableValue(context, field.data_type, attrs) + + +def CreateLookupContext(idl: Idl, cluster: Cluster) -> TypeLookupContext: + """ + A filter to mark a lookup context to be within a specific cluster. + + This is used to specify how structure/enum/other names are looked up. + Generally one looks up within the specific cluster then if cluster does + not contain a definition, we loop at global namespacing. + """ + return TypeLookupContext(idl, cluster) + + +def CanGenerateSubscribe(attr: Attribute, lookup: TypeLookupContext) -> bool: + """ + Filter that returns if an attribute can be subscribed to. + + Uses the given attribute and the lookupContext to figure out the attribute + type. + """ + # For backwards compatibility, we do not subscribe to structs + # (although list of structs is ok ...) + if attr.definition.is_list: + return True + + return not lookup.is_struct_type(attr.definition.data_type.name) + + +class JavaGenerator(CodeGenerator): + """ + Generation of java code for matter. + """ + + def __init__(self, storage: GeneratorStorage, idl: Idl): + """ + Inintialization is specific for java generation and will add + filters as required by the java .jinja templates to function. + """ + super().__init__(storage, idl) + + self.jinja_env.filters['attributesWithCallback'] = attributesWithSupportedCallback + self.jinja_env.filters['callbackName'] = CallbackName + self.jinja_env.filters['commandCallbackName'] = CommandCallbackName + self.jinja_env.filters['named'] = NamedFilter + self.jinja_env.filters['toBoxedJavaType'] = ToBoxedJavaType + self.jinja_env.filters['lowercaseFirst'] = LowercaseFirst + self.jinja_env.filters['asEncodable'] = EncodableValueFrom + self.jinja_env.filters['createLookupContext'] = CreateLookupContext + self.jinja_env.filters['canGenerateSubscribe'] = CanGenerateSubscribe + + def internal_render_all(self): + """ + Renders .CPP files required for JNI support. + """ + # Every cluster has its own impl, to avoid + # very large compilations (running out of RAM) + for cluster in self.idl.clusters: + if cluster.side != ClusterSide.CLIENT: + continue + + self.internal_render_one_output( + template_path="java/ChipClustersRead.jinja", + output_file_name="jni/%sClient-ReadImpl.cpp" % cluster.name, + vars={ + 'cluster': cluster, + 'typeLookup': TypeLookupContext(self.idl, cluster), + } + ) + + self.internal_render_one_output( + template_path="java/ChipClustersCpp.jinja", + output_file_name="jni/%sClient-InvokeSubscribeImpl.cpp" % cluster.name, + vars={ + 'cluster': cluster, + 'typeLookup': TypeLookupContext(self.idl, cluster), + } + ) diff --git a/scripts/idl/build/lib/generators/registry.py b/scripts/idl/build/lib/generators/registry.py new file mode 100644 index 00000000000000..815bc8d58a5386 --- /dev/null +++ b/scripts/idl/build/lib/generators/registry.py @@ -0,0 +1,58 @@ +# Copyright (c) 2022 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. + +import enum + +from idl.generators.java import JavaGenerator +from idl.generators.bridge import BridgeGenerator +from idl.generators.cpp.application import CppApplicationGenerator + + +class CodeGenerator(enum.Enum): + """ + Represents every generator type supported by codegen and maps + the simple enum value (user friendly and can be a command line input) + into underlying generators. + """ + JAVA = enum.auto() + BRIDGE = enum.auto() + CPP_APPLICATION = enum.auto() + + def Create(self, *args, **kargs): + if self == CodeGenerator.JAVA: + return JavaGenerator(*args, **kargs) + elif self == CodeGenerator.BRIDGE: + return BridgeGenerator(*args, **kargs) + elif self == CodeGenerator.CPP_APPLICATION: + return CppApplicationGenerator(*args, **kargs) + else: + raise NameError("Unknown code generator type") + + @staticmethod + def FromString(name): + global GENERATORS + + if name.lower() in GENERATORS: + return GENERATORS[name.lower()] + else: + raise NameError("Unknown code generator type '%s'" % name) + +# Contains all known code generators along with a string +# to uniquely identify them when running command line tools or +# executing tests +GENERATORS = { + 'java': CodeGenerator.JAVA, + 'bridge': CodeGenerator.BRIDGE, + 'cpp-app': CodeGenerator.CPP_APPLICATION, +} diff --git a/scripts/idl/build/lib/generators/types.py b/scripts/idl/build/lib/generators/types.py new file mode 100644 index 00000000000000..b6f216802de0d8 --- /dev/null +++ b/scripts/idl/build/lib/generators/types.py @@ -0,0 +1,407 @@ +# Copyright (c) 2022 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. + +import logging +import enum + +from idl.matter_idl_types import DataType +from idl import matter_idl_types # to explicitly say 'Enum' + +from typing import Union, List, Optional +from dataclasses import dataclass + + +def ToPowerOfTwo(bits: int) -> int: + """ + Given a number, find the next power of two that is >= to the given value. + + Can be used to figure out a variable size given non-standard bit sizes in + matter: eg. a int24 can be stored in an int32, so ToPortOfTwo(24) == 32. + + """ + # probably bit manipulation can be faster, but this should be ok as well + result = 1 + while result < bits: + result = result * 2 + return result + + +@dataclass +class BasicInteger: + """ + Represents something that is stored as a basic integer. + """ + idl_name: str + byte_count: int # NOTE: may NOT be a power of 2 for odd sized integers + is_signed: bool + + @property + def bits(self): + return self.byte_count * 8 + + @property + def power_of_two_bits(self): + return ToPowerOfTwo(self.bits) + + +@dataclass +class BasicString: + """ + Represents either a string or a binary string (blob). + """ + idl_name: str + is_binary: bool + max_length: Union[int, None] = None + + +class FundamentalType(enum.Enum): + """ + Native types, generally available across C++/ObjC/Java/python/other. + """ + BOOL = enum.auto() + FLOAT = enum.auto() + DOUBLE = enum.auto() + + @property + def idl_name(self): + if self == FundamentalType.BOOL: + return "bool" + elif self == FundamentalType.FLOAT: + return "single" + elif self == FundamentalType.DOUBLE: + return "double" + else: + raise Error("Type not handled: %r" % self) + + @property + def byte_count(self): + if self == FundamentalType.BOOL: + return 1 + elif self == FundamentalType.FLOAT: + return 4 + elif self == FundamentalType.DOUBLE: + return 8 + else: + raise Error("Type not handled: %r" % self) + + @property + def bits(self): + return self.byte_count * 8 + + +@dataclass +class IdlEnumType: + """ + An enumeration type. Enumerations are constants with an underlying + base type that is an interger. + """ + idl_name: str + base_type: BasicInteger + + @property + def byte_count(self): + return base_type.byte_count() + + @property + def bits(self): + return base_type.bits() + + +@dataclass +class IdlBitmapType: + """ + Bitmaps mark that each bit (or a subset of said bits) have a meaning. + + Examples include "feature maps" where bits represent feature available or not. + """ + idl_name: str + base_type: BasicInteger + + @property + def byte_count(self): + return base_type.byte_count() + + @property + def bits(self): + return base_type.bits() + + +class IdlItemType(enum.Enum): + UNKNOWN = enum.auto() + STRUCT = enum.auto() + + +@dataclass +class IdlType: + """ + A type defined within the IDL. + + IDLs would generally only define structures as all other types are + described in other things like enums/bitmaps/basic types etc. + + However since IDL parsing is not yet codegen just syntactically, we allow + the option to have a type that is marked 'unknown' (likely invalid/never + defined). + """ + idl_name: str + item_type: IdlItemType + + @property + def is_struct(self) -> bool: + return self.item_type == IdlItemType.STRUCT + + +# Data types, held by ZAP in chip-types.xml and generally by the spec. +__CHIP_SIZED_TYPES__ = { + "bitmap16": BasicInteger(idl_name="bitmap16", byte_count=2, is_signed=False), + "bitmap24": BasicInteger(idl_name="bitmap24", byte_count=3, is_signed=False), + "bitmap32": BasicInteger(idl_name="bitmap32", byte_count=4, is_signed=False), + "bitmap64": BasicInteger(idl_name="bitmap64", byte_count=8, is_signed=False), + "bitmap8": BasicInteger(idl_name="bitmap8", byte_count=1, is_signed=False), + "enum16": BasicInteger(idl_name="enum16", byte_count=2, is_signed=False), + "enum32": BasicInteger(idl_name="enum32", byte_count=4, is_signed=False), + "enum8": BasicInteger(idl_name="enum8", byte_count=1, is_signed=False), + "int16s": BasicInteger(idl_name="int16s", byte_count=2, is_signed=True), + "int16u": BasicInteger(idl_name="int16u", byte_count=2, is_signed=False), + "int24s": BasicInteger(idl_name="int24s", byte_count=3, is_signed=True), + "int24u": BasicInteger(idl_name="int24u", byte_count=3, is_signed=False), + "int32s": BasicInteger(idl_name="int32s", byte_count=4, is_signed=True), + "int32u": BasicInteger(idl_name="int32u", byte_count=4, is_signed=False), + "int40s": BasicInteger(idl_name="int40s", byte_count=5, is_signed=True), + "int40u": BasicInteger(idl_name="int40u", byte_count=5, is_signed=False), + "int48s": BasicInteger(idl_name="int48s", byte_count=6, is_signed=True), + "int48u": BasicInteger(idl_name="int48u", byte_count=6, is_signed=False), + "int56s": BasicInteger(idl_name="int56s", byte_count=7, is_signed=True), + "int56u": BasicInteger(idl_name="int56u", byte_count=7, is_signed=False), + "int64s": BasicInteger(idl_name="int64s", byte_count=8, is_signed=True), + "int64u": BasicInteger(idl_name="int64u", byte_count=8, is_signed=False), + "int8s": BasicInteger(idl_name="int8s", byte_count=1, is_signed=True), + "int8u": BasicInteger(idl_name="int8u", byte_count=1, is_signed=False), + # Derived types + # Specification describes them in section '7.18.2. Derived Data Types' + "action_id": BasicInteger(idl_name="action_id", byte_count=1, is_signed=False), + "attrib_id": BasicInteger(idl_name="attrib_id", byte_count=4, is_signed=False), + "cluster_id": BasicInteger(idl_name="cluster_id", byte_count=4, is_signed=False), + "command_id": BasicInteger(idl_name="command_id", byte_count=4, is_signed=False), + "data_ver": BasicInteger(idl_name="data_ver", byte_count=4, is_signed=False), + "date": BasicInteger(idl_name="date", byte_count=4, is_signed=False), + "devtype_id": BasicInteger(idl_name="devtype_id", byte_count=4, is_signed=False), + "endpoint_no": BasicInteger(idl_name="endpoint_no", byte_count=2, is_signed=False), + "epoch_s": BasicInteger(idl_name="epoch_s", byte_count=4, is_signed=False), + "epoch_us": BasicInteger(idl_name="epoch_us", byte_count=8, is_signed=False), + "event_id": BasicInteger(idl_name="event_id", byte_count=4, is_signed=False), + "event_no": BasicInteger(idl_name="event_no", byte_count=8, is_signed=False), + "fabric_id": BasicInteger(idl_name="fabric_id", byte_count=8, is_signed=False), + "fabric_idx": BasicInteger(idl_name="fabric_idx", byte_count=1, is_signed=False), + "field_id": BasicInteger(idl_name="field_id", byte_count=4, is_signed=False), + "group_id": BasicInteger(idl_name="group_id", byte_count=2, is_signed=False), + "node_id": BasicInteger(idl_name="node_id", byte_count=8, is_signed=False), + "percent": BasicInteger(idl_name="percent", byte_count=1, is_signed=False), + "percent100ths": BasicInteger(idl_name="percent100ths", byte_count=2, is_signed=False), + "status": BasicInteger(idl_name="status", byte_count=2, is_signed=False), + "systime_us": BasicInteger(idl_name="systime_us", byte_count=8, is_signed=False), + "tod": BasicInteger(idl_name="tod", byte_count=4, is_signed=False), + "trans_id": BasicInteger(idl_name="trans_id", byte_count=4, is_signed=False), + "vendor_id": BasicInteger(idl_name="vendor_id", byte_count=2, is_signed=False), +} + + +class TypeLookupContext: + """ + Handles type lookups within a scope. + + Generally when looking for a struct/enum, the lookup will be first done + at a cluster level, then at a global level. + + Example: + + ================ test.matter ============== + enum A {} + + server cluster X { + struct A {} + struct B {} + } + + server cluster Y { + enum C {} + } + =========================================== + + When considering a lookup context of global (i.e. cluster is not set) + "A" is defined as an enum (::A) + "B" is undefined + "C" is undefined + + When considering a lookup context of cluster X + "A" is defined as a struct (X::A) + "B" is defined as a struct (X::B) + "C" is undefined + + When considering a lookup context of cluster Y + "A" is defined as an enum (::A) + "B" is undefined + "C" is defined as an enum (Y::C) + + """ + + def __init__(self, idl: matter_idl_types.Idl, cluster: Optional[matter_idl_types.Cluster]): + self.idl = idl + self.cluster = cluster + + def find_enum(self, name) -> Optional[matter_idl_types.Enum]: + """ + Find the first enumeration matching the given name for the given + lookup rules (searches cluster first, then global). + """ + for e in self.all_enums: + if e.name == name: + return e + + return None + + def find_struct(self, name) -> Optional[matter_idl_types.Struct]: + for s in self.all_structs: + if s.name == name: + return s + + return None + + def find_bitmap(self, name) -> Optional[matter_idl_types.Bitmap]: + for s in self.all_bitmaps: + if s.name == name: + return s + + return None + + @property + def all_enums(self): + """ + All enumerations, ordered by lookup priority. + + If an enum A is defined both in the cluster and globally, this WILL + return both instances, however it will return the cluster version first. + """ + if self.cluster: + for e in self.cluster.enums: + yield e + for e in self.idl.enums: + yield e + + @property + def all_bitmaps(self): + """ + All bitmaps defined within this lookup context. + + bitmaps are only defined at cluster level. If lookup context does not + include a cluster, the bitmal list will be empty. + """ + if self.cluster: + for b in self.cluster.bitmaps: + yield b + + @property + def all_structs(self): + """All structs, ordered by lookup prioroty. + + If a struct A is defined both in the cluster and globally, this WILL + return both instances, however it will return the cluster version first. + """ + if self.cluster: + for e in self.cluster.structs: + yield e + for e in self.idl.structs: + yield e + + def is_enum_type(self, name: str): + """ + Determine if the given type name is an enumeration. + + Handles both standard names (like enum8) as well as enumerations defined + within the current lookup context. + """ + if name.lower() in ["enum8", "enum16", "enum32"]: + return True + return any(map(lambda e: e.name == name, self.all_enums)) + + def is_struct_type(self, name: str): + """ + Determine if the given type name is type that is known to be a struct + """ + return any(map(lambda s: s.name == name, self.all_structs)) + + def is_bitmap_type(self, name: str): + """ + Determine if the given type name is type that is known to be a bitmap. + + Handles both standard/zcl names (like bitmap32) and types defined within + the current lookup context. + """ + if name.lower() in ["bitmap8", "bitmap16", "bitmap24", "bitmap32", "bitmap64"]: + return True + + return any(map(lambda s: s.name == name, self.all_bitmaps)) + + +def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[BasicInteger, BasicString, FundamentalType, IdlType]: + """ + Given a AST data type and a lookup context, match it to a type that can be later + be used for generation. + + AST parsing is textual, so it does not understand what "foo" means. This method + looks up what "foo" actually means: includes basic types (e.g. bool), + zcl types (like enums or bitmaps) and does lookups to find structs/enums/bitmaps/etc + that are defined in the given lookup context. + """ + + lowercase_name = data_type.name.lower() + + if lowercase_name == 'boolean': + return FundamentalType.BOOL + if lowercase_name == 'single': + return FundamentalType.FLOAT + elif lowercase_name == 'double': + return FundamentalType.DOUBLE + elif lowercase_name in ['char_string', 'long_char_string']: + return BasicString(idl_name=lowercase_name, is_binary=False, max_length=data_type.max_length) + elif lowercase_name in ['octet_string', 'long_octet_string']: + return BasicString(idl_name=lowercase_name, is_binary=True, max_length=data_type.max_length) + elif lowercase_name in ['enum8', 'enum16', 'enum32']: + return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name]) + elif lowercase_name in ['bitmap8', 'bitmap16', 'bitmap24', 'bitmap32']: + return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name]) + + int_type = __CHIP_SIZED_TYPES__.get(lowercase_name, None) + if int_type is not None: + return int_type + + # All fast checks done, now check against known data types + e = lookup.find_enum(data_type.name) + if e: + # Valid enum found. it MUST be based on a valid data type + return IdlEnumType(idl_name=data_type.name, base_type=__CHIP_SIZED_TYPES__[e.base_type.lower()]) + + b = lookup.find_bitmap(data_type.name) + if b: + # Valid enum found. it MUST be based on a valid data type + return IdlBitmapType(idl_name=data_type.name, base_type=__CHIP_SIZED_TYPES__[b.base_type.lower()]) + + result = IdlType(idl_name=data_type.name, item_type=IdlItemType.UNKNOWN) + if lookup.find_struct(data_type.name): + result.item_type = IdlItemType.STRUCT + else: + logging.warn( + "Data type %s is NOT known, but treating it as a generic IDL type." % data_type) + + return result diff --git a/scripts/idl/build/lib/lint/__init__.py b/scripts/idl/build/lib/lint/__init__.py new file mode 100644 index 00000000000000..503bdf4086f77e --- /dev/null +++ b/scripts/idl/build/lib/lint/__init__.py @@ -0,0 +1,15 @@ +# Copyright (c) 2022 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. + +from .lint_rules_parser import CreateParser diff --git a/scripts/idl/build/lib/lint/lint_rules_parser.py b/scripts/idl/build/lib/lint/lint_rules_parser.py new file mode 100644 index 00000000000000..9af6b8c0f05724 --- /dev/null +++ b/scripts/idl/build/lib/lint/lint_rules_parser.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python + +import logging +import os +import xml.etree.ElementTree + +from dataclasses import dataclass, field +from typing import List, Optional, Mapping +from lark import Lark +from lark.visitors import Transformer, v_args, Discard +import stringcase +import traceback + +try: + from .types import RequiredAttributesRule, AttributeRequirement, ClusterRequirement, RequiredCommandsRule, ClusterCommandRequirement +except: + import sys + + sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "..")) + from idl.lint.types import RequiredAttributesRule, AttributeRequirement, ClusterRequirement, RequiredCommandsRule, ClusterCommandRequirement + + +def parseNumberString(n): + if n.startswith('0x'): + return int(n[2:], 16) + else: + return int(n) + + +@dataclass +class RequiredAttribute: + name: str + code: int + + +@dataclass +class RequiredCommand: + name: str + code: int + + +@dataclass +class DecodedCluster: + name: str + code: int + required_attributes: List[RequiredAttribute] + required_commands: List[RequiredCommand] + + +def DecodeClusterFromXml(element: xml.etree.ElementTree.Element): + if element.tag != 'cluster': + logging.error("Not a cluster element: %r" % element) + return None + + # cluster elements contain among other children + # - name (general name for this cluster) + # - code (unique identifier, may be hex or numeric) + # - attribute with side, code and optional attributes + + try: + name = element.find('name').text.replace(' ', '') + required_attributes = [] + required_commands = [] + + for attr in element.findall('attribute'): + if attr.attrib['side'] != 'server': + continue + + if 'optional' in attr.attrib and attr.attrib['optional'] == 'true': + continue + + # when introducing access controls, the content of attributes may either be: + # myName + # or + # myName... + attr_name = attr.text + if attr.find('description') is not None: + attr_name = attr.find('description').text + + required_attributes.append( + RequiredAttribute( + name=attr_name, + code=parseNumberString(attr.attrib['code']) + )) + + for cmd in element.findall('command'): + if cmd.attrib['source'] != 'client': + continue + + if 'optional' in cmd.attrib and cmd.attrib['optional'] == 'true': + continue + + required_commands.append(RequiredCommand(name=cmd.attrib["name"], code=parseNumberString(cmd.attrib['code']))) + + return DecodedCluster( + name=name, + code=parseNumberString(element.find('code').text), + required_attributes=required_attributes, + required_commands=required_commands + ) + except Exception as e: + logging.exception("Failed to decode cluster %r" % element) + return None + + +def ClustersInXmlFile(path: str): + logging.info("Loading XML from %s" % path) + + # root is expected to be just a "configurator" object + configurator = xml.etree.ElementTree.parse(path).getroot() + for child in configurator: + if child.tag != 'cluster': + continue + yield child + + +class LintRulesContext: + """Represents a context for loadint lint rules. + + Handles: + - loading referenced files (matter xml definitions) + - adding linter rules as data is parsed + - Looking up identifiers for various rules + """ + + def __init__(self): + self._required_attributes_rule = RequiredAttributesRule("Required attributes") + self._required_commands_rule = RequiredCommandsRule("Required commands") + + # Map cluster names to the underlying code + self._cluster_codes: Mapping[str, int] = {} + + def GetLinterRules(self): + return [self._required_attributes_rule, self._required_commands_rule] + + def RequireAttribute(self, r: AttributeRequirement): + self._required_attributes_rule.RequireAttribute(r) + + def RequireClusterInEndpoint(self, name: str, code: int): + """Mark that a specific cluster is always required in the given endpoint + """ + if name not in self._cluster_codes: + # Name may be a number. If this can be parsed as a number, accept it anyway + try: + cluster_code = parseNumberString(name) + name = "ID_%s" % name + except ValueError: + logging.error("UNKNOWN cluster name %s" % name) + logging.error("Known names: %s" % (",".join(self._cluster_codes.keys()), )) + return + else: + cluster_code = self._cluster_codes[name] + + self._required_attributes_rule.RequireClusterInEndpoint(ClusterRequirement( + endpoint_id=code, + cluster_code=cluster_code, + cluster_name=name, + )) + + def LoadXml(self, path: str): + """Load XML data from the given path and add it to + internal processing. Adds attribute requirement rules + as needed. + """ + for cluster in ClustersInXmlFile(path): + decoded = DecodeClusterFromXml(cluster) + + if not decoded: + continue + + self._cluster_codes[decoded.name] = decoded.code + + for attr in decoded.required_attributes: + self._required_attributes_rule.RequireAttribute(AttributeRequirement( + code=attr.code, name=attr.name, filter_cluster=decoded.code)) + + for cmd in decoded.required_commands: + self._required_commands_rule.RequireCommand( + ClusterCommandRequirement( + cluster_code=decoded.code, + command_code=cmd.code, + command_name=cmd.name + )) + + +class LintRulesTransformer(Transformer): + """ + A transformer capable to transform data parsed by Lark according to + lint_rules_grammar.lark. + """ + + def __init__(self, file_name: str): + self.context = LintRulesContext() + self.file_name = file_name + + def positive_integer(self, tokens): + """Numbers in the grammar are integers or hex numbers. + """ + if len(tokens) != 1: + raise Error("Unexpected argument counts") + + return parseNumberString(tokens[0].value) + + @v_args(inline=True) + def negative_integer(self, value): + return -value + + @v_args(inline=True) + def integer(self, value): + return value + + def id(self, tokens): + """An id is a string containing an identifier + """ + if len(tokens) != 1: + raise Error("Unexpected argument counts") + return tokens[0].value + + def ESCAPED_STRING(self, s): + # handle escapes, skip the start and end quotes + return s.value[1:-1].encode('utf-8').decode('unicode-escape') + + def start(self, instructions): + # At this point processing is considered done, return all + # linter rules that were found + return self.context.GetLinterRules() + + def instruction(self, instruction): + return Discard + + def all_endpoint_rule(self, attributes): + for attribute in attributes: + self.context.RequireAttribute(attribute) + + return Discard + + @v_args(inline=True) + def load_xml(self, path): + if not os.path.isabs(path): + path = os.path.abspath(os.path.join(os.path.dirname(self.file_name), path)) + + self.context.LoadXml(path) + + @v_args(inline=True) + def required_global_attribute(self, name, code): + return AttributeRequirement(code=code, name=name) + + @v_args(inline=True) + def specific_endpoint_rule(self, code, *names): + for name in names: + self.context.RequireClusterInEndpoint(name, code) + return Discard + + @v_args(inline=True) + def required_server_cluster(self, id): + return id + + +class Parser: + def __init__(self, parser, file_name: str): + self.parser = parser + self.file_name = file_name + + def parse(self): + data = LintRulesTransformer(self.file_name).transform(self.parser.parse(open(self.file_name, "rt").read())) + return data + + +def CreateParser(file_name: str): + """ + Generates a parser that will process a ".matter" file into a IDL + """ + return Parser(Lark.open('lint_rules_grammar.lark', rel_to=__file__, parser='lalr', propagate_positions=True), file_name=file_name) + + +if __name__ == '__main__': + # This Parser is generally not intended to be run as a stand-alone binary. + # The ability to run is for debug and to print out the parsed AST. + import click + import coloredlogs + + # Supported log levels, mapping string values required for argument + # parsing into logging constants + __LOG_LEVELS__ = { + 'debug': logging.DEBUG, + 'info': logging.INFO, + 'warn': logging.WARN, + 'fatal': logging.FATAL, + } + + @click.command() + @click.option( + '--log-level', + default='INFO', + type=click.Choice(__LOG_LEVELS__.keys(), case_sensitive=False), + help='Determines the verbosity of script output.') + @click.argument('filename') + def main(log_level, filename=None): + coloredlogs.install(level=__LOG_LEVELS__[ + log_level], fmt='%(asctime)s %(levelname)-7s %(message)s') + + logging.info("Starting to parse ...") + data = CreateParser(filename).parse() + logging.info("Parse completed") + + logging.info("Data:") + logging.info("%r" % data) + + main() diff --git a/scripts/idl/build/lib/lint/types.py b/scripts/idl/build/lib/lint/types.py new file mode 100644 index 00000000000000..85dfbdeacd0bc3 --- /dev/null +++ b/scripts/idl/build/lib/lint/types.py @@ -0,0 +1,259 @@ +# Copyright (c) 2022 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. + +from idl.matter_idl_types import Idl, ParseMetaData, ClusterSide +from abc import ABC, abstractmethod +from typing import List, Optional +from dataclasses import dataclass, field + + +@dataclass +class LocationInFile: + file_name: str + line: int + column: int + + def __init__(self, file_name: str, meta: ParseMetaData): + self.file_name = file_name + self.line = meta.line + self.column = meta.column + + +@dataclass +class LintError: + """Represents a lint error, potentially at a specific location in a file""" + + message: str + location: Optional[LocationInFile] = field(default=None) + + def __init__(self, text: str, location: Optional[LocationInFile] = None): + self.message = text + if location: + self.message += " at %s:%d:%d" % (location.file_name, location.line, location.column) + + def __str__(self): + return self.message + + +class LintRule(ABC): + """Validates a linter rule on an idl""" + + def __init__(self, name): + self.name = name + + @abstractmethod + def LintIdl(self, idl: Idl) -> List[LintError]: + """Runs the linter on the given IDL and returns back any errors it may find""" + pass + + +@dataclass +class AttributeRequirement: + """Contains information about a required attribute""" + code: int # required attributes are searched by codes + name: str # the name of this attribute. Expect it to be exposed properly + + # Optional filters to apply to specific locations + filter_cluster: Optional[int] = field(default=None) + + +@dataclass +class ClusterRequirement: + endpoint_id: int + cluster_code: int + cluster_name: str + + +class ErrorAccumulatingRule(LintRule): + """Contains a lint error list and helps helpers to add to such a list of rules.""" + + def __init__(self, name): + super(ErrorAccumulatingRule, self).__init__(name) + self._lint_errors = [] + self._idl = None + + def _AddLintError(self, text, location): + self._lint_errors.append(LintError("%s: %s" % (self.name, text), location)) + + def _ParseLocation(self, meta: Optional[ParseMetaData]) -> Optional[LocationInFile]: + """Create a location in the current file that is being parsed. """ + if not meta or not self._idl.parse_file_name: + return None + return LocationInFile(self._idl.parse_file_name, meta) + + def LintIdl(self, idl: Idl) -> List[LintError]: + self._idl = idl + self._lint_errors = [] + self._LintImpl() + return self._lint_errors + + @abstractmethod + def _LintImpl(self): + """Implements actual linting of the IDL. + + Uses the underlying _idl for validation. + """ + pass + + +class RequiredAttributesRule(ErrorAccumulatingRule): + def __init__(self, name): + super(RequiredAttributesRule, self).__init__(name) + # Map attribute code to name + self._mandatory_attributes: List[AttributeRequirement] = [] + self._mandatory_clusters: List[ClusterRequirement] = [] + + def __repr__(self): + result = "RequiredAttributesRule{\n" + + if self._mandatory_attributes: + result += " mandatory_attributes:\n" + for attr in self._mandatory_attributes: + result += " - %r\n" % attr + + if self._mandatory_clusters: + result += " mandatory_clusters:\n" + for cluster in self._mandatory_clusters: + result += " - %r\n" % cluster + + result += "}" + return result + + def RequireAttribute(self, attr: AttributeRequirement): + """Mark an attribute required""" + self._mandatory_attributes.append(attr) + + def RequireClusterInEndpoint(self, requirement: ClusterRequirement): + self._mandatory_clusters.append(requirement) + + def _ServerClusterDefinition(self, name: str, location: Optional[LocationInFile]): + """Finds the server cluster definition with the given name. + + On error returns None and _lint_errors is updated internlly + """ + cluster_definition = [ + c for c in self._idl.clusters if c.name == name and c.side == ClusterSide.SERVER + ] + if not cluster_definition: + self._AddLintError("Cluster definition for %s not found" % cluster.name, location) + return None + + if len(cluster_definition) > 1: + self._AddLintError("Multiple cluster definitions found for %s" % cluster.name, location) + return None + + return cluster_definition[0] + + def _LintImpl(self): + for endpoint in self._idl.endpoints: + + cluster_codes = set() + + for cluster in endpoint.server_clusters: + cluster_definition = self._ServerClusterDefinition(cluster.name, self._ParseLocation(cluster.parse_meta)) + if not cluster_definition: + continue + + cluster_codes.add(cluster_definition.code) + + # Cluster contains enabled attributes by name + # cluster_definition contains the definition of the attributes themseves + # + # Join the two to receive attribute codes + name_to_code_map = {} + for attr in cluster_definition.attributes: + name_to_code_map[attr.definition.name] = attr.definition.code + + attribute_codes = set() + # For all the instantiated attributes, figure out their code + for attr in cluster.attributes: + if attr.name not in name_to_code_map: + self._AddLintError("Could not find attribute defintion (no code) for %s:%s" % + (cluster.name, attr.name), self._ParseLocation(cluster.parse_meta)) + continue + + attribute_codes.add(name_to_code_map[attr.name]) + + # Linting codes now + for check in self._mandatory_attributes: + if check.filter_cluster is not None and check.filter_cluster != cluster_definition.code: + continue + + if check.code not in attribute_codes: + self._AddLintError("EP%d:%s does not expose %s(%d) attribute" % + (endpoint.number, cluster.name, check.name, check.code), self._ParseLocation(cluster.parse_meta)) + + for requirement in self._mandatory_clusters: + if requirement.endpoint_id != endpoint.number: + continue + + if requirement.cluster_code not in cluster_codes: + self._AddLintError("Endpoint %d does not expose cluster %s (%d)" % + (requirement.endpoint_id, requirement.cluster_name, requirement.cluster_code), location=None) + + +@dataclass +class ClusterCommandRequirement: + cluster_code: int + command_code: int + command_name: str + + +class RequiredCommandsRule(ErrorAccumulatingRule): + def __init__(self, name): + super(RequiredCommandsRule, self).__init__(name) + + # Maps cluster id to mandatory cluster requirement + self._mandatory_commands: Maping[int, List[ClusterCommandRequirement]] = {} + + def __repr__(self): + result = "RequiredCommandsRule{\n" + + if self._mandatory_commands: + result += " mandatory_commands:\n" + for key, value in self._mandatory_commands.items(): + result += " - cluster %d:\n" % key + for requirement in value: + result += " - %r\n" % requirement + + result += "}" + return result + + def RequireCommand(self, cmd: ClusterCommandRequirement): + """Mark a command required""" + + if cmd.cluster_code in self._mandatory_commands: + self._mandatory_commands[cmd.cluster_code].append(cmd) + else: + self._mandatory_commands[cmd.cluster_code] = [cmd] + + def _LintImpl(self): + for cluster in self._idl.clusters: + if cluster.side != ClusterSide.SERVER: + continue # only validate server-side: + + if cluster.code not in self._mandatory_commands: + continue # no known mandatory commands + + defined_commands = set([c.code for c in cluster.commands]) + + for requirement in self._mandatory_commands[cluster.code]: + if requirement.command_code in defined_commands: + continue # command exists + + self._AddLintError( + "Cluster %s does not define mandatory command %s(%d)" % ( + cluster.name, requirement.command_name, requirement.command_code), + self._ParseLocation(cluster.parse_meta) + ) diff --git a/scripts/idl/build/lib/zapxml/__init__.py b/scripts/idl/build/lib/zapxml/__init__.py new file mode 100644 index 00000000000000..332d1c244bea3b --- /dev/null +++ b/scripts/idl/build/lib/zapxml/__init__.py @@ -0,0 +1,118 @@ +# Copyright (c) 2022 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. + +import logging +import typing +import xml.sax.handler + +from dataclasses import dataclass +from typing import Optional, Union, List + +from idl.zapxml.handlers import Context, ZapXmlHandler +from idl.matter_idl_types import Idl + + +class ParseHandler(xml.sax.handler.ContentHandler): + """A parser for ZAP-style XML data definitions. + + Defers its processing to ZapXmlHandler and keeps track of: + - an internal context for all handlers + - the parsed Idl structure that is incrementally built + - sets up parsing location within the context + - keeps track of ParsePath + + Overall converts a python SAX handler into idl.zapxml.handlers + """ + + def __init__(self, include_meta_data=True): + super().__init__() + self._idl = Idl() + self._processing_stack = [] + # Context persists across all + self._context = Context() + self._include_meta_data = include_meta_data + + def PrepareParsing(self, filename): + # This is a bit ugly: filename keeps changing during parse + # IDL meta is not prepared for this (as source is XML and .matter is + # single file) + if self._include_meta_data: + self._idl.parse_file_name = filename + + def Finish(self) -> Idl: + self._context.PostProcess(self._idl) + return self._idl + + def startDocument(self): + if self._include_meta_data: + self._context.locator = self._locator + self._processing_stack = [ZapXmlHandler(self._context, self._idl)] + + def endDocument(self): + if len(self._processing_stack) != 1: + raise Exception("Unexpected nesting!") + + def startElement(self, name: str, attrs): + logging.debug("ELEMENT START: %r / %r" % (name, attrs)) + self._context.path.push(name) + self._processing_stack.append(self._processing_stack[-1].GetNextProcessor(name, attrs)) + + def endElement(self, name: str): + logging.debug("ELEMENT END: %r" % name) + + last = self._processing_stack.pop() + last.EndProcessing() + + # important to pop AFTER processing end to allow processing + # end to access the current context + self._context.path.pop() + + def characters(self, content): + self._processing_stack[-1].HandleContent(content) + + +@dataclass +class ParseSource: + """Represents an input sopurce for ParseXmls. + + Allows for named data sources to be parsed. + """ + source: Union[str, typing.IO] # filename or stream + name: Optional[str] = None # actual filename to use, None if the source is a filename already + + @ property + def source_file_name(self): + if self.name: + return self.name + return self.source # assume string + + +def ParseXmls(sources: List[ParseSource], include_meta_data=True) -> Idl: + """Parse one or more XML inputs and return the resulting Idl data. + + Params: + sources - what to parse + include_meta_data - if parsing location data should be included in the Idl + """ + handler = ParseHandler(include_meta_data=include_meta_data) + + for source in sources: + logging.info('Parsing %s...' % source.source_file_name) + handler.PrepareParsing(source.source_file_name) + + parser = xml.sax.make_parser() + parser.setContentHandler(handler) + parser.parse(source.source) + + return handler.Finish() diff --git a/scripts/idl/build/lib/zapxml/handlers/__init__.py b/scripts/idl/build/lib/zapxml/handlers/__init__.py new file mode 100644 index 00000000000000..7a6bfa04682921 --- /dev/null +++ b/scripts/idl/build/lib/zapxml/handlers/__init__.py @@ -0,0 +1,36 @@ +# Copyright (c) 2022 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. + +from .base import BaseHandler +from .context import Context +from .handlers import ConfiguratorHandler + +from idl.matter_idl_types import Idl + + +class ZapXmlHandler(BaseHandler): + """Handles the top level (/) of a zap xml file. + + Generally these files only contain a 'configurator' element in them + """ + + def __init__(self, context: Context, idl: Idl): + super().__init__(context) + self._idl = idl + + def GetNextProcessor(self, name, attrs): + if name.lower() == 'configurator': + return ConfiguratorHandler(self.context, self._idl) + else: + return BaseHandler(self.context) diff --git a/scripts/idl/build/lib/zapxml/handlers/base.py b/scripts/idl/build/lib/zapxml/handlers/base.py new file mode 100644 index 00000000000000..bb2ca95566a4ae --- /dev/null +++ b/scripts/idl/build/lib/zapxml/handlers/base.py @@ -0,0 +1,62 @@ +# Copyright (c) 2022 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. + +import enum +from .context import Context + + +class HandledDepth: + """Defines how deep a XML element has been handled.""" + NOT_HANDLED = enum.auto() # Unknown/parsed element + ENTIRE_TREE = enum.auto() # Entire tree can be ignored + SINGLE_TAG = enum.auto() # Single tag processed, but not sub-items + + +class BaseHandler: + """A generic element handler. + + XML processing is done in the form of depth-first processing: + - Tree is descended into using `GetNextProcessor` + - Processors are expected to extend `BaseHandler` and allow for: + - GetNextProcessor to recurse + - HandleContent in case the text content is relevant + - EndProcessing once the entire tree has been walked (when xml element ends) + + BaseHandler keeps track if it has been handled or ot by its `_handled` setting and + init parameter. Non-handled elements will be tagged within the context, resulting + in logs. This is to detect if unknown/new tags appear in XML files. + """ + + def __init__(self, context: Context, handled=HandledDepth.NOT_HANDLED): + self.context = context + self._handled = handled + + def GetNextProcessor(self, name, attrs): + """Get the next processor to use for the given name""" + + if self._handled == HandledDepth.SINGLE_TAG: + handled = HandledDepth.NOT_HANDLED + else: + handled = self._handled + + return BaseHandler(context=self.context, handled=handled) + + def HandleContent(self, content): + """Processes some content""" + pass + + def EndProcessing(self): + """Finalizes the processing of the current element""" + if self._handled == HandledDepth.NOT_HANDLED: + self.context.MarkTagNotHandled() diff --git a/scripts/idl/build/lib/zapxml/handlers/context.py b/scripts/idl/build/lib/zapxml/handlers/context.py new file mode 100644 index 00000000000000..2d82153d76d959 --- /dev/null +++ b/scripts/idl/build/lib/zapxml/handlers/context.py @@ -0,0 +1,124 @@ +# Copyright (c) 2022 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. + +import logging +import xml.sax.xmlreader + +from idl.matter_idl_types import Idl, ParseMetaData, Attribute +from typing import Optional, List + + +class IdlPostProcessor: + """Defines a callback that will apply after an entire parsing + is complete. + """ + + def FinalizeProcessing(self, idl: Idl): + """Update idl with any post-processing directives.""" + pass + + +class ProcessingPath: + """Maintains the current path of tags within xml processing. + + As processing descents into an xml like `....` + paths will have contents like ['configurator', 'cluster', ...]. + + The main purpose for this is to log and keep track of what was visited + and in general to report things like 'this path found but was not handled'. + """ + + def __init__(self, paths: List[str] = None): + if paths is None: + paths = [] + self.paths = paths + + def push(self, name: str): + self.paths.append(name) + + def pop(self): + self.paths.pop() + + def __str__(self): + return '::'.join(self.paths) + + def __repr__(self): + return 'ProcessingPath(%r)' % self.paths + + +class Context: + """ + Contains a processing state during XML reading. + + The purpose of this is to allow elements to interact with each other, share + data and defer processing. + + Usage: + - globally shared data: + > locator: parsing location, for error reporting + > path: current ProcessingPath for any logging of where we are located + - shared data: + > global attributes are parsed by one handler, but used by others + - post-processing support: + > can register AddIdlPostProcessor to perform some processing once + a full parsing pass has been done + + More data may be added in time if it involves separate XML parse handlers + needing to interact with each other. + """ + + def __init__(self, locator: Optional[xml.sax.xmlreader.Locator] = None): + self.path = ProcessingPath() + self.locator = locator + self._not_handled = set() + self._idl_post_processors = [] + + # Map of code -> attribute + self._global_attributes = {} + + def GetCurrentLocationMeta(self) -> ParseMetaData: + if not self.locator: + return None + + return ParseMetaData(line=self.locator.getLineNumber(), column=self.locator.getColumnNumber()) + + def GetGlobalAttribute(self, code): + if code in self._global_attributes: + return self._global_attributes[code] + + raise Exception( + 'Global attribute 0x%X (%d) not found. You probably need to load global-attributes.xml' % (code, code)) + + def AddGlobalAttribute(self, attribute: Attribute): + # NOTE: this may get added several times as both 'client' and 'server' + # however matter should not differentiate between the two + code = attribute.definition.code + logging.info('Adding global attribute 0x%X (%d): %s' % (code, code, attribute.definition.name)) + + self._global_attributes[code] = attribute + + def MarkTagNotHandled(self): + path = str(self.path) + if path not in self._not_handled: + logging.warning("TAG %s was not handled/recognized" % path) + self._not_handled.add(path) + + def AddIdlPostProcessor(self, processor: IdlPostProcessor): + self._idl_post_processors.append(processor) + + def PostProcess(self, idl: Idl): + for p in self._idl_post_processors: + p.FinalizeProcessing(idl) + + self._idl_post_processors = [] diff --git a/scripts/idl/build/lib/zapxml/handlers/handlers.py b/scripts/idl/build/lib/zapxml/handlers/handlers.py new file mode 100644 index 00000000000000..6048b271ecf3ac --- /dev/null +++ b/scripts/idl/build/lib/zapxml/handlers/handlers.py @@ -0,0 +1,614 @@ +# Copyright (c) 2022 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. + +import logging + +from idl.matter_idl_types import * +from typing import Optional, Union, List + +from .context import Context, IdlPostProcessor +from .parsing import ParseInt, AttrsToAccessPrivilege, AttrsToAttribute +from .base import HandledDepth, BaseHandler + + +class ClusterNameHandler(BaseHandler): + """Handles /configurator/cluster/name elements.""" + + def __init__(self, context: Context, cluster: Cluster): + super().__init__(context, handled=HandledDepth.SINGLE_TAG) + self._cluster = cluster + + def HandleContent(self, content): + self._cluster.name = content.replace(' ', '') + + +class AttributeDescriptionHandler(BaseHandler): + """Handles /configurator/cluster/attribute/description elements.""" + + def __init__(self, context: Context, attribute: Attribute): + super().__init__(context, handled=HandledDepth.SINGLE_TAG) + self._attribute = attribute + + def HandleContent(self, content: str): + self._attribute.definition.name = content.replace(' ', '') + + +class ClusterCodeHandler(BaseHandler): + """Handles /configurator/cluster/code elements.""" + + def __init__(self, context: Context, cluster: Cluster): + super().__init__(context, handled=HandledDepth.SINGLE_TAG) + self._cluster = cluster + + def HandleContent(self, content: str): + self._cluster.code = ParseInt(content) + + +class EventHandler(BaseHandler): + """Handles /configurator/cluster/event elements.""" + + def __init__(self, context: Context, cluster: Cluster, attrs): + super().__init__(context) + self._cluster = cluster + + if attrs['priority'] == 'debug': + priority = EventPriority.DEBUG + elif attrs['priority'] == 'info': + priority = EventPriority.INFO + elif attrs['priority'] == 'critical': + priority = EventPriority.CRITICAL + else: + raise Exception("Unknown event priority: %s" % attrs['priority']) + + self._event = Event( + priority=priority, + code=ParseInt(attrs['code']), + name=attrs['name'], + fields=[], + ) + + if attrs.get('isFabricSensitive', "false").lower() == 'true': + self._event.qualities |= EventQuality.FABRIC_SENSITIVE + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'field': + data_type = DataType(name=attrs['type']) + if 'length' in attrs: + data_type.max_length = ParseInt(attrs['length']) + + field = Field( + data_type=data_type, + code=ParseInt(attrs['id']), + name=attrs['name'], + is_list=(attrs.get('array', 'false').lower() == 'true'), + ) + + if attrs.get('optional', "false").lower() == 'true': + field.qualities |= FieldQuality.OPTIONAL + + if attrs.get('isNullable', "false").lower() == 'true': + field.qualities |= FieldQuality.NULLABLE + + self._event.fields.append(field) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'access': + self._event.readacl = AttrsToAccessPrivilege(attrs) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'description': + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + else: + return BaseHandler(self.context) + + def EndProcessing(self): + self._cluster.events.append(self._event) + + +class AttributeHandler(BaseHandler): + """Handles /configurator/cluster/attribute elements.""" + + def __init__(self, context: Context, cluster: Cluster, attrs): + super().__init__(context) + self._cluster = cluster + self._attribute = AttrsToAttribute(attrs) + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'access': + # Modifier not currently used: fabric scoped exists on the structure itself. + if 'modifier' in attrs: + if attrs['modifier'] != 'fabric-scoped': + raise Exception("UNKNOWN MODIFIER: %s" % attrs['modifier']) + + if ('role' in attrs) or ('privilege' in attrs): + role = AttrsToAccessPrivilege(attrs) + + if attrs['op'] == 'read': + self._attribute.readacl = role + elif attrs['op'] == 'write': + self._attribute.writeacl = role + else: + logging.error("Unknown access: %r" % attrs['op']) + + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'description': + return AttributeDescriptionHandler(self.context, self._attribute) + else: + return BaseHandler(self.context) + + def HandleContent(self, content: str): + # Content generally is the name EXCEPT if access controls + # exist, in which case `description` contains the name + content = content.strip() + if content and not self._attribute.definition.name: + self._attribute.definition.name = content + + def EndProcessing(self): + if self._attribute.definition.name is None: + raise Exception("Name for attribute was not parsed.") + + self._cluster.attributes.append(self._attribute) + + +class StructHandler(BaseHandler, IdlPostProcessor): + """ Handling /configurator/struct elements.""" + + def __init__(self, context: Context, attrs): + super().__init__(context) + + # if set, struct belongs to a specific cluster + self._cluster_codes = set() + self._struct = Struct(name=attrs['name'], fields=[]) + self._field_index = 0 + # The following are not set: + # - tag not set because not a request/response + # - code not set because not a response + + if attrs.get('isFabricScoped', "false").lower() == 'true': + self._struct.qualities |= StructQuality.FABRIC_SCOPED + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'item': + data_type = DataType( + name=attrs['type'] + ) + + if 'fieldId' in attrs: + self._field_index = ParseInt(attrs['fieldId']) + else: + # NOTE: code does NOT exist, so the number is incremental here + # this seems a defficiency in XML format. + self._field_index += 1 + + if 'length' in attrs: + data_type.max_length = ParseInt(attrs['length']) + + field = Field( + data_type=data_type, + code=self._field_index, + name=attrs['name'], + is_list=(attrs.get('array', 'false').lower() == 'true'), + ) + + if attrs.get('optional', "false").lower() == 'true': + field.qualities |= FieldQuality.OPTIONAL + + if attrs.get('isNullable', "false").lower() == 'true': + field.qualities |= FieldQuality.NULLABLE + + if attrs.get('isFabricSensitive', "false").lower() == 'true': + field.qualities |= FieldQuality.FABRIC_SENSITIVE + + self._struct.fields.append(field) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'cluster': + self._cluster_codes.add(ParseInt(attrs['code'])) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + else: + return BaseHandler(self.context) + + def FinalizeProcessing(self, idl: Idl): + # We have two choices of adding a struct: + # - inside a cluster if a code exists + # - inside top level if no codes were associated + if self._cluster_codes: + for code in self._cluster_codes: + found = False + for c in idl.clusters: + if c.code == code: + c.structs.append(self._struct) + found = True + + if not found: + logging.error('Enum %s could not find cluster (code %d/0x%X)' % + (self._struct.name, code, code)) + else: + idl.structs.append(self._struct) + + def EndProcessing(self): + self.context.AddIdlPostProcessor(self) + + +class EnumHandler(BaseHandler, IdlPostProcessor): + """ Handling /configurator/enum elements.""" + + def __init__(self, context: Context, attrs): + super().__init__(context) + self._cluster_code = None # if set, enum belongs to a specific cluster + self._enum = Enum(name=attrs['name'], base_type=attrs['type'], entries=[]) + + def GetNextProcessor(self, name, attrs): + if name.lower() == 'item': + self._enum.entries.append(ConstantEntry( + name=attrs['name'], + code=ParseInt(attrs['value']) + )) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'cluster': + if self._cluster_code is not None: + raise Exception('Multiple cluster codes for enum %s' % self._enum.name) + self._cluster_code = ParseInt(attrs['code']) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + else: + return BaseHandler(self.context) + + def FinalizeProcessing(self, idl: Idl): + # We have two choices of adding an enum: + # - inside a cluster if a code exists + # - inside top level if a code does not exist + + if self._cluster_code is None: + idl.enums.append(self._enum) + else: + found = False + for c in idl.clusters: + if c.code == self._cluster_code: + c.enums.append(self._enum) + found = True + + if not found: + logging.error('Enum %s could not find its cluster (code %d/0x%X)' % + (self._enum.name, self._cluster_code, self._cluster_code)) + + def EndProcessing(self): + self.context.AddIdlPostProcessor(self) + + +class BitmapHandler(BaseHandler): + """ Handling /configurator/bitmap elements.""" + + def __init__(self, context: Context, attrs): + super().__init__(context) + self._cluster_codes = set() + self._bitmap = Bitmap(name=attrs['name'], base_type=attrs['type'], entries=[]) + + def GetNextProcessor(self, name, attrs): + if name.lower() == 'cluster': + # Multiple clusters may be associated, like IasZoneStatus + self._cluster_codes.add(ParseInt(attrs['code'])) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'field': + self._bitmap.entries.append(ConstantEntry( + name=attrs['name'], + code=ParseInt(attrs['mask']) + )) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'description': + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + else: + return BaseHandler(self.context) + + def FinalizeProcessing(self, idl: Idl): + # We have two choices of adding an enum: + # - inside a cluster if a code exists + # - inside top level if a code does not exist + if not self._cluster_codes: + # Log only instead of critical, as not our XML is well formed. + # For example at the time of writing this, SwitchFeature in switch-cluster.xml + # did not have a code associated with it. + logging.error("Bitmap %r has no cluster codes" % self._bitmap) + return + + for code in self._cluster_codes: + found = False + for c in idl.clusters: + if c.code == code: + c.bitmaps.append(self._bitmap) + found = True + if not found: + logging.error('Bitmap %s could not find its cluster (code %d/0x%X)' % + (self._bitmap.name, code, code)) + + def EndProcessing(self): + self.context.AddIdlPostProcessor(self) + + +class CommandHandler(BaseHandler): + """Handles /configurator/cluster/command elements.""" + + def __init__(self, context: Context, cluster: Cluster, attrs): + super().__init__(context) + self._cluster = cluster + self._command = None + self._struct = Struct(name=attrs['name'], fields=[]) + self._field_index = 0 # commands DO NOT support field index it seems + + if attrs['source'].lower() == 'client': + self._struct.tag = StructTag.REQUEST + + name = attrs['name'] + + if name.endswith('Request'): + request_name = name + command_name = name[:-7] + else: + request_name = name+'Request' + command_name = name + + self._struct.name = request_name + + if 'response' in attrs: + response_name = attrs['response'] + else: + response_name = 'DefaultResponse' + + self._command = Command( + name=name, + code=ParseInt(attrs['code']), + input_param=request_name, + output_param=response_name, + ) + + if attrs.get('isFabricScoped', 'false') == 'true': + self._command.qualities |= CommandQuality.FABRIC_SCOPED + + if attrs.get('mustUseTimedInvoke', 'false') == 'true': + self._command.qualities |= CommandQuality.TIMED_INVOKE + + else: + self._struct.tag = StructTag.RESPONSE + self._struct.code = ParseInt(attrs['code']) + + def GetArgumentField(self, attrs): + data_type = DataType(name=attrs['type']) + + if 'length' in attrs: + data_type.max_length = ParseInt(attrs['length']) + + self._field_index += 1 + + field = Field( + data_type=data_type, + code=self._field_index, + name=attrs['name'], + is_list=(attrs.get('array', 'false') == 'true') + ) + + if attrs.get('optional', "false").lower() == 'true': + field.qualities |= FieldQuality.OPTIONAL + + if attrs.get('isNullable', "false").lower() == 'true': + field.qualities |= FieldQuality.NULLABLE + + return field + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'access': + if attrs['op'] != 'invoke': + raise Exception('Unknown access for %r' % self._struct) + + if self._command: + self._command.invokeacl = AttrsToAccessPrivilege(attrs) + else: + logging.warning("Ignored access role for reply %r" % self._struct) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'arg': + self._struct.fields.append(self.GetArgumentField(attrs)) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + elif name.lower() == 'description': + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + else: + return BaseHandler(self.context) + + def EndProcessing(self): + + if self._struct.fields: + self._cluster.structs.append(self._struct) + else: + # no input + self._command.input_param = None + + if self._command: + self._cluster.commands.append(self._command) + + +class ClusterGlobalAttributeHandler(BaseHandler): + """Handles /configurator/cluster/globalAttribute elements.""" + + def __init__(self, context: Context, cluster: Cluster, code: int): + super().__init__(context) + self._cluster = cluster + self._code = code + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'featurebit': + # It is uncler what featurebits mean. likely a bitmap should be created + # here, however only one such example exists currently: door-lock-cluster.xml + logging.info('Ignoring featurebit tag for global attribute 0x%X (%d)' % (self._code, self._code)) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + else: + return BaseHandler(self.context) + + def EndProcessing(self): + self._cluster.attributes.append(self.context.GetGlobalAttribute(self._code)) + + +class ClusterHandler(BaseHandler): + """Handles /configurator/cluster elements.""" + + def __init__(self, context: Context, idl: Idl): + super().__init__(context) + self._cluster = Cluster( + side=ClusterSide.CLIENT, + name=None, + code=None, + parse_meta=context.GetCurrentLocationMeta() + ) + self._idl = idl + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'code': + return ClusterCodeHandler(self.context, self._cluster) + elif name.lower() == 'name': + return ClusterNameHandler(self.context, self._cluster) + elif name.lower() == 'attribute': + return AttributeHandler(self.context, self._cluster, attrs) + elif name.lower() == 'event': + return EventHandler(self.context, self._cluster, attrs) + elif name.lower() == 'globalattribute': + # We ignore 'side' and 'value' since they do not seem useful + return ClusterGlobalAttributeHandler(self.context, self._cluster, ParseInt(attrs['code'])) + elif name.lower() == 'command': + return CommandHandler(self.context, self._cluster, attrs) + elif name.lower() in ['define', 'description', 'domain', 'tag', 'client', 'server']: + # NOTE: we COULD use client and server to create separate definitions + # of each, but the usefulness of this is unclear as the definitions are + # likely identical and matter has no concept of differences between the two + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + else: + return BaseHandler(self.context) + + def EndProcessing(self): + if self._cluster.name is None: + raise Exception("Missing cluster name") + elif self._cluster.code is None: + raise Exception("Missing cluster code") + + self._idl.clusters.append(self._cluster) + +# Cluster extensions have extra bits for existing clusters. Can only be loaded +# IF the underlying cluster exits + + +class ClusterExtensionHandler(ClusterHandler, IdlPostProcessor): + """Handling /configurator/clusterExtension elements.""" + + def __init__(self, context: Context, code: int): + # NOTE: IDL is set to NONE so that ClusterHandler cannot + # inadvertently change it (it will be invalid anyway) + super().__init__(context, None) + self._cluster_code = code + + def EndProcessing(self): + self.context.AddIdlPostProcessor(self) + + def FinalizeProcessing(self, idl: Idl): + found = False + for c in idl.clusters: + if c.code == self._cluster_code: + found = True + + # Append everything that can be appended + c.enums.extend(self._cluster.enums) + c.bitmaps.extend(self._cluster.bitmaps) + c.events.extend(self._cluster.events) + c.attributes.extend(self._cluster.attributes) + c.structs.extend(self._cluster.structs) + c.commands.extend(self._cluster.commands) + + if not found: + logging.error('Could not extend cluster 0x%X (%d): cluster not found' % + (self._cluster_code, self._cluster_code)) + + +class GlobalAttributeHandler(BaseHandler): + """Handling configurator/global/globalAttribute elements.""" + + def __init__(self, context: Context, attribute: Attribute): + super().__init__(context, handled=HandledDepth.SINGLE_TAG) + self._attribute = attribute + + def HandleContent(self, content: str): + # Content generally is the name EXCEPT if access controls + # exist, in which case `description` contains the name + # + # Global attributes do not currently have access controls, so this + # case is not handled here + content = content.strip() + if content and not self._attribute.definition.name: + self._attribute.definition.name = content + + def EndProcessing(self): + if self._attribute.definition.name is None: + raise Exception("Name for attribute was not parsed.") + + self.context.AddGlobalAttribute(self._attribute) + + +class GlobalHandler(BaseHandler): + """Handling configurator/global elements.""" + + def __init__(self, context: Context): + super().__init__(context, handled=HandledDepth.SINGLE_TAG) + + def GetNextProcessor(self, name, attrs): + if name.lower() == 'attribute': + if attrs['side'].lower() == 'client': + # We expect to also have 'server' equivalent, so ignore client + # side attributes + logging.debug('Ignoring global client-side attribute %s' % (attrs['code'])) + return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) + + return GlobalAttributeHandler(self.context, AttrsToAttribute(attrs)) + else: + return BaseHandler(self.context) + + +class ConfiguratorHandler(BaseHandler): + """ Handling /configurator elements.""" + + def __init__(self, context: Context, idl: Idl): + super().__init__(context, handled=HandledDepth.SINGLE_TAG) + self._idl = idl + + def GetNextProcessor(self, name: str, attrs): + if name.lower() == 'cluster': + return ClusterHandler(self.context, self._idl) + elif name.lower() == 'enum': + return EnumHandler(self.context, attrs) + elif name.lower() == 'struct': + return StructHandler(self.context, attrs) + elif name.lower() == 'bitmap': + return BitmapHandler(self.context, attrs) + elif name.lower() == 'domain': + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + elif name.lower() == 'clusterextension': + return ClusterExtensionHandler(self.context, ParseInt(attrs['code'])) + elif name.lower() == 'accesscontrol': + # These contain operation/role/modifier and generally only contain a + # description. These do not seem as useful to parse. + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + elif name.lower() == 'atomic': + # A list of types in 'chip-types' + # Generally does not seem useful - matches a type id to a description, size and some discrete/analog flags + # + # Could be eventually used as a preload of types into base types, however matter idl + # generator logic has hardcoded sizing as well. + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + elif name.lower() == 'devicetype': + # A list of device types in 'matter-devices.xml' + # Useful for conformance tests, but does not seem usable for serialization logic + return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) + elif name.lower() == 'global': + return GlobalHandler(self.context) + else: + return BaseHandler(self.context) diff --git a/scripts/idl/build/lib/zapxml/handlers/parsing.py b/scripts/idl/build/lib/zapxml/handlers/parsing.py new file mode 100644 index 00000000000000..f9315f3dab6875 --- /dev/null +++ b/scripts/idl/build/lib/zapxml/handlers/parsing.py @@ -0,0 +1,96 @@ +# Copyright (c) 2022 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. + +from idl.matter_idl_types import * + + +def ParseInt(value: str) -> int: + """Convert a string that is a known integer into an actual number. + + Supports decimal or hex values prefixed with '0x' + """ + if value.startswith('0x'): + return int(value[2:], 16) + else: + return int(value) + + +def AttrsToAccessPrivilege(attrs) -> AccessPrivilege: + """Given attributes of an '' tag, generate the underlying + access privilege by looking at the role/privilege attribute. + """ + + # XML seems to use both role and privilege to mean the same thing + # they are used interchangeably + if 'role' in attrs: + role = attrs['role'] + else: + role = attrs['privilege'] + + if role.lower() == 'view': + return AccessPrivilege.VIEW + elif role.lower() == 'operate': + return AccessPrivilege.OPERATE + elif role.lower() == 'manage': + return AccessPrivilege.MANAGE + elif role.lower() == 'administer': + return AccessPrivilege.ADMINISTER + else: + raise Exception('Unknown ACL role: %r' % role) + + +def AttrsToAttribute(attrs) -> Attribute: + """Given the attributes of an '' tag, generate the + underlying IDL Attribute dataclass. + """ + + if attrs['type'].lower() == 'array': + data_type = DataType(name=attrs['entryType']) + else: + data_type = DataType(name=attrs['type']) + + if 'length' in attrs: + data_type.max_length = ParseInt(attrs['length']) + + field = Field( + data_type=data_type, + code=ParseInt(attrs['code']), + name=None, + is_list=(attrs['type'].lower() == 'array') + ) + + attribute = Attribute(definition=field) + + if attrs.get('optional', "false").lower() == 'true': + attribute.definition.qualities |= FieldQuality.OPTIONAL + + if attrs.get('isNullable', "false").lower() == 'true': + attribute.definition.qualities |= FieldQuality.NULLABLE + + if attrs.get('readable', "true").lower() == 'true': + attribute.qualities |= AttributeQuality.READABLE + + if attrs.get('writable', "false").lower() == 'true': + attribute.qualities |= AttributeQuality.WRITABLE + + # TODO(#22937): NOSUBSCRIBE attribute tag is not available - could find no + # clear source to get this info. + + # NOTE: default values are also present in this XML, however generally IDL + # **DATA** definitions would not care about the defaults. The + # defaults should be used to initializ storage for devices, hence + # they are part of endpoint definition/composition. We are not doing + # that here, so defaults are ignored. + + return attribute diff --git a/scripts/idl/generators/registry.py b/scripts/idl/generators/registry.py new file mode 100644 index 00000000000000..8feeb2c48d1124 --- /dev/null +++ b/scripts/idl/generators/registry.py @@ -0,0 +1,59 @@ +# Copyright (c) 2022 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. + +import enum + +from idl.generators.java import JavaGenerator +from idl.generators.bridge import BridgeGenerator +from idl.generators.cpp.application import CppApplicationGenerator + + +class CodeGenerator(enum.Enum): + """ + Represents every generator type supported by codegen and maps + the simple enum value (user friendly and can be a command line input) + into underlying generators. + """ + JAVA = enum.auto() + BRIDGE = enum.auto() + CPP_APPLICATION = enum.auto() + + def Create(self, *args, **kargs): + if self == CodeGenerator.JAVA: + return JavaGenerator(*args, **kargs) + elif self == CodeGenerator.BRIDGE: + return BridgeGenerator(*args, **kargs) + elif self == CodeGenerator.CPP_APPLICATION: + return CppApplicationGenerator(*args, **kargs) + else: + raise NameError("Unknown code generator type") + + @staticmethod + def FromString(name): + global GENERATORS + + if name.lower() in GENERATORS: + return GENERATORS[name.lower()] + else: + raise NameError("Unknown code generator type '%s'" % name) + + +# Contains all known code generators along with a string +# to uniquely identify them when running command line tools or +# executing tests +GENERATORS = { + 'java': CodeGenerator.JAVA, + 'bridge': CodeGenerator.BRIDGE, + 'cpp-app': CodeGenerator.CPP_APPLICATION, +} diff --git a/scripts/run_codegen_targets.sh b/scripts/run_codegen_targets.sh index f3fc871371ecf0..1ff52e72b3a3e9 100755 --- a/scripts/run_codegen_targets.sh +++ b/scripts/run_codegen_targets.sh @@ -24,28 +24,28 @@ set -e OUT_DIR="$1" if [ ! -d "$OUT_DIR" ]; then - echo "Input directory '${OUT_DIR}' does not exist. " + echo "Input directory '$OUT_DIR' does not exist. " echo "USAGE: $0 " exit 1 fi # Code generation for build config files (via buildconfig_header) -for name in $(ninja -C "${OUT_DIR}" -t targets | grep -E '^gen_.*_buildconfig:' | sed 's/: .*//'); do - echo "Generating $name ..." - ninja -C "${OUT_DIR}" $name +for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E '^gen_.*_buildconfig:' | sed 's/: .*//')"; do + echo "Generating $name ..." + ninja -C "$OUT_DIR" "$name" done # Code generation (based on zap/matter) -for name in $(ninja -C "${OUT_DIR}" -t targets | grep -E '_codegen:' | sed 's/: .*//'); do - echo "Generating $name ..." - ninja -C "${OUT_DIR}" $name +for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E '_codegen:' | sed 's/: .*//')"; do + echo "Generating $name ..." + ninja -C "$OUT_DIR" "$name" done # Linus targets: dbus generate hdeaders -for name in $(ninja -C "${OUT_DIR}" -t targets | grep -E 'dbus.*codegen:' | sed 's/: .*//'); do - echo "Generating $name ..." - ninja -C "${OUT_DIR}" $name +for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E 'dbus.*codegen:' | sed 's/: .*//')"; do + echo "Generating $name ..." + ninja -C "$OUT_DIR" "$name" done # ASN1 has no specific rule -ninja -C "${OUT_DIR}" gen_asn1oid +ninja -C "$OUT_DIR" gen_asn1oid From 94722a753e63823d9648c76f5cedf66ca2ad281d Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 12:36:15 -0400 Subject: [PATCH 10/23] Undo undesired file creation --- scripts/idl/build/lib/generators/__init__.py | 171 ----- .../build/lib/generators/bridge/__init__.py | 193 ------ .../idl/build/lib/generators/cpp/__init__.py | 0 .../generators/cpp/application/__init__.py | 61 -- scripts/idl/build/lib/generators/filters.py | 34 - .../idl/build/lib/generators/java/__init__.py | 394 ----------- scripts/idl/build/lib/generators/registry.py | 58 -- scripts/idl/build/lib/generators/types.py | 407 ------------ scripts/idl/build/lib/lint/__init__.py | 15 - .../idl/build/lib/lint/lint_rules_parser.py | 309 --------- scripts/idl/build/lib/lint/types.py | 259 -------- scripts/idl/build/lib/zapxml/__init__.py | 118 ---- .../idl/build/lib/zapxml/handlers/__init__.py | 36 - scripts/idl/build/lib/zapxml/handlers/base.py | 62 -- .../idl/build/lib/zapxml/handlers/context.py | 124 ---- .../idl/build/lib/zapxml/handlers/handlers.py | 614 ------------------ .../idl/build/lib/zapxml/handlers/parsing.py | 96 --- 17 files changed, 2951 deletions(-) delete mode 100644 scripts/idl/build/lib/generators/__init__.py delete mode 100644 scripts/idl/build/lib/generators/bridge/__init__.py delete mode 100644 scripts/idl/build/lib/generators/cpp/__init__.py delete mode 100644 scripts/idl/build/lib/generators/cpp/application/__init__.py delete mode 100644 scripts/idl/build/lib/generators/filters.py delete mode 100644 scripts/idl/build/lib/generators/java/__init__.py delete mode 100644 scripts/idl/build/lib/generators/registry.py delete mode 100644 scripts/idl/build/lib/generators/types.py delete mode 100644 scripts/idl/build/lib/lint/__init__.py delete mode 100644 scripts/idl/build/lib/lint/lint_rules_parser.py delete mode 100644 scripts/idl/build/lib/lint/types.py delete mode 100644 scripts/idl/build/lib/zapxml/__init__.py delete mode 100644 scripts/idl/build/lib/zapxml/handlers/__init__.py delete mode 100644 scripts/idl/build/lib/zapxml/handlers/base.py delete mode 100644 scripts/idl/build/lib/zapxml/handlers/context.py delete mode 100644 scripts/idl/build/lib/zapxml/handlers/handlers.py delete mode 100644 scripts/idl/build/lib/zapxml/handlers/parsing.py diff --git a/scripts/idl/build/lib/generators/__init__.py b/scripts/idl/build/lib/generators/__init__.py deleted file mode 100644 index 1adbb6d4d0071b..00000000000000 --- a/scripts/idl/build/lib/generators/__init__.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2022 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. - -import os -import logging -import jinja2 - -from typing import Dict -from idl.matter_idl_types import Idl - -from .filters import RegisterCommonFilters - - -class GeneratorStorage: - """ - Handles file operations for generator output. Specifically can create - required files for output. - - Is overriden for unit tests. - """ - - def __init__(self): - self._generated_paths = set() - - @property - def generated_paths(self): - return self._generated_paths - - def report_output_file(self, relative_path: str): - self._generated_paths.add(relative_path) - - def get_existing_data(self, relative_path: str): - """Gets the existing data at the given path. - If such data does not exist, will return None. - """ - raise NotImplementedError() - - def write_new_data(self, relative_path: str, content: str): - """Write new data to the given path.""" - raise NotImplementedError() - - -class FileSystemGeneratorStorage(GeneratorStorage): - """ - A storage generator which will physically write files to disk into - a given output folder. - """ - - def __init__(self, output_dir: str): - super().__init__() - self.output_dir = output_dir - - def get_existing_data(self, relative_path: str): - """Gets the existing data at the given path. - If such data does not exist, will return None. - """ - target = os.path.join(self.output_dir, relative_path) - - if not os.path.exists(target): - return None - - logging.info("Checking existing data in %s" % target) - with open(target, 'rt') as existing: - return existing.read() - - def write_new_data(self, relative_path: str, content: str): - """Write new data to the given path.""" - - target = os.path.join(self.output_dir, relative_path) - target_dir = os.path.dirname(target) - if not os.path.exists(target_dir): - logging.info("Creating output directory: %s" % target_dir) - os.makedirs(target_dir) - - logging.info("Writing new data to: %s" % target) - with open(target, "wt") as out: - out.write(content) - - -class CodeGenerator: - """ - Defines the general interface for things that can generate code output. - - A CodeGenerator takes a AST as input (a `Idl` type) and generates files - as output (like java/cpp/mm/other). - - Its public interface surface is reasonably small: - 'storage' init argument specifies where generated code goes - 'idl' is the input AST to generate - 'render' will perform a rendering of all files. - - As special optimizations, CodeGenerators generally will try to read - existing data and will not re-write content if not changed (so that - write time of files do not change and rebuilds are not triggered). - """ - - def __init__(self, storage: GeneratorStorage, idl: Idl): - """ - A code generator will render a parsed IDL (a AST) into a given storage. - """ - self.storage = storage - self.idl = idl - self.jinja_env = jinja2.Environment( - loader=jinja2.FileSystemLoader(searchpath=os.path.dirname(__file__)), - keep_trailing_newline=True) - self.dry_run = False - - RegisterCommonFilters(self.jinja_env.filters) - - def render(self, dry_run=False): - """ - Renders all required files given the idl contained in the code generator. - Reset the list of generated outputs. - - Args: - dry_run: if true, outputs are not actually written to disk. - if false, outputs are actually written to disk. - """ - self.dry_run = dry_run - self.internal_render_all() - - def internal_render_all(self): - """This method is to be implemented by subclasses to run all generation - as needed. - """ - raise NotImplementedError("Method should be implemented by subclasses") - - def internal_render_one_output(self, template_path: str, output_file_name: str, vars: Dict): - """ - Method to be called by subclasses to mark that a template is to be generated. - - File will either actually do a jinja2 generation or just log things - if dry-run was requested during `render`. - - NOTE: to make this method suitable for rebuilds, this file will NOT alter - the timestamp of the output file if the file content would not - change (i.e. no write will be invoked in that case.) - - Args: - template_path - the path to the template to be loaded for file generation. - Template MUST be a jinja2 template. - output_file_name - File name that the template is to be generated to. - vars - variables used for template generation - """ - logging.info("File to be generated: %s" % output_file_name) - if self.dry_run: - return - - rendered = self.jinja_env.get_template(template_path).render(vars) - - # Report regardless if it has changed or not. This is because even if - # files are unchanged, validation of what the correct output is should - # still be done. - self.storage.report_output_file(output_file_name) - - if rendered == self.storage.get_existing_data(output_file_name): - logging.info("File content not changed") - else: - self.storage.write_new_data(output_file_name, rendered) diff --git a/scripts/idl/build/lib/generators/bridge/__init__.py b/scripts/idl/build/lib/generators/bridge/__init__.py deleted file mode 100644 index 5d0bace9faf431..00000000000000 --- a/scripts/idl/build/lib/generators/bridge/__init__.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2022 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. - -import enum -import logging -import re - -from idl.generators import CodeGenerator, GeneratorStorage -from idl.matter_idl_types import (Idl, Field, Attribute, Cluster) -from idl import matter_idl_types -from idl.generators.types import (ParseDataType, BasicString, BasicInteger, FundamentalType, - IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext) -from typing import Union, List, Set - - -def camel_to_const(s): - return re.sub("([a-z])([A-Z])", lambda y: y.group(1) + "_" + y.group(2), s).upper() - - -def create_lookup_context(idl: Idl, cluster: Cluster) -> TypeLookupContext: - """ - A filter to mark a lookup context to be within a specific cluster. - - This is used to specify how structure/enum/other names are looked up. - Generally one looks up within the specific cluster then if cluster does - not contain a definition, we loop at global namespacing. - """ - return TypeLookupContext(idl, cluster) - - -def get_field_info(definition: Field, cluster: Cluster, idl: Idl): - context = create_lookup_context(idl, cluster) - actual = ParseDataType(definition.data_type, context) - - orig = actual - is_enum = type(actual) == IdlEnumType - - if type(actual) == IdlEnumType: - actual = actual.base_type - elif type(actual) == IdlBitmapType: - actual = actual.base_type - - if type(actual) == BasicString: - return 'OctetString', 'char', actual.max_length, \ - 'ZCL_%s_ATTRIBUTE_TYPE' % orig.idl_name.upper() - - if type(actual) == BasicInteger: - name = orig.idl_name.upper() - if is_enum: - name = actual.idl_name.upper() - ty = "int%d_t" % actual.power_of_two_bits - if not actual.is_signed: - ty = "u" + ty - return "", ty, actual.byte_count, "ZCL_%s_ATTRIBUTE_TYPE" % name - if type(actual) == FundamentalType: - if actual == FundamentalType.BOOL: - return "", "bool", 1, "ZCL_BOOLEAN_ATTRIBUTE_TYPE" - if actual == FundamentalType.FLOAT: - return "", "float", 4, "ZCL_SINGLE_ATTRIBUTE_TYPE" - if actual == FundamentalType.DOUBLE: - return "", "double", 8, "ZCL_DOUBLE_ATTRIBUTE_TYPE" - logging.warn('Unknown fundamental type: %r' % actual) - return None - if type(actual) == IdlType: - return '', actual.idl_name, 'sizeof(%s)' % actual.idl_name, \ - 'ZCL_STRUCT_ATTRIBUTE_TYPE' - logging.warn('Unknown type: %r' % actual) - return None - - -def get_raw_size_and_type(attr: Attribute, cluster: Cluster, idl: Idl): - container, cType, size, matterType = get_field_info(attr.definition, cluster, idl) - if attr.definition.is_list: - return 'ZCL_ARRAY_ATTRIBUTE_TYPE, {}'.format(size) - return '{}, {}'.format(matterType, size) - - -def get_field_type(definition: Field, cluster: Cluster, idl: Idl): - container, cType, size, matterType = get_field_info(definition, cluster, idl) - if container == 'OctetString': - return 'std::string' - if definition.is_list: - cType = 'std::vector<{}>'.format(cType) - if definition.is_nullable: - cType = '::chip::app::DataModel::Nullable<{}>'.format(cType) - if definition.is_nullable: - cType = '::chip::Optional<{}>'.format(cType) - return cType - - -def get_attr_type(attr: Attribute, cluster: Cluster, idl: Idl): - return get_field_type(attr.definition, cluster, idl) - - -def get_attr_init(attr: Attribute, cluster: Cluster, idl: Idl): - if attr.definition.name == 'clusterRevision': - return ', ZCL_' + camel_to_const(cluster.name) + '_CLUSTER_REVISION' - return '' - - -def get_attr_mask(attr: Attribute, cluster: Cluster, idl: Idl): - masks = [] - if attr.is_writable: - masks.append('ATTRIBUTE_MASK_WRITABLE') - if masks: - return ' | '.join(masks) - return '0' - - -def get_dynamic_endpoint(idl: Idl): - for ep in idl.endpoints: - if ep.number == 2: - return ep - - -def is_dynamic_cluster(cluster: Cluster, idl: Idl): - ep = get_dynamic_endpoint(idl) - if not ep: - return True - for c in ep.server_clusters: - if cluster.name == c.name: - return True - return False - - -class BridgeGenerator(CodeGenerator): - """ - Generation of bridge cpp code for matter. - """ - - def __init__(self, storage: GeneratorStorage, idl: Idl): - """ - Inintialization is specific for cpp generation and will add - filters as required by the cpp .jinja templates to function. - """ - super().__init__(storage, idl) - - self.jinja_env.filters['getType'] = get_attr_type - self.jinja_env.filters['getRawSizeAndType'] = get_raw_size_and_type - self.jinja_env.filters['getField'] = get_field_type - self.jinja_env.filters['getMask'] = get_attr_mask - self.jinja_env.filters['getInit'] = get_attr_init - self.jinja_env.filters['dynamicCluster'] = is_dynamic_cluster - # constcase will transform ID to I_D which is not what we want - # instead make the requirement a transition from lower to upper - self.jinja_env.filters['cameltoconst'] = camel_to_const - - def internal_render_all(self): - """ - Renders C++ - """ - for cluster in self.idl.clusters: - if not is_dynamic_cluster(cluster, self.idl): - continue - - self.internal_render_one_output( - template_path="bridge/BridgeClustersCpp.jinja", - output_file_name="bridge/%s.h" % cluster.name, - vars={ - 'cluster': cluster, - 'idl': self.idl, - } - ) - - self.internal_render_one_output( - template_path="bridge/BridgeClustersCommon.jinja", - output_file_name="bridge/BridgeClustersImpl.h", - vars={ - 'clusters': self.idl.clusters, - 'idl': self.idl, - } - ) - - self.internal_render_one_output( - template_path="bridge/BridgeClustersGlobalStructs.jinja", - output_file_name="bridge/BridgeGlobalStructs.h", - vars={ - 'idl': self.idl, - 'structs': self.idl.structs, - } - ) diff --git a/scripts/idl/build/lib/generators/cpp/__init__.py b/scripts/idl/build/lib/generators/cpp/__init__.py deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/scripts/idl/build/lib/generators/cpp/application/__init__.py b/scripts/idl/build/lib/generators/cpp/application/__init__.py deleted file mode 100644 index 40a4bb26b0b34b..00000000000000 --- a/scripts/idl/build/lib/generators/cpp/application/__init__.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (c) 2022 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. - -from idl.generators import CodeGenerator, GeneratorStorage -from idl.matter_idl_types import Idl, ClusterSide, Field, Attribute, Cluster, FieldQuality, Command, DataType -from idl import matter_idl_types -from idl.generators.types import ParseDataType, BasicString, BasicInteger, FundamentalType, IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext -from typing import Union, List, Set -from stringcase import capitalcase - -import enum -import logging - - -def clusterSideString(side: ClusterSide): - if side == ClusterSide.CLIENT: - return "Client" - elif side == ClusterSide.SERVER: - return "Server" - else: - raise Exception("Unknown cluster side %r" % (side, )) - - -class CppApplicationGenerator(CodeGenerator): - """ - Generation of cpp code for application implementation for matter. - """ - - def __init__(self, storage: GeneratorStorage, idl: Idl): - """ - Inintialization is specific for java generation and will add - filters as required by the java .jinja templates to function. - """ - super().__init__(storage, idl) - - self.jinja_env.filters['clusterSideString'] = clusterSideString - - def internal_render_all(self): - """ - Renders the cpp and header files required for applications - """ - - # Header containing a macro to initialize all cluster plugins - self.internal_render_one_output( - template_path="cpp/application/PluginApplicationCallbacksHeader.jinja", - output_file_name="app/PluginApplicationCallbacks.h", - vars={ - 'clusters': self.idl.clusters, - } - ) diff --git a/scripts/idl/build/lib/generators/filters.py b/scripts/idl/build/lib/generators/filters.py deleted file mode 100644 index 13e84d37233be1..00000000000000 --- a/scripts/idl/build/lib/generators/filters.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2022 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. - -import logging -import stringcase - - -def RegisterCommonFilters(filtermap): - """ - Register filters that are NOT considered platform-generator specific. - - Codegen often needs standardized names, like "method names are CamelCase" - or "command names need-to-be-spinal-case" so these filters are often - generally registered on all generators. - """ - - # General casing for output naming - filtermap['camelcase'] = stringcase.camelcase - filtermap['capitalcase'] = stringcase.capitalcase - filtermap['constcase'] = stringcase.constcase - filtermap['pascalcase'] = stringcase.pascalcase - filtermap['snakecase'] = stringcase.snakecase - filtermap['spinalcase'] = stringcase.spinalcase diff --git a/scripts/idl/build/lib/generators/java/__init__.py b/scripts/idl/build/lib/generators/java/__init__.py deleted file mode 100644 index 6f18e9629304e5..00000000000000 --- a/scripts/idl/build/lib/generators/java/__init__.py +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2022 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. - -from idl.generators import CodeGenerator, GeneratorStorage -from idl.matter_idl_types import Idl, ClusterSide, Field, Attribute, Cluster, FieldQuality, Command, DataType -from idl import matter_idl_types -from idl.generators.types import ParseDataType, BasicString, BasicInteger, FundamentalType, IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext -from typing import Union, List, Set -from stringcase import capitalcase - -import enum -import logging - - -def FieldToGlobalName(field: Field, context: TypeLookupContext) -> Union[str, None]: - """Global names are used for generic callbacks shared across - all clusters (e.g. for bool/float/uint32 and similar) - """ - if field.is_list: - return None # lists are always specific per cluster - - if FieldQuality.NULLABLE & field.qualities: - return None - - if FieldQuality.OPTIONAL & field.qualities: - return None - - actual = ParseDataType(field.data_type, context) - if type(actual) == IdlEnumType: - actual = actual.base_type - elif type(actual) == IdlBitmapType: - actual = actual.base_type - - if type(actual) == BasicString: - if actual.is_binary: - return 'OctetString' - else: - return 'CharString' - elif type(actual) == BasicInteger: - # TODO: unclear why this, but tries to match zap: - if actual.idl_name.lower() in ['vendor_id', 'fabric_idx']: - return None - - if actual.is_signed: - return "Int{}s".format(actual.power_of_two_bits) - else: - return "Int{}u".format(actual.power_of_two_bits) - elif type(actual) == FundamentalType: - if actual == FundamentalType.BOOL: - return 'Boolean' - elif actual == FundamentalType.FLOAT: - return 'Float' - elif actual == FundamentalType.DOUBLE: - return 'Double' - else: - logging.warn('Unknown fundamental type: %r' % actual) - - return None - - -def CallbackName(attr: Attribute, cluster: Cluster, context: TypeLookupContext) -> str: - """ - Figure out what callback name to use when a variable requires a read callback. - - These are split into native types, like Boolean/Float/Double/CharString, where - one callback type can support anything. - - For specific types (e.g. A struct) codegen will generate its own callback name - specific to that type. - """ - global_name = FieldToGlobalName(attr.definition, context) - - if global_name: - return 'CHIP{}AttributeCallback'.format(capitalcase(global_name)) - - return 'CHIP{}{}AttributeCallback'.format( - capitalcase(cluster.name), - capitalcase(attr.definition.name) - ) - - -def CommandCallbackName(command: Command, cluster: Cluster): - if command.output_param.lower() == 'defaultsuccess': - return 'DefaultSuccess' - return '{}Cluster{}'.format(cluster.name, command.output_param) - - -def attributesWithSupportedCallback(attrs, context: TypeLookupContext): - for attr in attrs: - # Attributes will be generated for all types - # except non-list structures - if not attr.definition.is_list: - underlying = ParseDataType(attr.definition.data_type, context) - if type(underlying) == IdlType: - continue - - yield attr - - -def NamedFilter(choices: List, name: str): - for choice in choices: - if choice.name == name: - return choice - raise Exception("No item named %s in %r" % (name, choices)) - - -def ToBoxedJavaType(field: Field): - if field.is_optional: - return 'jobject' - elif field.data_type.name.lower() in ['octet_string', 'long_octet_string']: - return 'jbyteArray' - elif field.data_type.name.lower() in ['char_string', 'long_char_string']: - return 'jstring' - else: - return 'jobject' - - -def LowercaseFirst(name: str) -> str: - """ - Change the first letter of a string to lowercase as long as the 2nd - letter is not uppercase. - - Can be used for variable naming, eg insider structures, codegen will - call things "Foo foo" (notice variable name is lowercase). - """ - if len(name) > 1 and name[1].lower() != name[1]: - # Odd workaround: PAKEVerifier should not become pAKEVerifier - return name - return name[0].lower() + name[1:] - - -class EncodableValueAttr(enum.Enum): - LIST = enum.auto() - NULLABLE = enum.auto() - OPTIONAL = enum.auto() - - -class EncodableValue: - """ - Contains helpers for encoding values, specifically lookups - for optionality, lists and recursive data type lookups within - the IDL and cluster - - Intended use is to be able to: - - derive types (see clone and without_* methods) such that codegen - can implement things like 'if x != null { treat non-null x}' - - Java specific conversions: get boxed types and JNI string signautes - for the underlying types. - """ - - def __init__(self, context: TypeLookupContext, data_type: DataType, attrs: Set[EncodableValueAttr]): - self.context = context - self.data_type = data_type - self.attrs = attrs - - @property - def is_nullable(self): - return EncodableValueAttr.NULLABLE in self.attrs - - @property - def is_optional(self): - return EncodableValueAttr.OPTIONAL in self.attrs - - @property - def is_list(self): - return EncodableValueAttr.LIST in self.attrs - - @property - def is_octet_string(self): - return self.data_type.name.lower() in ['octet_string', 'long_octet_string'] - - @property - def is_char_string(self): - return self.data_type.name.lower() in ['char_string', 'long_char_string'] - - @property - def is_struct(self): - return self.context.is_struct_type(self.data_type.name) - - @property - def is_enum(self): - return self.context.is_enum_type(self.data_type.name) - - @property - def is_bitmap(self): - self.context.is_bitmap_type(self.data_type.name) - - def clone(self): - return EncodableValue(self.context, self.data_type, self.attrs) - - def without_nullable(self): - result = self.clone() - result.attrs.remove(EncodableValueAttr.NULLABLE) - return result - - def without_optional(self): - result = self.clone() - result.attrs.remove(EncodableValueAttr.OPTIONAL) - return result - - def without_list(self): - result = self.clone() - result.attrs.remove(EncodableValueAttr.LIST) - return result - - def get_underlying_struct(self): - s = self.context.find_struct(self.data_type.name) - if not s: - raise Exception("Struct %s not found" % self.data_type.name) - return s - - def get_underlying_enum(self): - e = self.context.find_enum(self.data_type.name) - if not e: - raise Exception("Enum %s not found" % self.data_type.name) - return e - - @property - def boxed_java_type(self): - t = ParseDataType(self.data_type, self.context) - - if type(t) == FundamentalType: - if t == FundamentalType.BOOL: - return "Boolean" - elif t == FundamentalType.FLOAT: - return "Float" - elif t == FundamentalType.DOUBLE: - return "Double" - else: - raise Error("Unknown fundamental type") - elif type(t) == BasicInteger: - if t.byte_count >= 4: - return "Long" - else: - return "Integer" - elif type(t) == BasicString: - if t.is_binary: - return "byte[]" - else: - return "String" - elif type(t) == IdlEnumType: - return "Integer" - elif type(t) == IdlBitmapType: - return "Integer" - else: - return "Object" - - @property - def boxed_java_signature(self): - # Optional takes precedence over list - Optional compiles down to just java.util.Optional. - if self.is_optional: - return "Ljava/util/Optional;" - - if self.is_list: - return "Ljava/util/ArrayList;" - - t = ParseDataType(self.data_type, self.context) - - if type(t) == FundamentalType: - if t == FundamentalType.BOOL: - return "Ljava/lang/Boolean;" - elif t == FundamentalType.FLOAT: - return "Ljava/lang/Float;" - elif t == FundamentalType.DOUBLE: - return "Ljava/lang/Double;" - else: - raise Error("Unknown fundamental type") - elif type(t) == BasicInteger: - if t.byte_count >= 4: - return "Ljava/lang/Long;" - else: - return "Ljava/lang/Integer;" - elif type(t) == BasicString: - if t.is_binary: - return "[B" - else: - return "Ljava/lang/String;" - elif type(t) == IdlEnumType: - return "Ljava/lang/Integer;" - elif type(t) == IdlBitmapType: - return "Ljava/lang/Integer;" - else: - return "Lchip/devicecontroller/ChipStructs${}Cluster{};".format(self.context.cluster.name, self.data_type.name) - - -def EncodableValueFrom(field: Field, context: TypeLookupContext) -> EncodableValue: - """ - Filter to convert a standard field to an EncodableValue. - - This converts the AST information (field name/info + lookup context) into - a java-generator specific wrapper that can be manipulated and - queried for properties like java native name or JNI string signature. - """ - attrs = set() - - if field.is_optional: - attrs.add(EncodableValueAttr.OPTIONAL) - - if field.is_nullable: - attrs.add(EncodableValueAttr.NULLABLE) - - if field.is_list: - attrs.add(EncodableValueAttr.LIST) - - return EncodableValue(context, field.data_type, attrs) - - -def CreateLookupContext(idl: Idl, cluster: Cluster) -> TypeLookupContext: - """ - A filter to mark a lookup context to be within a specific cluster. - - This is used to specify how structure/enum/other names are looked up. - Generally one looks up within the specific cluster then if cluster does - not contain a definition, we loop at global namespacing. - """ - return TypeLookupContext(idl, cluster) - - -def CanGenerateSubscribe(attr: Attribute, lookup: TypeLookupContext) -> bool: - """ - Filter that returns if an attribute can be subscribed to. - - Uses the given attribute and the lookupContext to figure out the attribute - type. - """ - # For backwards compatibility, we do not subscribe to structs - # (although list of structs is ok ...) - if attr.definition.is_list: - return True - - return not lookup.is_struct_type(attr.definition.data_type.name) - - -class JavaGenerator(CodeGenerator): - """ - Generation of java code for matter. - """ - - def __init__(self, storage: GeneratorStorage, idl: Idl): - """ - Inintialization is specific for java generation and will add - filters as required by the java .jinja templates to function. - """ - super().__init__(storage, idl) - - self.jinja_env.filters['attributesWithCallback'] = attributesWithSupportedCallback - self.jinja_env.filters['callbackName'] = CallbackName - self.jinja_env.filters['commandCallbackName'] = CommandCallbackName - self.jinja_env.filters['named'] = NamedFilter - self.jinja_env.filters['toBoxedJavaType'] = ToBoxedJavaType - self.jinja_env.filters['lowercaseFirst'] = LowercaseFirst - self.jinja_env.filters['asEncodable'] = EncodableValueFrom - self.jinja_env.filters['createLookupContext'] = CreateLookupContext - self.jinja_env.filters['canGenerateSubscribe'] = CanGenerateSubscribe - - def internal_render_all(self): - """ - Renders .CPP files required for JNI support. - """ - # Every cluster has its own impl, to avoid - # very large compilations (running out of RAM) - for cluster in self.idl.clusters: - if cluster.side != ClusterSide.CLIENT: - continue - - self.internal_render_one_output( - template_path="java/ChipClustersRead.jinja", - output_file_name="jni/%sClient-ReadImpl.cpp" % cluster.name, - vars={ - 'cluster': cluster, - 'typeLookup': TypeLookupContext(self.idl, cluster), - } - ) - - self.internal_render_one_output( - template_path="java/ChipClustersCpp.jinja", - output_file_name="jni/%sClient-InvokeSubscribeImpl.cpp" % cluster.name, - vars={ - 'cluster': cluster, - 'typeLookup': TypeLookupContext(self.idl, cluster), - } - ) diff --git a/scripts/idl/build/lib/generators/registry.py b/scripts/idl/build/lib/generators/registry.py deleted file mode 100644 index 815bc8d58a5386..00000000000000 --- a/scripts/idl/build/lib/generators/registry.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2022 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. - -import enum - -from idl.generators.java import JavaGenerator -from idl.generators.bridge import BridgeGenerator -from idl.generators.cpp.application import CppApplicationGenerator - - -class CodeGenerator(enum.Enum): - """ - Represents every generator type supported by codegen and maps - the simple enum value (user friendly and can be a command line input) - into underlying generators. - """ - JAVA = enum.auto() - BRIDGE = enum.auto() - CPP_APPLICATION = enum.auto() - - def Create(self, *args, **kargs): - if self == CodeGenerator.JAVA: - return JavaGenerator(*args, **kargs) - elif self == CodeGenerator.BRIDGE: - return BridgeGenerator(*args, **kargs) - elif self == CodeGenerator.CPP_APPLICATION: - return CppApplicationGenerator(*args, **kargs) - else: - raise NameError("Unknown code generator type") - - @staticmethod - def FromString(name): - global GENERATORS - - if name.lower() in GENERATORS: - return GENERATORS[name.lower()] - else: - raise NameError("Unknown code generator type '%s'" % name) - -# Contains all known code generators along with a string -# to uniquely identify them when running command line tools or -# executing tests -GENERATORS = { - 'java': CodeGenerator.JAVA, - 'bridge': CodeGenerator.BRIDGE, - 'cpp-app': CodeGenerator.CPP_APPLICATION, -} diff --git a/scripts/idl/build/lib/generators/types.py b/scripts/idl/build/lib/generators/types.py deleted file mode 100644 index b6f216802de0d8..00000000000000 --- a/scripts/idl/build/lib/generators/types.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright (c) 2022 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. - -import logging -import enum - -from idl.matter_idl_types import DataType -from idl import matter_idl_types # to explicitly say 'Enum' - -from typing import Union, List, Optional -from dataclasses import dataclass - - -def ToPowerOfTwo(bits: int) -> int: - """ - Given a number, find the next power of two that is >= to the given value. - - Can be used to figure out a variable size given non-standard bit sizes in - matter: eg. a int24 can be stored in an int32, so ToPortOfTwo(24) == 32. - - """ - # probably bit manipulation can be faster, but this should be ok as well - result = 1 - while result < bits: - result = result * 2 - return result - - -@dataclass -class BasicInteger: - """ - Represents something that is stored as a basic integer. - """ - idl_name: str - byte_count: int # NOTE: may NOT be a power of 2 for odd sized integers - is_signed: bool - - @property - def bits(self): - return self.byte_count * 8 - - @property - def power_of_two_bits(self): - return ToPowerOfTwo(self.bits) - - -@dataclass -class BasicString: - """ - Represents either a string or a binary string (blob). - """ - idl_name: str - is_binary: bool - max_length: Union[int, None] = None - - -class FundamentalType(enum.Enum): - """ - Native types, generally available across C++/ObjC/Java/python/other. - """ - BOOL = enum.auto() - FLOAT = enum.auto() - DOUBLE = enum.auto() - - @property - def idl_name(self): - if self == FundamentalType.BOOL: - return "bool" - elif self == FundamentalType.FLOAT: - return "single" - elif self == FundamentalType.DOUBLE: - return "double" - else: - raise Error("Type not handled: %r" % self) - - @property - def byte_count(self): - if self == FundamentalType.BOOL: - return 1 - elif self == FundamentalType.FLOAT: - return 4 - elif self == FundamentalType.DOUBLE: - return 8 - else: - raise Error("Type not handled: %r" % self) - - @property - def bits(self): - return self.byte_count * 8 - - -@dataclass -class IdlEnumType: - """ - An enumeration type. Enumerations are constants with an underlying - base type that is an interger. - """ - idl_name: str - base_type: BasicInteger - - @property - def byte_count(self): - return base_type.byte_count() - - @property - def bits(self): - return base_type.bits() - - -@dataclass -class IdlBitmapType: - """ - Bitmaps mark that each bit (or a subset of said bits) have a meaning. - - Examples include "feature maps" where bits represent feature available or not. - """ - idl_name: str - base_type: BasicInteger - - @property - def byte_count(self): - return base_type.byte_count() - - @property - def bits(self): - return base_type.bits() - - -class IdlItemType(enum.Enum): - UNKNOWN = enum.auto() - STRUCT = enum.auto() - - -@dataclass -class IdlType: - """ - A type defined within the IDL. - - IDLs would generally only define structures as all other types are - described in other things like enums/bitmaps/basic types etc. - - However since IDL parsing is not yet codegen just syntactically, we allow - the option to have a type that is marked 'unknown' (likely invalid/never - defined). - """ - idl_name: str - item_type: IdlItemType - - @property - def is_struct(self) -> bool: - return self.item_type == IdlItemType.STRUCT - - -# Data types, held by ZAP in chip-types.xml and generally by the spec. -__CHIP_SIZED_TYPES__ = { - "bitmap16": BasicInteger(idl_name="bitmap16", byte_count=2, is_signed=False), - "bitmap24": BasicInteger(idl_name="bitmap24", byte_count=3, is_signed=False), - "bitmap32": BasicInteger(idl_name="bitmap32", byte_count=4, is_signed=False), - "bitmap64": BasicInteger(idl_name="bitmap64", byte_count=8, is_signed=False), - "bitmap8": BasicInteger(idl_name="bitmap8", byte_count=1, is_signed=False), - "enum16": BasicInteger(idl_name="enum16", byte_count=2, is_signed=False), - "enum32": BasicInteger(idl_name="enum32", byte_count=4, is_signed=False), - "enum8": BasicInteger(idl_name="enum8", byte_count=1, is_signed=False), - "int16s": BasicInteger(idl_name="int16s", byte_count=2, is_signed=True), - "int16u": BasicInteger(idl_name="int16u", byte_count=2, is_signed=False), - "int24s": BasicInteger(idl_name="int24s", byte_count=3, is_signed=True), - "int24u": BasicInteger(idl_name="int24u", byte_count=3, is_signed=False), - "int32s": BasicInteger(idl_name="int32s", byte_count=4, is_signed=True), - "int32u": BasicInteger(idl_name="int32u", byte_count=4, is_signed=False), - "int40s": BasicInteger(idl_name="int40s", byte_count=5, is_signed=True), - "int40u": BasicInteger(idl_name="int40u", byte_count=5, is_signed=False), - "int48s": BasicInteger(idl_name="int48s", byte_count=6, is_signed=True), - "int48u": BasicInteger(idl_name="int48u", byte_count=6, is_signed=False), - "int56s": BasicInteger(idl_name="int56s", byte_count=7, is_signed=True), - "int56u": BasicInteger(idl_name="int56u", byte_count=7, is_signed=False), - "int64s": BasicInteger(idl_name="int64s", byte_count=8, is_signed=True), - "int64u": BasicInteger(idl_name="int64u", byte_count=8, is_signed=False), - "int8s": BasicInteger(idl_name="int8s", byte_count=1, is_signed=True), - "int8u": BasicInteger(idl_name="int8u", byte_count=1, is_signed=False), - # Derived types - # Specification describes them in section '7.18.2. Derived Data Types' - "action_id": BasicInteger(idl_name="action_id", byte_count=1, is_signed=False), - "attrib_id": BasicInteger(idl_name="attrib_id", byte_count=4, is_signed=False), - "cluster_id": BasicInteger(idl_name="cluster_id", byte_count=4, is_signed=False), - "command_id": BasicInteger(idl_name="command_id", byte_count=4, is_signed=False), - "data_ver": BasicInteger(idl_name="data_ver", byte_count=4, is_signed=False), - "date": BasicInteger(idl_name="date", byte_count=4, is_signed=False), - "devtype_id": BasicInteger(idl_name="devtype_id", byte_count=4, is_signed=False), - "endpoint_no": BasicInteger(idl_name="endpoint_no", byte_count=2, is_signed=False), - "epoch_s": BasicInteger(idl_name="epoch_s", byte_count=4, is_signed=False), - "epoch_us": BasicInteger(idl_name="epoch_us", byte_count=8, is_signed=False), - "event_id": BasicInteger(idl_name="event_id", byte_count=4, is_signed=False), - "event_no": BasicInteger(idl_name="event_no", byte_count=8, is_signed=False), - "fabric_id": BasicInteger(idl_name="fabric_id", byte_count=8, is_signed=False), - "fabric_idx": BasicInteger(idl_name="fabric_idx", byte_count=1, is_signed=False), - "field_id": BasicInteger(idl_name="field_id", byte_count=4, is_signed=False), - "group_id": BasicInteger(idl_name="group_id", byte_count=2, is_signed=False), - "node_id": BasicInteger(idl_name="node_id", byte_count=8, is_signed=False), - "percent": BasicInteger(idl_name="percent", byte_count=1, is_signed=False), - "percent100ths": BasicInteger(idl_name="percent100ths", byte_count=2, is_signed=False), - "status": BasicInteger(idl_name="status", byte_count=2, is_signed=False), - "systime_us": BasicInteger(idl_name="systime_us", byte_count=8, is_signed=False), - "tod": BasicInteger(idl_name="tod", byte_count=4, is_signed=False), - "trans_id": BasicInteger(idl_name="trans_id", byte_count=4, is_signed=False), - "vendor_id": BasicInteger(idl_name="vendor_id", byte_count=2, is_signed=False), -} - - -class TypeLookupContext: - """ - Handles type lookups within a scope. - - Generally when looking for a struct/enum, the lookup will be first done - at a cluster level, then at a global level. - - Example: - - ================ test.matter ============== - enum A {} - - server cluster X { - struct A {} - struct B {} - } - - server cluster Y { - enum C {} - } - =========================================== - - When considering a lookup context of global (i.e. cluster is not set) - "A" is defined as an enum (::A) - "B" is undefined - "C" is undefined - - When considering a lookup context of cluster X - "A" is defined as a struct (X::A) - "B" is defined as a struct (X::B) - "C" is undefined - - When considering a lookup context of cluster Y - "A" is defined as an enum (::A) - "B" is undefined - "C" is defined as an enum (Y::C) - - """ - - def __init__(self, idl: matter_idl_types.Idl, cluster: Optional[matter_idl_types.Cluster]): - self.idl = idl - self.cluster = cluster - - def find_enum(self, name) -> Optional[matter_idl_types.Enum]: - """ - Find the first enumeration matching the given name for the given - lookup rules (searches cluster first, then global). - """ - for e in self.all_enums: - if e.name == name: - return e - - return None - - def find_struct(self, name) -> Optional[matter_idl_types.Struct]: - for s in self.all_structs: - if s.name == name: - return s - - return None - - def find_bitmap(self, name) -> Optional[matter_idl_types.Bitmap]: - for s in self.all_bitmaps: - if s.name == name: - return s - - return None - - @property - def all_enums(self): - """ - All enumerations, ordered by lookup priority. - - If an enum A is defined both in the cluster and globally, this WILL - return both instances, however it will return the cluster version first. - """ - if self.cluster: - for e in self.cluster.enums: - yield e - for e in self.idl.enums: - yield e - - @property - def all_bitmaps(self): - """ - All bitmaps defined within this lookup context. - - bitmaps are only defined at cluster level. If lookup context does not - include a cluster, the bitmal list will be empty. - """ - if self.cluster: - for b in self.cluster.bitmaps: - yield b - - @property - def all_structs(self): - """All structs, ordered by lookup prioroty. - - If a struct A is defined both in the cluster and globally, this WILL - return both instances, however it will return the cluster version first. - """ - if self.cluster: - for e in self.cluster.structs: - yield e - for e in self.idl.structs: - yield e - - def is_enum_type(self, name: str): - """ - Determine if the given type name is an enumeration. - - Handles both standard names (like enum8) as well as enumerations defined - within the current lookup context. - """ - if name.lower() in ["enum8", "enum16", "enum32"]: - return True - return any(map(lambda e: e.name == name, self.all_enums)) - - def is_struct_type(self, name: str): - """ - Determine if the given type name is type that is known to be a struct - """ - return any(map(lambda s: s.name == name, self.all_structs)) - - def is_bitmap_type(self, name: str): - """ - Determine if the given type name is type that is known to be a bitmap. - - Handles both standard/zcl names (like bitmap32) and types defined within - the current lookup context. - """ - if name.lower() in ["bitmap8", "bitmap16", "bitmap24", "bitmap32", "bitmap64"]: - return True - - return any(map(lambda s: s.name == name, self.all_bitmaps)) - - -def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[BasicInteger, BasicString, FundamentalType, IdlType]: - """ - Given a AST data type and a lookup context, match it to a type that can be later - be used for generation. - - AST parsing is textual, so it does not understand what "foo" means. This method - looks up what "foo" actually means: includes basic types (e.g. bool), - zcl types (like enums or bitmaps) and does lookups to find structs/enums/bitmaps/etc - that are defined in the given lookup context. - """ - - lowercase_name = data_type.name.lower() - - if lowercase_name == 'boolean': - return FundamentalType.BOOL - if lowercase_name == 'single': - return FundamentalType.FLOAT - elif lowercase_name == 'double': - return FundamentalType.DOUBLE - elif lowercase_name in ['char_string', 'long_char_string']: - return BasicString(idl_name=lowercase_name, is_binary=False, max_length=data_type.max_length) - elif lowercase_name in ['octet_string', 'long_octet_string']: - return BasicString(idl_name=lowercase_name, is_binary=True, max_length=data_type.max_length) - elif lowercase_name in ['enum8', 'enum16', 'enum32']: - return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name]) - elif lowercase_name in ['bitmap8', 'bitmap16', 'bitmap24', 'bitmap32']: - return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name]) - - int_type = __CHIP_SIZED_TYPES__.get(lowercase_name, None) - if int_type is not None: - return int_type - - # All fast checks done, now check against known data types - e = lookup.find_enum(data_type.name) - if e: - # Valid enum found. it MUST be based on a valid data type - return IdlEnumType(idl_name=data_type.name, base_type=__CHIP_SIZED_TYPES__[e.base_type.lower()]) - - b = lookup.find_bitmap(data_type.name) - if b: - # Valid enum found. it MUST be based on a valid data type - return IdlBitmapType(idl_name=data_type.name, base_type=__CHIP_SIZED_TYPES__[b.base_type.lower()]) - - result = IdlType(idl_name=data_type.name, item_type=IdlItemType.UNKNOWN) - if lookup.find_struct(data_type.name): - result.item_type = IdlItemType.STRUCT - else: - logging.warn( - "Data type %s is NOT known, but treating it as a generic IDL type." % data_type) - - return result diff --git a/scripts/idl/build/lib/lint/__init__.py b/scripts/idl/build/lib/lint/__init__.py deleted file mode 100644 index 503bdf4086f77e..00000000000000 --- a/scripts/idl/build/lib/lint/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2022 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. - -from .lint_rules_parser import CreateParser diff --git a/scripts/idl/build/lib/lint/lint_rules_parser.py b/scripts/idl/build/lib/lint/lint_rules_parser.py deleted file mode 100644 index 9af6b8c0f05724..00000000000000 --- a/scripts/idl/build/lib/lint/lint_rules_parser.py +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env python - -import logging -import os -import xml.etree.ElementTree - -from dataclasses import dataclass, field -from typing import List, Optional, Mapping -from lark import Lark -from lark.visitors import Transformer, v_args, Discard -import stringcase -import traceback - -try: - from .types import RequiredAttributesRule, AttributeRequirement, ClusterRequirement, RequiredCommandsRule, ClusterCommandRequirement -except: - import sys - - sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "..")) - from idl.lint.types import RequiredAttributesRule, AttributeRequirement, ClusterRequirement, RequiredCommandsRule, ClusterCommandRequirement - - -def parseNumberString(n): - if n.startswith('0x'): - return int(n[2:], 16) - else: - return int(n) - - -@dataclass -class RequiredAttribute: - name: str - code: int - - -@dataclass -class RequiredCommand: - name: str - code: int - - -@dataclass -class DecodedCluster: - name: str - code: int - required_attributes: List[RequiredAttribute] - required_commands: List[RequiredCommand] - - -def DecodeClusterFromXml(element: xml.etree.ElementTree.Element): - if element.tag != 'cluster': - logging.error("Not a cluster element: %r" % element) - return None - - # cluster elements contain among other children - # - name (general name for this cluster) - # - code (unique identifier, may be hex or numeric) - # - attribute with side, code and optional attributes - - try: - name = element.find('name').text.replace(' ', '') - required_attributes = [] - required_commands = [] - - for attr in element.findall('attribute'): - if attr.attrib['side'] != 'server': - continue - - if 'optional' in attr.attrib and attr.attrib['optional'] == 'true': - continue - - # when introducing access controls, the content of attributes may either be: - # myName - # or - # myName... - attr_name = attr.text - if attr.find('description') is not None: - attr_name = attr.find('description').text - - required_attributes.append( - RequiredAttribute( - name=attr_name, - code=parseNumberString(attr.attrib['code']) - )) - - for cmd in element.findall('command'): - if cmd.attrib['source'] != 'client': - continue - - if 'optional' in cmd.attrib and cmd.attrib['optional'] == 'true': - continue - - required_commands.append(RequiredCommand(name=cmd.attrib["name"], code=parseNumberString(cmd.attrib['code']))) - - return DecodedCluster( - name=name, - code=parseNumberString(element.find('code').text), - required_attributes=required_attributes, - required_commands=required_commands - ) - except Exception as e: - logging.exception("Failed to decode cluster %r" % element) - return None - - -def ClustersInXmlFile(path: str): - logging.info("Loading XML from %s" % path) - - # root is expected to be just a "configurator" object - configurator = xml.etree.ElementTree.parse(path).getroot() - for child in configurator: - if child.tag != 'cluster': - continue - yield child - - -class LintRulesContext: - """Represents a context for loadint lint rules. - - Handles: - - loading referenced files (matter xml definitions) - - adding linter rules as data is parsed - - Looking up identifiers for various rules - """ - - def __init__(self): - self._required_attributes_rule = RequiredAttributesRule("Required attributes") - self._required_commands_rule = RequiredCommandsRule("Required commands") - - # Map cluster names to the underlying code - self._cluster_codes: Mapping[str, int] = {} - - def GetLinterRules(self): - return [self._required_attributes_rule, self._required_commands_rule] - - def RequireAttribute(self, r: AttributeRequirement): - self._required_attributes_rule.RequireAttribute(r) - - def RequireClusterInEndpoint(self, name: str, code: int): - """Mark that a specific cluster is always required in the given endpoint - """ - if name not in self._cluster_codes: - # Name may be a number. If this can be parsed as a number, accept it anyway - try: - cluster_code = parseNumberString(name) - name = "ID_%s" % name - except ValueError: - logging.error("UNKNOWN cluster name %s" % name) - logging.error("Known names: %s" % (",".join(self._cluster_codes.keys()), )) - return - else: - cluster_code = self._cluster_codes[name] - - self._required_attributes_rule.RequireClusterInEndpoint(ClusterRequirement( - endpoint_id=code, - cluster_code=cluster_code, - cluster_name=name, - )) - - def LoadXml(self, path: str): - """Load XML data from the given path and add it to - internal processing. Adds attribute requirement rules - as needed. - """ - for cluster in ClustersInXmlFile(path): - decoded = DecodeClusterFromXml(cluster) - - if not decoded: - continue - - self._cluster_codes[decoded.name] = decoded.code - - for attr in decoded.required_attributes: - self._required_attributes_rule.RequireAttribute(AttributeRequirement( - code=attr.code, name=attr.name, filter_cluster=decoded.code)) - - for cmd in decoded.required_commands: - self._required_commands_rule.RequireCommand( - ClusterCommandRequirement( - cluster_code=decoded.code, - command_code=cmd.code, - command_name=cmd.name - )) - - -class LintRulesTransformer(Transformer): - """ - A transformer capable to transform data parsed by Lark according to - lint_rules_grammar.lark. - """ - - def __init__(self, file_name: str): - self.context = LintRulesContext() - self.file_name = file_name - - def positive_integer(self, tokens): - """Numbers in the grammar are integers or hex numbers. - """ - if len(tokens) != 1: - raise Error("Unexpected argument counts") - - return parseNumberString(tokens[0].value) - - @v_args(inline=True) - def negative_integer(self, value): - return -value - - @v_args(inline=True) - def integer(self, value): - return value - - def id(self, tokens): - """An id is a string containing an identifier - """ - if len(tokens) != 1: - raise Error("Unexpected argument counts") - return tokens[0].value - - def ESCAPED_STRING(self, s): - # handle escapes, skip the start and end quotes - return s.value[1:-1].encode('utf-8').decode('unicode-escape') - - def start(self, instructions): - # At this point processing is considered done, return all - # linter rules that were found - return self.context.GetLinterRules() - - def instruction(self, instruction): - return Discard - - def all_endpoint_rule(self, attributes): - for attribute in attributes: - self.context.RequireAttribute(attribute) - - return Discard - - @v_args(inline=True) - def load_xml(self, path): - if not os.path.isabs(path): - path = os.path.abspath(os.path.join(os.path.dirname(self.file_name), path)) - - self.context.LoadXml(path) - - @v_args(inline=True) - def required_global_attribute(self, name, code): - return AttributeRequirement(code=code, name=name) - - @v_args(inline=True) - def specific_endpoint_rule(self, code, *names): - for name in names: - self.context.RequireClusterInEndpoint(name, code) - return Discard - - @v_args(inline=True) - def required_server_cluster(self, id): - return id - - -class Parser: - def __init__(self, parser, file_name: str): - self.parser = parser - self.file_name = file_name - - def parse(self): - data = LintRulesTransformer(self.file_name).transform(self.parser.parse(open(self.file_name, "rt").read())) - return data - - -def CreateParser(file_name: str): - """ - Generates a parser that will process a ".matter" file into a IDL - """ - return Parser(Lark.open('lint_rules_grammar.lark', rel_to=__file__, parser='lalr', propagate_positions=True), file_name=file_name) - - -if __name__ == '__main__': - # This Parser is generally not intended to be run as a stand-alone binary. - # The ability to run is for debug and to print out the parsed AST. - import click - import coloredlogs - - # Supported log levels, mapping string values required for argument - # parsing into logging constants - __LOG_LEVELS__ = { - 'debug': logging.DEBUG, - 'info': logging.INFO, - 'warn': logging.WARN, - 'fatal': logging.FATAL, - } - - @click.command() - @click.option( - '--log-level', - default='INFO', - type=click.Choice(__LOG_LEVELS__.keys(), case_sensitive=False), - help='Determines the verbosity of script output.') - @click.argument('filename') - def main(log_level, filename=None): - coloredlogs.install(level=__LOG_LEVELS__[ - log_level], fmt='%(asctime)s %(levelname)-7s %(message)s') - - logging.info("Starting to parse ...") - data = CreateParser(filename).parse() - logging.info("Parse completed") - - logging.info("Data:") - logging.info("%r" % data) - - main() diff --git a/scripts/idl/build/lib/lint/types.py b/scripts/idl/build/lib/lint/types.py deleted file mode 100644 index 85dfbdeacd0bc3..00000000000000 --- a/scripts/idl/build/lib/lint/types.py +++ /dev/null @@ -1,259 +0,0 @@ -# Copyright (c) 2022 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. - -from idl.matter_idl_types import Idl, ParseMetaData, ClusterSide -from abc import ABC, abstractmethod -from typing import List, Optional -from dataclasses import dataclass, field - - -@dataclass -class LocationInFile: - file_name: str - line: int - column: int - - def __init__(self, file_name: str, meta: ParseMetaData): - self.file_name = file_name - self.line = meta.line - self.column = meta.column - - -@dataclass -class LintError: - """Represents a lint error, potentially at a specific location in a file""" - - message: str - location: Optional[LocationInFile] = field(default=None) - - def __init__(self, text: str, location: Optional[LocationInFile] = None): - self.message = text - if location: - self.message += " at %s:%d:%d" % (location.file_name, location.line, location.column) - - def __str__(self): - return self.message - - -class LintRule(ABC): - """Validates a linter rule on an idl""" - - def __init__(self, name): - self.name = name - - @abstractmethod - def LintIdl(self, idl: Idl) -> List[LintError]: - """Runs the linter on the given IDL and returns back any errors it may find""" - pass - - -@dataclass -class AttributeRequirement: - """Contains information about a required attribute""" - code: int # required attributes are searched by codes - name: str # the name of this attribute. Expect it to be exposed properly - - # Optional filters to apply to specific locations - filter_cluster: Optional[int] = field(default=None) - - -@dataclass -class ClusterRequirement: - endpoint_id: int - cluster_code: int - cluster_name: str - - -class ErrorAccumulatingRule(LintRule): - """Contains a lint error list and helps helpers to add to such a list of rules.""" - - def __init__(self, name): - super(ErrorAccumulatingRule, self).__init__(name) - self._lint_errors = [] - self._idl = None - - def _AddLintError(self, text, location): - self._lint_errors.append(LintError("%s: %s" % (self.name, text), location)) - - def _ParseLocation(self, meta: Optional[ParseMetaData]) -> Optional[LocationInFile]: - """Create a location in the current file that is being parsed. """ - if not meta or not self._idl.parse_file_name: - return None - return LocationInFile(self._idl.parse_file_name, meta) - - def LintIdl(self, idl: Idl) -> List[LintError]: - self._idl = idl - self._lint_errors = [] - self._LintImpl() - return self._lint_errors - - @abstractmethod - def _LintImpl(self): - """Implements actual linting of the IDL. - - Uses the underlying _idl for validation. - """ - pass - - -class RequiredAttributesRule(ErrorAccumulatingRule): - def __init__(self, name): - super(RequiredAttributesRule, self).__init__(name) - # Map attribute code to name - self._mandatory_attributes: List[AttributeRequirement] = [] - self._mandatory_clusters: List[ClusterRequirement] = [] - - def __repr__(self): - result = "RequiredAttributesRule{\n" - - if self._mandatory_attributes: - result += " mandatory_attributes:\n" - for attr in self._mandatory_attributes: - result += " - %r\n" % attr - - if self._mandatory_clusters: - result += " mandatory_clusters:\n" - for cluster in self._mandatory_clusters: - result += " - %r\n" % cluster - - result += "}" - return result - - def RequireAttribute(self, attr: AttributeRequirement): - """Mark an attribute required""" - self._mandatory_attributes.append(attr) - - def RequireClusterInEndpoint(self, requirement: ClusterRequirement): - self._mandatory_clusters.append(requirement) - - def _ServerClusterDefinition(self, name: str, location: Optional[LocationInFile]): - """Finds the server cluster definition with the given name. - - On error returns None and _lint_errors is updated internlly - """ - cluster_definition = [ - c for c in self._idl.clusters if c.name == name and c.side == ClusterSide.SERVER - ] - if not cluster_definition: - self._AddLintError("Cluster definition for %s not found" % cluster.name, location) - return None - - if len(cluster_definition) > 1: - self._AddLintError("Multiple cluster definitions found for %s" % cluster.name, location) - return None - - return cluster_definition[0] - - def _LintImpl(self): - for endpoint in self._idl.endpoints: - - cluster_codes = set() - - for cluster in endpoint.server_clusters: - cluster_definition = self._ServerClusterDefinition(cluster.name, self._ParseLocation(cluster.parse_meta)) - if not cluster_definition: - continue - - cluster_codes.add(cluster_definition.code) - - # Cluster contains enabled attributes by name - # cluster_definition contains the definition of the attributes themseves - # - # Join the two to receive attribute codes - name_to_code_map = {} - for attr in cluster_definition.attributes: - name_to_code_map[attr.definition.name] = attr.definition.code - - attribute_codes = set() - # For all the instantiated attributes, figure out their code - for attr in cluster.attributes: - if attr.name not in name_to_code_map: - self._AddLintError("Could not find attribute defintion (no code) for %s:%s" % - (cluster.name, attr.name), self._ParseLocation(cluster.parse_meta)) - continue - - attribute_codes.add(name_to_code_map[attr.name]) - - # Linting codes now - for check in self._mandatory_attributes: - if check.filter_cluster is not None and check.filter_cluster != cluster_definition.code: - continue - - if check.code not in attribute_codes: - self._AddLintError("EP%d:%s does not expose %s(%d) attribute" % - (endpoint.number, cluster.name, check.name, check.code), self._ParseLocation(cluster.parse_meta)) - - for requirement in self._mandatory_clusters: - if requirement.endpoint_id != endpoint.number: - continue - - if requirement.cluster_code not in cluster_codes: - self._AddLintError("Endpoint %d does not expose cluster %s (%d)" % - (requirement.endpoint_id, requirement.cluster_name, requirement.cluster_code), location=None) - - -@dataclass -class ClusterCommandRequirement: - cluster_code: int - command_code: int - command_name: str - - -class RequiredCommandsRule(ErrorAccumulatingRule): - def __init__(self, name): - super(RequiredCommandsRule, self).__init__(name) - - # Maps cluster id to mandatory cluster requirement - self._mandatory_commands: Maping[int, List[ClusterCommandRequirement]] = {} - - def __repr__(self): - result = "RequiredCommandsRule{\n" - - if self._mandatory_commands: - result += " mandatory_commands:\n" - for key, value in self._mandatory_commands.items(): - result += " - cluster %d:\n" % key - for requirement in value: - result += " - %r\n" % requirement - - result += "}" - return result - - def RequireCommand(self, cmd: ClusterCommandRequirement): - """Mark a command required""" - - if cmd.cluster_code in self._mandatory_commands: - self._mandatory_commands[cmd.cluster_code].append(cmd) - else: - self._mandatory_commands[cmd.cluster_code] = [cmd] - - def _LintImpl(self): - for cluster in self._idl.clusters: - if cluster.side != ClusterSide.SERVER: - continue # only validate server-side: - - if cluster.code not in self._mandatory_commands: - continue # no known mandatory commands - - defined_commands = set([c.code for c in cluster.commands]) - - for requirement in self._mandatory_commands[cluster.code]: - if requirement.command_code in defined_commands: - continue # command exists - - self._AddLintError( - "Cluster %s does not define mandatory command %s(%d)" % ( - cluster.name, requirement.command_name, requirement.command_code), - self._ParseLocation(cluster.parse_meta) - ) diff --git a/scripts/idl/build/lib/zapxml/__init__.py b/scripts/idl/build/lib/zapxml/__init__.py deleted file mode 100644 index 332d1c244bea3b..00000000000000 --- a/scripts/idl/build/lib/zapxml/__init__.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright (c) 2022 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. - -import logging -import typing -import xml.sax.handler - -from dataclasses import dataclass -from typing import Optional, Union, List - -from idl.zapxml.handlers import Context, ZapXmlHandler -from idl.matter_idl_types import Idl - - -class ParseHandler(xml.sax.handler.ContentHandler): - """A parser for ZAP-style XML data definitions. - - Defers its processing to ZapXmlHandler and keeps track of: - - an internal context for all handlers - - the parsed Idl structure that is incrementally built - - sets up parsing location within the context - - keeps track of ParsePath - - Overall converts a python SAX handler into idl.zapxml.handlers - """ - - def __init__(self, include_meta_data=True): - super().__init__() - self._idl = Idl() - self._processing_stack = [] - # Context persists across all - self._context = Context() - self._include_meta_data = include_meta_data - - def PrepareParsing(self, filename): - # This is a bit ugly: filename keeps changing during parse - # IDL meta is not prepared for this (as source is XML and .matter is - # single file) - if self._include_meta_data: - self._idl.parse_file_name = filename - - def Finish(self) -> Idl: - self._context.PostProcess(self._idl) - return self._idl - - def startDocument(self): - if self._include_meta_data: - self._context.locator = self._locator - self._processing_stack = [ZapXmlHandler(self._context, self._idl)] - - def endDocument(self): - if len(self._processing_stack) != 1: - raise Exception("Unexpected nesting!") - - def startElement(self, name: str, attrs): - logging.debug("ELEMENT START: %r / %r" % (name, attrs)) - self._context.path.push(name) - self._processing_stack.append(self._processing_stack[-1].GetNextProcessor(name, attrs)) - - def endElement(self, name: str): - logging.debug("ELEMENT END: %r" % name) - - last = self._processing_stack.pop() - last.EndProcessing() - - # important to pop AFTER processing end to allow processing - # end to access the current context - self._context.path.pop() - - def characters(self, content): - self._processing_stack[-1].HandleContent(content) - - -@dataclass -class ParseSource: - """Represents an input sopurce for ParseXmls. - - Allows for named data sources to be parsed. - """ - source: Union[str, typing.IO] # filename or stream - name: Optional[str] = None # actual filename to use, None if the source is a filename already - - @ property - def source_file_name(self): - if self.name: - return self.name - return self.source # assume string - - -def ParseXmls(sources: List[ParseSource], include_meta_data=True) -> Idl: - """Parse one or more XML inputs and return the resulting Idl data. - - Params: - sources - what to parse - include_meta_data - if parsing location data should be included in the Idl - """ - handler = ParseHandler(include_meta_data=include_meta_data) - - for source in sources: - logging.info('Parsing %s...' % source.source_file_name) - handler.PrepareParsing(source.source_file_name) - - parser = xml.sax.make_parser() - parser.setContentHandler(handler) - parser.parse(source.source) - - return handler.Finish() diff --git a/scripts/idl/build/lib/zapxml/handlers/__init__.py b/scripts/idl/build/lib/zapxml/handlers/__init__.py deleted file mode 100644 index 7a6bfa04682921..00000000000000 --- a/scripts/idl/build/lib/zapxml/handlers/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2022 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. - -from .base import BaseHandler -from .context import Context -from .handlers import ConfiguratorHandler - -from idl.matter_idl_types import Idl - - -class ZapXmlHandler(BaseHandler): - """Handles the top level (/) of a zap xml file. - - Generally these files only contain a 'configurator' element in them - """ - - def __init__(self, context: Context, idl: Idl): - super().__init__(context) - self._idl = idl - - def GetNextProcessor(self, name, attrs): - if name.lower() == 'configurator': - return ConfiguratorHandler(self.context, self._idl) - else: - return BaseHandler(self.context) diff --git a/scripts/idl/build/lib/zapxml/handlers/base.py b/scripts/idl/build/lib/zapxml/handlers/base.py deleted file mode 100644 index bb2ca95566a4ae..00000000000000 --- a/scripts/idl/build/lib/zapxml/handlers/base.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (c) 2022 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. - -import enum -from .context import Context - - -class HandledDepth: - """Defines how deep a XML element has been handled.""" - NOT_HANDLED = enum.auto() # Unknown/parsed element - ENTIRE_TREE = enum.auto() # Entire tree can be ignored - SINGLE_TAG = enum.auto() # Single tag processed, but not sub-items - - -class BaseHandler: - """A generic element handler. - - XML processing is done in the form of depth-first processing: - - Tree is descended into using `GetNextProcessor` - - Processors are expected to extend `BaseHandler` and allow for: - - GetNextProcessor to recurse - - HandleContent in case the text content is relevant - - EndProcessing once the entire tree has been walked (when xml element ends) - - BaseHandler keeps track if it has been handled or ot by its `_handled` setting and - init parameter. Non-handled elements will be tagged within the context, resulting - in logs. This is to detect if unknown/new tags appear in XML files. - """ - - def __init__(self, context: Context, handled=HandledDepth.NOT_HANDLED): - self.context = context - self._handled = handled - - def GetNextProcessor(self, name, attrs): - """Get the next processor to use for the given name""" - - if self._handled == HandledDepth.SINGLE_TAG: - handled = HandledDepth.NOT_HANDLED - else: - handled = self._handled - - return BaseHandler(context=self.context, handled=handled) - - def HandleContent(self, content): - """Processes some content""" - pass - - def EndProcessing(self): - """Finalizes the processing of the current element""" - if self._handled == HandledDepth.NOT_HANDLED: - self.context.MarkTagNotHandled() diff --git a/scripts/idl/build/lib/zapxml/handlers/context.py b/scripts/idl/build/lib/zapxml/handlers/context.py deleted file mode 100644 index 2d82153d76d959..00000000000000 --- a/scripts/idl/build/lib/zapxml/handlers/context.py +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) 2022 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. - -import logging -import xml.sax.xmlreader - -from idl.matter_idl_types import Idl, ParseMetaData, Attribute -from typing import Optional, List - - -class IdlPostProcessor: - """Defines a callback that will apply after an entire parsing - is complete. - """ - - def FinalizeProcessing(self, idl: Idl): - """Update idl with any post-processing directives.""" - pass - - -class ProcessingPath: - """Maintains the current path of tags within xml processing. - - As processing descents into an xml like `....` - paths will have contents like ['configurator', 'cluster', ...]. - - The main purpose for this is to log and keep track of what was visited - and in general to report things like 'this path found but was not handled'. - """ - - def __init__(self, paths: List[str] = None): - if paths is None: - paths = [] - self.paths = paths - - def push(self, name: str): - self.paths.append(name) - - def pop(self): - self.paths.pop() - - def __str__(self): - return '::'.join(self.paths) - - def __repr__(self): - return 'ProcessingPath(%r)' % self.paths - - -class Context: - """ - Contains a processing state during XML reading. - - The purpose of this is to allow elements to interact with each other, share - data and defer processing. - - Usage: - - globally shared data: - > locator: parsing location, for error reporting - > path: current ProcessingPath for any logging of where we are located - - shared data: - > global attributes are parsed by one handler, but used by others - - post-processing support: - > can register AddIdlPostProcessor to perform some processing once - a full parsing pass has been done - - More data may be added in time if it involves separate XML parse handlers - needing to interact with each other. - """ - - def __init__(self, locator: Optional[xml.sax.xmlreader.Locator] = None): - self.path = ProcessingPath() - self.locator = locator - self._not_handled = set() - self._idl_post_processors = [] - - # Map of code -> attribute - self._global_attributes = {} - - def GetCurrentLocationMeta(self) -> ParseMetaData: - if not self.locator: - return None - - return ParseMetaData(line=self.locator.getLineNumber(), column=self.locator.getColumnNumber()) - - def GetGlobalAttribute(self, code): - if code in self._global_attributes: - return self._global_attributes[code] - - raise Exception( - 'Global attribute 0x%X (%d) not found. You probably need to load global-attributes.xml' % (code, code)) - - def AddGlobalAttribute(self, attribute: Attribute): - # NOTE: this may get added several times as both 'client' and 'server' - # however matter should not differentiate between the two - code = attribute.definition.code - logging.info('Adding global attribute 0x%X (%d): %s' % (code, code, attribute.definition.name)) - - self._global_attributes[code] = attribute - - def MarkTagNotHandled(self): - path = str(self.path) - if path not in self._not_handled: - logging.warning("TAG %s was not handled/recognized" % path) - self._not_handled.add(path) - - def AddIdlPostProcessor(self, processor: IdlPostProcessor): - self._idl_post_processors.append(processor) - - def PostProcess(self, idl: Idl): - for p in self._idl_post_processors: - p.FinalizeProcessing(idl) - - self._idl_post_processors = [] diff --git a/scripts/idl/build/lib/zapxml/handlers/handlers.py b/scripts/idl/build/lib/zapxml/handlers/handlers.py deleted file mode 100644 index 6048b271ecf3ac..00000000000000 --- a/scripts/idl/build/lib/zapxml/handlers/handlers.py +++ /dev/null @@ -1,614 +0,0 @@ -# Copyright (c) 2022 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. - -import logging - -from idl.matter_idl_types import * -from typing import Optional, Union, List - -from .context import Context, IdlPostProcessor -from .parsing import ParseInt, AttrsToAccessPrivilege, AttrsToAttribute -from .base import HandledDepth, BaseHandler - - -class ClusterNameHandler(BaseHandler): - """Handles /configurator/cluster/name elements.""" - - def __init__(self, context: Context, cluster: Cluster): - super().__init__(context, handled=HandledDepth.SINGLE_TAG) - self._cluster = cluster - - def HandleContent(self, content): - self._cluster.name = content.replace(' ', '') - - -class AttributeDescriptionHandler(BaseHandler): - """Handles /configurator/cluster/attribute/description elements.""" - - def __init__(self, context: Context, attribute: Attribute): - super().__init__(context, handled=HandledDepth.SINGLE_TAG) - self._attribute = attribute - - def HandleContent(self, content: str): - self._attribute.definition.name = content.replace(' ', '') - - -class ClusterCodeHandler(BaseHandler): - """Handles /configurator/cluster/code elements.""" - - def __init__(self, context: Context, cluster: Cluster): - super().__init__(context, handled=HandledDepth.SINGLE_TAG) - self._cluster = cluster - - def HandleContent(self, content: str): - self._cluster.code = ParseInt(content) - - -class EventHandler(BaseHandler): - """Handles /configurator/cluster/event elements.""" - - def __init__(self, context: Context, cluster: Cluster, attrs): - super().__init__(context) - self._cluster = cluster - - if attrs['priority'] == 'debug': - priority = EventPriority.DEBUG - elif attrs['priority'] == 'info': - priority = EventPriority.INFO - elif attrs['priority'] == 'critical': - priority = EventPriority.CRITICAL - else: - raise Exception("Unknown event priority: %s" % attrs['priority']) - - self._event = Event( - priority=priority, - code=ParseInt(attrs['code']), - name=attrs['name'], - fields=[], - ) - - if attrs.get('isFabricSensitive', "false").lower() == 'true': - self._event.qualities |= EventQuality.FABRIC_SENSITIVE - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'field': - data_type = DataType(name=attrs['type']) - if 'length' in attrs: - data_type.max_length = ParseInt(attrs['length']) - - field = Field( - data_type=data_type, - code=ParseInt(attrs['id']), - name=attrs['name'], - is_list=(attrs.get('array', 'false').lower() == 'true'), - ) - - if attrs.get('optional', "false").lower() == 'true': - field.qualities |= FieldQuality.OPTIONAL - - if attrs.get('isNullable', "false").lower() == 'true': - field.qualities |= FieldQuality.NULLABLE - - self._event.fields.append(field) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'access': - self._event.readacl = AttrsToAccessPrivilege(attrs) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'description': - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - else: - return BaseHandler(self.context) - - def EndProcessing(self): - self._cluster.events.append(self._event) - - -class AttributeHandler(BaseHandler): - """Handles /configurator/cluster/attribute elements.""" - - def __init__(self, context: Context, cluster: Cluster, attrs): - super().__init__(context) - self._cluster = cluster - self._attribute = AttrsToAttribute(attrs) - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'access': - # Modifier not currently used: fabric scoped exists on the structure itself. - if 'modifier' in attrs: - if attrs['modifier'] != 'fabric-scoped': - raise Exception("UNKNOWN MODIFIER: %s" % attrs['modifier']) - - if ('role' in attrs) or ('privilege' in attrs): - role = AttrsToAccessPrivilege(attrs) - - if attrs['op'] == 'read': - self._attribute.readacl = role - elif attrs['op'] == 'write': - self._attribute.writeacl = role - else: - logging.error("Unknown access: %r" % attrs['op']) - - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'description': - return AttributeDescriptionHandler(self.context, self._attribute) - else: - return BaseHandler(self.context) - - def HandleContent(self, content: str): - # Content generally is the name EXCEPT if access controls - # exist, in which case `description` contains the name - content = content.strip() - if content and not self._attribute.definition.name: - self._attribute.definition.name = content - - def EndProcessing(self): - if self._attribute.definition.name is None: - raise Exception("Name for attribute was not parsed.") - - self._cluster.attributes.append(self._attribute) - - -class StructHandler(BaseHandler, IdlPostProcessor): - """ Handling /configurator/struct elements.""" - - def __init__(self, context: Context, attrs): - super().__init__(context) - - # if set, struct belongs to a specific cluster - self._cluster_codes = set() - self._struct = Struct(name=attrs['name'], fields=[]) - self._field_index = 0 - # The following are not set: - # - tag not set because not a request/response - # - code not set because not a response - - if attrs.get('isFabricScoped', "false").lower() == 'true': - self._struct.qualities |= StructQuality.FABRIC_SCOPED - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'item': - data_type = DataType( - name=attrs['type'] - ) - - if 'fieldId' in attrs: - self._field_index = ParseInt(attrs['fieldId']) - else: - # NOTE: code does NOT exist, so the number is incremental here - # this seems a defficiency in XML format. - self._field_index += 1 - - if 'length' in attrs: - data_type.max_length = ParseInt(attrs['length']) - - field = Field( - data_type=data_type, - code=self._field_index, - name=attrs['name'], - is_list=(attrs.get('array', 'false').lower() == 'true'), - ) - - if attrs.get('optional', "false").lower() == 'true': - field.qualities |= FieldQuality.OPTIONAL - - if attrs.get('isNullable', "false").lower() == 'true': - field.qualities |= FieldQuality.NULLABLE - - if attrs.get('isFabricSensitive', "false").lower() == 'true': - field.qualities |= FieldQuality.FABRIC_SENSITIVE - - self._struct.fields.append(field) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'cluster': - self._cluster_codes.add(ParseInt(attrs['code'])) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - else: - return BaseHandler(self.context) - - def FinalizeProcessing(self, idl: Idl): - # We have two choices of adding a struct: - # - inside a cluster if a code exists - # - inside top level if no codes were associated - if self._cluster_codes: - for code in self._cluster_codes: - found = False - for c in idl.clusters: - if c.code == code: - c.structs.append(self._struct) - found = True - - if not found: - logging.error('Enum %s could not find cluster (code %d/0x%X)' % - (self._struct.name, code, code)) - else: - idl.structs.append(self._struct) - - def EndProcessing(self): - self.context.AddIdlPostProcessor(self) - - -class EnumHandler(BaseHandler, IdlPostProcessor): - """ Handling /configurator/enum elements.""" - - def __init__(self, context: Context, attrs): - super().__init__(context) - self._cluster_code = None # if set, enum belongs to a specific cluster - self._enum = Enum(name=attrs['name'], base_type=attrs['type'], entries=[]) - - def GetNextProcessor(self, name, attrs): - if name.lower() == 'item': - self._enum.entries.append(ConstantEntry( - name=attrs['name'], - code=ParseInt(attrs['value']) - )) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'cluster': - if self._cluster_code is not None: - raise Exception('Multiple cluster codes for enum %s' % self._enum.name) - self._cluster_code = ParseInt(attrs['code']) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - else: - return BaseHandler(self.context) - - def FinalizeProcessing(self, idl: Idl): - # We have two choices of adding an enum: - # - inside a cluster if a code exists - # - inside top level if a code does not exist - - if self._cluster_code is None: - idl.enums.append(self._enum) - else: - found = False - for c in idl.clusters: - if c.code == self._cluster_code: - c.enums.append(self._enum) - found = True - - if not found: - logging.error('Enum %s could not find its cluster (code %d/0x%X)' % - (self._enum.name, self._cluster_code, self._cluster_code)) - - def EndProcessing(self): - self.context.AddIdlPostProcessor(self) - - -class BitmapHandler(BaseHandler): - """ Handling /configurator/bitmap elements.""" - - def __init__(self, context: Context, attrs): - super().__init__(context) - self._cluster_codes = set() - self._bitmap = Bitmap(name=attrs['name'], base_type=attrs['type'], entries=[]) - - def GetNextProcessor(self, name, attrs): - if name.lower() == 'cluster': - # Multiple clusters may be associated, like IasZoneStatus - self._cluster_codes.add(ParseInt(attrs['code'])) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'field': - self._bitmap.entries.append(ConstantEntry( - name=attrs['name'], - code=ParseInt(attrs['mask']) - )) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'description': - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - else: - return BaseHandler(self.context) - - def FinalizeProcessing(self, idl: Idl): - # We have two choices of adding an enum: - # - inside a cluster if a code exists - # - inside top level if a code does not exist - if not self._cluster_codes: - # Log only instead of critical, as not our XML is well formed. - # For example at the time of writing this, SwitchFeature in switch-cluster.xml - # did not have a code associated with it. - logging.error("Bitmap %r has no cluster codes" % self._bitmap) - return - - for code in self._cluster_codes: - found = False - for c in idl.clusters: - if c.code == code: - c.bitmaps.append(self._bitmap) - found = True - if not found: - logging.error('Bitmap %s could not find its cluster (code %d/0x%X)' % - (self._bitmap.name, code, code)) - - def EndProcessing(self): - self.context.AddIdlPostProcessor(self) - - -class CommandHandler(BaseHandler): - """Handles /configurator/cluster/command elements.""" - - def __init__(self, context: Context, cluster: Cluster, attrs): - super().__init__(context) - self._cluster = cluster - self._command = None - self._struct = Struct(name=attrs['name'], fields=[]) - self._field_index = 0 # commands DO NOT support field index it seems - - if attrs['source'].lower() == 'client': - self._struct.tag = StructTag.REQUEST - - name = attrs['name'] - - if name.endswith('Request'): - request_name = name - command_name = name[:-7] - else: - request_name = name+'Request' - command_name = name - - self._struct.name = request_name - - if 'response' in attrs: - response_name = attrs['response'] - else: - response_name = 'DefaultResponse' - - self._command = Command( - name=name, - code=ParseInt(attrs['code']), - input_param=request_name, - output_param=response_name, - ) - - if attrs.get('isFabricScoped', 'false') == 'true': - self._command.qualities |= CommandQuality.FABRIC_SCOPED - - if attrs.get('mustUseTimedInvoke', 'false') == 'true': - self._command.qualities |= CommandQuality.TIMED_INVOKE - - else: - self._struct.tag = StructTag.RESPONSE - self._struct.code = ParseInt(attrs['code']) - - def GetArgumentField(self, attrs): - data_type = DataType(name=attrs['type']) - - if 'length' in attrs: - data_type.max_length = ParseInt(attrs['length']) - - self._field_index += 1 - - field = Field( - data_type=data_type, - code=self._field_index, - name=attrs['name'], - is_list=(attrs.get('array', 'false') == 'true') - ) - - if attrs.get('optional', "false").lower() == 'true': - field.qualities |= FieldQuality.OPTIONAL - - if attrs.get('isNullable', "false").lower() == 'true': - field.qualities |= FieldQuality.NULLABLE - - return field - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'access': - if attrs['op'] != 'invoke': - raise Exception('Unknown access for %r' % self._struct) - - if self._command: - self._command.invokeacl = AttrsToAccessPrivilege(attrs) - else: - logging.warning("Ignored access role for reply %r" % self._struct) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'arg': - self._struct.fields.append(self.GetArgumentField(attrs)) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - elif name.lower() == 'description': - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - else: - return BaseHandler(self.context) - - def EndProcessing(self): - - if self._struct.fields: - self._cluster.structs.append(self._struct) - else: - # no input - self._command.input_param = None - - if self._command: - self._cluster.commands.append(self._command) - - -class ClusterGlobalAttributeHandler(BaseHandler): - """Handles /configurator/cluster/globalAttribute elements.""" - - def __init__(self, context: Context, cluster: Cluster, code: int): - super().__init__(context) - self._cluster = cluster - self._code = code - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'featurebit': - # It is uncler what featurebits mean. likely a bitmap should be created - # here, however only one such example exists currently: door-lock-cluster.xml - logging.info('Ignoring featurebit tag for global attribute 0x%X (%d)' % (self._code, self._code)) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - else: - return BaseHandler(self.context) - - def EndProcessing(self): - self._cluster.attributes.append(self.context.GetGlobalAttribute(self._code)) - - -class ClusterHandler(BaseHandler): - """Handles /configurator/cluster elements.""" - - def __init__(self, context: Context, idl: Idl): - super().__init__(context) - self._cluster = Cluster( - side=ClusterSide.CLIENT, - name=None, - code=None, - parse_meta=context.GetCurrentLocationMeta() - ) - self._idl = idl - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'code': - return ClusterCodeHandler(self.context, self._cluster) - elif name.lower() == 'name': - return ClusterNameHandler(self.context, self._cluster) - elif name.lower() == 'attribute': - return AttributeHandler(self.context, self._cluster, attrs) - elif name.lower() == 'event': - return EventHandler(self.context, self._cluster, attrs) - elif name.lower() == 'globalattribute': - # We ignore 'side' and 'value' since they do not seem useful - return ClusterGlobalAttributeHandler(self.context, self._cluster, ParseInt(attrs['code'])) - elif name.lower() == 'command': - return CommandHandler(self.context, self._cluster, attrs) - elif name.lower() in ['define', 'description', 'domain', 'tag', 'client', 'server']: - # NOTE: we COULD use client and server to create separate definitions - # of each, but the usefulness of this is unclear as the definitions are - # likely identical and matter has no concept of differences between the two - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - else: - return BaseHandler(self.context) - - def EndProcessing(self): - if self._cluster.name is None: - raise Exception("Missing cluster name") - elif self._cluster.code is None: - raise Exception("Missing cluster code") - - self._idl.clusters.append(self._cluster) - -# Cluster extensions have extra bits for existing clusters. Can only be loaded -# IF the underlying cluster exits - - -class ClusterExtensionHandler(ClusterHandler, IdlPostProcessor): - """Handling /configurator/clusterExtension elements.""" - - def __init__(self, context: Context, code: int): - # NOTE: IDL is set to NONE so that ClusterHandler cannot - # inadvertently change it (it will be invalid anyway) - super().__init__(context, None) - self._cluster_code = code - - def EndProcessing(self): - self.context.AddIdlPostProcessor(self) - - def FinalizeProcessing(self, idl: Idl): - found = False - for c in idl.clusters: - if c.code == self._cluster_code: - found = True - - # Append everything that can be appended - c.enums.extend(self._cluster.enums) - c.bitmaps.extend(self._cluster.bitmaps) - c.events.extend(self._cluster.events) - c.attributes.extend(self._cluster.attributes) - c.structs.extend(self._cluster.structs) - c.commands.extend(self._cluster.commands) - - if not found: - logging.error('Could not extend cluster 0x%X (%d): cluster not found' % - (self._cluster_code, self._cluster_code)) - - -class GlobalAttributeHandler(BaseHandler): - """Handling configurator/global/globalAttribute elements.""" - - def __init__(self, context: Context, attribute: Attribute): - super().__init__(context, handled=HandledDepth.SINGLE_TAG) - self._attribute = attribute - - def HandleContent(self, content: str): - # Content generally is the name EXCEPT if access controls - # exist, in which case `description` contains the name - # - # Global attributes do not currently have access controls, so this - # case is not handled here - content = content.strip() - if content and not self._attribute.definition.name: - self._attribute.definition.name = content - - def EndProcessing(self): - if self._attribute.definition.name is None: - raise Exception("Name for attribute was not parsed.") - - self.context.AddGlobalAttribute(self._attribute) - - -class GlobalHandler(BaseHandler): - """Handling configurator/global elements.""" - - def __init__(self, context: Context): - super().__init__(context, handled=HandledDepth.SINGLE_TAG) - - def GetNextProcessor(self, name, attrs): - if name.lower() == 'attribute': - if attrs['side'].lower() == 'client': - # We expect to also have 'server' equivalent, so ignore client - # side attributes - logging.debug('Ignoring global client-side attribute %s' % (attrs['code'])) - return BaseHandler(self.context, handled=HandledDepth.SINGLE_TAG) - - return GlobalAttributeHandler(self.context, AttrsToAttribute(attrs)) - else: - return BaseHandler(self.context) - - -class ConfiguratorHandler(BaseHandler): - """ Handling /configurator elements.""" - - def __init__(self, context: Context, idl: Idl): - super().__init__(context, handled=HandledDepth.SINGLE_TAG) - self._idl = idl - - def GetNextProcessor(self, name: str, attrs): - if name.lower() == 'cluster': - return ClusterHandler(self.context, self._idl) - elif name.lower() == 'enum': - return EnumHandler(self.context, attrs) - elif name.lower() == 'struct': - return StructHandler(self.context, attrs) - elif name.lower() == 'bitmap': - return BitmapHandler(self.context, attrs) - elif name.lower() == 'domain': - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - elif name.lower() == 'clusterextension': - return ClusterExtensionHandler(self.context, ParseInt(attrs['code'])) - elif name.lower() == 'accesscontrol': - # These contain operation/role/modifier and generally only contain a - # description. These do not seem as useful to parse. - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - elif name.lower() == 'atomic': - # A list of types in 'chip-types' - # Generally does not seem useful - matches a type id to a description, size and some discrete/analog flags - # - # Could be eventually used as a preload of types into base types, however matter idl - # generator logic has hardcoded sizing as well. - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - elif name.lower() == 'devicetype': - # A list of device types in 'matter-devices.xml' - # Useful for conformance tests, but does not seem usable for serialization logic - return BaseHandler(self.context, handled=HandledDepth.ENTIRE_TREE) - elif name.lower() == 'global': - return GlobalHandler(self.context) - else: - return BaseHandler(self.context) diff --git a/scripts/idl/build/lib/zapxml/handlers/parsing.py b/scripts/idl/build/lib/zapxml/handlers/parsing.py deleted file mode 100644 index f9315f3dab6875..00000000000000 --- a/scripts/idl/build/lib/zapxml/handlers/parsing.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2022 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. - -from idl.matter_idl_types import * - - -def ParseInt(value: str) -> int: - """Convert a string that is a known integer into an actual number. - - Supports decimal or hex values prefixed with '0x' - """ - if value.startswith('0x'): - return int(value[2:], 16) - else: - return int(value) - - -def AttrsToAccessPrivilege(attrs) -> AccessPrivilege: - """Given attributes of an '' tag, generate the underlying - access privilege by looking at the role/privilege attribute. - """ - - # XML seems to use both role and privilege to mean the same thing - # they are used interchangeably - if 'role' in attrs: - role = attrs['role'] - else: - role = attrs['privilege'] - - if role.lower() == 'view': - return AccessPrivilege.VIEW - elif role.lower() == 'operate': - return AccessPrivilege.OPERATE - elif role.lower() == 'manage': - return AccessPrivilege.MANAGE - elif role.lower() == 'administer': - return AccessPrivilege.ADMINISTER - else: - raise Exception('Unknown ACL role: %r' % role) - - -def AttrsToAttribute(attrs) -> Attribute: - """Given the attributes of an '' tag, generate the - underlying IDL Attribute dataclass. - """ - - if attrs['type'].lower() == 'array': - data_type = DataType(name=attrs['entryType']) - else: - data_type = DataType(name=attrs['type']) - - if 'length' in attrs: - data_type.max_length = ParseInt(attrs['length']) - - field = Field( - data_type=data_type, - code=ParseInt(attrs['code']), - name=None, - is_list=(attrs['type'].lower() == 'array') - ) - - attribute = Attribute(definition=field) - - if attrs.get('optional', "false").lower() == 'true': - attribute.definition.qualities |= FieldQuality.OPTIONAL - - if attrs.get('isNullable', "false").lower() == 'true': - attribute.definition.qualities |= FieldQuality.NULLABLE - - if attrs.get('readable', "true").lower() == 'true': - attribute.qualities |= AttributeQuality.READABLE - - if attrs.get('writable', "false").lower() == 'true': - attribute.qualities |= AttributeQuality.WRITABLE - - # TODO(#22937): NOSUBSCRIBE attribute tag is not available - could find no - # clear source to get this info. - - # NOTE: default values are also present in this XML, however generally IDL - # **DATA** definitions would not care about the defaults. The - # defaults should be used to initializ storage for devices, hence - # they are part of endpoint definition/composition. We are not doing - # that here, so defaults are ignored. - - return attribute From 8fa24716b4b8a2a87ba695ac6cf71e3c379a3164 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 12:40:17 -0400 Subject: [PATCH 11/23] Adjust the run_codegen_targets a bit --- scripts/run_codegen_targets.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/run_codegen_targets.sh b/scripts/run_codegen_targets.sh index 1ff52e72b3a3e9..14d67f94e83f7b 100755 --- a/scripts/run_codegen_targets.sh +++ b/scripts/run_codegen_targets.sh @@ -29,8 +29,16 @@ if [ ! -d "$OUT_DIR" ]; then exit 1 fi -# Code generation for build config files (via buildconfig_header) -for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E '^gen_.*_buildconfig:' | sed 's/: .*//')"; do +# Code generation for build config files and asn1. Captures things like: +# +# gen_additional_data_payload_buildconfig +# gen_app_buildconfig +# gen_asn1oid +# gen_ble_buildconfig +# ... +# +# Most are buildconfig rules, but asn1oid is special +for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E '^gen_' | sed 's/: .*//')"; do echo "Generating $name ..." ninja -C "$OUT_DIR" "$name" done @@ -46,6 +54,3 @@ for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E 'dbus.*codegen:' | sed ' echo "Generating $name ..." ninja -C "$OUT_DIR" "$name" done - -# ASN1 has no specific rule -ninja -C "$OUT_DIR" gen_asn1oid From dd5a18133dd2db9aa4382beec7514f4e4efe4900 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 12:42:05 -0400 Subject: [PATCH 12/23] Undo shellharden: it breaks the script --- scripts/run_codegen_targets.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/run_codegen_targets.sh b/scripts/run_codegen_targets.sh index 14d67f94e83f7b..5f8bcd5d51f138 100755 --- a/scripts/run_codegen_targets.sh +++ b/scripts/run_codegen_targets.sh @@ -38,19 +38,19 @@ fi # ... # # Most are buildconfig rules, but asn1oid is special -for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E '^gen_' | sed 's/: .*//')"; do +for name in $(ninja -C "$OUT_DIR" -t targets | grep -E '^gen_' | sed 's/: .*//'); do echo "Generating $name ..." ninja -C "$OUT_DIR" "$name" done # Code generation (based on zap/matter) -for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E '_codegen:' | sed 's/: .*//')"; do +for name in $(ninja -C "$OUT_DIR" -t targets | grep -E '_codegen:' | sed 's/: .*//'); do echo "Generating $name ..." ninja -C "$OUT_DIR" "$name" done # Linus targets: dbus generate hdeaders -for name in "$(ninja -C "$OUT_DIR" -t targets | grep -E 'dbus.*codegen:' | sed 's/: .*//')"; do +for name in $(ninja -C "$OUT_DIR" -t targets | grep -E 'dbus.*codegen:' | sed 's/: .*//'); do echo "Generating $name ..." ninja -C "$OUT_DIR" "$name" done From c07b25ee8df8ca038468675322012f8723146973 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 12:44:00 -0400 Subject: [PATCH 13/23] Add exception on shellharden on run_codegen_targets --- .restyled.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.restyled.yaml b/.restyled.yaml index 195765b70a34d4..f9bdfd3966b85f 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -74,6 +74,7 @@ exclude: - "examples/chef/zzz_generated/**/*" - "examples/platform/nxp/k32w/k32w0/scripts/demo_generated_certs/**/*" - "integrations/cloudbuild/*.yaml" # uglier long command line content + - "scripts/run_codegen_targets.sh" # shellharden breaks for loops over command outputs changed_paths: From 892e39ad56c4fcb94fa9a8f222dd8c2962897512 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 19 Oct 2022 13:57:22 -0400 Subject: [PATCH 14/23] Fix clang tidy location for darwin: it uses out/default not out/sanitizers --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1f375a3148360f..1773ffc4f07ea4 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -408,7 +408,7 @@ jobs: - name: Ensure codegen is done for sanitize timeout-minutes: 45 run: | - ./scripts/run_in_build_env.sh "./scripts/run_codegen_targets.sh out/sanitizers" + ./scripts/run_in_build_env.sh "./scripts/run_codegen_targets.sh out/default" - name: Clang-tidy validation timeout-minutes: 45 run: | From ae38dc48085fa56b9ececda1c8df53d277679925 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 11:55:00 -0400 Subject: [PATCH 15/23] Add a server cluster to the several_clusters unit test, to validate that we generate server callbacks to --- .../idl/tests/inputs/several_clusters.matter | 20 +++++++++++++++++++ .../bridge/BridgeClustersImpl.h | 9 +++++++++ .../outputs/several_clusters/bridge/Third.h | 5 ++++- .../cpp-app/PluginApplicationCallbacks.h | 3 ++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/scripts/idl/tests/inputs/several_clusters.matter b/scripts/idl/tests/inputs/several_clusters.matter index 3c56b1a628f449..a9963a3e3bcee0 100644 --- a/scripts/idl/tests/inputs/several_clusters.matter +++ b/scripts/idl/tests/inputs/several_clusters.matter @@ -14,3 +14,23 @@ client cluster Third = 3 { attribute MyEnum someEnum = 10; } + +server cluster Third = 3 { + enum MyEnum : enum8 { + kUnknown = 0; + kKnown = 100; + } + + attribute MyEnum someEnum = 10; + readonly attribute int16u clusterRevision = 65533; +} + +endpoint 0 { + device type rootdevice = 22; + binding cluster Second; + + server cluster Third { + ram attribute someEnum; + ram attribute clusterRevision default = 2; + } +} diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/BridgeClustersImpl.h b/scripts/idl/tests/outputs/several_clusters/bridge/BridgeClustersImpl.h index 16dafc39a900f4..e94ca747c56970 100644 --- a/scripts/idl/tests/outputs/several_clusters/bridge/BridgeClustersImpl.h +++ b/scripts/idl/tests/outputs/several_clusters/bridge/BridgeClustersImpl.h @@ -4,6 +4,7 @@ #include "bridge/First.h" #include "bridge/Second.h" #include "bridge/Third.h" +#include "bridge/Third.h" namespace clusters { @@ -39,6 +40,14 @@ struct ClusterInfo return new(mem) ThirdCluster(); }, }, + { + 3, + "Third", + sizeof(ThirdCluster), + [](void *mem) -> GeneratedCluster* { + return new(mem) ThirdCluster(); + }, + }, }; } diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/Third.h b/scripts/idl/tests/outputs/several_clusters/bridge/Third.h index 3779b80fa8a264..48e8c4537e4799 100644 --- a/scripts/idl/tests/outputs/several_clusters/bridge/Third.h +++ b/scripts/idl/tests/outputs/several_clusters/bridge/Third.h @@ -8,7 +8,8 @@ struct ThirdCluster : public GeneratedCluster { ThirdCluster() : - mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1) + mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1), + mClusterRevision(chip::CharSpan("clusterRevision"), 65533, 0, ZCL_INT16U_ATTRIBUTE_TYPE, 2, ZCL_THIRD_CLUSTER_REVISION) { } @@ -19,11 +20,13 @@ struct ThirdCluster : public GeneratedCluster { return std::vector({ static_cast(&mSomeEnum), + static_cast(&mClusterRevision), }); } Attribute mSomeEnum; + Attribute mClusterRevision; }; } diff --git a/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h b/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h index 1cb70f041e620d..00041de30d3ea9 100644 --- a/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h +++ b/scripts/idl/tests/outputs/several_clusters/cpp-app/PluginApplicationCallbacks.h @@ -5,5 +5,6 @@ #define MATTER_PLUGINS_INIT \ MatterFirstPluginClientInitCallback(); \ MatterSecondPluginClientInitCallback(); \ - MatterThirdPluginClientInitCallback(); + MatterThirdPluginClientInitCallback(); \ + MatterThirdPluginServerInitCallback(); From cf2decaf924956238394635f9aa08349d2ff567a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 13:34:07 -0400 Subject: [PATCH 16/23] Make bridge generate ONLY client clusters as it reuses the same name of generation --- scripts/idl/generators/bridge/__init__.py | 5 ++++- scripts/idl/test_generators.py | 1 + scripts/idl/tests/outputs/several_clusters/bridge/Third.h | 5 +---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/idl/generators/bridge/__init__.py b/scripts/idl/generators/bridge/__init__.py index 5d0bace9faf431..a1f58b14de150a 100644 --- a/scripts/idl/generators/bridge/__init__.py +++ b/scripts/idl/generators/bridge/__init__.py @@ -18,7 +18,7 @@ import re from idl.generators import CodeGenerator, GeneratorStorage -from idl.matter_idl_types import (Idl, Field, Attribute, Cluster) +from idl.matter_idl_types import Idl, Field, Attribute, Cluster, ClusterSide from idl import matter_idl_types from idl.generators.types import (ParseDataType, BasicString, BasicInteger, FundamentalType, IdlType, IdlEnumType, IdlBitmapType, TypeLookupContext) @@ -165,6 +165,9 @@ def internal_render_all(self): if not is_dynamic_cluster(cluster, self.idl): continue + if cluster.side != ClusterSide.CLIENT: + continue + self.internal_render_one_output( template_path="bridge/BridgeClustersCpp.jinja", output_file_name="bridge/%s.h" % cluster.name, diff --git a/scripts/idl/test_generators.py b/scripts/idl/test_generators.py index bd7dfc7c232987..730bfdbc610762 100755 --- a/scripts/idl/test_generators.py +++ b/scripts/idl/test_generators.py @@ -87,6 +87,7 @@ def get_existing_data(self, relative_path: str): def write_new_data(self, relative_path: str, content: str): if REGENERATE_GOLDEN_IMAGES: + print("RE-GENERATING %r" % relative_path) # Expect writing only on regeneration with open(self.get_existing_data_path(relative_path), 'wt') as golden: golden.write(content) diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/Third.h b/scripts/idl/tests/outputs/several_clusters/bridge/Third.h index 48e8c4537e4799..3779b80fa8a264 100644 --- a/scripts/idl/tests/outputs/several_clusters/bridge/Third.h +++ b/scripts/idl/tests/outputs/several_clusters/bridge/Third.h @@ -8,8 +8,7 @@ struct ThirdCluster : public GeneratedCluster { ThirdCluster() : - mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1), - mClusterRevision(chip::CharSpan("clusterRevision"), 65533, 0, ZCL_INT16U_ATTRIBUTE_TYPE, 2, ZCL_THIRD_CLUSTER_REVISION) + mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1) { } @@ -20,13 +19,11 @@ struct ThirdCluster : public GeneratedCluster { return std::vector({ static_cast(&mSomeEnum), - static_cast(&mClusterRevision), }); } Attribute mSomeEnum; - Attribute mClusterRevision; }; } From 575fd5d3649c6c45bf77c1dc811f4d90f1026e9c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 13:41:46 -0400 Subject: [PATCH 17/23] Separate client and server headers for bridge codegen --- scripts/idl/generators/bridge/__init__.py | 8 +++-- scripts/idl/tests/available_tests.yaml | 1 + .../several_clusters/bridge/ThirdClient.h | 32 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h diff --git a/scripts/idl/generators/bridge/__init__.py b/scripts/idl/generators/bridge/__init__.py index a1f58b14de150a..6fd4480bbdbf47 100644 --- a/scripts/idl/generators/bridge/__init__.py +++ b/scripts/idl/generators/bridge/__init__.py @@ -165,12 +165,14 @@ def internal_render_all(self): if not is_dynamic_cluster(cluster, self.idl): continue - if cluster.side != ClusterSide.CLIENT: - continue + if cluster.side != ClusterSide.SERVER: + output_file_name = "bridge/%s.h" % cluster.name + else: + output_file_name = "bridge/%sClient.h" % cluster.name self.internal_render_one_output( template_path="bridge/BridgeClustersCpp.jinja", - output_file_name="bridge/%s.h" % cluster.name, + output_file_name=output_file_name, vars={ 'cluster': cluster, 'idl': self.idl, diff --git a/scripts/idl/tests/available_tests.yaml b/scripts/idl/tests/available_tests.yaml index 0cd859af001681..3a651af988d6d8 100644 --- a/scripts/idl/tests/available_tests.yaml +++ b/scripts/idl/tests/available_tests.yaml @@ -57,6 +57,7 @@ bridge: bridge/First.h: outputs/several_clusters/bridge/First.h bridge/Second.h: outputs/several_clusters/bridge/Second.h bridge/Third.h: outputs/several_clusters/bridge/Third.h + bridge/ThirdClient.h: outputs/several_clusters/bridge/ThirdClient.h cpp-app: inputs/several_clusters.matter: diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h b/scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h new file mode 100644 index 00000000000000..48e8c4537e4799 --- /dev/null +++ b/scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h @@ -0,0 +1,32 @@ +#pragma once + +#include "BridgeGlobalStructs.h" +#include "third_party/connectedhomeip/examples/dynamic-bridge-app/linux/include/GeneratedClusters.h" + +namespace clusters { +struct ThirdCluster : public GeneratedCluster +{ + + ThirdCluster() : + mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1), + mClusterRevision(chip::CharSpan("clusterRevision"), 65533, 0, ZCL_INT16U_ATTRIBUTE_TYPE, 2, ZCL_THIRD_CLUSTER_REVISION) + { + } + + static constexpr uint32_t kClusterId =3; + chip::ClusterId GetClusterId() override { return kClusterId; } + + std::vector GetAttributes() override + { + return std::vector({ + static_cast(&mSomeEnum), + static_cast(&mClusterRevision), + }); + } + + + Attribute mSomeEnum; + Attribute mClusterRevision; +}; + +} From 34eddf49c70006e6e0924468083ca70def7be61f Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 13:47:10 -0400 Subject: [PATCH 18/23] Resolve bridge: clients have default names, Server headers are separate. This is until we figure out real names --- examples/dynamic-bridge-app/bridge-common/BUILD.gn | 2 +- scripts/idl/generators/bridge/__init__.py | 4 ++-- scripts/idl/tests/available_tests.yaml | 12 ++++++------ .../bridge/{DemoCluster.h => DemoClusterServer.h} | 0 .../bridge/{DemoCluster.h => DemoClusterServer.h} | 0 .../bridge/{First.h => FirstServer.h} | 0 .../bridge/{Second.h => SecondServer.h} | 0 .../tests/outputs/several_clusters/bridge/Third.h | 5 ++++- .../bridge/{ThirdClient.h => ThirdServer.h} | 5 +---- .../bridge/{MyCluster.h => MyClusterServer.h} | 0 10 files changed, 14 insertions(+), 14 deletions(-) rename scripts/idl/tests/outputs/cluster_struct_attribute/bridge/{DemoCluster.h => DemoClusterServer.h} (100%) rename scripts/idl/tests/outputs/global_struct_attribute/bridge/{DemoCluster.h => DemoClusterServer.h} (100%) rename scripts/idl/tests/outputs/several_clusters/bridge/{First.h => FirstServer.h} (100%) rename scripts/idl/tests/outputs/several_clusters/bridge/{Second.h => SecondServer.h} (100%) rename scripts/idl/tests/outputs/several_clusters/bridge/{ThirdClient.h => ThirdServer.h} (70%) rename scripts/idl/tests/outputs/simple_attribute/bridge/{MyCluster.h => MyClusterServer.h} (100%) diff --git a/examples/dynamic-bridge-app/bridge-common/BUILD.gn b/examples/dynamic-bridge-app/bridge-common/BUILD.gn index 0482fed92cc782..584e172b654b7c 100644 --- a/examples/dynamic-bridge-app/bridge-common/BUILD.gn +++ b/examples/dynamic-bridge-app/bridge-common/BUILD.gn @@ -31,7 +31,7 @@ chip_data_model("dynamic-bridge-common") { if (chip_enable_pw_rpc) { import("//build_overrides/pigweed.gni") - import("$dir_pw_protobuf_compiler/proto.gni") + IMPORT("$dir_pw_protobuf_compiler/proto.gni") pw_proto_library("bridge_service") { sources = [ "protos/bridge_service.proto" ] diff --git a/scripts/idl/generators/bridge/__init__.py b/scripts/idl/generators/bridge/__init__.py index 6fd4480bbdbf47..7e993dd965b66e 100644 --- a/scripts/idl/generators/bridge/__init__.py +++ b/scripts/idl/generators/bridge/__init__.py @@ -166,9 +166,9 @@ def internal_render_all(self): continue if cluster.side != ClusterSide.SERVER: - output_file_name = "bridge/%s.h" % cluster.name + output_file_name = "bridge/%sServer.h" % cluster.name else: - output_file_name = "bridge/%sClient.h" % cluster.name + output_file_name = "bridge/%s.h" % cluster.name self.internal_render_one_output( template_path="bridge/BridgeClustersCpp.jinja", diff --git a/scripts/idl/tests/available_tests.yaml b/scripts/idl/tests/available_tests.yaml index 3a651af988d6d8..a6d78a346e7f8e 100644 --- a/scripts/idl/tests/available_tests.yaml +++ b/scripts/idl/tests/available_tests.yaml @@ -39,25 +39,25 @@ bridge: inputs/simple_attribute.matter: bridge/BridgeClustersImpl.h: outputs/simple_attribute/bridge/BridgeClustersImpl.h bridge/BridgeGlobalStructs.h: outputs/simple_attribute/bridge/BridgeGlobalStructs.h - bridge/MyCluster.h: outputs/simple_attribute/bridge/MyCluster.h + bridge/MyClusterServer.h: outputs/simple_attribute/bridge/MyClusterServer.h inputs/global_struct_attribute.matter: bridge/BridgeClustersImpl.h: outputs/global_struct_attribute/bridge/BridgeClustersImpl.h bridge/BridgeGlobalStructs.h: outputs/global_struct_attribute/bridge/BridgeGlobalStructs.h - bridge/DemoCluster.h: outputs/global_struct_attribute/bridge/DemoCluster.h + bridge/DemoClusterServer.h: outputs/global_struct_attribute/bridge/DemoClusterServer.h inputs/cluster_struct_attribute.matter: bridge/BridgeClustersImpl.h: outputs/cluster_struct_attribute/bridge/BridgeClustersImpl.h bridge/BridgeGlobalStructs.h: outputs/cluster_struct_attribute/bridge/BridgeGlobalStructs.h - bridge/DemoCluster.h: outputs/cluster_struct_attribute/bridge/DemoCluster.h + bridge/DemoClusterServer.h: outputs/cluster_struct_attribute/bridge/DemoClusterServer.h inputs/several_clusters.matter: bridge/BridgeClustersImpl.h: outputs/several_clusters/bridge/BridgeClustersImpl.h bridge/BridgeGlobalStructs.h: outputs/several_clusters/bridge/BridgeGlobalStructs.h - bridge/First.h: outputs/several_clusters/bridge/First.h - bridge/Second.h: outputs/several_clusters/bridge/Second.h + bridge/FirstServer.h: outputs/several_clusters/bridge/FirstServer.h + bridge/SecondServer.h: outputs/several_clusters/bridge/SecondServer.h + bridge/ThirdServer.h: outputs/several_clusters/bridge/ThirdServer.h bridge/Third.h: outputs/several_clusters/bridge/Third.h - bridge/ThirdClient.h: outputs/several_clusters/bridge/ThirdClient.h cpp-app: inputs/several_clusters.matter: diff --git a/scripts/idl/tests/outputs/cluster_struct_attribute/bridge/DemoCluster.h b/scripts/idl/tests/outputs/cluster_struct_attribute/bridge/DemoClusterServer.h similarity index 100% rename from scripts/idl/tests/outputs/cluster_struct_attribute/bridge/DemoCluster.h rename to scripts/idl/tests/outputs/cluster_struct_attribute/bridge/DemoClusterServer.h diff --git a/scripts/idl/tests/outputs/global_struct_attribute/bridge/DemoCluster.h b/scripts/idl/tests/outputs/global_struct_attribute/bridge/DemoClusterServer.h similarity index 100% rename from scripts/idl/tests/outputs/global_struct_attribute/bridge/DemoCluster.h rename to scripts/idl/tests/outputs/global_struct_attribute/bridge/DemoClusterServer.h diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/First.h b/scripts/idl/tests/outputs/several_clusters/bridge/FirstServer.h similarity index 100% rename from scripts/idl/tests/outputs/several_clusters/bridge/First.h rename to scripts/idl/tests/outputs/several_clusters/bridge/FirstServer.h diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/Second.h b/scripts/idl/tests/outputs/several_clusters/bridge/SecondServer.h similarity index 100% rename from scripts/idl/tests/outputs/several_clusters/bridge/Second.h rename to scripts/idl/tests/outputs/several_clusters/bridge/SecondServer.h diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/Third.h b/scripts/idl/tests/outputs/several_clusters/bridge/Third.h index 3779b80fa8a264..48e8c4537e4799 100644 --- a/scripts/idl/tests/outputs/several_clusters/bridge/Third.h +++ b/scripts/idl/tests/outputs/several_clusters/bridge/Third.h @@ -8,7 +8,8 @@ struct ThirdCluster : public GeneratedCluster { ThirdCluster() : - mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1) + mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1), + mClusterRevision(chip::CharSpan("clusterRevision"), 65533, 0, ZCL_INT16U_ATTRIBUTE_TYPE, 2, ZCL_THIRD_CLUSTER_REVISION) { } @@ -19,11 +20,13 @@ struct ThirdCluster : public GeneratedCluster { return std::vector({ static_cast(&mSomeEnum), + static_cast(&mClusterRevision), }); } Attribute mSomeEnum; + Attribute mClusterRevision; }; } diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h b/scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h similarity index 70% rename from scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h rename to scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h index 48e8c4537e4799..3779b80fa8a264 100644 --- a/scripts/idl/tests/outputs/several_clusters/bridge/ThirdClient.h +++ b/scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h @@ -8,8 +8,7 @@ struct ThirdCluster : public GeneratedCluster { ThirdCluster() : - mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1), - mClusterRevision(chip::CharSpan("clusterRevision"), 65533, 0, ZCL_INT16U_ATTRIBUTE_TYPE, 2, ZCL_THIRD_CLUSTER_REVISION) + mSomeEnum(chip::CharSpan("someEnum"), 10, ATTRIBUTE_MASK_WRITABLE, ZCL_ENUM8_ATTRIBUTE_TYPE, 1) { } @@ -20,13 +19,11 @@ struct ThirdCluster : public GeneratedCluster { return std::vector({ static_cast(&mSomeEnum), - static_cast(&mClusterRevision), }); } Attribute mSomeEnum; - Attribute mClusterRevision; }; } diff --git a/scripts/idl/tests/outputs/simple_attribute/bridge/MyCluster.h b/scripts/idl/tests/outputs/simple_attribute/bridge/MyClusterServer.h similarity index 100% rename from scripts/idl/tests/outputs/simple_attribute/bridge/MyCluster.h rename to scripts/idl/tests/outputs/simple_attribute/bridge/MyClusterServer.h From a730f6e217cf4b2343cc5e41c36ced7c58f89ba2 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 13:49:03 -0400 Subject: [PATCH 19/23] Fix build rules --- scripts/idl/BUILD.gn | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/idl/BUILD.gn b/scripts/idl/BUILD.gn index 741b22ec45aff1..359f50e89d4159 100644 --- a/scripts/idl/BUILD.gn +++ b/scripts/idl/BUILD.gn @@ -41,21 +41,22 @@ pw_python_package("idl") { "tests/inputs/simple_attribute.matter", "tests/outputs/cluster_struct_attribute/bridge/BridgeClustersImpl.h", "tests/outputs/cluster_struct_attribute/bridge/BridgeGlobalStructs.h", - "tests/outputs/cluster_struct_attribute/bridge/DemoCluster.h", + "tests/outputs/cluster_struct_attribute/bridge/DemoClusterServer.h", "tests/outputs/cluster_struct_attribute/jni/DemoClusterClient-ReadImpl.cpp", "tests/outputs/cluster_struct_attribute/jni/DemoClusterClient-InvokeSubscribeImpl.cpp", "tests/outputs/global_struct_attribute/bridge/BridgeClustersImpl.h", "tests/outputs/global_struct_attribute/bridge/BridgeGlobalStructs.h", - "tests/outputs/global_struct_attribute/bridge/DemoCluster.h", + "tests/outputs/global_struct_attribute/bridge/DemoClusterServer.h", "tests/outputs/global_struct_attribute/jni/DemoClusterClient-ReadImpl.cpp", "tests/outputs/global_struct_attribute/jni/DemoClusterClient-InvokeSubscribeImpl.cpp", "tests/outputs/optional_argument/jni/MyClusterClient-ReadImpl.cpp", "tests/outputs/optional_argument/jni/MyClusterClient-InvokeSubscribeImpl.cpp", "tests/outputs/several_clusters/bridge/BridgeClustersImpl.h", "tests/outputs/several_clusters/bridge/BridgeGlobalStructs.h", - "tests/outputs/several_clusters/bridge/First.h", - "tests/outputs/several_clusters/bridge/Second.h", + "tests/outputs/several_clusters/bridge/FirstServer.h", + "tests/outputs/several_clusters/bridge/SecondServer.h", "tests/outputs/several_clusters/bridge/Third.h", + "tests/outputs/several_clusters/bridge/ThirdServer.h", "tests/outputs/several_clusters/jni/FirstClient-ReadImpl.cpp", "tests/outputs/several_clusters/jni/SecondClient-ReadImpl.cpp", "tests/outputs/several_clusters/jni/ThirdClient-ReadImpl.cpp", @@ -64,7 +65,7 @@ pw_python_package("idl") { "tests/outputs/several_clusters/jni/ThirdClient-InvokeSubscribeImpl.cpp", "tests/outputs/simple_attribute/bridge/BridgeClustersImpl.h", "tests/outputs/simple_attribute/bridge/BridgeGlobalStructs.h", - "tests/outputs/simple_attribute/bridge/MyCluster.h", + "tests/outputs/simple_attribute/bridge/MyClusterServer.h", "tests/outputs/simple_attribute/jni/MyClusterClient-ReadImpl.cpp", "tests/outputs/simple_attribute/jni/MyClusterClient-InvokeSubscribeImpl.cpp", ] From 1dbe8891d487bd97c1fb7a47fb6b2a7ec8e1bad8 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 14:27:05 -0400 Subject: [PATCH 20/23] Do not lint test matter files for spec compliance --- .github/workflows/lint.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6c980a2dbd1445..5af53cca882e1d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -97,6 +97,9 @@ jobs: if [ "$idl_file" = './examples/thermostat/thermostat-common/thermostat.matter' ]; then continue; fi if [ "$idl_file" = './examples/window-app/common/window-app.matter' ]; then continue; fi + # Test files are intentionally small and not spec-compilant, just parse-compliant + if [[ "$idl_file" == "./scripts/idl/tests/inputs/"* ]]; then continue; fi + ./scripts/run_in_build_env.sh "./scripts/idl_lint.py --log-level warn $idl_file" >/dev/null || exit 1 done From b1e8c7755e686186ad3f717ea408f722627d0af4 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 14:47:07 -0400 Subject: [PATCH 21/23] Github runners do not use bash by default. Make the conditionals different for lint skipping --- .github/workflows/lint.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5af53cca882e1d..c8f486cb3288cc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -98,7 +98,11 @@ jobs: if [ "$idl_file" = './examples/window-app/common/window-app.matter' ]; then continue; fi # Test files are intentionally small and not spec-compilant, just parse-compliant - if [[ "$idl_file" == "./scripts/idl/tests/inputs/"* ]]; then continue; fi + if [ "$idl_file" == "./scripts/idl/tests/inputs/cluster_struct_attribute.matter" ]; then continue; fi + if [ "$idl_file" == "./scripts/idl/tests/inputs/global_struct_attribute.matter" ]; then continue; fi + if [ "$idl_file" == "./scripts/idl/tests/inputs/optional_argument.matter" ]; then continue; fi + if [ "$idl_file" == "./scripts/idl/tests/inputs/several_clusters.matter" ]; then continue; fi + if [ "$idl_file" == "./scripts/idl/tests/inputs/simple_attribute.matter" ]; then continue; fi ./scripts/run_in_build_env.sh "./scripts/idl_lint.py --log-level warn $idl_file" >/dev/null || exit 1 done From 209d0c93a02fe18c8904ae1430eef6a4401114cb Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 14:59:13 -0400 Subject: [PATCH 22/23] Fix operator for lint exception check --- .github/workflows/lint.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c8f486cb3288cc..9eebd41beb3384 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -98,11 +98,11 @@ jobs: if [ "$idl_file" = './examples/window-app/common/window-app.matter' ]; then continue; fi # Test files are intentionally small and not spec-compilant, just parse-compliant - if [ "$idl_file" == "./scripts/idl/tests/inputs/cluster_struct_attribute.matter" ]; then continue; fi - if [ "$idl_file" == "./scripts/idl/tests/inputs/global_struct_attribute.matter" ]; then continue; fi - if [ "$idl_file" == "./scripts/idl/tests/inputs/optional_argument.matter" ]; then continue; fi - if [ "$idl_file" == "./scripts/idl/tests/inputs/several_clusters.matter" ]; then continue; fi - if [ "$idl_file" == "./scripts/idl/tests/inputs/simple_attribute.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/cluster_struct_attribute.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/global_struct_attribute.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/optional_argument.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/several_clusters.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/simple_attribute.matter" ]; then continue; fi ./scripts/run_in_build_env.sh "./scripts/idl_lint.py --log-level warn $idl_file" >/dev/null || exit 1 done From 3568c884383455c53bc1fffa14c4d0c617d0bd95 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Oct 2022 22:43:04 -0400 Subject: [PATCH 23/23] Undo typo --- examples/ota-requestor-app/esp32/main/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ota-requestor-app/esp32/main/CMakeLists.txt b/examples/ota-requestor-app/esp32/main/CMakeLists.txt index 5939f42f6f4f66..a0633511cfaded 100644 --- a/examples/ota-requestor-app/esp32/main/CMakeLists.txt +++ b/examples/ota-requestor-app/esp32/main/CMakeLists.txt @@ -100,7 +100,7 @@ target_compile_options(${COMPONENT_LIB} PUBLIC if (CONFIG_ENABLE_PW_RPC) -set(PIGWEED_ROOT "${cHIP_ROOT}/third_party/pigweed/repo") +set(PIGWEED_ROOT "${CHIP_ROOT}/third_party/pigweed/repo") include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) include(${PIGWEED_ROOT}/pw_protobuf_compiler/proto.cmake) set(dir_pw_third_party_nanopb "${CHIP_ROOT}/third_party/nanopb/repo" CACHE STRING "" FORCE)