Skip to content

Commit

Permalink
Add Darwin codegen support for global structs and enums. (#34527)
Browse files Browse the repository at this point in the history
There's a bunch of refactoring of templates to avoid copy/paste for the global
case.  But the generated output is the same so far, until some ZAP-side changes
happen that would let us actually enable the global bits.
  • Loading branch information
bzbarsky-apple authored Jul 26, 2024
1 parent 9ef5bbf commit e58954d
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 122 deletions.
51 changes: 7 additions & 44 deletions src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -107,53 +107,16 @@ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptio
{{/unless}}
{{/zcl_clusters}}

{{#zcl_clusters}}
{{#zcl_enums}}
{{#*inline "enumDef"}}
typedef NS_ENUM({{asUnderlyingZclType name}}, {{objCEnumName clusterName enumName}}) {
{{#zcl_enum_items}}
{{#if (isSupported ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}}
{{objCEnumName ../clusterName ../enumName}}{{asUpperCamelCase label preserveAcronyms=true}} {{availability ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true) deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../../name preserveAcronyms=true) ../label) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}},
{{/if}}
{{#*inline "oldNameItemDecl"}}
{{#if oldItemName}}
{{#if (isSupported ../clusterName enum=../enumName enumValue=oldItemName)}}
{{objCEnumName ../clusterName ../enumName}}{{objCEnumItemLabel oldItemName}} {{availability ../clusterName enum=../enumName enumValue=oldItemName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../../name preserveAcronyms=true) ../label) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}},
{{/if}}
{{/if}}
{{/inline}}
{{> oldNameItemDecl oldItemName=(oldName ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}}
{{/zcl_enum_items}}
{{!We had extra "Not Supported" values for DoorLockUserStatus/DoorLockUserType that we have to wedge in here manually for now.}}
{{#if (and (isStrEqual clusterName "DoorLock")
(or (isStrEqual enumName "UserTypeEnum") (isStrEqual enumName "UserStatusEnum"))
(isSupported clusterName enum=enumName enumValue="NotSupported"))}}
{{objCEnumName clusterName enumName}}{{objCEnumItemLabel "NotSupported"}} {{availability clusterName enum=enumName enumValue="NotSupported" deprecationMessage="This value is not part of the specification and will be removed"}} = 0xFF,
{{/if}}
}
{{/inline}}
{{#if (isSupported (asUpperCamelCase ../name preserveAcronyms=true) enum=(asUpperCamelCase label preserveAcronyms=true))}}
{{> enumDef name=name clusterName=(asUpperCamelCase ../name preserveAcronyms=true) enumName=(asUpperCamelCase label preserveAcronyms=true)}} {{availability (asUpperCamelCase ../name preserveAcronyms=true) enum=(asUpperCamelCase label preserveAcronyms=true) deprecationMessage="This enum is unused and will be removed"}};
{{/if}}
{{! Takes the name of the enum to use as enumName. }}
{{#*inline "oldNameDecl"}}
{{#if (isSupported (compatClusterNameRemapping ../name) enum=enumName)}}
{{#if has_no_clusters}}
{{> enum_decl cluster="Globals" name=name enumLabel=label}}

{{> enumDef name=name clusterName=(compatClusterNameRemapping ../name) enumName=enumName}} {{availability (compatClusterNameRemapping ../name) enum=enumName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../name preserveAcronyms=true) label))}};
{{/if}}
{{/inline}}
{{! Takes the old name of the enum, if any, as oldEnumName. }}
{{#*inline "oldNameCheck"}}
{{#if (or oldEnumName
(hasOldName (asUpperCamelCase ../name preserveAcronyms=true)))}}
{{#if oldEnumName}}
{{> oldNameDecl enumName=oldEnumName}}
{{else}}
{{> oldNameDecl enumName=(asUpperCamelCase label preserveAcronyms=true)}}
{{/if}}
{{/if}}
{{/inline}}
{{> oldNameCheck oldEnumName=(oldName (asUpperCamelCase ../name preserveAcronyms=true) enum=(asUpperCamelCase label preserveAcronyms=true))}}
{{/zcl_enums}}

{{#zcl_clusters}}
{{#zcl_enums}}
{{> enum_decl cluster=../name name=name enumLabel=label}}

{{/zcl_enums}}
{{#zcl_bitmaps}}
Expand Down
59 changes: 6 additions & 53 deletions src/darwin/Framework/CHIP/templates/MTRStructsObjc-src.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,15 @@

NS_ASSUME_NONNULL_BEGIN

{{#zcl_clusters}}
{{#zcl_structs}}
{{#*inline "interfaceImpl"}}
@implementation {{interfaceName}}
- (instancetype)init
{
if (self = [super init]) {
{{#zcl_struct_items}}
{{#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))}}
{{>init_struct_member label=label type=type cluster=parent.parent.name}}
{{/if}}
{{/zcl_struct_items}}
}
return self;
}

- (id)copyWithZone:(NSZone * _Nullable)zone
{
auto other = [[{{interfaceName}} alloc] init];

{{#zcl_struct_items}}
{{#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))}}
other.{{asStructPropertyName label}} = self.{{asStructPropertyName label}};
{{/if}}
{{/zcl_struct_items}}

return other;
}

- (NSString *)description
{
NSString *descriptionString = [NSString stringWithFormat:@"<%@: {{#zcl_struct_items~}}
{{~#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))~}}
{{~asStructPropertyName label}}:%@; {{!Just here to keep the preceding space}}
{{~/if~}}
{{~/zcl_struct_items}}>", NSStringFromClass([self class]){{#zcl_struct_items~}}
{{~#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))~}}
,{{#if isArray}}_{{asStructPropertyName label}}{{else if (isOctetString type)}}[_{{asStructPropertyName label}} base64EncodedStringWithOptions:0]{{else}}_{{asStructPropertyName label}}{{/if}}
{{~/if~}}
{{~/zcl_struct_items}}];
return descriptionString;
}
{{#zcl_struct_items}}
{{#if (and (hasOldName (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(asStructPropertyName label))
(isSupported (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(oldName (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(asStructPropertyName label))))}}

{{> renamed_struct_field_impl cluster=../../name type=type newName=label oldName=(oldName (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(asStructPropertyName label))}}
{{#if has_no_clusters}}
{{> struct_interface_impl cluster="Globals" struct=name}}
{{/if}}
{{/zcl_struct_items}}

@end
{{/inline}}
{{/zcl_structs}}

{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true))}}
{{> interfaceImpl interfaceName=(concat "MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))}}
{{/if}}
{{#zcl_clusters}}
{{#zcl_structs}}
{{> struct_interface_impl cluster=parent.name struct=name}}

{{! Takes the name of the struct to use as structName. }}
{{#*inline "oldNameImpl"}}
Expand Down
36 changes: 11 additions & 25 deletions src/darwin/Framework/CHIP/templates/MTRStructsObjc.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,22 @@

NS_ASSUME_NONNULL_BEGIN

{{#zcl_clusters}}
{{#zcl_structs}}
{{#*inline "interfaceDecl"}}
{{#zcl_struct_items}}
{{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}}
{{> struct_field_decl cluster=../cluster type=type label=label}} {{availability (asUpperCamelCase ../cluster preserveAcronyms=true) struct=../struct structField=(asStructPropertyName label) deprecationMessage=(concat "Please use MTR" (asUpperCamelCase ../../name preserveAcronyms=true) "Cluster" (asUpperCamelCase ../name preserveAcronyms=true))}};
{{/if}}
{{#if (hasOldName ../cluster struct=../struct structField=(asStructPropertyName label))}}
{{#if (isSupported ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)))}}
{{> struct_field_decl cluster=../cluster type=type label=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))}} {{availability ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)) deprecationMessage=(concat "Please use " (asStructPropertyName label))}};
{{/if}}
{{#if has_no_clusters}}
{{> struct_interface_decl cluster="Globals" originalCluster="Globals" struct=(asUpperCamelCase name preserveAcronyms=true) baseName="" deprecationMessage="This struct is unused and will be removed"}}
{{/if}}
{{/zcl_struct_items}}
{{/inline}}
{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true))}}
{{availability (asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true) deprecationMessage="This struct is unused and will be removed"}}
@interface MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}} : NSObject <NSCopying>
{{> interfaceDecl cluster=(asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true)}}
@end
{{/zcl_structs}}

{{/if}}
{{#zcl_clusters}}
{{#zcl_structs}}
{{> struct_interface_decl cluster=(asUpperCamelCase parent.name preserveAcronyms=true) originalCluster=parent.name struct=(asUpperCamelCase name preserveAcronyms=true) baseName="" deprecationMessage="This struct is unused and will be removed"}}
{{! Takes the name of the struct to use as structName. }}
{{#*inline "oldNameDecl"}}
{{#if (isSupported (compatClusterNameRemapping parent.name) struct=structName)}}
{{availability (compatClusterNameRemapping parent.name) struct=structName deprecationMessage=(concat "Please use MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))}}
@interface MTR{{compatClusterNameRemapping parent.name}}Cluster{{structName}} : MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}}
{{> interfaceDecl cluster=(compatClusterNameRemapping parent.name) struct=structName}}
@end

{{/if}}
{{> struct_interface_decl cluster=(compatClusterNameRemapping parent.name)
originalCluster=parent.name
struct=structName
baseName=(concat "MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))
deprecationMessage=(concat "Please use MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))}}
{{/inline}}
{{! Takes the old name of the struct, if any, as oldStructName. }}
{{#*inline "oldNameCheck"}}
Expand Down
9 changes: 9 additions & 0 deletions src/darwin/Framework/CHIP/templates/availability.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9717,3 +9717,12 @@
Feature:
# Targeting 1.4
- ActionSwitch
removed:
structs:
Globals:
# Don't enable TestGlobalStruct until the ZAP side is fixed to handle it properly
- TestGlobalStruct
enums:
Globals:
# Don't enable TestGlobalEnum until the ZAP side is fixed to handle it properly
- TestGlobalEnum
46 changes: 46 additions & 0 deletions src/darwin/Framework/CHIP/templates/partials/enum_decl.zapt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{{! Arguments: cluster (might be "Globals", is not case-canonicalized), name, enumLabel }}
{{#*inline "enumDef"}}
typedef NS_ENUM({{asUnderlyingZclType name}}, {{objCEnumName clusterName enumName}}) {
{{#zcl_enum_items}}
{{#if (isSupported ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}}
{{objCEnumName ../clusterName ../enumName}}{{asUpperCamelCase label preserveAcronyms=true}} {{availability ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true) deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../cluster preserveAcronyms=true) ../enumLabel) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}},
{{/if}}
{{#*inline "oldNameItemDecl"}}
{{#if oldItemName}}
{{#if (isSupported ../clusterName enum=../enumName enumValue=oldItemName)}}
{{objCEnumName ../clusterName ../enumName}}{{objCEnumItemLabel oldItemName}} {{availability ../clusterName enum=../enumName enumValue=oldItemName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../cluster preserveAcronyms=true) ../enumLabel) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}},
{{/if}}
{{/if}}
{{/inline}}
{{> oldNameItemDecl oldItemName=(oldName ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}}
{{/zcl_enum_items}}
{{!We had extra "Not Supported" values for DoorLockUserStatus/DoorLockUserType that we have to wedge in here manually for now.}}
{{#if (and (isStrEqual clusterName "DoorLock")
(or (isStrEqual enumName "UserTypeEnum") (isStrEqual enumName "UserStatusEnum"))
(isSupported clusterName enum=enumName enumValue="NotSupported"))}}
{{objCEnumName clusterName enumName}}{{objCEnumItemLabel "NotSupported"}} {{availability clusterName enum=enumName enumValue="NotSupported" deprecationMessage="This value is not part of the specification and will be removed"}} = 0xFF,
{{/if}}
}
{{/inline}}
{{#if (isSupported (asUpperCamelCase cluster preserveAcronyms=true) enum=(asUpperCamelCase enumLabel preserveAcronyms=true))}}
{{> enumDef name=name clusterName=(asUpperCamelCase cluster preserveAcronyms=true) enumName=(asUpperCamelCase enumLabel preserveAcronyms=true)}} {{availability (asUpperCamelCase cluster preserveAcronyms=true) enum=(asUpperCamelCase enumLabel preserveAcronyms=true) deprecationMessage="This enum is unused and will be removed"}};
{{/if}}
{{! Takes the name of the enum to use as enumName. }}
{{#*inline "oldNameDecl"}}
{{#if (isSupported (compatClusterNameRemapping cluster) enum=enumName)}}

{{> enumDef name=name clusterName=(compatClusterNameRemapping cluster) enumName=enumName}} {{availability (compatClusterNameRemapping cluster) enum=enumName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase cluster preserveAcronyms=true) enumLabel))}};
{{/if}}
{{/inline}}
{{! Takes the old name of the enum, if any, as oldEnumName. }}
{{#*inline "oldNameCheck"}}
{{#if (or oldEnumName
(hasOldName (asUpperCamelCase cluster preserveAcronyms=true)))}}
{{#if oldEnumName}}
{{> oldNameDecl enumName=oldEnumName}}
{{else}}
{{> oldNameDecl enumName=(asUpperCamelCase enumLabel preserveAcronyms=true)}}
{{/if}}
{{/if}}
{{/inline}}
{{> oldNameCheck oldEnumName=(oldName (asUpperCamelCase cluster preserveAcronyms=true) enum=(asUpperCamelCase enumLabel preserveAcronyms=true))}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{{! Arguments: cluster (might be "Globals", is case-canonicalized already), originalCluster (the name before remapping and whatnot), struct, baseName (might be "" to indicate NSObject), deprecationMessage }}
{{#if (isSupported cluster struct=struct)}}
{{availability cluster struct=struct deprecationMessage=deprecationMessage}}
@interface {{#if (isStrEqual cluster "Globals") ~}}
MTRDataType{{struct}}
{{~else~}}
MTR{{cluster}}Cluster{{struct}}
{{~/if}} : {{#if (isStrEqual baseName "")~}}
NSObject<NSCopying>
{{~else~}}
{{baseName}}
{{~/if}}
{{#zcl_struct_items}}
{{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}}
{{> struct_field_decl cluster=../cluster type=type label=label}} {{availability ../cluster struct=../struct structField=(asStructPropertyName label) deprecationMessage=(concat "Please use MTR" (asUpperCamelCase ../originalCluster preserveAcronyms=true) "Cluster" (asUpperCamelCase ../name preserveAcronyms=true))}};
{{/if}}
{{#if (hasOldName ../cluster struct=../struct structField=(asStructPropertyName label))}}
{{#if (isSupported ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)))}}
{{> struct_field_decl cluster=../cluster type=type label=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))}} {{availability ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)) deprecationMessage=(concat "Please use " (asStructPropertyName label))}};
{{/if}}
{{/if}}
{{/zcl_struct_items}}
@end

{{/if}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{{! Arguments: cluster (might be "Globals", not case-canonicalized), struct }}
{{! Avoid uppercasing stuff all the time by wrapping the whole thing in an inline that takes cluster,
originalCluster, and struct, where cluster and struct are uppercased }}
{{#*inline "interfaceImpl"}}
{{#if (isSupported cluster struct=struct)}}
@implementation {{asObjectiveCClass struct cluster}}
- (instancetype)init
{
if (self = [super init]) {
{{#zcl_struct_items}}
{{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}}
{{>init_struct_member label=label type=type cluster=../originalCluster}}
{{/if}}
{{/zcl_struct_items}}
}
return self;
}

- (id)copyWithZone:(NSZone * _Nullable)zone
{
auto other = [[{{asObjectiveCClass struct cluster}} alloc] init];

{{#zcl_struct_items}}
{{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}}
other.{{asStructPropertyName label}} = self.{{asStructPropertyName label}};
{{/if}}
{{/zcl_struct_items}}

return other;
}

- (NSString *)description
{
NSString *descriptionString = [NSString stringWithFormat:@"<%@: {{#zcl_struct_items~}}
{{~#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))~}}
{{~asStructPropertyName label}}:%@; {{!Just here to keep the preceding space}}
{{~/if~}}
{{~/zcl_struct_items}}>", NSStringFromClass([self class]){{#zcl_struct_items~}}
{{~#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))~}}
,{{#if isArray}}_{{asStructPropertyName label}}{{else if (isOctetString type)}}[_{{asStructPropertyName label}} base64EncodedStringWithOptions:0]{{else}}_{{asStructPropertyName label}}{{/if}}
{{~/if~}}
{{~/zcl_struct_items}}];
return descriptionString;
}
{{#zcl_struct_items}}
{{#if (and (hasOldName ../cluster struct=../struct structField=(asStructPropertyName label))
(isSupported ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))))}}

{{> renamed_struct_field_impl cluster=../originalCluster type=type newName=label oldName=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))}}
{{/if}}
{{/zcl_struct_items}}

@end

{{/if}}
{{/inline}}
{{> interfaceImpl cluster=(asUpperCamelCase cluster preserveAcronyms=true) originalCluster=cluster struct=(asUpperCamelCase struct preserveAcronyms=true)}}
12 changes: 12 additions & 0 deletions src/darwin/Framework/CHIP/templates/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
"name": "struct_field_decl",
"path": "partials/struct_field_decl.zapt"
},
{
"name": "struct_interface_decl",
"path": "partials/struct_interface_decl.zapt"
},
{
"name": "struct_interface_impl",
"path": "partials/struct_interface_impl.zapt"
},
{
"name": "enum_decl",
"path": "partials/enum_decl.zapt"
},
{
"name": "renamed_struct_field_impl",
"path": "partials/renamed_struct_field_impl.zapt"
Expand Down

0 comments on commit e58954d

Please sign in to comment.