diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index eb860b0..f295697 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -14,105 +14,160 @@
  * limitations under the License.
  */
 
-use anyhow::{ensure, Context, Result};
+use anyhow::{bail, ensure, Context, Result};
 use clap::ValueEnum;
 use protobuf::Message;
-use serde::{Deserialize, Serialize};
-use std::fmt;
 use std::io::Read;
 use std::path::PathBuf;
 
-use crate::aconfig::{FlagDeclarations, FlagState, FlagValue, Permission};
-use crate::cache::{Cache, CacheBuilder, Item};
 use crate::codegen_cpp::generate_cpp_code;
 use crate::codegen_java::generate_java_code;
 use crate::codegen_rust::generate_rust_code;
-use crate::protos::ProtoParsedFlags;
-
-#[derive(Serialize, Deserialize, Clone, Debug)]
-pub enum Source {
-    #[allow(dead_code)] // only used in unit tests
-    Memory,
-    File(String),
-}
-
-impl fmt::Display for Source {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            Self::Memory => write!(f, "<memory>"),
-            Self::File(path) => write!(f, "{}", path),
-        }
-    }
-}
+use crate::protos::{
+    ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag, ProtoParsedFlags, ProtoTracepoint,
+};
 
 pub struct Input {
-    pub source: Source,
+    pub source: String,
     pub reader: Box<dyn Read>,
 }
 
+impl Input {
+    fn try_parse_flags(&mut self) -> Result<ProtoParsedFlags> {
+        let mut buffer = Vec::new();
+        self.reader.read_to_end(&mut buffer)?;
+        crate::protos::parsed_flags::try_from_binary_proto(&buffer)
+    }
+}
+
 pub struct OutputFile {
     pub path: PathBuf, // relative to some root directory only main knows about
     pub contents: Vec<u8>,
 }
 
