Merge "aconfig: update c/c++ codegen" into main am: 4dc569ae49

Original change: https://android-review.googlesource.com/c/platform/build/+/2878827

Change-Id: I3bb654bb1346f8d786abf0404f1ff857f14b9946
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Dennis Shen
2023-12-18 14:22:00 +00:00
committed by Automerger Merge Worker
6 changed files with 247 additions and 38 deletions

View File

@@ -135,6 +135,7 @@ fn create_class_element(package: &str, pf: &ProtoParsedFlag, rw_count: &mut i32)
#[cfg(test)]
mod tests {
use super::*;
use crate::protos::ProtoParsedFlags;
use std::collections::HashMap;
const EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
@@ -732,8 +733,127 @@ void com_android_aconfig_test_reset_flags() {
"#;
fn test_generate_cpp_code(mode: CodegenMode) {
let parsed_flags = crate::test::parse_test_flags();
const READ_ONLY_EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
#pragma once
#ifndef COM_ANDROID_ACONFIG_TEST
#define COM_ANDROID_ACONFIG_TEST(FLAG) COM_ANDROID_ACONFIG_TEST_##FLAG
#endif
#ifndef COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO
#define COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO false
#endif
#ifndef COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO
#define COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO true
#endif
#ifdef __cplusplus
#include <memory>
namespace com::android::aconfig::test {
class flag_provider_interface {
public:
virtual ~flag_provider_interface() = default;
virtual bool disabled_fixed_ro() = 0;
virtual bool disabled_ro() = 0;
virtual bool enabled_fixed_ro() = 0;
virtual bool enabled_ro() = 0;
};
extern std::unique_ptr<flag_provider_interface> provider_;
inline bool disabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO;
}
inline bool disabled_ro() {
return false;
}
inline bool enabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
}
inline bool enabled_ro() {
return true;
}
}
extern "C" {
#endif // __cplusplus
bool com_android_aconfig_test_disabled_fixed_ro();
bool com_android_aconfig_test_disabled_ro();
bool com_android_aconfig_test_enabled_fixed_ro();
bool com_android_aconfig_test_enabled_ro();
#ifdef __cplusplus
} // extern "C"
#endif
"#;
const READ_ONLY_PROD_SOURCE_FILE_EXPECTED: &str = r#"
#include "com_android_aconfig_test.h"
namespace com::android::aconfig::test {
class flag_provider : public flag_provider_interface {
public:
virtual bool disabled_fixed_ro() override {
return COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO;
}
virtual bool disabled_ro() override {
return false;
}
virtual bool enabled_fixed_ro() override {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
}
virtual bool enabled_ro() override {
return true;
}
};
std::unique_ptr<flag_provider_interface> provider_ =
std::make_unique<flag_provider>();
}
bool com_android_aconfig_test_disabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO;
}
bool com_android_aconfig_test_disabled_ro() {
return false;
}
bool com_android_aconfig_test_enabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
}
bool com_android_aconfig_test_enabled_ro() {
return true;
}
"#;
fn test_generate_cpp_code(
parsed_flags: ProtoParsedFlags,
mode: CodegenMode,
expected_header: &str,
expected_src: &str,
) {
let generated = generate_cpp_code(
crate::test::TEST_PACKAGE,
parsed_flags.parsed_flag.into_iter(),
@@ -753,12 +873,7 @@ void com_android_aconfig_test_reset_flags() {
assert_eq!(
None,
crate::test::first_significant_code_diff(
match mode {
CodegenMode::Production => EXPORTED_PROD_HEADER_EXPECTED,
CodegenMode::Test => EXPORTED_TEST_HEADER_EXPECTED,
CodegenMode::Exported =>
todo!("exported mode not yet supported for cpp, see b/313894653."),
},
expected_header,
generated_files_map.get(&target_file_path).unwrap()
)
);
@@ -768,12 +883,7 @@ void com_android_aconfig_test_reset_flags() {
assert_eq!(
None,
crate::test::first_significant_code_diff(
match mode {
CodegenMode::Production => PROD_SOURCE_FILE_EXPECTED,
CodegenMode::Test => TEST_SOURCE_FILE_EXPECTED,
CodegenMode::Exported =>
todo!("exported mode not yet supported for cpp, see b/313894653."),
},
expected_src,
generated_files_map.get(&target_file_path).unwrap()
)
);
@@ -781,11 +891,34 @@ void com_android_aconfig_test_reset_flags() {
#[test]
fn test_generate_cpp_code_for_prod() {
test_generate_cpp_code(CodegenMode::Production);
let parsed_flags = crate::test::parse_test_flags();
test_generate_cpp_code(
parsed_flags,
CodegenMode::Production,
EXPORTED_PROD_HEADER_EXPECTED,
PROD_SOURCE_FILE_EXPECTED,
);
}
#[test]
fn test_generate_cpp_code_for_test() {
test_generate_cpp_code(CodegenMode::Test);
let parsed_flags = crate::test::parse_test_flags();
test_generate_cpp_code(
parsed_flags,
CodegenMode::Test,
EXPORTED_TEST_HEADER_EXPECTED,
TEST_SOURCE_FILE_EXPECTED,
);
}
#[test]
fn test_generate_cpp_code_for_read_only_prod() {
let parsed_flags = crate::test::parse_read_only_test_flags();
test_generate_cpp_code(
parsed_flags,
CodegenMode::Production,
READ_ONLY_EXPORTED_PROD_HEADER_EXPECTED,
READ_ONLY_PROD_SOURCE_FILE_EXPECTED,
);
}
}

View File

@@ -225,6 +225,24 @@ parsed_flag {
}
"#;
pub fn parse_read_only_test_flags() -> ProtoParsedFlags {
let bytes = crate::commands::parse_flags(
"com.android.aconfig.test",
Some("system"),
vec![Input {
source: "tests/read_only_test.aconfig".to_string(),
reader: Box::new(include_bytes!("../tests/read_only_test.aconfig").as_slice()),
}],
vec![Input {
source: "tests/read_only_test.values".to_string(),
reader: Box::new(include_bytes!("../tests/read_only_test.values").as_slice()),
}],
crate::commands::DEFAULT_FLAG_PERMISSION,
)
.unwrap();
crate::protos::parsed_flags::try_from_binary_proto(&bytes).unwrap()
}
pub fn parse_test_flags() -> ProtoParsedFlags {
let bytes = crate::commands::parse_flags(
"com.android.aconfig.test",

View File

@@ -5,12 +5,14 @@
#ifndef {package_macro}
#define {package_macro}(FLAG) {package_macro}_##FLAG
#endif
{{ for item in class_elements- }}
{{ for item in class_elements }}
{{ if item.is_fixed_read_only- }}
#ifndef {package_macro}_{item.flag_macro}
#define {package_macro}_{item.flag_macro} {item.default_value}
#endif
{{ endif }}
{{ -endif }}
{{ -endfor }}
{{ -endif }}
{{ -endif }}
@@ -27,7 +29,7 @@ public:
{{ for item in class_elements}}
virtual bool {item.flag_name}() = 0;
{{ if for_test }}
{{ if for_test- }}
virtual void {item.flag_name}(bool val) = 0;
{{ -endif }}
{{ -endfor }}
@@ -41,13 +43,13 @@ extern std::unique_ptr<flag_provider_interface> provider_;
{{ for item in class_elements}}
inline bool {item.flag_name}() \{
{{ if for_test }}
{{ if for_test- }}
return provider_->{item.flag_name}();
{{ -else- }}
{{ if item.readwrite- }}
return provider_->{item.flag_name}();
{{ -else- }}
{{ if item.is_fixed_read_only }}
{{ if item.is_fixed_read_only- }}
return {package_macro}_{item.flag_macro};
{{ -else- }}
return {item.default_value};
@@ -56,14 +58,14 @@ inline bool {item.flag_name}() \{
{{ -endif }}
}
{{ if for_test }}
{{ if for_test- }}
inline void {item.flag_name}(bool val) \{
provider_->{item.flag_name}(val);
}
{{ -endif }}
{{ -endfor }}
{{ if for_test }}
{{ if for_test- }}
inline void reset_flags() \{
return provider_->reset_flags();
}
@@ -77,12 +79,12 @@ extern "C" \{
{{ for item in class_elements }}
bool {header}_{item.flag_name}();
{{ if for_test }}
{{ if for_test- }}
void set_{header}_{item.flag_name}(bool val);
{{ -endif }}
{{ -endfor }}
{{ if for_test }}
{{ if for_test- }}
void {header}_reset_flags();
{{ -endif }}

View File

@@ -1,17 +1,21 @@
#include "{header}.h"
{{ if readwrite }}
{{ if readwrite- }}
#include <server_configurable_flags/get_flags.h>
{{ endif }}
{{ if for_test }}
{{ -endif }}
{{ if for_test- }}
#include <unordered_map>
#include <string>
{{ -else- }}
{{ if readwrite- }}
#include <vector>
{{ endif }}
{{ -endif }}
{{ -endif }}
namespace {cpp_namespace} \{
{{ if for_test }}
{{ if for_test- }}
class flag_provider : public flag_provider_interface \{
private:
std::unordered_map<std::string, bool> overrides_;
@@ -21,7 +25,7 @@ namespace {cpp_namespace} \{
: overrides_()
\{}
{{ for item in class_elements}}
{{ for item in class_elements }}
virtual bool {item.flag_name}() override \{
auto it = overrides_.find("{item.flag_name}");
if (it != overrides_.end()) \{
@@ -41,7 +45,7 @@ namespace {cpp_namespace} \{
virtual void {item.flag_name}(bool val) override \{
overrides_["{item.flag_name}"] = val;
}
{{ endfor }}
{{ -endfor }}
virtual void reset_flags() override \{
overrides_.clear();
@@ -52,7 +56,8 @@ namespace {cpp_namespace} \{
class flag_provider : public flag_provider_interface \{
public:
{{ for item in class_elements}}
{{ for item in class_elements }}
virtual bool {item.flag_name}() override \{
{{ if item.readwrite- }}
if (cache_[{item.readwrite_idx}] == -1) \{
@@ -71,8 +76,10 @@ namespace {cpp_namespace} \{
{{ -endif }}
}
{{ endfor }}
{{ if readwrite- }}
private:
std::vector<int8_t> cache_ = std::vector<int8_t>({readwrite_count}, -1);
{{ -endif }}
};
@@ -82,10 +89,9 @@ std::unique_ptr<flag_provider_interface> provider_ =
std::make_unique<flag_provider>();
}
{{ for item in class_elements}}
{{ for item in class_elements }}
bool {header}_{item.flag_name}() \{
{{ if for_test }}
{{ if for_test- }}
return {cpp_namespace}::{item.flag_name}();
{{ -else- }}
{{ if item.readwrite- }}
@@ -100,12 +106,12 @@ bool {header}_{item.flag_name}() \{
{{ -endif }}
}
{{ if for_test }}
{{ if for_test- }}
void set_{header}_{item.flag_name}(bool val) \{
{cpp_namespace}::{item.flag_name}(val);
}
{{ -endif }}
{{ endfor -}}
{{ endfor-}}
{{ if for_test }}
void {header}_reset_flags() \{

View File

@@ -0,0 +1,32 @@
package: "com.android.aconfig.test"
container: "system"
flag {
name: "enabled_ro"
namespace: "aconfig_test"
description: "This flag is ENABLED + READ_ONLY"
bug: "abc"
}
flag {
name: "disabled_ro"
namespace: "aconfig_test"
description: "This flag is DISABLED + READ_ONLY"
bug: "123"
}
flag {
name: "enabled_fixed_ro"
namespace: "aconfig_test"
description: "This flag is fixed READ_ONLY + ENABLED"
bug: ""
is_fixed_read_only: true
}
flag {
name: "disabled_fixed_ro"
namespace: "aconfig_test"
description: "This flag is fixed READ_ONLY + DISABLED"
bug: ""
is_fixed_read_only: true
}

View File

@@ -0,0 +1,18 @@
flag_value {
package: "com.android.aconfig.test"
name: "disabled_ro"
state: DISABLED
permission: READ_ONLY
}
flag_value {
package: "com.android.aconfig.test"
name: "enabled_ro"
state: ENABLED
permission: READ_ONLY
}
flag_value {
package: "com.android.aconfig.test"
name: "enabled_fixed_ro"
state: ENABLED
permission: READ_ONLY
}