Merge "Use boot image extension in the JIT-zygote experiment."
diff --git a/common/math.mk b/common/math.mk
index ac3151e..83f2218 100644
--- a/common/math.mk
+++ b/common/math.mk
@@ -33,8 +33,8 @@
 math-expect-error :=
 
 # Run the math tests with:
-#  make -f ${ANDROID_BUILD_TOP}/build/make/core/math.mk RUN_MATH_TESTS=true
-#  $(get_build_var CKATI) -f ${ANDROID_BUILD_TOP}//build/make/core/math.mk RUN_MATH_TESTS=true
+#  make -f ${ANDROID_BUILD_TOP}/build/make/common/math.mk RUN_MATH_TESTS=true
+#  $(get_build_var CKATI) -f ${ANDROID_BUILD_TOP}//build/make/common/math.mk RUN_MATH_TESTS=true
 ifdef RUN_MATH_TESTS
   MATH_TEST_FAILURE :=
   MATH_TEST_ERROR :=
@@ -134,6 +134,10 @@
 $(if $(filter $(1),$(call math_max,$(1),$(2))),true)
 endef
 
+define math_gt
+$(if $(call math_gt_or_eq,$(2),$(1)),,true)
+endef
+
 define math_lt
 $(if $(call math_gt_or_eq,$(1),$(2)),,true)
 endef
@@ -141,6 +145,12 @@
 $(call math-expect-true,(call math_gt_or_eq, 2, 1))
 $(call math-expect-true,(call math_gt_or_eq, 1, 1))
 $(call math-expect-false,(call math_gt_or_eq, 1, 2))
+$(call math-expect-true,(call math_gt, 4, 3))
+$(call math-expect-false,(call math_gt, 5, 5))
+$(call math-expect-false,(call math_gt, 6, 7))
+$(call math-expect-false,(call math_lt, 1, 0))
+$(call math-expect-false,(call math_lt, 8, 8))
+$(call math-expect-true,(call math_lt, 10, 11))
 
 # $1 is the variable name to increment
 define inc_and_print
diff --git a/core/binary.mk b/core/binary.mk
index cf3cfd5..560fff7 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -816,7 +816,7 @@
     $(intermediates)/,$(y_yacc_sources:.y=.c))
 ifneq ($(y_yacc_cs),)
 $(y_yacc_cs): $(intermediates)/%.c: \
-    $(TOPDIR)$(LOCAL_PATH)/%.y $(BISON) $(BISON_DATA) \
+    $(TOPDIR)$(LOCAL_PATH)/%.y $(BISON) $(BISON_DATA) $(M4) \
     $(my_additional_dependencies)
 	$(call transform-y-to-c-or-cpp)
 $(call track-src-file-gen,$(y_yacc_sources),$(y_yacc_cs))
