Add support for transforming a property set after its contents

This change adds support for transforming a property set after its
contents. This allows a transform to recursively prune empty property
sets that were created for a module.

The transformPropertySet method was renamed to
transformPropertySetBeforeContents and a new
transformPropertySetAfterContents method was added.

Bug: 148933848
Test: m nothing
Change-Id: Ia198d47e042b98c69406db4bc12859869816a387
diff --git a/sdk/bp.go b/sdk/bp.go
index 5c340cd..c2a75e4 100644
--- a/sdk/bp.go
+++ b/sdk/bp.go
@@ -94,9 +94,11 @@
 }
 
 func transformPropertySet(transformer bpPropertyTransformer, name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
-	newPropertySet, newTag := transformer.transformPropertySet(name, propertySet, tag)
+	newPropertySet, newTag := transformer.transformPropertySetBeforeContents(name, propertySet, tag)
 	if newPropertySet != nil {
 		newPropertySet.transformContents(transformer)
+
+		newPropertySet, newTag = transformer.transformPropertySetAfterContents(name, newPropertySet, newTag)
 	}
 	return newPropertySet, newTag
 }
@@ -149,7 +151,17 @@
 	// The name will be "" for the top level property set.
 	//
 	// Returning (nil, ...) will cause the property set to be removed.
-	transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
+	transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
+
+	// Transform the property set, returning the new property set/tag to insert back into the
+	// parent property set (or module if this is the top level property set).
+	//
+	// This will be called after transforming the properties in the supplied set.
+	//
+	// The name will be "" for the top level property set.
+	//
+	// Returning (nil, ...) will cause the property set to be removed.
+	transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
 
 	// Transform a property, return the new value/tag to insert back into the property set.
 	//
@@ -178,7 +190,11 @@
 	return module
 }
 
-func (t identityTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+func (t identityTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+	return propertySet, tag
+}
+
+func (t identityTransformation) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
 	return propertySet, tag
 }
 
@@ -197,7 +213,9 @@
 	return transformedModule
 }
 
-type deepCopyTransformation struct{}
+type deepCopyTransformation struct {
+	identityTransformation
+}
 
 func (t deepCopyTransformation) transformModule(module *bpModule) *bpModule {
 	// Take a shallow copy of the module. Any mutable property values will be copied by the
@@ -206,7 +224,7 @@
 	return &moduleCopy
 }
 
-func (t deepCopyTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+func (t deepCopyTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
 	// Create a shallow copy of the properties map. Any mutable property values will be copied by the
 	// transformer.
 	propertiesCopy := make(map[string]interface{})
diff --git a/sdk/bp_test.go b/sdk/bp_test.go
index 4414ee9..f89f38c 100644
--- a/sdk/bp_test.go
+++ b/sdk/bp_test.go
@@ -31,13 +31,20 @@
 	return value, tag
 }
 
-func (t removeFredTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+func (t removeFredTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
 	if name == "fred" {
 		return nil, nil
 	}
 	return propertySet, tag
 }
 
+func (t removeFredTransformation) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+	if len(propertySet.properties) == 0 {
+		return nil, nil
+	}
+	return propertySet, tag
+}
+
 func TestTransformRemoveProperty(t *testing.T) {
 
 	helper := &TestHelper{t}