Factor out json from soong_config.mk

Factor out the json functions from soong_config.mk, and extend them
to support maps.

Bug: 119412419
Test: no change to soong.variables
Change-Id: Ieea08fdd2aa202f60945103e3ca82538f098a942
diff --git a/core/json.mk b/core/json.mk
new file mode 100644
index 0000000..ba8ffa7
--- /dev/null
+++ b/core/json.mk
@@ -0,0 +1,35 @@
+4space :=$= $(space)$(space)$(space)$(space)
+invert_bool =$= $(if $(strip $(1)),,true)
+
+# Converts a list to a JSON list.
+# $1: List separator.
+# $2: List.
+_json_list =$= [$(if $(2),"$(subst $(1),"$(comma)",$(2))")]
+
+# Converts a space-separated list to a JSON list.
+json_list =$= $(call _json_list,$(space),$(1))
+
+# Converts a comma-separated list to a JSON list.
+csv_to_json_list =$= $(call _json_list,$(comma),$(1))
+
+# Adds or removes 4 spaces from _json_indent
+json_increase_indent =$= $(eval _json_indent := $$(_json_indent)$$(4space))
+json_decrease_indent =$= $(eval _json_indent := $$(subst _,$$(space),$$(patsubst %____,%,$$(subst $$(space),_,$$(_json_indent)))))
+
+# 1: Key name
+# 2: Value
+add_json_val =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent)"$$(strip $$(1))": $$(strip $$(2))$$(comma)$$(newline))
+add_json_str =$= $(call add_json_val,$(1),"$(strip $(2))")
+add_json_list =$= $(call add_json_val,$(1),$(call json_list,$(patsubst %,%,$(2))))
+add_json_csv =$= $(call add_json_val,$(1),$(call csv_to_json_list,$(strip $(2))))
+add_json_bool =$= $(call add_json_val,$(1),$(if $(strip $(2)),true,false))
+add_json_map =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent)"$$(strip $$(1))": {$$(newline))$(json_increase_indent)
+end_json_map =$= $(json_decrease_indent)$(eval _json_contents := $$(_json_contents)$$(if $$(filter %$$(comma),$$(lastword $$(_json_contents))),__SV_END)$$(_json_indent)},$$(newline))
+
+# Clears _json_contents to start a new json file
+json_start =$= $(eval _json_contents := {$$(newline))$(eval _json_indent := $$(4space))
+
+# Adds the trailing close brace to _json_contents, and removes any trailing commas if necessary
+json_end =$= $(eval _json_contents := $$(subst $$(comma)$$(newline)__SV_END,$$(newline),$$(_json_contents)__SV_END}$$(newline)))
+
+json_contents =$= $(_json_contents)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 7a884e0..6470d22 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -14,31 +14,13 @@
 endif
 
 ifeq ($(WRITE_SOONG_VARIABLES),true)
-# Converts a list to a JSON list.
-# $1: List separator.
-# $2: List.
-_json_list = [$(if $(2),"$(subst $(1),"$(comma)",$(2))")]
 
-# Converts a space-separated list to a JSON list.
-json_list = $(call _json_list,$(space),$(1))
-
-# Converts a comma-separated list to a JSON list.
-csv_to_json_list = $(call _json_list,$(comma),$(1))
-
-# 1: Key name
-# 2: Value
-add_json_val = $(eval _contents := $$(_contents)    "$$(strip $$(1))":$$(space)$$(strip $$(2))$$(comma)$$(newline))
-add_json_str = $(call add_json_val,$(1),"$(strip $(2))")
-add_json_list = $(call add_json_val,$(1),$(call json_list,$(patsubst %,%,$(2))))
-add_json_csv = $(call add_json_val,$(1),$(call csv_to_json_list,$(strip $(2))))
-add_json_bool = $(call add_json_val,$(1),$(if $(strip $(2)),true,false))
-
-invert_bool = $(if $(strip $(1)),,true)
+include $(BUILD_SYSTEM)/json.mk
 
 # Create soong.variables with copies of makefile settings.  Runs every build,
 # but only updates soong.variables if it changes
 $(shell mkdir -p $(dir $(SOONG_VARIABLES)))
-_contents := {$(newline)
+$(call json_start)
 
 $(call add_json_str,  Make_suffix, -$(TARGET_PRODUCT))
 
@@ -154,17 +136,17 @@
 $(call add_json_list, BoardPlatPublicSepolicyDirs,       $(BOARD_PLAT_PUBLIC_SEPOLICY_DIR))
 $(call add_json_list, BoardPlatPrivateSepolicyDirs,      $(BOARD_PLAT_PRIVATE_SEPOLICY_DIR))
 
-_contents := $(_contents)    "VendorVars": {$(newline)
+$(call add_json_map, VendorVars)
 $(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
-  $(eval _contents := $$(_contents)        "$(namespace)": {$$(newline)) \
+  $(call add_json_map, $(namespace))\
   $(foreach key,$(SOONG_CONFIG_$(namespace)),\
-    $(eval _contents := $$(_contents)            "$(key)": "$(SOONG_CONFIG_$(namespace)_$(key))",$$(newline)))\
-  $(eval _contents := $$(_contents)$(if $(strip $(SOONG_CONFIG_$(namespace))),__SV_END)        },$$(newline)))
-_contents := $(_contents)$(if $(strip $(SOONG_CONFIG_NAMESPACES)),__SV_END)    },$(newline)
+    $(call add_json_str,$(key),$(SOONG_CONFIG_$(namespace)_$(key))))\
+  $(call end_json_map))
+$(call end_json_map)
 
-_contents := $(subst $(comma)$(newline)__SV_END,$(newline),$(_contents)__SV_END}$(newline))
+$(call json_end)
 
-$(file >$(SOONG_VARIABLES).tmp,$(_contents))
+$(file >$(SOONG_VARIABLES).tmp,$(json_contents))
 
 $(shell if ! cmp -s $(SOONG_VARIABLES).tmp $(SOONG_VARIABLES); then \
 	  mv $(SOONG_VARIABLES).tmp $(SOONG_VARIABLES); \
@@ -172,15 +154,4 @@
 	  rm $(SOONG_VARIABLES).tmp; \
 	fi)
 
-_json_list :=
-json_list :=
-csv_to_json_list :=
-add_json_val :=
-add_json_str :=
-add_json_list :=
-add_json_csv :=
-add_json_bool :=
-invert_bool :=
-_contents :=
-
 endif # CONFIGURE_SOONG