@@ -829,7 +829,7 @@
     $(intermediates)/,$(yy_yacc_sources:.yy=$(LOCAL_CPP_EXTENSION)))
 ifneq ($(yy_yacc_cpps),)
 $(yy_yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
-    $(TOPDIR)$(LOCAL_PATH)/%.yy $(BISON) $(BISON_DATA) \
+    $(TOPDIR)$(LOCAL_PATH)/%.yy $(BISON) $(BISON_DATA) $(M4) \
     $(my_additional_dependencies)
 	$(call transform-y-to-c-or-cpp)
 $(call track-src-file-gen,$(yy_yacc_sources),$(yy_yacc_cpps))
@@ -845,6 +845,7 @@
 l_lex_cs := $(addprefix \
     $(intermediates)/,$(l_lex_sources:.l=.c))
 ifneq ($(l_lex_cs),)
+$(l_lex_cs): $(LEX) $(M4)
 $(l_lex_cs): $(intermediates)/%.c: \
     $(TOPDIR)$(LOCAL_PATH)/%.l
 	$(transform-l-to-c-or-cpp)
@@ -857,6 +858,7 @@
 ll_lex_cpps := $(addprefix \
     $(intermediates)/,$(ll_lex_sources:.ll=$(LOCAL_CPP_EXTENSION)))
 ifneq ($(ll_lex_cpps),)
+$(ll_lex_cpps): $(LEX) $(M4)
 $(ll_lex_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
     $(TOPDIR)$(LOCAL_PATH)/%.ll
 	$(transform-l-to-c-or-cpp)
diff --git a/core/config.mk b/core/config.mk
index 4cc78b8..c5f54de 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -553,6 +553,7 @@
 BISON := $(prebuilt_build_tools_bin_noasan)/bison
 YACC := $(BISON) -d
 BISON_DATA := $(wildcard $(BISON_PKGDATADIR)/* $(BISON_PKGDATADIR)/*/*)
+M4 :=$= $(prebuilt_build_tools_bin_noasan)/m4
 
 YASM := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/yasm/yasm
 
@@ -709,19 +710,37 @@
   PRODUCT_USE_VNDK := $(PRODUCT_USE_VNDK_OVERRIDE)
 else ifeq ($(PRODUCT_SHIPPING_API_LEVEL),)
   # No shipping level defined
-else ifeq ($(call math_gt_or_eq,27,$(PRODUCT_SHIPPING_API_LEVEL)),)
+else ifeq ($(call math_gt,$(PRODUCT_SHIPPING_API_LEVEL),27),true)
   PRODUCT_USE_VNDK := $(PRODUCT_FULL_TREBLE)
 endif
 
+# Define PRODUCT_PRODUCT_VNDK_VERSION if PRODUCT_USE_VNDK is true and
+# PRODUCT_SHIPPING_API_LEVEL is greater than 29.
+PRODUCT_USE_PRODUCT_VNDK := false
 ifeq ($(PRODUCT_USE_VNDK),true)
+  ifneq ($(PRODUCT_USE_PRODUCT_VNDK_OVERRIDE),)
+    PRODUCT_USE_PRODUCT_VNDK := $(PRODUCT_USE_PRODUCT_VNDK_OVERRIDE)
+  else ifeq ($(PRODUCT_SHIPPING_API_LEVEL),)
+    # No shipping level defined
+  else ifeq ($(call math_gt,$(PRODUCT_SHIPPING_API_LEVEL),29),true)
+    PRODUCT_USE_PRODUCT_VNDK := true
+  endif
+
   ifndef BOARD_VNDK_VERSION
     BOARD_VNDK_VERSION := current
   endif
+
+  ifeq ($(PRODUCT_USE_PRODUCT_VNDK),true)
+    ifndef PRODUCT_PRODUCT_VNDK_VERSION
+      PRODUCT_PRODUCT_VNDK_VERSION := current
+    endif
+  endif
 endif
 
-$(KATI_obsolete_var PRODUCT_USE_VNDK_OVERRIDE,Use PRODUCT_USE_VNDK instead)
-.KATI_READONLY := \
-    PRODUCT_USE_VNDK
+$(KATI_obsolete_var PRODUCT_USE_VNDK,Use BOARD_VNDK_VERSION instead)
+$(KATI_obsolete_var PRODUCT_USE_VNDK_OVERRIDE,Use BOARD_VNDK_VERSION instead)
+$(KATI_obsolete_var PRODUCT_USE_PRODUCT_VNDK,Use PRODUCT_PRODUCT_VNDK_VERSION instead)
+$(KATI_obsolete_var PRODUCT_USE_PRODUCT_VNDK_OVERRIDE,Use PRODUCT_PRODUCT_VNDK_VERSION instead)
 
 # Set BOARD_SYSTEMSDK_VERSIONS to the latest SystemSDK version starting from P-launching
 # devices if unset.
diff --git a/core/definitions.mk b/core/definitions.mk
index ff435e2..49747ed 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -889,7 +889,7 @@
 define transform-l-to-c-or-cpp
 @echo "Lex: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
-$(hide) $(LEX) -o$@ $<
+M4=$(M4) $(LEX) -o$@ $<
 endef
 
 ###########################################################
@@ -900,7 +900,7 @@
 define transform-y-to-c-or-cpp
 @echo "Yacc: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
-$(YACC) $(PRIVATE_YACCFLAGS) \
+M4=$(M4) $(YACC) $(PRIVATE_YACCFLAGS) \
   --defines=$(basename $@).h \
   -o $@ $<
 endef
diff --git a/core/tasks/boot_jars_package_check.mk b/core/tasks/boot_jars_package_check.mk
index ba383f5..ceaff54 100644
--- a/core/tasks/boot_jars_package_check.mk
+++ b/core/tasks/boot_jars_package_check.mk
@@ -22,10 +22,23 @@
 
 intermediates := $(call intermediates-dir-for, PACKAGING, boot-jars-package-check,,COMMON)
 stamp := $(intermediates)/stamp
-art_boot_jars := $(addsuffix .com.android.art.release,$(filter $(ART_APEX_JARS), $(PRODUCT_BOOT_JARS)))
-conscrypt_boot_jars := $(addsuffix .com.android.conscrypt,$(filter conscrypt, $(PRODUCT_BOOT_JARS)))
-noncore_boot_jars := $(filter-out $(ART_APEX_JARS) conscrypt, $(PRODUCT_BOOT_JARS))
-built_boot_jars := $(foreach j, $(art_boot_jars) $(conscrypt_boot_jars) $(noncore_boot_jars), \
+
+# The actual names for the updatable jars are <jar_name>.<apex_name> e.g., updatable-media.com.android.media
+updatable_boot_jars := $(foreach pair,$(PRODUCT_UPDATABLE_BOOT_JARS),\
+  $(eval apex := $(call word-colon,1,$(pair)))\
+  $(eval jar := $(call word-colon,2,$(pair)))\
+  $(jar).$(apex)\
+)
+#TODO(jiyong) merge art_boot_jars into updatable_boot_jars
+art_boot_jars := $(addsuffix .com.android.art.release,$(filter $(ART_APEX_JARS),$(PRODUCT_BOOT_JARS)))
+
+platform_boot_jars := $(filter-out \
+  $(ART_APEX_JARS)\
+  $(foreach pair,$(PRODUCT_UPDATABLE_BOOT_JARS),$(call word-colon,2,$(pair))),\
+  $(PRODUCT_BOOT_JARS)\
+)
+
+built_boot_jars := $(foreach j, $(updatable_boot_jars) $(art_boot_jars) $(platform_boot_jars), \
   $(call intermediates-dir-for, JAVA_LIBRARIES, $(j),,COMMON)/classes.jar)
 script := build/make/core/tasks/check_boot_jars/check_boot_jars.py
 whitelist_file := build/make/core/tasks/check_boot_jars/package_whitelist.txt
diff --git a/core/tasks/check_boot_jars/check_boot_jars.py b/core/tasks/check_boot_jars/check_boot_jars.py
index 9d71553..67b73d5 100755
--- a/core/tasks/check_boot_jars/check_boot_jars.py
+++ b/core/tasks/check_boot_jars/check_boot_jars.py
@@ -53,10 +53,9 @@
     if f.endswith('.class'):
       package_name = os.path.dirname(f)
       package_name = package_name.replace('/', '.')
-      # Skip class without a package name
-      if package_name and not whitelist_re.match(package_name):
-        print >> sys.stderr, ('Error: %s contains class file %s, whose package name %s is not '
-                              'in the whitelist %s of packages allowed on the bootclasspath.'
+      if not package_name or not whitelist_re.match(package_name):
+        print >> sys.stderr, ('Error: %s contains class file %s, whose package name %s is empty or'
+                              ' not in the whitelist %s of packages allowed on the bootclasspath.'
                               % (jar, f, package_name, whitelist_path))
         return False
   return True
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index b0a0e02..6a6f119 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -62,7 +62,7 @@
           'Warning: releasetools script should be invoked as hermetic Python '
           'executable -- build and run `{}` directly.'.format(script_name[:-3]),
           file=sys.stderr)
-    self.search_path = os.path.realpath(os.path.join(exec_path, '..'))
+    self.search_path = os.path.realpath(os.path.join(os.path.dirname(exec_path), '..'))
 
     self.signapk_path = "framework/signapk.jar"  # Relative to search_path
     self.signapk_shared_library_path = "lib64"   # Relative to search_path
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 35b11c1..fffbace 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -552,8 +552,13 @@
 
     # Ask add_img_to_target_files to rebuild the recovery patch if needed.
     elif filename in ("SYSTEM/recovery-from-boot.p",
+                      "VENDOR/recovery-from-boot.p",
+
                       "SYSTEM/etc/recovery.img",
-                      "SYSTEM/bin/install-recovery.sh"):
+                      "VENDOR/etc/recovery.img",
+
+                      "SYSTEM/bin/install-recovery.sh",
+                      "VENDOR/bin/install-recovery.sh"):
       OPTIONS.rebuild_recovery = True
 
     # Don't copy OTA certs if we're replacing them.
diff --git a/tools/warn/android_project_list.py b/tools/warn/android_project_list.py
index 1e9e276..4726fa2 100644
--- a/tools/warn/android_project_list.py
+++ b/tools/warn/android_project_list.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,161 +16,160 @@
 """Define a project list to sort warnings by project directory path."""
 
 
-def project_name_and_pattern(name, pattern):
-  return [name, '(^|.*/)' + pattern + '/.*: warning:']
-
-
-def simple_project_pattern(pattern):
-  return project_name_and_pattern(pattern, pattern)
+def create_pattern(name, pattern=None):
+  if pattern is not None:
+    return [name, '(^|.*/)' + pattern + '/.*: warning:']
+  return [name, '(^|.*/)' + name + '/.*: warning:']
 
 
 # A list of [project_name, file_path_pattern].
 # project_name should not contain comma, to be used in CSV output.
 project_list = [
-    simple_project_pattern('art'),
-    simple_project_pattern('bionic'),
-    simple_project_pattern('bootable'),
-    simple_project_pattern('build'),
-    simple_project_pattern('cts'),
-    simple_project_pattern('dalvik'),
-    simple_project_pattern('developers'),
-    simple_project_pattern('development'),
-    simple_project_pattern('device'),
-    simple_project_pattern('doc'),
+    create_pattern('art'),
+    create_pattern('bionic'),
+    create_pattern('bootable'),
+    create_pattern('build'),
+    create_pattern('cts'),
+    create_pattern('dalvik'),
+    create_pattern('developers'),
+    create_pattern('development'),
+    create_pattern('device'),
+    create_pattern('doc'),
     # match external/google* before external/
-    project_name_and_pattern('external/google', 'external/google.*'),
-    project_name_and_pattern('external/non-google', 'external'),
-    simple_project_pattern('frameworks/av/camera'),
-    simple_project_pattern('frameworks/av/cmds'),
-    simple_project_pattern('frameworks/av/drm'),
-    simple_project_pattern('frameworks/av/include'),
-    simple_project_pattern('frameworks/av/media/img_utils'),
-    simple_project_pattern('frameworks/av/media/libcpustats'),
-    simple_project_pattern('frameworks/av/media/libeffects'),
-    simple_project_pattern('frameworks/av/media/libmediaplayerservice'),
-    simple_project_pattern('frameworks/av/media/libmedia'),
-    simple_project_pattern('frameworks/av/media/libstagefright'),
-    simple_project_pattern('frameworks/av/media/mtp'),
-    simple_project_pattern('frameworks/av/media/ndk'),
-    simple_project_pattern('frameworks/av/media/utils'),
-    project_name_and_pattern('frameworks/av/media/Other',
-                             'frameworks/av/media'),
-    simple_project_pattern('frameworks/av/radio'),
-    simple_project_pattern('frameworks/av/services'),
-    simple_project_pattern('frameworks/av/soundtrigger'),
-    project_name_and_pattern('frameworks/av/Other', 'frameworks/av'),
-    simple_project_pattern('frameworks/base/cmds'),
-    simple_project_pattern('frameworks/base/core'),
-    simple_project_pattern('frameworks/base/drm'),
-    simple_project_pattern('frameworks/base/media'),
-    simple_project_pattern('frameworks/base/libs'),
-    simple_project_pattern('frameworks/base/native'),
-    simple_project_pattern('frameworks/base/packages'),
-    simple_project_pattern('frameworks/base/rs'),
-    simple_project_pattern('frameworks/base/services'),
-    simple_project_pattern('frameworks/base/tests'),
-    simple_project_pattern('frameworks/base/tools'),
-    project_name_and_pattern('frameworks/base/Other', 'frameworks/base'),
-    simple_project_pattern('frameworks/compile/libbcc'),
-    simple_project_pattern('frameworks/compile/mclinker'),
-    simple_project_pattern('frameworks/compile/slang'),
-    project_name_and_pattern('frameworks/compile/Other', 'frameworks/compile'),
-    simple_project_pattern('frameworks/minikin'),
-    simple_project_pattern('frameworks/ml'),
-    simple_project_pattern('frameworks/native/cmds'),
-    simple_project_pattern('frameworks/native/include'),
-    simple_project_pattern('frameworks/native/libs'),
-    simple_project_pattern('frameworks/native/opengl'),
-    simple_project_pattern('frameworks/native/services'),
-    simple_project_pattern('frameworks/native/vulkan'),
-    project_name_and_pattern('frameworks/native/Other', 'frameworks/native'),
-    simple_project_pattern('frameworks/opt'),
-    simple_project_pattern('frameworks/rs'),
-    simple_project_pattern('frameworks/webview'),
-    simple_project_pattern('frameworks/wilhelm'),
-    project_name_and_pattern('frameworks/Other', 'frameworks'),
-    simple_project_pattern('hardware/akm'),
-    simple_project_pattern('hardware/broadcom'),
-    simple_project_pattern('hardware/google'),
-    simple_project_pattern('hardware/intel'),
-    simple_project_pattern('hardware/interfaces'),
-    simple_project_pattern('hardware/libhardware'),
-    simple_project_pattern('hardware/libhardware_legacy'),
-    simple_project_pattern('hardware/qcom'),
-    simple_project_pattern('hardware/ril'),
-    project_name_and_pattern('hardware/Other', 'hardware'),
-    simple_project_pattern('kernel'),
-    simple_project_pattern('libcore'),
-    simple_project_pattern('libnativehelper'),
-    simple_project_pattern('ndk'),
+    create_pattern('external/google', 'external/google.*'),
+    create_pattern('external/non-google', 'external'),
+    create_pattern('frameworks/av/camera'),
+    create_pattern('frameworks/av/cmds'),
+    create_pattern('frameworks/av/drm'),
+    create_pattern('frameworks/av/include'),
+    create_pattern('frameworks/av/media/img_utils'),
+    create_pattern('frameworks/av/media/libcpustats'),
+    create_pattern('frameworks/av/media/libeffects'),
+    create_pattern('frameworks/av/media/libmediaplayerservice'),
+    create_pattern('frameworks/av/media/libmedia'),
+    create_pattern('frameworks/av/media/libstagefright'),
+    create_pattern('frameworks/av/media/mtp'),
+    create_pattern('frameworks/av/media/ndk'),
+    create_pattern('frameworks/av/media/utils'),
+    create_pattern('frameworks/av/media/Other', 'frameworks/av/media'),
+    create_pattern('frameworks/av/radio'),
+    create_pattern('frameworks/av/services'),
+    create_pattern('frameworks/av/soundtrigger'),
+    create_pattern('frameworks/av/Other', 'frameworks/av'),
+    create_pattern('frameworks/base/cmds'),
+    create_pattern('frameworks/base/core'),
+    create_pattern('frameworks/base/drm'),
+    create_pattern('frameworks/base/media'),
+    create_pattern('frameworks/base/libs'),
+    create_pattern('frameworks/base/native'),
+    create_pattern('frameworks/base/packages'),
+    create_pattern('frameworks/base/rs'),
+    create_pattern('frameworks/base/services'),
+    create_pattern('frameworks/base/tests'),
+    create_pattern('frameworks/base/tools'),
+    create_pattern('frameworks/base/Other', 'frameworks/base'),
+    create_pattern('frameworks/compile/libbcc'),
+    create_pattern('frameworks/compile/mclinker'),
+    create_pattern('frameworks/compile/slang'),
+    create_pattern('frameworks/compile/Other', 'frameworks/compile'),
+    create_pattern('frameworks/minikin'),
+    create_pattern('frameworks/ml'),
+    create_pattern('frameworks/native/cmds'),
+    create_pattern('frameworks/native/include'),
+    create_pattern('frameworks/native/libs'),
+    create_pattern('frameworks/native/opengl'),
+    create_pattern('frameworks/native/services'),
+    create_pattern('frameworks/native/vulkan'),
+    create_pattern('frameworks/native/Other', 'frameworks/native'),
+    create_pattern('frameworks/opt'),
+    create_pattern('frameworks/rs'),
+    create_pattern('frameworks/webview'),
+    create_pattern('frameworks/wilhelm'),
+    create_pattern('frameworks/Other', 'frameworks'),
+    create_pattern('hardware/akm'),
+    create_pattern('hardware/broadcom'),
+    create_pattern('hardware/google'),
+    create_pattern('hardware/intel'),
+    create_pattern('hardware/interfaces'),
+    create_pattern('hardware/libhardware'),
+    create_pattern('hardware/libhardware_legacy'),
+    create_pattern('hardware/qcom'),
+    create_pattern('hardware/ril'),
+    create_pattern('hardware/Other', 'hardware'),
+    create_pattern('kernel'),
+    create_pattern('libcore'),
+    create_pattern('libnativehelper'),
+    create_pattern('ndk'),
     # match vendor/unbungled_google/packages before other packages
-    simple_project_pattern('unbundled_google'),
-    simple_project_pattern('packages'),
-    simple_project_pattern('pdk'),
-    simple_project_pattern('prebuilts'),
-    simple_project_pattern('system/bt'),
-    simple_project_pattern('system/connectivity'),
-    simple_project_pattern('system/core/adb'),
-    simple_project_pattern('system/core/base'),
-    simple_project_pattern('system/core/debuggerd'),
-    simple_project_pattern('system/core/fastboot'),
-    simple_project_pattern('system/core/fingerprintd'),
-    simple_project_pattern('system/core/fs_mgr'),
-    simple_project_pattern('system/core/gatekeeperd'),
-    simple_project_pattern('system/core/healthd'),
-    simple_project_pattern('system/core/include'),
-    simple_project_pattern('system/core/init'),
-    simple_project_pattern('system/core/libbacktrace'),
-    simple_project_pattern('system/core/liblog'),
-    simple_project_pattern('system/core/libpixelflinger'),
-    simple_project_pattern('system/core/libprocessgroup'),
-    simple_project_pattern('system/core/libsysutils'),
-    simple_project_pattern('system/core/logcat'),
-    simple_project_pattern('system/core/logd'),
-    simple_project_pattern('system/core/run-as'),
-    simple_project_pattern('system/core/sdcard'),
-    simple_project_pattern('system/core/toolbox'),
-    project_name_and_pattern('system/core/Other', 'system/core'),
-    simple_project_pattern('system/extras/ANRdaemon'),
-    simple_project_pattern('system/extras/cpustats'),
-    simple_project_pattern('system/extras/crypto-perf'),
-    simple_project_pattern('system/extras/ext4_utils'),
-    simple_project_pattern('system/extras/f2fs_utils'),
-    simple_project_pattern('system/extras/iotop'),
-    simple_project_pattern('system/extras/libfec'),
-    simple_project_pattern('system/extras/memory_replay'),
-    simple_project_pattern('system/extras/mmap-perf'),
-    simple_project_pattern('system/extras/multinetwork'),
-    simple_project_pattern('system/extras/procrank'),
-    simple_project_pattern('system/extras/runconuid'),
-    simple_project_pattern('system/extras/showmap'),
-    simple_project_pattern('system/extras/simpleperf'),
-    simple_project_pattern('system/extras/su'),
-    simple_project_pattern('system/extras/tests'),
-    simple_project_pattern('system/extras/verity'),
-    project_name_and_pattern('system/extras/Other', 'system/extras'),
-    simple_project_pattern('system/gatekeeper'),
-    simple_project_pattern('system/keymaster'),
-    simple_project_pattern('system/libhidl'),
-    simple_project_pattern('system/libhwbinder'),
-    simple_project_pattern('system/media'),
-    simple_project_pattern('system/netd'),
-    simple_project_pattern('system/nvram'),
-    simple_project_pattern('system/security'),
-    simple_project_pattern('system/sepolicy'),
-    simple_project_pattern('system/tools'),
-    simple_project_pattern('system/update_engine'),
-    simple_project_pattern('system/vold'),
-    project_name_and_pattern('system/Other', 'system'),
-    simple_project_pattern('toolchain'),
-    simple_project_pattern('test'),
-    simple_project_pattern('tools'),
+    create_pattern('unbundled_google'),
+    create_pattern('packages'),
+    create_pattern('pdk'),
+    create_pattern('prebuilts'),
+    create_pattern('system/bt'),
+    create_pattern('system/connectivity'),
+    create_pattern('system/core/adb'),
+    create_pattern('system/core/base'),
+    create_pattern('system/core/debuggerd'),
+    create_pattern('system/core/fastboot'),
+    create_pattern('system/core/fingerprintd'),
+    create_pattern('system/core/fs_mgr'),
+    create_pattern('system/core/gatekeeperd'),
+    create_pattern('system/core/healthd'),
+    create_pattern('system/core/include'),
+    create_pattern('system/core/init'),
+    create_pattern('system/core/libbacktrace'),
+    create_pattern('system/core/liblog'),
+    create_pattern('system/core/libpixelflinger'),
+    create_pattern('system/core/libprocessgroup'),
+    create_pattern('system/core/libsysutils'),
+    create_pattern('system/core/logcat'),
+    create_pattern('system/core/logd'),
+    create_pattern('system/core/run-as'),
+    create_pattern('system/core/sdcard'),
+    create_pattern('system/core/toolbox'),
+    create_pattern('system/core/Other', 'system/core'),
+    create_pattern('system/extras/ANRdaemon'),
+    create_pattern('system/extras/cpustats'),
+    create_pattern('system/extras/crypto-perf'),
+    create_pattern('system/extras/ext4_utils'),
+    create_pattern('system/extras/f2fs_utils'),
+    create_pattern('system/extras/iotop'),
+    create_pattern('system/extras/libfec'),
+    create_pattern('system/extras/memory_replay'),
+    create_pattern('system/extras/mmap-perf'),
+    create_pattern('system/extras/multinetwork'),
+    create_pattern('system/extras/perfprofd'),
+    create_pattern('system/extras/procrank'),
+    create_pattern('system/extras/runconuid'),
+    create_pattern('system/extras/showmap'),
+    create_pattern('system/extras/simpleperf'),
+    create_pattern('system/extras/su'),
+    create_pattern('system/extras/tests'),
+    create_pattern('system/extras/verity'),
+    create_pattern('system/extras/Other', 'system/extras'),
+    create_pattern('system/gatekeeper'),
+    create_pattern('system/keymaster'),
+    create_pattern('system/libhidl'),
+    create_pattern('system/libhwbinder'),
+    create_pattern('system/media'),
+    create_pattern('system/netd'),
+    create_pattern('system/nvram'),
+    create_pattern('system/security'),
+    create_pattern('system/sepolicy'),
+    create_pattern('system/tools'),
+    create_pattern('system/update_engine'),
+    create_pattern('system/vold'),
+    create_pattern('system/Other', 'system'),
+    create_pattern('toolchain'),
+    create_pattern('test'),
+    create_pattern('tools'),
     # match vendor/google* before vendor/
-    project_name_and_pattern('vendor/google', 'vendor/google.*'),
-    project_name_and_pattern('vendor/non-google', 'vendor'),
+    create_pattern('vendor/google', 'vendor/google.*'),
+    create_pattern('vendor/non-google', 'vendor'),
     # keep out/obj and other patterns at the end.
-    ['out/obj',
-     '.*/(gen|obj[^/]*)/(include|EXECUTABLES|SHARED_LIBRARIES|'
-     'STATIC_LIBRARIES|NATIVE_TESTS)/.*: warning:'],
+    [
+        'out/obj', '.*/(gen|obj[^/]*)/(include|EXECUTABLES|SHARED_LIBRARIES|'
+        'STATIC_LIBRARIES|NATIVE_TESTS)/.*: warning:'
+    ],
     ['other', '.*']  # all other unrecognized patterns
 ]
diff --git a/tools/warn/cpp_warn_patterns.py b/tools/warn/cpp_warn_patterns.py
index ce10693..af8bfe8 100644
--- a/tools/warn/cpp_warn_patterns.py
+++ b/tools/warn/cpp_warn_patterns.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,9 +15,14 @@
 
 """Warning patterns for C/C++ compiler, but not clang-tidy."""
 
-from severity import Severity
+import re
 
-patterns = [
+# pylint:disable=relative-beyond-top-level
+# pylint:disable=g-importing-member
+from .severity import Severity
+
+
+warn_patterns = [
     # pylint:disable=line-too-long,g-inconsistent-quotes
     {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wimplicit-function-declaration',
      'description': 'Implicit function declaration',
@@ -125,9 +130,6 @@
     {'category': 'libpng', 'severity': Severity.MEDIUM,
      'description': 'libpng: zero area',
      'patterns': [r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"]},
-    {'category': 'aapt', 'severity': Severity.MEDIUM,
-     'description': 'aapt: no comment for public symbol',
-     'patterns': [r".*: warning: No comment for public symbol .+"]},
     {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmissing-braces',
      'description': 'Missing braces around initializer',
      'patterns': [r".*: warning: missing braces around initializer.*"]},
@@ -578,3 +580,14 @@
      'patterns': [r".*: warning: '.+' defined as a .+ here but previously declared as a .+mismatched-tags",
                   r".*: warning: .+ was previously declared as a .+mismatched-tags"]},
 ]
+
+
+def compile_patterns(patterns):
+  """Precompiling every pattern speeds up parsing by about 30x."""
+  for i in patterns:
+    i['compiled_patterns'] = []
+    for pat in i['patterns']:
+      i['compiled_patterns'].append(re.compile(pat))
+
+
+compile_patterns(warn_patterns)
diff --git a/tools/warn/java_warn_patterns.py b/tools/warn/java_warn_patterns.py
index 77b80a4..3a3a676 100644
--- a/tools/warn/java_warn_patterns.py
+++ b/tools/warn/java_warn_patterns.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +15,10 @@
 
 """Warning patterns for Java compiler tools."""
 
-from severity import Severity
+# pylint:disable=relative-beyond-top-level
+from .cpp_warn_patterns import compile_patterns
+# pylint:disable=g-importing-member
+from .severity import Severity
 
 
 def java_warn(severity, description, pattern_list):
@@ -39,7 +42,7 @@
   return java_warn(Severity.LOW, description, pattern_list)
 
 
-patterns = [
+warn_patterns = [
     # pylint:disable=line-too-long,g-inconsistent-quotes
     # Warnings from Javac
     java_medium('Use of deprecated',
@@ -742,3 +745,5 @@
     java_medium('Supported version from annotation processor',
                 [r".*: warning: Supported source version .+ from annotation processor"]),
 ]
+
+compile_patterns(warn_patterns)
diff --git a/tools/warn/make_warn_patterns.py b/tools/warn/make_warn_patterns.py
index ac3c508..327fce4 100644
--- a/tools/warn/make_warn_patterns.py
+++ b/tools/warn/make_warn_patterns.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,9 +15,12 @@
 
 """Warning patterns for build make tools."""
 
-from severity import Severity
+# pylint:disable=relative-beyond-top-level
+from .cpp_warn_patterns import compile_patterns
+# pylint:disable=g-importing-member
+from .severity import Severity
 
-patterns = [
+warn_patterns = [
     # pylint:disable=line-too-long,g-inconsistent-quotes
     {'category': 'make', 'severity': Severity.MEDIUM,
      'description': 'make: overriding commands/ignoring old commands',
@@ -51,3 +54,6 @@
      'description': 'make: please convert to soong',
      'patterns': [r".*: warning: .* has been deprecated. Please convert to Soong."]},
 ]
+
+
+compile_patterns(warn_patterns)
diff --git a/tools/warn/other_warn_patterns.py b/tools/warn/other_warn_patterns.py
index 524673e..1331bc6 100644
--- a/tools/warn/other_warn_patterns.py
+++ b/tools/warn/other_warn_patterns.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +15,10 @@
 
 """Warning patterns from other tools."""
 
-from severity import Severity
+# pylint:disable=relative-beyond-top-level
+from .cpp_warn_patterns import compile_patterns
+# pylint:disable=g-importing-member
+from .severity import Severity
 
 
 def warn(name, severity, description, pattern_list):
@@ -43,9 +46,11 @@
   return warn('Kotlin', Severity.MEDIUM, description, pattern_list)
 
 
-patterns = [
+warn_patterns = [
     # pylint:disable=line-too-long,g-inconsistent-quotes
     # aapt warnings
+    aapt('No comment for public symbol',
+         [r".*: warning: No comment for public symbol .+"]),
     aapt('No default translation',
          [r".*: warning: string '.+' has no default translation in .*"]),
     aapt('Missing default or required localization',
@@ -94,7 +99,7 @@
      'patterns': [r".*: warning: .* generate guard with empty availability: obsoleted ="]},
     # Protoc warnings
     {'category': 'Protoc', 'severity': Severity.MEDIUM,
-     'description': 'Proto: Enum name colision after strip',
+     'description': 'Proto: Enum name collision after strip',
      'patterns': [r".*: warning: Enum .* has the same name .* ignore case and strip"]},
     {'category': 'Protoc', 'severity': Severity.MEDIUM,
      'description': 'Proto: Import not used',
@@ -128,7 +133,10 @@
      'description': 'skip, In file included from ...',
      'patterns': [r".*: warning: In file included from .+,"]},
     # catch-all for warnings this script doesn't know about yet
-    {'category': 'C/C++', 'severity': Severity.UNKNOWN,
+    {'category': 'C/C++', 'severity': Severity.UNMATCHED,
      'description': 'Unclassified/unrecognized warnings',
      'patterns': [r".*: warning: .+"]},
 ]
+
+
+compile_patterns(warn_patterns)
diff --git a/tools/warn/severity.py b/tools/warn/severity.py
index bb23f2c..b1c38e4 100644
--- a/tools/warn/severity.py
+++ b/tools/warn/severity.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,35 +13,45 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Severity levels and attributes."""
+"""Clang_Tidy_Warn Severity class definition.
+
+This file stores definition for class Severity that is used in warn_patterns.
+"""
 
 
-class Severity(object):
-  """Severity levels and attributes."""
-  # numbered by dump order
-  FIXMENOW = 0
-  HIGH = 1
-  MEDIUM = 2
-  LOW = 3
-  ANALYZER = 4
-  TIDY = 5
-  HARMLESS = 6
-  UNKNOWN = 7
-  SKIP = 8
-  range = range(SKIP + 1)
-  attributes = [
-      # pylint:disable=bad-whitespace
-      ['fuchsia',   'FixNow',    'Critical warnings, fix me now'],
-      ['red',       'High',      'High severity warnings'],
-      ['orange',    'Medium',    'Medium severity warnings'],
-      ['yellow',    'Low',       'Low severity warnings'],
-      ['hotpink',   'Analyzer',  'Clang-Analyzer warnings'],
-      ['peachpuff', 'Tidy',      'Clang-Tidy warnings'],
-      ['limegreen', 'Harmless',  'Harmless warnings'],
-      ['lightblue', 'Unknown',   'Unknown warnings'],
-      ['grey',      'Unhandled', 'Unhandled warnings']
+# pylint:disable=old-style-class
+class Severity:
+  """Class of Severity levels where each level is a SeverityInfo."""
+
+  class SeverityInfo:
+
+    def __init__(self, value, color, column_header, header):
+      self.value = value
+      self.color = color
+      self.column_header = column_header
+      self.header = header
+
+  # SEVERITY_UNKNOWN should never occur since every warn_pattern listed has
+  # a specified severity. It exists for protobuf, the other values must
+  # map to non-zero values (since 0 is reserved for a default UNKNOWN), but
+  # logic in clang_tidy_warn.py assumes severity level values are consecutive
+  # ints starting with 0.
+  SEVERITY_UNKNOWN = SeverityInfo(0, 'blueviolet', 'Errors of unknown severity',
+                                  'Unknown severity (should not occur)')
+  FIXMENOW = SeverityInfo(1, 'fuschia', 'FixNow',
+                          'Critical warnings, fix me now')
+  HIGH = SeverityInfo(2, 'red', 'High', 'High severity warnings')
+  MEDIUM = SeverityInfo(3, 'orange', 'Medium', 'Medium severity warnings')
+  LOW = SeverityInfo(4, 'yellow', 'Low', 'Low severity warnings')
+  ANALYZER = SeverityInfo(5, 'hotpink', 'Analyzer', 'Clang-Analyzer warnings')
+  TIDY = SeverityInfo(6, 'peachpuff', 'Tidy', 'Clang-Tidy warnings')
+  HARMLESS = SeverityInfo(7, 'limegreen', 'Harmless', 'Harmless warnings')
+  UNMATCHED = SeverityInfo(8, 'lightblue', 'Unmatched', 'Unmatched warnings')
+  SKIP = SeverityInfo(9, 'grey', 'Unhandled', 'Unhandled warnings')
+
+  levels = [
+      SEVERITY_UNKNOWN, FIXMENOW, HIGH, MEDIUM, LOW, ANALYZER, TIDY, HARMLESS,
+      UNMATCHED, SKIP
   ]
-  colors = [a[0] for a in attributes]
-  column_headers = [a[1] for a in attributes]
-  headers = [a[2] for a in attributes]
-
+  # HTML relies on ordering by value. Sort here to ensure that this is proper
+  levels = sorted(levels, key=lambda severity: severity.value)
diff --git a/tools/warn/tidy_warn_patterns.py b/tools/warn/tidy_warn_patterns.py
index a26b388..2c5ab79 100644
--- a/tools/warn/tidy_warn_patterns.py
+++ b/tools/warn/tidy_warn_patterns.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +15,10 @@
 
 """Warning patterns for clang-tidy."""
 
-from severity import Severity
+# pylint:disable=relative-beyond-top-level
+from .cpp_warn_patterns import compile_patterns
+# pylint:disable=g-importing-member
+from .severity import Severity
 
 
 def tidy_warn_pattern(description, pattern):
@@ -35,13 +38,13 @@
   return tidy_warn_pattern(description, description + r'-.+')
 
 
-def analyzer_high(description, pattern_list):
+def analyzer_high(description, patterns):
   # Important clang analyzer warnings to be fixed ASAP.
   return {
       'category': 'C/C++',
       'severity': Severity.HIGH,
       'description': description,
-      'patterns': pattern_list
+      'patterns': patterns
   }
 
 
@@ -53,12 +56,12 @@
   return analyzer_high(check, [r'.*: .+\[' + check + r'.+\]$'])
 
 
-def analyzer_warn(description, pattern_list):
+def analyzer_warn(description, patterns):
   return {
       'category': 'C/C++',
       'severity': Severity.ANALYZER,
       'description': description,
-      'patterns': pattern_list
+      'patterns': patterns
   }
 
 
@@ -70,7 +73,7 @@
   return analyzer_warn(check, [r'.*: .+\[' + check + r'.+\]$'])
 
 
-patterns = [
+warn_patterns = [
     # pylint:disable=line-too-long,g-inconsistent-quotes
     group_tidy_warn_pattern('android'),
     simple_tidy_warn_pattern('abseil-string-find-startswith'),
@@ -136,6 +139,13 @@
     simple_tidy_warn_pattern('portability-simd-intrinsics'),
     group_tidy_warn_pattern('performance'),
     group_tidy_warn_pattern('readability'),
+    simple_tidy_warn_pattern('abseil-string-find-startwith'),
+    simple_tidy_warn_pattern('abseil-faster-strsplit-delimiter'),
+    simple_tidy_warn_pattern('abseil-no-namespace'),
+    simple_tidy_warn_pattern('abseil-no-internal-dependencies'),
+    group_tidy_warn_pattern('abseil'),
+    simple_tidy_warn_pattern('portability-simd-intrinsics'),
+    group_tidy_warn_pattern('portability'),
 
     # warnings from clang-tidy's clang-analyzer checks
     analyzer_high('clang-analyzer-core, null pointer',
@@ -189,5 +199,8 @@
     analyzer_high_check('clang-analyzer-cplusplus.NewDeleteLeaks'),
     analyzer_high_check('clang-analyzer-cplusplus.NewDelete'),
     analyzer_group_check('clang-analyzer-unix'),
-    analyzer_group_check('clang-analyzer'),  # catch al
+    analyzer_group_check('clang-analyzer'),  # catch all
 ]
+
+
+compile_patterns(warn_patterns)
diff --git a/tools/warn/warn.py b/tools/warn/warn.py
index 252f073..bdfd489 100755
--- a/tools/warn/warn.py
+++ b/tools/warn/warn.py
@@ -19,6 +19,7 @@
 import multiprocessing
 
 # pylint:disable=relative-beyond-top-level
+# pylint:disable=g-importing-member
 from .warn_common import common_main
 
 
diff --git a/tools/warn/warn_common.py b/tools/warn/warn_common.py
index de4b805..9f392ed 100755
--- a/tools/warn/warn_common.py
+++ b/tools/warn/warn_common.py
@@ -1,4 +1,4 @@
-#
+# python3
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,10 +24,6 @@
 #
 # To parse and keep warning message in the input file:
 #   severity:                classification of message severity
-#   severity.range           [0, 1, ... last_severity_level]
-#   severity.colors          for header background
-#   severity.column_headers  for the warning count table
-#   severity.headers         for warning message tables
 #   warn_patterns:
 #   warn_patterns[w]['category']     tool that issued the warning, not used now
 #   warn_patterns[w]['description']  table heading
@@ -35,7 +31,7 @@
 #   warn_patterns[w]['option']       compiler flag to control the warning
 #   warn_patterns[w]['patterns']     regular expressions to match warnings
 #   warn_patterns[w]['projects'][p]  number of warnings of pattern w in p
-#   warn_patterns[w]['severity']     severity level
+#   warn_patterns[w]['severity']     severity tuple
 #   project_list[p][0]               project name
 #   project_list[p][1]               regular expression to match a project path
 #   project_patterns[p]              re.compile(project_list[p][1])
@@ -48,7 +44,7 @@
 #   platform_version
 #   target_product
 #   target_variant
-#   compile_patterns, parse_input_file
+#   parse_input_file
 #
 # To emit html page of warning messages:
 #   flags: --byproject, --url, --separator
@@ -68,9 +64,9 @@
 #   Some data are copied from Python to JavaScript, to generate HTML elements.
 #   FlagURL                args.url
 #   FlagSeparator          args.separator
-#   SeverityColors:        severity.colors
-#   SeverityHeaders:       severity.headers
-#   SeverityColumnHeaders: severity.column_headers
+#   SeverityColors:        list of colors for all severity levels
+#   SeverityHeaders:       list of headers for all severity levels
+#   SeverityColumnHeaders: list of column_headers for all severity levels
 #   ProjectNames:          project_names, or project_list[*][0]
 #   WarnPatternsSeverity:     warn_patterns[*]['severity']
 #   WarnPatternsDescription:  warn_patterns[*]['description']
@@ -103,6 +99,7 @@
 from . import make_warn_patterns
 from . import other_warn_patterns
 from . import tidy_warn_patterns
+# pylint:disable=g-importing-member
 from .android_project_list import project_list
 from .severity import Severity
 
@@ -132,11 +129,11 @@
                     help='Path to build.log file')
 args = parser.parse_args()
 
-warn_patterns = make_warn_patterns.patterns
-warn_patterns.extend(cpp_warn_patterns.patterns)
-warn_patterns.extend(java_warn_patterns.patterns)
-warn_patterns.extend(tidy_warn_patterns.patterns)
-warn_patterns.extend(other_warn_patterns.patterns)
+warn_patterns = make_warn_patterns.warn_patterns
+warn_patterns.extend(cpp_warn_patterns.warn_patterns)
+warn_patterns.extend(java_warn_patterns.warn_patterns)
+warn_patterns.extend(tidy_warn_patterns.warn_patterns)
+warn_patterns.extend(other_warn_patterns.warn_patterns)
 
 project_patterns = []
 project_names = []
@@ -233,27 +230,33 @@
   """Dump a google chart table of warnings per project and severity."""
   # warnings[p][s] is number of warnings in project p of severity s.
   # pylint:disable=g-complex-comprehension
-  warnings = {p: {s: 0 for s in Severity.range} for p in project_names}
+  warnings = {p: {s.value: 0 for s in Severity.levels} for p in project_names}
   for i in warn_patterns:
-    s = i['severity']
+    # pytype: disable=attribute-error
+    s = i['severity'].value
+    # pytype: enable=attribute-error
     for p in i['projects']:
       warnings[p][s] += i['projects'][p]
 
   # total_by_project[p] is number of warnings in project p.
-  total_by_project = {p: sum(warnings[p][s] for s in Severity.range)
-                      for p in project_names}
+  total_by_project = {
+      p: sum(warnings[p][s.value] for s in Severity.levels)
+      for p in project_names
+  }
 
   # total_by_severity[s] is number of warnings of severity s.
-  total_by_severity = {s: sum(warnings[p][s] for p in project_names)
-                       for s in Severity.range}
+  total_by_severity = {
+      s.value: sum(warnings[p][s.value] for p in project_names)
+      for s in Severity.levels
+  }
 
   # emit table header
   stats_header = ['Project']
-  for s in Severity.range:
-    if total_by_severity[s]:
-      stats_header.append("<span style='background-color:{}'>{}</span>".
-                          format(Severity.colors[s],
-                                 Severity.column_headers[s]))
+  for s in Severity.levels:
+    if total_by_severity[s.value]:
+      stats_header.append(
+          '<span style=\'background-color:{}\'>{}</span>'.format(
+              s.color, s.column_header))
   stats_header.append('TOTAL')
 
   # emit a row of warning counts per project, skip no-warning projects
@@ -262,9 +265,9 @@
   for p in project_names:
     if total_by_project[p]:
       one_row = [p]
-      for s in Severity.range:
-        if total_by_severity[s]:
-          one_row.append(warnings[p][s])
+      for s in Severity.levels:
+        if total_by_severity[s.value]:
+          one_row.append(warnings[p][s.value])
       one_row.append(total_by_project[p])
       stats_rows.append(one_row)
       total_all_projects += total_by_project[p]
@@ -272,10 +275,10 @@
   # emit a row of warning counts per severity
   total_all_severities = 0
   one_row = ['<b>TOTAL</b>']
-  for s in Severity.range:
-    if total_by_severity[s]:
-      one_row.append(total_by_severity[s])
-      total_all_severities += total_by_severity[s]
+  for s in Severity.levels:
+    if total_by_severity[s.value]:
+      one_row.append(total_by_severity[s.value])
+      total_all_severities += total_by_severity[s.value]
   one_row.append(total_all_projects)
   stats_rows.append(one_row)
   print('<script>')
@@ -292,7 +295,7 @@
   unknown = 0
   sort_warnings()
   for i in warn_patterns:
-    if i['severity'] == Severity.UNKNOWN:
+    if i['severity'] == Severity.UNMATCHED:
       unknown += len(i['members'])
     elif i['severity'] == Severity.SKIP:
       skipped += len(i['members'])
@@ -380,6 +383,7 @@
   for i in range(len(warn_patterns)):
     w = warn_patterns[i]
     for cpat in w['compiled_patterns']:
+      # pytype: disable=attribute-error
       if cpat.match(line):
         p = find_project_index(line)
         results.append([line, i, p])
@@ -389,6 +393,7 @@
         # probably caused by 'make -j' mixing the output from
         # 2 or more concurrent compiles
         pass
+      # pytype: enable=attribute-error
 
 
 def classify_warnings(lines):
@@ -404,7 +409,6 @@
 
 def parallel_classify_warnings(warning_lines, parallel_process):
   """Classify all warning lines with num_cpu parallel processes."""
-  compile_patterns()
   num_cpu = args.processes
   if num_cpu > 1:
     groups = [[] for x in range(num_cpu)]
@@ -431,14 +435,6 @@
         pattern['projects'][pname] = 1
 
 
-def compile_patterns():
-  """Precompiling every pattern speeds up parsing by about 30x."""
-  for i in warn_patterns:
-    i['compiled_patterns'] = []
-    for pat in i['patterns']:
-      i['compiled_patterns'].append(re.compile(pat))
-
-
 def find_warn_py_and_android_root(path):
   """Set and return android_root path if it is found."""
   global android_root
@@ -475,7 +471,9 @@
           return
   # Do not use common prefix of a small number of paths.
   if count > 10:
+    # pytype: disable=wrong-arg-types
     root_path = os.path.commonprefix(warning_lines)
+    # pytype: enable=wrong-arg-types
     if len(root_path) > 2 and root_path[len(root_path) - 1] == '/':
       android_root = root_path[:-1]
 
@@ -575,7 +573,9 @@
 
 # Return s with escaped backslash and quotation characters.
 def escape_string(s):
+  # pytype: disable=attribute-error
   return s.replace('\\', '\\\\').replace('"', '\\"')
+  # pytype: enable=attribute-error
 
 
 # Return s without trailing '\n' and escape the quotation characters.
@@ -777,12 +777,16 @@
   """Dump dynamic HTML page's static JavaScript data."""
   emit_const_string('FlagURL', args.url if args.url else '')
   emit_const_string('FlagSeparator', args.separator if args.separator else '')
-  emit_const_string_array('SeverityColors', Severity.colors)
-  emit_const_string_array('SeverityHeaders', Severity.headers)
-  emit_const_string_array('SeverityColumnHeaders', Severity.column_headers)
+  emit_const_string_array('SeverityColors', [s.color for s in Severity.levels])
+  emit_const_string_array('SeverityHeaders',
+                          [s.header for s in Severity.levels])
+  emit_const_string_array('SeverityColumnHeaders',
+                          [s.column_header for s in Severity.levels])
   emit_const_string_array('ProjectNames', project_names)
+  # pytype: disable=attribute-error
   emit_const_int_array('WarnPatternsSeverity',
-                       [w['severity'] for w in warn_patterns])
+                       [w['severity'].value for w in warn_patterns])
+  # pytype: enable=attribute-error
   emit_const_html_string_array('WarnPatternsDescription',
                                [w['description'] for w in warn_patterns])
   emit_const_html_string_array('WarnPatternsOption',
@@ -851,7 +855,9 @@
       warning = kind + ': ' + description_for_csv(i)
       writer.writerow([n, '', warning])
       # print number of warnings for each project, ordered by project name.
+      # pytype: disable=attribute-error
       projects = sorted(i['projects'].keys())
+      # pytype: enable=attribute-error
       for p in projects:
         writer.writerow([i['projects'][p], p, warning])
   writer.writerow([total, '', kind + ' warnings'])
@@ -864,8 +870,9 @@
   """Dump number of warnings in csv format to stdout."""
   sort_warnings()
   total = 0
-  for s in Severity.range:
-    total += count_severity(writer, s, Severity.column_headers[s])
+  for s in Severity.levels:
+    if s != Severity.SEVERITY_UNKNOWN:
+      total += count_severity(writer, s, s.column_header)
   writer.writerow([total, '', 'All warnings'])