fix code gen for Bitmap types (#23707)

* fix code gen for Bitmap types

* Add a bitmap8 data type to our golden image unit tests, to validate that codegen for bitmaps does not regress

Co-authored-by: Andrei Litvin <andy314@gmail.com>
diff --git a/scripts/idl/generators/bridge/__init__.py b/scripts/idl/generators/bridge/__init__.py
index 7e993dd..7a43c9e 100644
--- a/scripts/idl/generators/bridge/__init__.py
+++ b/scripts/idl/generators/bridge/__init__.py
@@ -44,22 +44,15 @@
     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:
+    if type(actual) == IdlEnumType or 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()
+            'ZCL_%s_ATTRIBUTE_TYPE' % actual.idl_name.upper()
 
     if type(actual) == BasicInteger:
-        name = orig.idl_name.upper()
-        if is_enum:
-            name = actual.idl_name.upper()
+        name = actual.idl_name.upper()
         ty = "int%d_t" % actual.power_of_two_bits
         if not actual.is_signed:
             ty = "u" + ty
diff --git a/scripts/idl/tests/inputs/several_clusters.matter b/scripts/idl/tests/inputs/several_clusters.matter
index a9963a3..48832dd 100644
--- a/scripts/idl/tests/inputs/several_clusters.matter
+++ b/scripts/idl/tests/inputs/several_clusters.matter
@@ -12,7 +12,13 @@
       kKnown = 100;
     }
 
+    bitmap LevelControlOptions : BITMAP8 {
+      kExecuteIfOff = 0x1;
+      kCoupleColorTempToLevel = 0x2;
+    }
+
     attribute MyEnum someEnum = 10;
+    attribute LevelControlOptions options = 20;
 }
 
 server cluster Third = 3 {
diff --git a/scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h b/scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h
index 3779b80..6f52806 100644
--- a/scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h
+++ b/scripts/idl/tests/outputs/several_clusters/bridge/ThirdServer.h
@@ -8,7 +8,8 @@
 {
 
   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),
+      mOptions(chip::CharSpan("options"), 20, ATTRIBUTE_MASK_WRITABLE, ZCL_BITMAP8_ATTRIBUTE_TYPE, 1)
   {
   }
 
@@ -19,11 +20,13 @@
   {
     return std::vector<AttributeInterface*>({
       static_cast<AttributeInterface*>(&mSomeEnum),
+      static_cast<AttributeInterface*>(&mOptions),
     });
   }
 
 
   Attribute<uint8_t> mSomeEnum;
+  Attribute<uint8_t> mOptions;
 };
 
 }
diff --git a/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-InvokeSubscribeImpl.cpp b/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-InvokeSubscribeImpl.cpp
index d39226d..125e9a9 100644
--- a/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-InvokeSubscribeImpl.cpp
+++ b/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-InvokeSubscribeImpl.cpp
@@ -53,4 +53,25 @@
 
     onSuccess.release();
     onFailure.release();
+}JNI_METHOD(void, ThirdCluster, subscribeOptionsAttribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jint minInterval, jint maxInterval)
+{
+    chip::DeviceLayer::StackLock lock;std::unique_ptr<CHIPInt8uAttributeCallback, void (*)(CHIPInt8uAttributeCallback *)> onSuccess(Platform::New<CHIPInt8uAttributeCallback>(callback, true), chip::Platform::Delete<CHIPInt8uAttributeCallback>);
+    VerifyOrReturn(onSuccess.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY));
+
+    std::unique_ptr<CHIPDefaultFailureCallback, void (*)(CHIPDefaultFailureCallback *)> onFailure(Platform::New<CHIPDefaultFailureCallback>(callback), chip::Platform::Delete<CHIPDefaultFailureCallback>);
+    VerifyOrReturn(onFailure.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY));
+
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    ThirdCluster * cppCluster = reinterpret_cast<ThirdCluster *>(clusterPtr);
+    VerifyOrReturn(cppCluster != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE));
+
+    using TypeInfo = chip::app::Clusters::Third::Attributes::Options::TypeInfo;
+    auto successFn = chip::Callback::Callback<CHIPThirdClusterOptionsAttributeCallbackType>::FromCancelable(onSuccess->Cancel());
+    auto failureFn = chip::Callback::Callback<CHIPDefaultFailureCallbackType>::FromCancelable(onFailure->Cancel());
+
+    err = cppCluster->SubscribeAttribute<TypeInfo>(onSuccess->mContext, successFn->mCall, failureFn->mCall, static_cast<uint16_t>(minInterval), static_cast<uint16_t>(maxInterval), CHIPInt8uAttributeCallback::OnSubscriptionEstablished);
+    VerifyOrReturn(err == CHIP_NO_ERROR, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error subscribing to attribute", err));
+
+    onSuccess.release();
+    onFailure.release();
 }
diff --git a/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-ReadImpl.cpp b/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-ReadImpl.cpp
index a18afd7..2cc8eb1 100644
--- a/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-ReadImpl.cpp
+++ b/scripts/idl/tests/outputs/several_clusters/jni/ThirdClient-ReadImpl.cpp
@@ -36,3 +36,27 @@
 }
 
 
+JNI_METHOD(void, ThirdCluster, readOptionsAttribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback)
+{
+    chip::DeviceLayer::StackLock lock;
+    using TypeInfo = chip::app::Clusters::Third::Attributes::Options::TypeInfo;
+    std::unique_ptr<CHIPInt8uAttributeCallback, void (*)(CHIPInt8uAttributeCallback *)> onSuccess(chip::Platform::New<CHIPInt8uAttributeCallback>(callback, false), chip::Platform::Delete<CHIPInt8uAttributeCallback>);
+    VerifyOrReturn(onSuccess.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY));
+
+    std::unique_ptr<chip::CHIPDefaultFailureCallback, void (*)(chip::CHIPDefaultFailureCallback *)> onFailure(chip::Platform::New<chip::CHIPDefaultFailureCallback>(callback), chip::Platform::Delete<chip::CHIPDefaultFailureCallback>);
+    VerifyOrReturn(onFailure.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY));
+
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    chip::Controller::ThirdCluster * cppCluster = reinterpret_cast<chip::Controller::ThirdCluster *>(clusterPtr);
+    VerifyOrReturn(cppCluster != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE));
+
+    auto successFn = chip::Callback::Callback<CHIPThirdClusterOptionsAttributeCallbackType>::FromCancelable(onSuccess->Cancel());
+    auto failureFn = chip::Callback::Callback<CHIPDefaultFailureCallbackType>::FromCancelable(onFailure->Cancel());
+    err = cppCluster->ReadAttribute<TypeInfo>(onSuccess->mContext, successFn->mCall, failureFn->mCall);
+    VerifyOrReturn(err == CHIP_NO_ERROR, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error reading attribute", err));
+
+    onSuccess.release();
+    onFailure.release();
+}
+
+