aconfig: add proto `bug` field

Add a `bug` field on the flag_declaration and parsed_flag proto
messages. This field is optional in the sense that it can occur zero or
more times, and aconfig will simply pass any value through.

Bug fields are included in the aconfig dump format, which can be
processed by other tools.

Also unify how protos.rs checks that fields marked 'optional' in the
proto file, but in practice are 'required', are actually set.

Test: atest aconfig.test aconfig.test.java
Bug: 288261336
Change-Id: I93de0005674822c6ff4d699bdc2c6509763a7f7f
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index f295697..bd5b49c 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -74,6 +74,7 @@
             parsed_flag.set_name(flag_declaration.take_name());
             parsed_flag.set_namespace(flag_declaration.take_namespace());
             parsed_flag.set_description(flag_declaration.take_description());
+            parsed_flag.bug.append(&mut flag_declaration.bug);
             parsed_flag.set_state(DEFAULT_FLAG_STATE);
             parsed_flag.set_permission(DEFAULT_FLAG_PERMISSION);
             let mut tracepoint = ProtoTracepoint::new();
@@ -311,6 +312,97 @@
         assert!(text.contains("com.android.aconfig.test/disabled_ro: DISABLED READ_ONLY"));
     }
 
+    #[test]
+    fn test_dump_protobuf_format() {
+        let text_proto = r#"
+parsed_flag {
+  package: "com.android.aconfig.test"
+  name: "disabled_ro"
+  namespace: "aconfig_test"
+  description: "This flag is DISABLED + READ_ONLY"
+  state: DISABLED
+  permission: READ_ONLY
+  trace {
+    source: "tests/test.aconfig"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  trace {
+    source: "tests/first.values"
+    state: DISABLED
+    permission: READ_ONLY
+  }
+  bug: "123"
+}
+parsed_flag {
+  package: "com.android.aconfig.test"
+  name: "disabled_rw"
+  namespace: "aconfig_test"
+  description: "This flag is DISABLED + READ_WRITE"
+  state: DISABLED
+  permission: READ_WRITE
+  trace {
+    source: "tests/test.aconfig"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  bug: "456"
+}
+parsed_flag {
+  package: "com.android.aconfig.test"
+  name: "enabled_ro"
+  namespace: "aconfig_test"
+  description: "This flag is ENABLED + READ_ONLY"
+  state: ENABLED
+  permission: READ_ONLY
+  trace {
+    source: "tests/test.aconfig"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  trace {
+    source: "tests/first.values"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  trace {
+    source: "tests/second.values"
+    state: ENABLED
+    permission: READ_ONLY
+  }
+  bug: "789"
+  bug: "abc"
+}
+parsed_flag {
+  package: "com.android.aconfig.test"
+  name: "enabled_rw"
+  namespace: "aconfig_test"
+  description: "This flag is ENABLED + READ_WRITE"
+  state: ENABLED
+  permission: READ_WRITE
+  trace {
+    source: "tests/test.aconfig"
+    state: DISABLED
+    permission: READ_WRITE
+  }
+  trace {
+    source: "tests/first.values"
+    state: ENABLED
+    permission: READ_WRITE
+  }
+}
+"#;
+        let expected = protobuf::text_format::parse_from_str::<ProtoParsedFlags>(text_proto)
+            .unwrap()
+            .write_to_bytes()
+            .unwrap();
+
+        let input = parse_test_flags_as_input();
+        let actual = dump_parsed_flags(vec![input], DumpFormat::Protobuf).unwrap();
+
+        assert_eq!(expected, actual);
+    }
+
     fn parse_test_flags_as_input() -> Input {
         let parsed_flags = crate::test::parse_test_flags();
         let binary_proto = parsed_flags.write_to_bytes().unwrap();