Merge "aconfig: update c/c++ codegen" into main

This commit is contained in:
Dennis Shen
2023-07-14 13:37:01 +00:00
committed by Gerrit Code Review
6 changed files with 174 additions and 126 deletions

View File

@@ -42,7 +42,7 @@ where
cpp_namespace, cpp_namespace,
package: package.to_string(), package: package.to_string(),
readwrite, readwrite,
for_prod: codegen_mode == CodegenMode::Production, for_test: codegen_mode == CodegenMode::Test,
class_elements, class_elements,
}; };
@@ -102,7 +102,7 @@ pub struct Context {
pub cpp_namespace: String, pub cpp_namespace: String,
pub package: String, pub package: String,
pub readwrite: bool, pub readwrite: bool,
pub for_prod: bool, pub for_test: bool,
pub class_elements: Vec<ClassElement>, pub class_elements: Vec<ClassElement>,
} }
@@ -111,7 +111,6 @@ pub struct ClassElement {
pub readwrite: bool, pub readwrite: bool,
pub default_value: String, pub default_value: String,
pub flag_name: String, pub flag_name: String,
pub uppercase_flag_name: String,
pub device_config_namespace: String, pub device_config_namespace: String,
pub device_config_flag: String, pub device_config_flag: String,
} }
@@ -125,7 +124,6 @@ fn create_class_element(package: &str, pf: &ProtoParsedFlag) -> ClassElement {
"false".to_string() "false".to_string()
}, },
flag_name: pf.name().to_string(), flag_name: pf.name().to_string(),
uppercase_flag_name: pf.name().to_string().to_ascii_uppercase(),
device_config_namespace: pf.namespace().to_string(), device_config_namespace: pf.namespace().to_string(),
device_config_flag: codegen::create_device_config_ident(package, pf.name()) device_config_flag: codegen::create_device_config_ident(package, pf.name())
.expect("values checked at flag parse time"), .expect("values checked at flag parse time"),
@@ -157,19 +155,10 @@ public:
virtual bool enabled_ro() = 0; virtual bool enabled_ro() = 0;
virtual bool enabled_rw() = 0; virtual bool enabled_rw() = 0;
virtual void override_flag(std::string const&, bool) {}
virtual void reset_overrides() {}
}; };
extern std::unique_ptr<flag_provider_interface> provider_; extern std::unique_ptr<flag_provider_interface> provider_;
extern std::string const DISABLED_RO;
extern std::string const DISABLED_RW;
extern std::string const ENABLED_RO;
extern std::string const ENABLED_RW;
inline bool disabled_ro() { inline bool disabled_ro() {
return false; return false;
} }
@@ -186,14 +175,6 @@ inline bool enabled_rw() {
return provider_->enabled_rw(); return provider_->enabled_rw();
} }
inline void override_flag(std::string const& name, bool val) {
return provider_->override_flag(name, val);
}
inline void reset_overrides() {
return provider_->reset_overrides();
}
} }
#endif #endif
"#; "#;
@@ -213,46 +194,59 @@ public:
virtual bool disabled_ro() = 0; virtual bool disabled_ro() = 0;
virtual void disabled_ro(bool val) = 0;
virtual bool disabled_rw() = 0; virtual bool disabled_rw() = 0;
virtual void disabled_rw(bool val) = 0;
virtual bool enabled_ro() = 0; virtual bool enabled_ro() = 0;
virtual void enabled_ro(bool val) = 0;
virtual bool enabled_rw() = 0; virtual bool enabled_rw() = 0;
virtual void override_flag(std::string const&, bool) {} virtual void enabled_rw(bool val) = 0;
virtual void reset_overrides() {} virtual void reset_flags() {}
}; };
extern std::unique_ptr<flag_provider_interface> provider_; extern std::unique_ptr<flag_provider_interface> provider_;
extern std::string const DISABLED_RO;
extern std::string const DISABLED_RW;
extern std::string const ENABLED_RO;
extern std::string const ENABLED_RW;
inline bool disabled_ro() { inline bool disabled_ro() {
return provider_->disabled_ro(); return provider_->disabled_ro();
} }
inline void disabled_ro(bool val) {
provider_->disabled_ro(val);
}
inline bool disabled_rw() { inline bool disabled_rw() {
return provider_->disabled_rw(); return provider_->disabled_rw();
} }
inline void disabled_rw(bool val) {
provider_->disabled_rw(val);
}
inline bool enabled_ro() { inline bool enabled_ro() {
return provider_->enabled_ro(); return provider_->enabled_ro();
} }
inline void enabled_ro(bool val) {
provider_->enabled_ro(val);
}
inline bool enabled_rw() { inline bool enabled_rw() {
return provider_->enabled_rw(); return provider_->enabled_rw();
} }
inline void override_flag(std::string const& name, bool val) { inline void enabled_rw(bool val) {
return provider_->override_flag(name, val); provider_->enabled_rw(val);
} }
inline void reset_overrides() { inline void reset_flags() {
return provider_->reset_overrides(); return provider_->reset_flags();
} }
} }
@@ -306,28 +300,20 @@ public:
using namespace server_configurable_flags; using namespace server_configurable_flags;
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <cassert>
namespace com::android::aconfig::test { namespace com::android::aconfig::test {
class flag_provider : public flag_provider_interface { class flag_provider : public flag_provider_interface {
private: private:
std::unordered_map<std::string, bool> overrides_; std::unordered_map<std::string, bool> overrides_;
std::unordered_set<std::string> flag_names_;
public: public:
flag_provider() flag_provider()
: overrides_(), : overrides_()
flag_names_() { {}
flag_names_.insert(DISABLED_RO);
flag_names_.insert(DISABLED_RW);
flag_names_.insert(ENABLED_RO);
flag_names_.insert(ENABLED_RW);
}
virtual bool disabled_ro() override { virtual bool disabled_ro() override {
auto it = overrides_.find(DISABLED_RO); auto it = overrides_.find("disabled_ro");
if (it != overrides_.end()) { if (it != overrides_.end()) {
return it->second; return it->second;
} else { } else {
@@ -335,8 +321,12 @@ public:
} }
} }
virtual void disabled_ro(bool val) override {
overrides_["disabled_ro"] = val;
}
virtual bool disabled_rw() override { virtual bool disabled_rw() override {
auto it = overrides_.find(DISABLED_RW); auto it = overrides_.find("disabled_rw");
if (it != overrides_.end()) { if (it != overrides_.end()) {
return it->second; return it->second;
} else { } else {
@@ -347,8 +337,12 @@ public:
} }
} }
virtual void disabled_rw(bool val) override {
overrides_["disabled_rw"] = val;
}
virtual bool enabled_ro() override { virtual bool enabled_ro() override {
auto it = overrides_.find(ENABLED_RO); auto it = overrides_.find("enabled_ro");
if (it != overrides_.end()) { if (it != overrides_.end()) {
return it->second; return it->second;
} else { } else {
@@ -356,8 +350,12 @@ public:
} }
} }
virtual void enabled_ro(bool val) override {
overrides_["enabled_ro"] = val;
}
virtual bool enabled_rw() override { virtual bool enabled_rw() override {
auto it = overrides_.find(ENABLED_RW); auto it = overrides_.find("enabled_rw");
if (it != overrides_.end()) { if (it != overrides_.end()) {
return it->second; return it->second;
} else { } else {
@@ -368,12 +366,11 @@ public:
} }
} }
virtual void override_flag(std::string const& flag, bool val) override { virtual void enabled_rw(bool val) override {
assert(flag_names_.count(flag)); overrides_["enabled_rw"] = val;
overrides_[flag] = val;
} }
virtual void reset_overrides() override { virtual void reset_flags() override {
overrides_.clear(); overrides_.clear();
} }
}; };
@@ -386,18 +383,12 @@ public:
#include "com_android_aconfig_test_flag_provider.h" #include "com_android_aconfig_test_flag_provider.h"
namespace com::android::aconfig::test { namespace com::android::aconfig::test {
std::string const DISABLED_RO = "com.android.aconfig.test.disabled_ro";
std::string const DISABLED_RW = "com.android.aconfig.test.disabled_rw";
std::string const ENABLED_RO = "com.android.aconfig.test.enabled_ro";
std::string const ENABLED_RW = "com.android.aconfig.test.enabled_rw";
std::unique_ptr<flag_provider_interface> provider_ = std::unique_ptr<flag_provider_interface> provider_ =
std::make_unique<flag_provider>(); std::make_unique<flag_provider>();
} }
"#; "#;
const C_EXPORTED_HEADER_EXPECTED: &str = r#" const C_EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
#ifndef com_android_aconfig_test_c_HEADER_H #ifndef com_android_aconfig_test_c_HEADER_H
#define com_android_aconfig_test_c_HEADER_H #define com_android_aconfig_test_c_HEADER_H
@@ -405,11 +396,6 @@ namespace com::android::aconfig::test {
extern "C" { extern "C" {
#endif #endif
extern const char* com_android_aconfig_test_DISABLED_RO;
extern const char* com_android_aconfig_test_DISABLED_RW;
extern const char* com_android_aconfig_test_ENABLED_RO;
extern const char* com_android_aconfig_test_ENABLED_RW;
bool com_android_aconfig_test_disabled_ro(); bool com_android_aconfig_test_disabled_ro();
bool com_android_aconfig_test_disabled_rw(); bool com_android_aconfig_test_disabled_rw();
@@ -418,9 +404,37 @@ bool com_android_aconfig_test_enabled_ro();
bool com_android_aconfig_test_enabled_rw(); bool com_android_aconfig_test_enabled_rw();
void com_android_aconfig_test_override_flag(const char* name, bool val); #ifdef __cplusplus
}
#endif
#endif
"#;
void com_android_aconfig_test_reset_overrides(); const C_EXPORTED_TEST_HEADER_EXPECTED: &str = r#"
#ifndef com_android_aconfig_test_c_HEADER_H
#define com_android_aconfig_test_c_HEADER_H
#ifdef __cplusplus
extern "C" {
#endif
bool com_android_aconfig_test_disabled_ro();
void set_com_android_aconfig_test_disabled_ro(bool val);
bool com_android_aconfig_test_disabled_rw();
void set_com_android_aconfig_test_disabled_rw(bool val);
bool com_android_aconfig_test_enabled_ro();
void set_com_android_aconfig_test_enabled_ro(bool val);
bool com_android_aconfig_test_enabled_rw();
void set_com_android_aconfig_test_enabled_rw(bool val);
void com_android_aconfig_test_reset_flags();
#ifdef __cplusplus #ifdef __cplusplus
} }
@@ -428,15 +442,9 @@ void com_android_aconfig_test_reset_overrides();
#endif #endif
"#; "#;
const C_SOURCE_FILE_EXPECTED: &str = r#" const C_PROD_SOURCE_FILE_EXPECTED: &str = r#"
#include "com_android_aconfig_test_c.h" #include "com_android_aconfig_test_c.h"
#include "com_android_aconfig_test.h" #include "com_android_aconfig_test.h"
#include <string>
const char* com_android_aconfig_test_DISABLED_RO = "com.android.aconfig.test.disabled_ro";
const char* com_android_aconfig_test_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
const char* com_android_aconfig_test_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
const char* com_android_aconfig_test_ENABLED_RW = "com.android.aconfig.test.enabled_rw";
bool com_android_aconfig_test_disabled_ro() { bool com_android_aconfig_test_disabled_ro() {
return com::android::aconfig::test::disabled_ro(); return com::android::aconfig::test::disabled_ro();
@@ -453,13 +461,46 @@ bool com_android_aconfig_test_enabled_ro() {
bool com_android_aconfig_test_enabled_rw() { bool com_android_aconfig_test_enabled_rw() {
return com::android::aconfig::test::enabled_rw(); return com::android::aconfig::test::enabled_rw();
} }
"#;
void com_android_aconfig_test_override_flag(const char* name, bool val) { const C_TEST_SOURCE_FILE_EXPECTED: &str = r#"
com::android::aconfig::test::override_flag(std::string(name), val); #include "com_android_aconfig_test_c.h"
#include "com_android_aconfig_test.h"
bool com_android_aconfig_test_disabled_ro() {
return com::android::aconfig::test::disabled_ro();
} }
void com_android_aconfig_test_reset_overrides() { void set_com_android_aconfig_test_disabled_ro(bool val) {
com::android::aconfig::test::reset_overrides(); com::android::aconfig::test::disabled_ro(val);
}
bool com_android_aconfig_test_disabled_rw() {
return com::android::aconfig::test::disabled_rw();
}
void set_com_android_aconfig_test_disabled_rw(bool val) {
com::android::aconfig::test::disabled_rw(val);
}
bool com_android_aconfig_test_enabled_ro() {
return com::android::aconfig::test::enabled_ro();
}
void set_com_android_aconfig_test_enabled_ro(bool val) {
com::android::aconfig::test::enabled_ro(val);
}
bool com_android_aconfig_test_enabled_rw() {
return com::android::aconfig::test::enabled_rw();
}
void set_com_android_aconfig_test_enabled_rw(bool val) {
com::android::aconfig::test::enabled_rw(val);
}
void com_android_aconfig_test_reset_flags() {
com::android::aconfig::test::reset_flags();
} }
"#; "#;
fn test_generate_cpp_code(mode: CodegenMode) { fn test_generate_cpp_code(mode: CodegenMode) {
@@ -516,7 +557,10 @@ void com_android_aconfig_test_reset_overrides() {
assert_eq!( assert_eq!(
None, None,
crate::test::first_significant_code_diff( crate::test::first_significant_code_diff(
C_EXPORTED_HEADER_EXPECTED, match mode {
CodegenMode::Production => C_EXPORTED_PROD_HEADER_EXPECTED,
CodegenMode::Test => C_EXPORTED_TEST_HEADER_EXPECTED,
},
generated_files_map.get(&target_file_path).unwrap() generated_files_map.get(&target_file_path).unwrap()
) )
); );
@@ -526,7 +570,10 @@ void com_android_aconfig_test_reset_overrides() {
assert_eq!( assert_eq!(
None, None,
crate::test::first_significant_code_diff( crate::test::first_significant_code_diff(
C_SOURCE_FILE_EXPECTED, match mode {
CodegenMode::Production => C_PROD_SOURCE_FILE_EXPECTED,
CodegenMode::Test => C_TEST_SOURCE_FILE_EXPECTED,
},
generated_files_map.get(&target_file_path).unwrap() generated_files_map.get(&target_file_path).unwrap()
) )
); );

View File

@@ -5,16 +5,17 @@
extern "C" \{ extern "C" \{
#endif #endif
{{ for item in class_elements}} {{ for item in class_elements }}
extern const char* {header}_{item.uppercase_flag_name}; bool {header}_{item.flag_name}();
{{ endfor -}}
{{ for item in class_elements}} {{ if for_test }}
bool {header}_{item.flag_name}();{{ endfor }} void set_{header}_{item.flag_name}(bool val);
{{ -endif }}
{{ endfor - }}
void {header}_override_flag(const char* name, bool val); {{ if for_test }}
void {header}_reset_flags();
void {header}_reset_overrides(); {{ -endif }}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,21 +1,20 @@
#include "{header}_c.h" #include "{header}_c.h"
#include "{header}.h" #include "{header}.h"
#include <string>
{{ for item in class_elements}}
const char* {header}_{item.uppercase_flag_name} = "{item.device_config_flag}";
{{ endfor - }}
{{ for item in class_elements}} {{ for item in class_elements}}
bool {header}_{item.flag_name}() \{ bool {header}_{item.flag_name}() \{
return {cpp_namespace}::{item.flag_name}(); return {cpp_namespace}::{item.flag_name}();
} }
{{ endfor }}
void {header}_override_flag(const char* name, bool val) \{ {{ if for_test }}
{cpp_namespace}::override_flag(std::string(name), val); void set_{header}_{item.flag_name}(bool val) \{
{cpp_namespace}::{item.flag_name}(val);
} }
{{ -endif }}
{{ endfor -}}
void {header}_reset_overrides() \{ {{ if for_test }}
{cpp_namespace}::reset_overrides(); void {header}_reset_flags() \{
{cpp_namespace}::reset_flags();
} }
{{ -endif }}

View File

@@ -11,35 +11,43 @@ public:
virtual ~flag_provider_interface() = default; virtual ~flag_provider_interface() = default;
{{ for item in class_elements}} {{ for item in class_elements}}
virtual bool {item.flag_name}() = 0; virtual bool {item.flag_name}() = 0;
{{ endfor }}
virtual void override_flag(std::string const&, bool) \{}
virtual void reset_overrides() \{} {{ if for_test }}
virtual void {item.flag_name}(bool val) = 0;
{{ -endif }}
{{ endfor }}
{{ if for_test }}
virtual void reset_flags() \{}
{{ -endif }}
}; };
extern std::unique_ptr<flag_provider_interface> provider_; extern std::unique_ptr<flag_provider_interface> provider_;
{{ for item in class_elements}}
extern std::string const {item.uppercase_flag_name};{{ endfor }}
{{ for item in class_elements}} {{ for item in class_elements}}
inline bool {item.flag_name}() \{ inline bool {item.flag_name}() \{
{{ if for_prod }} {{ if for_test }}
return provider_->{item.flag_name}();
{{ -else- }}
{{ if not item.readwrite- }} {{ if not item.readwrite- }}
return {item.default_value}; return {item.default_value};
{{ -else- }} {{ -else- }}
return provider_->{item.flag_name}(); return provider_->{item.flag_name}();
{{ -endif }} {{ -endif }}
{{ -else- }}
return provider_->{item.flag_name}();
{{ -endif }} {{ -endif }}
} }
{{ if for_test }}
inline void {item.flag_name}(bool val) \{
provider_->{item.flag_name}(val);
}
{{ -endif }}
{{ endfor }} {{ endfor }}
inline void override_flag(std::string const& name, bool val) \{
return provider_->override_flag(name, val);
}
inline void reset_overrides() \{ {{ if for_test }}
return provider_->reset_overrides(); inline void reset_flags() \{
return provider_->reset_flags();
} }
{{ -endif }}
} }
#endif #endif

View File

@@ -3,8 +3,6 @@
#include "{header}_flag_provider.h" #include "{header}_flag_provider.h"
namespace {cpp_namespace} \{ namespace {cpp_namespace} \{
{{ for item in class_elements}}
std::string const {item.uppercase_flag_name} = "{item.device_config_flag}";{{ endfor }}
std::unique_ptr<flag_provider_interface> provider_ = std::unique_ptr<flag_provider_interface> provider_ =
std::make_unique<flag_provider>(); std::make_unique<flag_provider>();
} }

View File

@@ -8,25 +8,20 @@ using namespace server_configurable_flags;
{{ endif }} {{ endif }}
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <cassert>
namespace {cpp_namespace} \{ namespace {cpp_namespace} \{
class flag_provider : public flag_provider_interface \{ class flag_provider : public flag_provider_interface \{
private: private:
std::unordered_map<std::string, bool> overrides_; std::unordered_map<std::string, bool> overrides_;
std::unordered_set<std::string> flag_names_;
public: public:
flag_provider() flag_provider()
: overrides_(), : overrides_()
flag_names_() \{ \{}
{{ for item in class_elements}}
flag_names_.insert({item.uppercase_flag_name});{{ endfor }}
}
{{ for item in class_elements}} {{ for item in class_elements}}
virtual bool {item.flag_name}() override \{ virtual bool {item.flag_name}() override \{
auto it = overrides_.find({item.uppercase_flag_name}); auto it = overrides_.find("{item.flag_name}");
if (it != overrides_.end()) \{ if (it != overrides_.end()) \{
return it->second; return it->second;
} else \{ } else \{
@@ -40,13 +35,13 @@ public:
{{ -endif }} {{ -endif }}
} }
} }
{{ endfor }}
virtual void override_flag(std::string const& flag, bool val) override \{
assert(flag_names_.count(flag));
overrides_[flag] = val;
}
virtual void reset_overrides() override \{ virtual void {item.flag_name}(bool val) override \{
overrides_["{item.flag_name}"] = val;
}
{{ endfor }}
virtual void reset_flags() override \{
overrides_.clear(); overrides_.clear();
} }
}; };