-pub fn create_cache(package: &str, declarations: Vec<Input>, values: Vec<Input>) -> Result<Cache> {
-    let mut builder = CacheBuilder::new(package.to_owned())?;
+const DEFAULT_FLAG_STATE: ProtoFlagState = ProtoFlagState::DISABLED;
+const DEFAULT_FLAG_PERMISSION: ProtoFlagPermission = ProtoFlagPermission::READ_WRITE;
+
+pub fn parse_flags(package: &str, declarations: Vec<Input>, values: Vec<Input>) -> Result<Vec<u8>> {
+    let mut parsed_flags = ProtoParsedFlags::new();
 
     for mut input in declarations {
         let mut contents = String::new();
         input.reader.read_to_string(&mut contents)?;
-        let dec_list = FlagDeclarations::try_from_text_proto(&contents)
+
+        let flag_declarations = crate::protos::flag_declarations::try_from_text_proto(&contents)
             .with_context(|| format!("Failed to parse {}", input.source))?;
         ensure!(
-            package == dec_list.package,
+            package == flag_declarations.package(),
             "Failed to parse {}: expected package {}, got {}",
             input.source,
             package,
-            dec_list.package
+            flag_declarations.package()
         );
-        for d in dec_list.flags.into_iter() {
-            builder.add_flag_declaration(input.source.clone(), d)?;
+        for mut flag_declaration in flag_declarations.flag.into_iter() {
+            crate::protos::flag_declaration::verify_fields(&flag_declaration)
+                .with_context(|| format!("Failed to parse {}", input.source))?;
+
+            // create ParsedFlag using FlagDeclaration and default values
+            let mut parsed_flag = ProtoParsedFlag::new();
+            parsed_flag.set_package(package.to_string());
+            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.set_state(DEFAULT_FLAG_STATE);
+            parsed_flag.set_permission(DEFAULT_FLAG_PERMISSION);
+            let mut tracepoint = ProtoTracepoint::new();
+            tracepoint.set_source(input.source.clone());
+            tracepoint.set_state(DEFAULT_FLAG_STATE);
+            tracepoint.set_permission(DEFAULT_FLAG_PERMISSION);
+            parsed_flag.trace.push(tracepoint);
+
+            // verify ParsedFlag looks reasonable
+            crate::protos::parsed_flag::verify_fields(&parsed_flag)?;
+
+            // verify ParsedFlag can be added
+            ensure!(
+                parsed_flags.parsed_flag.iter().all(|other| other.name() != parsed_flag.name()),
+                "failed to declare flag {} from {}: flag already declared",
+                parsed_flag.name(),
+                input.source
+            );
+
+            // add ParsedFlag to ParsedFlags
+            parsed_flags.parsed_flag.push(parsed_flag);
         }
     }
 
     for mut input in values {
         let mut contents = String::new();
         input.reader.read_to_string(&mut contents)?;
-        let values_list = FlagValue::try_from_text_proto_list(&contents)
+        let flag_values = crate::protos::flag_values::try_from_text_proto(&contents)
             .with_context(|| format!("Failed to parse {}", input.source))?;
-        for v in values_list {
-            // TODO: warn about flag values that do not take effect?
-            let _ = builder.add_flag_value(input.source.clone(), v);
+        for flag_value in flag_values.flag_value.into_iter() {
+            crate::protos::flag_value::verify_fields(&flag_value)
+                .with_context(|| format!("Failed to parse {}", input.source))?;
+
+            let Some(parsed_flag) = parsed_flags.parsed_flag.iter_mut().find(|pf| pf.package() == flag_value.package() && pf.name() == flag_value.name()) else {
+                // (silently) skip unknown flags
+                continue;
+            };
+
+            parsed_flag.set_state(flag_value.state());
+            parsed_flag.set_permission(flag_value.permission());
+            let mut tracepoint = ProtoTracepoint::new();
+            tracepoint.set_source(input.source.clone());
+            tracepoint.set_state(flag_value.state());
+            tracepoint.set_permission(flag_value.permission());
+            parsed_flag.trace.push(tracepoint);
         }
     }
 
-    Ok(builder.build())
-}
-
-pub fn create_java_lib(cache: Cache) -> Result<Vec<OutputFile>> {
-    generate_java_code(&cache)
-}
-
-pub fn create_cpp_lib(cache: Cache) -> Result<OutputFile> {
-    generate_cpp_code(&cache)
-}
-
-pub fn create_rust_lib(cache: Cache) -> Result<OutputFile> {
-    generate_rust_code(&cache)
-}
-
-pub fn create_device_config_defaults(caches: Vec<Cache>) -> Result<Vec<u8>> {
+    crate::protos::parsed_flags::verify_fields(&parsed_flags)?;
     let mut output = Vec::new();
-    for item in sort_and_iter_items(caches).filter(|item| item.permission == Permission::ReadWrite)
+    parsed_flags.write_to_vec(&mut output)?;
+    Ok(output)
+}
+
+pub fn create_java_lib(mut input: Input) -> Result<Vec<OutputFile>> {
+    let parsed_flags = input.try_parse_flags()?;
+    let Some(package) = find_unique_package(&parsed_flags) else {
+        bail!("no parsed flags, or the parsed flags use different packages");
+    };
+    generate_java_code(package, parsed_flags.parsed_flag.iter())
+}
+
+pub fn create_cpp_lib(mut input: Input) -> Result<OutputFile> {
+    let parsed_flags = input.try_parse_flags()?;
+    let Some(package) = find_unique_package(&parsed_flags) else {
+        bail!("no parsed flags, or the parsed flags use different packages");
+    };
+    generate_cpp_code(package, parsed_flags.parsed_flag.iter())
+}
+
+pub fn create_rust_lib(mut input: Input) -> Result<OutputFile> {
+    let parsed_flags = input.try_parse_flags()?;
+    let Some(package) = find_unique_package(&parsed_flags) else {
+        bail!("no parsed flags, or the parsed flags use different packages");
+    };
+    generate_rust_code(package, parsed_flags.parsed_flag.iter())
+}
+
+pub fn create_device_config_defaults(mut input: Input) -> Result<Vec<u8>> {
+    let parsed_flags = input.try_parse_flags()?;
+    let mut output = Vec::new();
+    for parsed_flag in parsed_flags
+        .parsed_flag
+        .into_iter()
+        .filter(|pf| pf.permission() == ProtoFlagPermission::READ_WRITE)
     {
         let line = format!(
             "{}:{}.{}={}\n",
-            item.namespace,
-            item.package,
-            item.name,
-            match item.state {
-                FlagState::Enabled => "enabled",
-                FlagState::Disabled => "disabled",
+            parsed_flag.namespace(),
+            parsed_flag.package(),
+            parsed_flag.name(),
+            match parsed_flag.state() {
+                ProtoFlagState::ENABLED => "enabled",
+                ProtoFlagState::DISABLED => "disabled",
             }
         );
         output.extend_from_slice(line.as_bytes());
@@ -120,17 +175,21 @@
     Ok(output)
 }
 
-pub fn create_device_config_sysprops(caches: Vec<Cache>) -> Result<Vec<u8>> {
+pub fn create_device_config_sysprops(mut input: Input) -> Result<Vec<u8>> {
+    let parsed_flags = input.try_parse_flags()?;
     let mut output = Vec::new();
-    for item in sort_and_iter_items(caches).filter(|item| item.permission == Permission::ReadWrite)
+    for parsed_flag in parsed_flags
+        .parsed_flag
+        .into_iter()
+        .filter(|pf| pf.permission() == ProtoFlagPermission::READ_WRITE)
     {
         let line = format!(
             "persist.device_config.{}.{}={}\n",
-            item.package,
-            item.name,
-            match item.state {
-                FlagState::Enabled => "true",
-                FlagState::Disabled => "false",
+            parsed_flag.package(),
+            parsed_flag.name(),
+            match parsed_flag.state() {
+                ProtoFlagState::ENABLED => "true",
+                ProtoFlagState::DISABLED => "false",
             }
         );
         output.extend_from_slice(line.as_bytes());
@@ -145,177 +204,118 @@
     Protobuf,
 }
 
-pub fn dump_cache(caches: Vec<Cache>, format: DumpFormat) -> Result<Vec<u8>> {
+pub fn dump_parsed_flags(mut input: Vec<Input>, format: DumpFormat) -> 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?)?;
+
     let mut output = Vec::new();
     match format {
         DumpFormat::Text => {
-            for item in sort_and_iter_items(caches) {
+            for parsed_flag in parsed_flags.parsed_flag.into_iter() {
                 let line = format!(
                     "{}/{}: {:?} {:?}\n",
-                    item.package, item.name, item.state, item.permission
+                    parsed_flag.package(),
+                    parsed_flag.name(),
+                    parsed_flag.state(),
+                    parsed_flag.permission()
                 );
                 output.extend_from_slice(line.as_bytes());
             }
         }
         DumpFormat::Debug => {
-            for item in sort_and_iter_items(caches) {
-                let line = format!("{:#?}\n", item);
+            for parsed_flag in parsed_flags.parsed_flag.into_iter() {
+                let line = format!("{:#?}\n", parsed_flag);
                 output.extend_from_slice(line.as_bytes());
             }
         }
         DumpFormat::Protobuf => {
-            for cache in sort_and_iter_caches(caches) {
-                let parsed_flags: ProtoParsedFlags = cache.into();
-                parsed_flags.write_to_vec(&mut output)?;
-            }
+            parsed_flags.write_to_vec(&mut output)?;
         }
     }
     Ok(output)
 }
 
-fn sort_and_iter_items(caches: Vec<Cache>) -> impl Iterator<Item = Item> {
-    sort_and_iter_caches(caches).flat_map(|cache| cache.into_iter())
-}
-
-fn sort_and_iter_caches(mut caches: Vec<Cache>) -> impl Iterator<Item = Cache> {
-    caches.sort_by_cached_key(|cache| cache.package().to_string());
-    caches.into_iter()
+fn find_unique_package(parsed_flags: &ProtoParsedFlags) -> Option<&str> {
+    let Some(package) = parsed_flags.parsed_flag.first().map(|pf| pf.package()) else {
+        return None;
+    };
+    if parsed_flags.parsed_flag.iter().any(|pf| pf.package() != package) {
+        return None;
+    }
+    Some(package)
 }
 
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::aconfig::{FlagState, Permission};
-
-    fn create_test_cache_com_example() -> Cache {
-        let s = r#"
-        package: "com.example"
-        flag {
-            name: "a"
-            namespace: "ns"
-            description: "Description of a"
-        }
-        flag {
-            name: "b"
-            namespace: "ns"
-            description: "Description of b"
-        }
-        "#;
-        let declarations = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
-        let o = r#"
-        flag_value {
-            package: "com.example"
-            name: "a"
-            state: DISABLED
-            permission: READ_ONLY
-        }
-        "#;
-        let values = vec![Input { source: Source::Memory, reader: Box::new(o.as_bytes()) }];
-        create_cache("com.example", declarations, values).unwrap()
-    }
-
-    fn create_test_cache_com_other() -> Cache {
-        let s = r#"
-        package: "com.other"
-        flag {
-            name: "c"
-            namespace: "ns"
-            description: "Description of c"
-        }
-        "#;
-        let declarations = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
-        let o = r#"
-        flag_value {
-            package: "com.other"
-            name: "c"
-            state: DISABLED
-            permission: READ_ONLY
-        }
-        "#;
-        let values = vec![Input { source: Source::Memory, reader: Box::new(o.as_bytes()) }];
-        create_cache("com.other", declarations, values).unwrap()
-    }
 
     #[test]
-    fn test_create_cache() {
-        let caches = create_test_cache_com_example(); // calls create_cache
-        let item = caches.iter().find(|&item| item.name == "a").unwrap();
-        assert_eq!(FlagState::Disabled, item.state);
-        assert_eq!(Permission::ReadOnly, item.permission);
+    fn test_parse_flags() {
+        let parsed_flags = crate::test::parse_test_flags(); // calls parse_flags
+        crate::protos::parsed_flags::verify_fields(&parsed_flags).unwrap();
+
+        let enabled_ro =
+            parsed_flags.parsed_flag.iter().find(|pf| pf.name() == "enabled_ro").unwrap();
+        assert!(crate::protos::parsed_flag::verify_fields(enabled_ro).is_ok());
+        assert_eq!("com.android.aconfig.test", enabled_ro.package());
+        assert_eq!("enabled_ro", enabled_ro.name());
+        assert_eq!("This flag is ENABLED + READ_ONLY", enabled_ro.description());
+        assert_eq!(ProtoFlagState::ENABLED, enabled_ro.state());
+        assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.permission());
+        assert_eq!(3, enabled_ro.trace.len());
+        assert_eq!("tests/test.aconfig", enabled_ro.trace[0].source());
+        assert_eq!(ProtoFlagState::DISABLED, enabled_ro.trace[0].state());
+        assert_eq!(ProtoFlagPermission::READ_WRITE, enabled_ro.trace[0].permission());
+        assert_eq!("tests/first.values", enabled_ro.trace[1].source());
+        assert_eq!(ProtoFlagState::DISABLED, enabled_ro.trace[1].state());
+        assert_eq!(ProtoFlagPermission::READ_WRITE, enabled_ro.trace[1].permission());
+        assert_eq!("tests/second.values", enabled_ro.trace[2].source());
+        assert_eq!(ProtoFlagState::ENABLED, enabled_ro.trace[2].state());
+        assert_eq!(ProtoFlagPermission::READ_ONLY, enabled_ro.trace[2].permission());
+
+        assert_eq!(4, parsed_flags.parsed_flag.len());
+        for pf in parsed_flags.parsed_flag.iter() {
+            let first = pf.trace.first().unwrap();
+            assert_eq!(DEFAULT_FLAG_STATE, first.state());
+            assert_eq!(DEFAULT_FLAG_PERMISSION, first.permission());
+
+            let last = pf.trace.last().unwrap();
+            assert_eq!(pf.state(), last.state());
+            assert_eq!(pf.permission(), last.permission());
+        }
     }
 
     #[test]
     fn test_create_device_config_defaults() {
-        let caches = vec![crate::test::create_cache()];
-        let bytes = create_device_config_defaults(caches).unwrap();
+        let input = parse_test_flags_as_input();
+        let bytes = create_device_config_defaults(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
         assert_eq!("aconfig_test:com.android.aconfig.test.disabled_rw=disabled\naconfig_test:com.android.aconfig.test.enabled_rw=enabled\n", text);
     }
 
     #[test]
     fn test_create_device_config_sysprops() {
-        let caches = vec![crate::test::create_cache()];
-        let bytes = create_device_config_sysprops(caches).unwrap();
+        let input = parse_test_flags_as_input();
+        let bytes = create_device_config_sysprops(input).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
         assert_eq!("persist.device_config.com.android.aconfig.test.disabled_rw=false\npersist.device_config.com.android.aconfig.test.enabled_rw=true\n", text);
     }
 
     #[test]
     fn test_dump_text_format() {
-        let caches = vec![create_test_cache_com_example()];
-        let bytes = dump_cache(caches, DumpFormat::Text).unwrap();
+        let input = parse_test_flags_as_input();
+        let bytes = dump_parsed_flags(vec![input], DumpFormat::Text).unwrap();
         let text = std::str::from_utf8(&bytes).unwrap();
-        assert!(text.contains("a: Disabled"));
+        assert!(text.contains("com.android.aconfig.test/disabled_ro: DISABLED READ_ONLY"));
     }
 
-    #[test]
-    fn test_dump_protobuf_format() {
-        use crate::protos::{ProtoFlagPermission, ProtoFlagState, ProtoTracepoint};
-        use protobuf::Message;
-
-        let caches = vec![create_test_cache_com_example()];
-        let bytes = dump_cache(caches, DumpFormat::Protobuf).unwrap();
-        let actual = ProtoParsedFlags::parse_from_bytes(&bytes).unwrap();
-
-        assert_eq!(
-            vec!["a".to_string(), "b".to_string()],
-            actual.parsed_flag.iter().map(|item| item.name.clone().unwrap()).collect::<Vec<_>>()
-        );
-
-        let item =
-            actual.parsed_flag.iter().find(|item| item.name == Some("b".to_string())).unwrap();
-        assert_eq!(item.package(), "com.example");
-        assert_eq!(item.name(), "b");
-        assert_eq!(item.description(), "Description of b");
-        assert_eq!(item.state(), ProtoFlagState::DISABLED);
-        assert_eq!(item.permission(), ProtoFlagPermission::READ_WRITE);
-        let mut tp = ProtoTracepoint::new();
-        tp.set_source("<memory>".to_string());
-        tp.set_state(ProtoFlagState::DISABLED);
-        tp.set_permission(ProtoFlagPermission::READ_WRITE);
-        assert_eq!(item.trace, vec![tp]);
-    }
-
-    #[test]
-    fn test_dump_multiple_caches() {
-        let caches = vec![create_test_cache_com_example(), create_test_cache_com_other()];
-        let bytes = dump_cache(caches, DumpFormat::Protobuf).unwrap();
-        let dump = ProtoParsedFlags::parse_from_bytes(&bytes).unwrap();
-        assert_eq!(
-            dump.parsed_flag
-                .iter()
-                .map(|parsed_flag| format!("{}/{}", parsed_flag.package(), parsed_flag.name()))
-                .collect::<Vec<_>>(),
-            vec![
-                "com.example/a".to_string(),
-                "com.example/b".to_string(),
-                "com.other/c".to_string()
-            ]
-        );
-
-        let caches = vec![create_test_cache_com_other(), create_test_cache_com_example()];
-        let bytes = dump_cache(caches, DumpFormat::Protobuf).unwrap();
-        let dump_reversed_input = ProtoParsedFlags::parse_from_bytes(&bytes).unwrap();
-        assert_eq!(dump, dump_reversed_input);
+    fn parse_test_flags_as_input() -> Input {
+        let parsed_flags = crate::test::parse_test_flags();
+        let binary_proto = parsed_flags.write_to_bytes().unwrap();
+        let cursor = std::io::Cursor::new(binary_proto);
+        let reader = Box::new(cursor);
+        Input { source: "test.data".to_string(), reader }
     }
 }
