Support aconfig dump --dedup

Add a flag to aconfig dump that will allow identical flags to be merged
without erroring.  This will allow merging the aconfig cache files from
dependencies for each module, which requires passing less data to Make
from Soong, and thus reduces the percentage of builds require Kati
analysis.

Bug: 313698230
Test: aconfig.test
Change-Id: Id2d9b78225720ce01defad4b13ea9395f6ab1033
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index ff0df1f..ed7489f 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -250,11 +250,11 @@
     Textproto,
 }
 
-pub fn dump_parsed_flags(mut input: Vec<Input>, format: DumpFormat) -> Result<Vec<u8>> {
+pub fn dump_parsed_flags(mut input: Vec<Input>, format: DumpFormat, dedup: bool) -> Result<Vec<u8>> {
     let individually_parsed_flags: Result<Vec<ProtoParsedFlags>> =
         input.iter_mut().map(|i| i.try_parse_flags()).collect();
     let parsed_flags: ProtoParsedFlags =
-        crate::protos::parsed_flags::merge(individually_parsed_flags?)?;
+        crate::protos::parsed_flags::merge(individually_parsed_flags?, dedup)?;
 
     let mut output = Vec::new();
     match format {
@@ -448,7 +448,7 @@
     #[test]
     fn test_dump_text_format() {
         let input = parse_test_flags_as_input();
-        let bytes = dump_parsed_flags(vec![input], DumpFormat::Text).unwrap();
+        let bytes = dump_parsed_flags(vec![input], DumpFormat::Text, false).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
         assert!(text.contains("com.android.aconfig.test.disabled_ro: READ_ONLY + DISABLED"));
     }
@@ -463,7 +463,7 @@
         .unwrap();
 
         let input = parse_test_flags_as_input();
-        let actual = dump_parsed_flags(vec![input], DumpFormat::Protobuf).unwrap();
+        let actual = dump_parsed_flags(vec![input], DumpFormat::Protobuf, false).unwrap();
 
         assert_eq!(expected, actual);
     }
@@ -471,7 +471,16 @@
     #[test]
     fn test_dump_textproto_format() {
         let input = parse_test_flags_as_input();
-        let bytes = dump_parsed_flags(vec![input], DumpFormat::Textproto).unwrap();
+        let bytes = dump_parsed_flags(vec![input], DumpFormat::Textproto, false).unwrap();
+        let text = std::str::from_utf8(&bytes).unwrap();
+        assert_eq!(crate::test::TEST_FLAGS_TEXTPROTO.trim(), text.trim());
+    }
+
+    #[test]
+    fn test_dump_textproto_format_dedup() {
+        let input = parse_test_flags_as_input();
+        let input2 = parse_test_flags_as_input();
+        let bytes = dump_parsed_flags(vec![input, input2], DumpFormat::Textproto, true).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
         assert_eq!(crate::test::TEST_FLAGS_TEXTPROTO.trim(), text.trim());
     }