Merge "Pass PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD to Soong" into main
diff --git a/core/Makefile b/core/Makefile
index b76a4f8..7d7b9e7 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -3582,8 +3582,19 @@
ifeq ($(BOARD_AVB_ENABLE),true)
$(BUILT_SYSTEMIMAGE): $(BOARD_AVB_SYSTEM_KEY_PATH)
endif
+
+ifeq ($(USE_SOONG_DEFINED_SYSTEM_IMAGE),true)
+ifeq ($(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE),)
+$(error PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE must be set if USE_SOONG_DEFINED_SYSTEM_IMAGE is true)
+endif
+soong_defined_system_image := $(call intermediates-dir-for,ETC,$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE))/$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE)
+$(BUILT_SYSTEMIMAGE): $(INSTALLED_FILES_FILE) $(systemimage_intermediates)/file_list.txt $(soong_defined_system_image)
+$(eval $(call copy-one-file, $(soong_defined_system_image), $(BUILT_SYSTEMIMAGE)))
+soong_defined_system_image :=
+else
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(systemimage_intermediates)/file_list.txt
$(call build-systemimage-target,$@)
+endif
$(call declare-1p-container,$(BUILT_SYSTEMIMAGE),system/extras)
$(call declare-container-license-deps,$(BUILT_SYSTEMIMAGE),$(FULL_SYSTEMIMAGE_DEPS),$(PRODUCT_OUT)/:/)
@@ -7851,6 +7862,29 @@
# Extract platform fonts used in Layoutlib
include $(BUILD_SYSTEM)/layoutlib_data.mk
+# -----------------------------------------------------------------
+# Desktop pack image hook.
+ifneq (,$(strip $(PACK_DESKTOP_FILESYSTEM_IMAGES)))
+PACK_IMAGE_TARGET := $(PRODUCT_OUT)/android-desktop_image.bin
+PACK_IMAGE_SCRIPT := $(HOST_OUT_EXECUTABLES)/pack_image
+IMAGES := $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_SUPERIMAGE_TARGET) \
+ $(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
+ $(INSTALLED_VENDOR_BOOTIMAGE_TARGET) \
+ $(INSTALLED_VBMETAIMAGE_TARGET) \
+ $(INSTALLED_USERDATAIMAGE_TARGET)
+
+$(PACK_IMAGE_TARGET): $(IMAGES) $(PACK_IMAGE_SCRIPT)
+ $(PACK_IMAGE_SCRIPT) --out_dir $(PRODUCT_OUT) --noarchive
+
+PACKED_IMAGE_ARCHIVE_TARGET := $(PACK_IMAGE_TARGET).gz
+
+$(PACKED_IMAGE_ARCHIVE_TARGET): $(PACK_IMAGE_TARGET) | $(GZIP)
+ $(GZIP) -fk $(PACK_IMAGE_TARGET)
+
+droidcore-unbundled: $(PACKED_IMAGE_ARCHIVE_TARGET)
+
+endif # PACK_DESKTOP_FILESYSTEM_IMAGES
# -----------------------------------------------------------------
# OS Licensing
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index f2ff286..b393886 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -28,6 +28,7 @@
$(call add_soong_config_var,ANDROID,BOARD_USES_ODMIMAGE)
$(call soong_config_set_bool,ANDROID,BOARD_USES_RECOVERY_AS_BOOT,$(BOARD_USES_RECOVERY_AS_BOOT))
+$(call soong_config_set_bool,ANDROID,BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT,$(BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT))
$(call add_soong_config_var,ANDROID,CHECK_DEV_TYPE_VIOLATIONS)
$(call add_soong_config_var,ANDROID,PLATFORM_SEPOLICY_VERSION)
$(call add_soong_config_var,ANDROID,PLATFORM_SEPOLICY_COMPAT_VERSIONS)
@@ -36,6 +37,10 @@
$(call add_soong_config_var,ANDROID,TARGET_ENABLE_MEDIADRM_64)
$(call add_soong_config_var,ANDROID,TARGET_DYNAMIC_64_32_MEDIASERVER)
+# For Sanitizers
+$(call soong_config_set_bool,ANDROID,ASAN_ENABLED,$(if $(filter address,$(SANITIZE_TARGET)),true,false))
+$(call soong_config_set_bool,ANDROID,SANITIZE_TARGET_SYSTEM_ENABLED,$(if $(filter true,$(SANITIZE_TARGET_SYSTEM)),true,false))
+
# PRODUCT_PRECOMPILED_SEPOLICY defaults to true. Explicitly check if it's "false" or not.
$(call soong_config_set_bool,ANDROID,PRODUCT_PRECOMPILED_SEPOLICY,$(if $(filter false,$(PRODUCT_PRECOMPILED_SEPOLICY)),false,true))
diff --git a/core/main.mk b/core/main.mk
index f3980f1..8d73793 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -688,11 +688,16 @@
$(eval my_testcases := $(HOST_OUT_TESTCASES)),\
$(eval my_testcases := $$(COMPATIBILITY_TESTCASES_OUT_$(suite))))\
$(eval target := $(my_testcases)/$(lastword $(subst /, ,$(dir $(f))))/$(notdir $(f)))\
+ $(eval link_target := ../../../$(lastword $(subst /, ,$(dir $(f))))/$(notdir $(f)))\
+ $(eval symlink := $(my_testcases)/$(m)/shared_libs/$(lastword $(subst /, ,$(dir $(f))))/$(notdir $(f)))\
+ $(eval COMPATIBILITY.$(suite).SYMLINKS := \
+ $$(COMPATIBILITY.$(suite).SYMLINKS) $(f):$(link_target):$(symlink))\
$(if $(strip $(ALL_TARGETS.$(target).META_LIC)),,$(call declare-copy-target-license-metadata,$(target),$(f)))\
$(eval COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES := \
$$(COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES) $(f):$(target))\
$(eval COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES := \
- $(sort $(COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES)))))))
+ $(sort $(COMPATIBILITY.$(suite).HOST_SHARED_LIBRARY.FILES))))))\
+ $(eval COMPATIBILITY.$(suite).SYMLINKS := $(sort $(COMPATIBILITY.$(suite).SYMLINKS))))
endef
$(call resolve-shared-libs-depes,TARGET_)
diff --git a/core/ravenwood_test_config_template.xml b/core/ravenwood_test_config_template.xml
index 16a22c0..088a55a 100644
--- a/core/ravenwood_test_config_template.xml
+++ b/core/ravenwood_test_config_template.xml
@@ -18,7 +18,7 @@
<option name="test-suite-tag" value="ravenwood" />
<option name="test-suite-tag" value="ravenwood-tests" />
- <option name="java-folder" value="prebuilts/jdk/jdk17/linux-x86/" />
+ <option name="java-folder" value="prebuilts/jdk/jdk21/linux-x86/" />
<option name="use-ravenwood-resources" value="true" />
<option name="exclude-paths" value="java" />
<option name="socket-timeout" value="10000" />
diff --git a/core/release_config.mk b/core/release_config.mk
index 2898868..fe2170e 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -131,6 +131,9 @@
_args += --guard=false
endif
_args += --allow-missing=true
+ ifneq (,$(TARGET_PRODUCT))
+ _args += --product $(TARGET_PRODUCT)
+ endif
_flags_dir:=$(OUT_DIR)/soong/release-config
_flags_file:=$(_flags_dir)/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).vars
# release-config generates $(_flags_varmk)
diff --git a/core/robolectric_test_config_template.xml b/core/robolectric_test_config_template.xml
index 56d2312..b1d0c2f 100644
--- a/core/robolectric_test_config_template.xml
+++ b/core/robolectric_test_config_template.xml
@@ -18,7 +18,7 @@
<option name="test-suite-tag" value="robolectric" />
<option name="test-suite-tag" value="robolectric-tests" />
- <option name="java-folder" value="prebuilts/jdk/jdk17/linux-x86/" />
+ <option name="java-folder" value="prebuilts/jdk/jdk21/linux-x86/" />
<option name="exclude-paths" value="java" />
<option name="use-robolectric-resources" value="true" />
diff --git a/core/rust_device_test_config_template.xml b/core/rust_device_test_config_template.xml
index bfd2f47..aacabcb 100644
--- a/core/rust_device_test_config_template.xml
+++ b/core/rust_device_test_config_template.xml
@@ -20,11 +20,11 @@
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
- <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
+ <option name="push" value="{MODULE}->{TEST_INSTALL_BASE}/{MODULE}" />
</target_preparer>
<test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
- <option name="test-device-path" value="/data/local/tmp" />
+ <option name="test-device-path" value="{TEST_INSTALL_BASE}" />
<option name="module-name" value="{MODULE}" />
</test>
</configuration>
diff --git a/core/sysprop_config.mk b/core/sysprop_config.mk
index 6e3da72..f9b9d1c 100644
--- a/core/sysprop_config.mk
+++ b/core/sysprop_config.mk
@@ -50,6 +50,12 @@
ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=false
endif
+ifeq ($(TARGET_BOOTS_16K),true)
+ADDITIONAL_PRODUCT_PROPERTIES += ro.product.page_size=16384
+else
+ADDITIONAL_PRODUCT_PROPERTIES += ro.product.page_size=4096
+endif
+
# Enable core platform API violation warnings on userdebug and eng builds.
ifneq ($(TARGET_BUILD_VARIANT),user)
ADDITIONAL_SYSTEM_PROPERTIES += persist.debug.dalvik.vm.core_platform_api_policy=just-warn
diff --git a/core/tasks/host-unit-tests.mk b/core/tasks/host-unit-tests.mk
index 733a2e2..4cb23c0 100644
--- a/core/tasks/host-unit-tests.mk
+++ b/core/tasks/host-unit-tests.mk
@@ -29,15 +29,28 @@
$(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
$(_cmf_src)))
+my_symlinks_for_host_unit_tests := $(foreach f,$(COMPATIBILITY.host-unit-tests.SYMLINKS),\
+ $(strip $(eval _cmf_tuple := $(subst :, ,$(f))) \
+ $(eval _cmf_dep := $(word 1,$(_cmf_tuple))) \
+ $(eval _cmf_src := $(word 2,$(_cmf_tuple))) \
+ $(eval _cmf_dest := $(word 3,$(_cmf_tuple))) \
+ $(call symlink-file,$(_cmf_dep),$(_cmf_src),$(_cmf_dest)) \
+ $(_cmf_dest)))
+
$(host_unit_tests_zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_host_unit_tests)
-$(host_unit_tests_zip) : $(COMPATIBILITY.host-unit-tests.FILES) $(my_host_shared_lib_for_host_unit_tests) $(SOONG_ZIP)
+$(host_unit_tests_zip) : PRIVATE_SYMLINKS := $(my_symlinks_for_host_unit_tests)
+
+$(host_unit_tests_zip) : $(COMPATIBILITY.host-unit-tests.FILES) $(my_host_shared_lib_for_host_unit_tests) $(my_symlinks_for_host_unit_tests) $(SOONG_ZIP)
echo $(sort $(COMPATIBILITY.host-unit-tests.FILES)) | tr " " "\n" > $@.list
grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
echo "" >> $@-host-libs.list
$(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
echo $$shared_lib >> $@-host-libs.list; \
done
+ $(hide) for symlink in $(PRIVATE_SYMLINKS); do \
+ echo $$symlink >> $@-host.list; \
+ done
grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
$(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list \
-P target -C $(PRODUCT_OUT) -l $@-target.list \
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index dc78368..58234a8 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -178,3 +178,6 @@
PRODUCT_SYSTEM_PROPERTIES += \
dalvik.vm.useartservice=true \
dalvik.vm.enable_pr_dexopt=true
+
+# Copy preopted files from system_b on first boot.
+PRODUCT_SYSTEM_PROPERTIES += ro.cp_system_other_odex=1
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 1a07363..3d56a80 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -40,3 +40,6 @@
ifeq ($(WITHOUT_CHECK_API),true)
$(error WITHOUT_CHECK_API cannot be set to true for SDK product builds)
endif
+
+# Include Wear flag values so that Wear-related APIs are build in sdks.
+PRODUCT_RELEASE_CONFIG_MAPS += $(wildcard vendor/google_shared/wear/release/release_config_map.textproto)
diff --git a/target/product/virtual_ab_ota/OWNERS b/target/product/virtual_ab_ota/OWNERS
new file mode 100644
index 0000000..8eb0686
--- /dev/null
+++ b/target/product/virtual_ab_ota/OWNERS
@@ -0,0 +1,4 @@
+zhangkelvin@google.com
+dvander@google.com
+akailash@google.com
+
diff --git a/tools/aconfig/TEST_MAPPING b/tools/aconfig/TEST_MAPPING
index 448d8cf..15e4187 100644
--- a/tools/aconfig/TEST_MAPPING
+++ b/tools/aconfig/TEST_MAPPING
@@ -98,6 +98,10 @@
{
// aconfig_storage file cpp integration tests
"name": "aconfig_storage_file.test.cpp"
+ },
+ {
+ // aconfig_storage file java integration tests
+ "name": "aconfig_storage_file.test.java"
}
],
"postsubmit": [
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index d3f074a..ec22ebc 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -20,22 +20,24 @@
use std::path::PathBuf;
use tinytemplate::TinyTemplate;
-use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag};
-
use crate::codegen;
use crate::codegen::CodegenMode;
use crate::commands::OutputFile;
+use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag};
+use std::collections::HashMap;
pub fn generate_java_code<I>(
package: &str,
parsed_flags_iter: I,
codegen_mode: CodegenMode,
+ flag_ids: HashMap<String, u16>,
+ allow_instrumentation: bool,
) -> Result<Vec<OutputFile>>
where
I: Iterator<Item = ProtoParsedFlag>,
{
let flag_elements: Vec<FlagElement> =
- parsed_flags_iter.map(|pf| create_flag_element(package, &pf)).collect();
+ parsed_flags_iter.map(|pf| create_flag_element(package, &pf, flag_ids.clone())).collect();
let namespace_flags = gen_flags_by_namespace(&flag_elements);
let properties_set: BTreeSet<String> =
flag_elements.iter().map(|fe| format_property_name(&fe.device_config_namespace)).collect();
@@ -43,6 +45,7 @@
let library_exported = codegen_mode == CodegenMode::Exported;
let runtime_lookup_required =
flag_elements.iter().any(|elem| elem.is_read_write) || library_exported;
+ let container = (flag_elements.first().expect("zero template flags").container).to_string();
let context = Context {
flag_elements,
@@ -52,6 +55,8 @@
properties_set,
package_name: package.to_string(),
library_exported,
+ allow_instrumentation,
+ container,
};
let mut template = TinyTemplate::new();
template.add_template("Flags.java", include_str!("../../templates/Flags.java.template"))?;
@@ -117,6 +122,8 @@
pub properties_set: BTreeSet<String>,
pub package_name: String,
pub library_exported: bool,
+ pub allow_instrumentation: bool,
+ pub container: String,
}
#[derive(Serialize, Debug)]
@@ -127,23 +134,31 @@
#[derive(Serialize, Clone, Debug)]
struct FlagElement {
+ pub container: String,
pub default_value: bool,
pub device_config_namespace: String,
pub device_config_flag: String,
pub flag_name_constant_suffix: String,
+ pub flag_offset: u16,
pub is_read_write: bool,
pub method_name: String,
pub properties: String,
}
-fn create_flag_element(package: &str, pf: &ProtoParsedFlag) -> FlagElement {
+fn create_flag_element(
+ package: &str,
+ pf: &ProtoParsedFlag,
+ flag_offsets: HashMap<String, u16>,
+) -> FlagElement {
let device_config_flag = codegen::create_device_config_ident(package, pf.name())
.expect("values checked at flag parse time");
FlagElement {
+ container: pf.container().to_string(),
default_value: pf.state() == ProtoFlagState::ENABLED,
device_config_namespace: pf.namespace().to_string(),
device_config_flag,
flag_name_constant_suffix: pf.name().to_ascii_uppercase(),
+ flag_offset: *flag_offsets.get(pf.name()).expect("didnt find package offset :("),
is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE,
method_name: format_java_method_name(pf.name()),
properties: format_property_name(pf.namespace()),
@@ -179,6 +194,7 @@
#[cfg(test)]
mod tests {
use super::*;
+ use crate::commands::assign_flag_ids;
use std::collections::HashMap;
const EXPECTED_FEATUREFLAGS_COMMON_CONTENT: &str = r#"
@@ -477,9 +493,16 @@
let mode = CodegenMode::Production;
let modified_parsed_flags =
crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
- let generated_files =
- generate_java_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
- .unwrap();
+ let flag_ids =
+ assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+ let generated_files = generate_java_code(
+ crate::test::TEST_PACKAGE,
+ modified_parsed_flags.into_iter(),
+ mode,
+ flag_ids,
+ false,
+ )
+ .unwrap();
let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
+ r#"
private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
@@ -647,9 +670,16 @@
let mode = CodegenMode::Exported;
let modified_parsed_flags =
crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
- let generated_files =
- generate_java_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
- .unwrap();
+ let flag_ids =
+ assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+ let generated_files = generate_java_code(
+ crate::test::TEST_PACKAGE,
+ modified_parsed_flags.into_iter(),
+ mode,
+ flag_ids,
+ false,
+ )
+ .unwrap();
let expect_flags_content = r#"
package com.android.aconfig.test;
@@ -833,9 +863,16 @@
let mode = CodegenMode::Test;
let modified_parsed_flags =
crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
- let generated_files =
- generate_java_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
- .unwrap();
+ let flag_ids =
+ assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+ let generated_files = generate_java_code(
+ crate::test::TEST_PACKAGE,
+ modified_parsed_flags.into_iter(),
+ mode,
+ flag_ids,
+ false,
+ )
+ .unwrap();
let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
+ r#"
@@ -850,69 +887,58 @@
"#;
let expect_featureflagsimpl_content = r#"
package com.android.aconfig.test;
- // TODO(b/303773055): Remove the annotation after access issue is resolved.
- import android.compat.annotation.UnsupportedAppUsage;
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags {
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean disabledRo() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean disabledRw() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean disabledRwExported() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean disabledRwInOtherNamespace() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean enabledFixedRo() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean enabledFixedRoExported() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean enabledRo() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean enabledRoExported() {
throw new UnsupportedOperationException(
"Method is not implemented.");
}
@Override
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
public boolean enabledRw() {
throw new UnsupportedOperationException(
"Method is not implemented.");
@@ -958,9 +984,16 @@
let mode = CodegenMode::ForceReadOnly;
let modified_parsed_flags =
crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
- let generated_files =
- generate_java_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
- .unwrap();
+ let flag_ids =
+ assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+ let generated_files = generate_java_code(
+ crate::test::TEST_PACKAGE,
+ modified_parsed_flags.into_iter(),
+ mode,
+ flag_ids,
+ false,
+ )
+ .unwrap();
let expect_featureflags_content = r#"
package com.android.aconfig.test;
// TODO(b/303773055): Remove the annotation after access issue is resolved.
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index 6945fd4..6d1c2f5 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -191,15 +191,25 @@
Ok(output)
}
-pub fn create_java_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Vec<OutputFile>> {
+pub fn create_java_lib(
+ mut input: Input,
+ codegen_mode: CodegenMode,
+ allow_instrumentation: bool,
+) -> Result<Vec<OutputFile>> {
let parsed_flags = input.try_parse_flags()?;
let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode)?;
let Some(package) = find_unique_package(&modified_parsed_flags) else {
bail!("no parsed flags, or the parsed flags use different packages");
};
let package = package.to_string();
- let _flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?;
- generate_java_code(&package, modified_parsed_flags.into_iter(), codegen_mode)
+ let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?;
+ generate_java_code(
+ &package,
+ modified_parsed_flags.into_iter(),
+ codegen_mode,
+ flag_ids,
+ allow_instrumentation,
+ )
}
pub fn create_cpp_lib(
diff --git a/tools/aconfig/aconfig/src/main.rs b/tools/aconfig/aconfig/src/main.rs
index 72be1c9..7ec272f 100644
--- a/tools/aconfig/aconfig/src/main.rs
+++ b/tools/aconfig/aconfig/src/main.rs
@@ -72,6 +72,12 @@
.long("mode")
.value_parser(EnumValueParser::<CodegenMode>::new())
.default_value("production"),
+ )
+ .arg(
+ Arg::new("allow-instrumentation")
+ .long("allow-instrumentation")
+ .value_parser(clap::value_parser!(bool))
+ .default_value("false"),
),
)
.subcommand(
@@ -237,8 +243,10 @@
Some(("create-java-lib", sub_matches)) => {
let cache = open_single_file(sub_matches, "cache")?;
let mode = get_required_arg::<CodegenMode>(sub_matches, "mode")?;
- let generated_files =
- commands::create_java_lib(cache, *mode).context("failed to create java lib")?;
+ let allow_instrumentation =
+ get_required_arg::<bool>(sub_matches, "allow-instrumentation")?;
+ let generated_files = commands::create_java_lib(cache, *mode, *allow_instrumentation)
+ .context("failed to create java lib")?;
let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
generated_files
.iter()
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
index 63c4f2d..cd2e3db 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
@@ -1,13 +1,23 @@
package {package_name};
+{{ -if not is_test_mode }}
{{ if not library_exported- }}
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
{{ -endif }}
-{{ -if not is_test_mode }}
+
{{ -if runtime_lookup_required }}
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
-{{ endif }}
+
+
+{{ -if allow_instrumentation }}
+import android.aconfig.storage.StorageInternalReader;
+import android.util.Log;
+
+import java.io.File;
+{{ -endif }}
+
+{{ -endif }}
/** @hide */
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ -if runtime_lookup_required }}
@@ -20,14 +30,47 @@
private static boolean {flag.method_name} = {flag.default_value};
{{ -endif }}
{{ -endfor }}
+{{ -if allow_instrumentation }}
+ StorageInternalReader reader;
+ boolean readFromNewStorage;
+
+ private final static String TAG = "AconfigJavaCodegen";
+
+ public FeatureFlagsImpl() \{
+ File file = new File("/metadata/aconfig_test_missions/mission_1");
+ if (file.exists()) \{
+ readFromNewStorage = true;
+ reader = new StorageInternalReader("{container}", "{package_name}");
+ }
+ }
+{{ -endif }}
{{ for namespace_with_flags in namespace_flags }}
private void load_overrides_{namespace_with_flags.namespace}() \{
try \{
+{{ -if allow_instrumentation }}
+ boolean val;
+{{ -endif }}
Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
{{ -for flag in namespace_with_flags.flags }}
{{ -if flag.is_read_write }}
{flag.method_name} =
properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
+{{ -if allow_instrumentation }}
+ if (readFromNewStorage) \{
+ try \{
+ val = reader.getBooleanFlagValue({flag.flag_offset});
+ if (val == {flag.method_name}) \{
+ Log.i(TAG, "success: {flag.method_name} value matches");
+ } else \{
+ Log.i(TAG, String.format(
+ "error: {flag.method_name} value mismatch, new storage value is %s, old storage value is %s",
+ val, {flag.method_name}));
+ }
+ } catch (Exception e) \{
+ Log.e(TAG,"error: failed to read flag value of {flag.method_name}");
+ }
+ }
+{{ -endif }}
{{ -endif }}
{{ -endfor }}
} catch (NullPointerException e) \{
@@ -70,7 +113,6 @@
@Override
{{ -if not library_exported }}
@com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
{{ -endif }}
public boolean {flag.method_name}() \{
throw new UnsupportedOperationException(
diff --git a/tools/aconfig/aconfig_device_paths/Android.bp b/tools/aconfig/aconfig_device_paths/Android.bp
index 2c771e0..2d943de 100644
--- a/tools/aconfig/aconfig_device_paths/Android.bp
+++ b/tools/aconfig/aconfig_device_paths/Android.bp
@@ -42,10 +42,11 @@
srcs: ["src/DevicePathsTemplate.java"],
out: ["DevicePaths.java"],
tool_files: ["partition_aconfig_flags_paths.txt"],
- cmd: "sed -e '/TEMPLATE/{r$(location partition_aconfig_flags_paths.txt)' -e 'd}' $(in) > $(out)"
+ cmd: "sed -e '/TEMPLATE/{r$(location partition_aconfig_flags_paths.txt)' -e 'd}' $(in) > $(out)",
}
java_library {
name: "aconfig_device_paths_java",
srcs: [":libaconfig_java_device_paths_src"],
+ sdk_version: "core_current",
}
diff --git a/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java b/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java
index f27b9bd..16355a3 100644
--- a/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java
+++ b/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java
@@ -36,7 +36,7 @@
* Returns the list of all on-device aconfig protos paths.
* @hide
*/
- public List<String> parsedFlagsProtoPaths() {
+ public static List<String> parsedFlagsProtoPaths() {
ArrayList<String> paths = new ArrayList(Arrays.asList(PATHS));
File apexDirectory = new File(APEX_DIR);
diff --git a/tools/aconfig/aconfig_storage_file/Android.bp b/tools/aconfig/aconfig_storage_file/Android.bp
index e066e31..3859194 100644
--- a/tools/aconfig/aconfig_storage_file/Android.bp
+++ b/tools/aconfig/aconfig_storage_file/Android.bp
@@ -137,3 +137,12 @@
min_sdk_version: "29",
double_loadable: true,
}
+
+// storage file parse api java cc_library
+java_library {
+ name: "aconfig_storage_file_java",
+ srcs: [
+ "srcs/**/*.java",
+ ],
+ sdk_version: "core_current",
+}
\ No newline at end of file
diff --git a/tools/ide_query/ide_query_proto/Android.bp b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/AconfigStorageException.java
similarity index 62%
copy from tools/ide_query/ide_query_proto/Android.bp
copy to tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/AconfigStorageException.java
index 70f15cd..86a75f2 100644
--- a/tools/ide_query/ide_query_proto/Android.bp
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/AconfigStorageException.java
@@ -14,20 +14,14 @@
* limitations under the License.
*/
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
+package android.aconfig.storage;
-cc_library_host_static {
- name: "ide_query_proto",
- srcs: [
- "ide_query.proto",
- ],
- proto: {
- export_proto_headers: true,
- type: "full",
- canonical_path_from_root: false,
- },
- compile_multilib: "64",
- shared_libs: ["libprotobuf-cpp-full"],
+public class AconfigStorageException extends RuntimeException {
+ public AconfigStorageException(String msg) {
+ super(msg);
+ }
+
+ public AconfigStorageException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
new file mode 100644
index 0000000..1c72364
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+
+public class ByteBufferReader {
+
+ private ByteBuffer mByteBuffer;
+
+ public ByteBufferReader(ByteBuffer byteBuffer) {
+ this.mByteBuffer = byteBuffer;
+ this.mByteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+
+ public int readByte() {
+ return Byte.toUnsignedInt(mByteBuffer.get());
+ }
+
+ public int readShort() {
+ return Short.toUnsignedInt(mByteBuffer.getShort());
+ }
+
+ public int readInt() {
+ return this.mByteBuffer.getInt();
+ }
+
+ public String readString() {
+ int length = readInt();
+ byte[] bytes = new byte[length];
+ mByteBuffer.get(bytes, 0, length);
+ return new String(bytes, StandardCharsets.UTF_8);
+ }
+
+ public void position(int newPosition) {
+ mByteBuffer.position(newPosition);
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FileType.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FileType.java
new file mode 100644
index 0000000..b0b1b9b
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FileType.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+public enum FileType {
+ PACKAGE_MAP(0),
+ FLAG_MAP(1),
+ FLAG_VAL(2),
+ FLAG_INFO(3);
+
+ public final int type;
+
+ FileType(int type) {
+ this.type = type;
+ }
+
+ public static FileType fromInt(int index) {
+ switch (index) {
+ case 0:
+ return PACKAGE_MAP;
+ case 1:
+ return FLAG_MAP;
+ case 2:
+ return FLAG_VAL;
+ case 3:
+ return FLAG_INFO;
+ default:
+ return null;
+ }
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java
new file mode 100644
index 0000000..e85fdee
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class FlagTable {
+
+ private Header mHeader;
+ private Map<String, Node> mNodeMap;
+
+ public static FlagTable fromBytes(ByteBuffer bytes) {
+ FlagTable flagTable = new FlagTable();
+ ByteBufferReader reader = new ByteBufferReader(bytes);
+ Header header = Header.fromBytes(reader);
+ flagTable.mHeader = header;
+ flagTable.mNodeMap = new HashMap(TableUtils.getTableSize(header.mNumFlags));
+ reader.position(header.mNodeOffset);
+ for (int i = 0; i < header.mNumFlags; i++) {
+ Node node = Node.fromBytes(reader);
+ flagTable.mNodeMap.put(makeKey(node.mPackageId, node.mFlagName), node);
+ }
+ return flagTable;
+ }
+
+ public Node get(int packageId, String flagName) {
+ return mNodeMap.get(makeKey(packageId, flagName));
+ }
+
+ public Header getHeader() {
+ return mHeader;
+ }
+
+ private static String makeKey(int packageId, String flagName) {
+ StringBuilder ret = new StringBuilder();
+ return ret.append(packageId).append('/').append(flagName).toString();
+ }
+
+ public static class Header {
+
+ private int mVersion;
+ private String mContainer;
+ private FileType mFileType;
+ private int mFileSize;
+ private int mNumFlags;
+ private int mBucketOffset;
+ private int mNodeOffset;
+
+ public static Header fromBytes(ByteBufferReader reader) {
+ Header header = new Header();
+ header.mVersion = reader.readInt();
+ header.mContainer = reader.readString();
+ header.mFileType = FileType.fromInt(reader.readByte());
+ header.mFileSize = reader.readInt();
+ header.mNumFlags = reader.readInt();
+ header.mBucketOffset = reader.readInt();
+ header.mNodeOffset = reader.readInt();
+
+ if (header.mFileType != FileType.FLAG_MAP) {
+ throw new AconfigStorageException("binary file is not a flag map");
+ }
+
+ return header;
+ }
+
+ public int getVersion() {
+ return mVersion;
+ }
+
+ public String getContainer() {
+ return mContainer;
+ }
+
+ public FileType getFileType() {
+ return mFileType;
+ }
+
+ public int getFileSize() {
+ return mFileSize;
+ }
+
+ public int getNumFlags() {
+ return mNumFlags;
+ }
+
+ public int getBucketOffset() {
+ return mBucketOffset;
+ }
+
+ public int getNodeOffset() {
+ return mNodeOffset;
+ }
+ }
+
+ public static class Node {
+
+ private String mFlagName;
+ private FlagType mFlagType;
+ private int mPackageId;
+ private int mFlagIndex;
+ private int mNextOffset;
+
+ public static Node fromBytes(ByteBufferReader reader) {
+ Node node = new Node();
+ node.mPackageId = reader.readInt();
+ node.mFlagName = reader.readString();
+ node.mFlagType = FlagType.fromInt(reader.readShort());
+ node.mFlagIndex = reader.readShort();
+ node.mNextOffset = reader.readInt();
+ node.mNextOffset = node.mNextOffset == 0 ? -1 : node.mNextOffset;
+ return node;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFlagName, mFlagType, mPackageId, mFlagIndex, mNextOffset);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || !(obj instanceof Node)) {
+ return false;
+ }
+
+ Node other = (Node) obj;
+ return Objects.equals(mFlagName, other.mFlagName)
+ && Objects.equals(mFlagType, other.mFlagType)
+ && mPackageId == other.mPackageId
+ && mFlagIndex == other.mFlagIndex
+ && mNextOffset == other.mNextOffset;
+ }
+
+ public String getFlagName() {
+ return mFlagName;
+ }
+
+ public FlagType getFlagType() {
+ return mFlagType;
+ }
+
+ public int getPackageId() {
+ return mPackageId;
+ }
+
+ public int getFlagIndex() {
+ return mFlagIndex;
+ }
+
+ public int getNextOffset() {
+ return mNextOffset;
+ }
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagType.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagType.java
new file mode 100644
index 0000000..385e2d9
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagType.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+public enum FlagType {
+ ReadWriteBoolean (0),
+ ReadOnlyBoolean(1),
+ FixedReadOnlyBoolean(2);
+
+ public final int type;
+
+ FlagType(int type) {
+ this.type = type;
+ }
+
+ public static FlagType fromInt(int index) {
+ switch (index) {
+ case 0:
+ return ReadWriteBoolean;
+ case 1:
+ return ReadOnlyBoolean;
+ case 2:
+ return FixedReadOnlyBoolean;
+ default:
+ return null;
+ }
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagValueList.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagValueList.java
new file mode 100644
index 0000000..0ddc147
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagValueList.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlagValueList {
+
+ private Header mHeader;
+ private List<Boolean> mList;
+
+ private int mSize;
+
+ public static FlagValueList fromBytes(ByteBuffer bytes) {
+ FlagValueList flagValueList = new FlagValueList();
+ ByteBufferReader reader = new ByteBufferReader(bytes);
+ Header header = Header.fromBytes(reader);
+ flagValueList.mHeader = header;
+ flagValueList.mList = new ArrayList(header.mNumFlags);
+ reader.position(header.mBooleanValueOffset);
+ for (int i = 0; i < header.mNumFlags; i++) {
+ boolean val = reader.readByte() == 1;
+ flagValueList.mList.add(val);
+ }
+ flagValueList.mSize = flagValueList.mList.size();
+ return flagValueList;
+ }
+
+ public boolean get(int index) {
+ return mList.get(index);
+ }
+
+ public Header getHeader() {
+ return mHeader;
+ }
+
+ public int size() {
+ return mSize;
+ }
+
+ public static class Header {
+
+ private int mVersion;
+ private String mContainer;
+ private FileType mFileType;
+ private int mFileSize;
+ private int mNumFlags;
+ private int mBooleanValueOffset;
+
+ public static Header fromBytes(ByteBufferReader reader) {
+ Header header = new Header();
+ header.mVersion = reader.readInt();
+ header.mContainer = reader.readString();
+ header.mFileType = FileType.fromInt(reader.readByte());
+ header.mFileSize = reader.readInt();
+ header.mNumFlags = reader.readInt();
+ header.mBooleanValueOffset = reader.readInt();
+
+ if (header.mFileType != FileType.FLAG_VAL) {
+ throw new AconfigStorageException("binary file is not a flag value file");
+ }
+
+ return header;
+ }
+
+ public int getVersion() {
+ return mVersion;
+ }
+
+ public String getContainer() {
+ return mContainer;
+ }
+
+ public FileType getFileType() {
+ return mFileType;
+ }
+
+ public int getFileSize() {
+ return mFileSize;
+ }
+
+ public int getNumFlags() {
+ return mNumFlags;
+ }
+
+ public int getBooleanValueOffset() {
+ return mBooleanValueOffset;
+ }
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
new file mode 100644
index 0000000..d04e1ac
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class PackageTable {
+
+ private Header mHeader;
+ private Map<String, Node> mNodeMap;
+
+ public static PackageTable fromBytes(ByteBuffer bytes) {
+ PackageTable packageTable = new PackageTable();
+ ByteBufferReader reader = new ByteBufferReader(bytes);
+ Header header = Header.fromBytes(reader);
+ packageTable.mHeader = header;
+ packageTable.mNodeMap = new HashMap(TableUtils.getTableSize(header.mNumPackages));
+ reader.position(header.mNodeOffset);
+ for (int i = 0; i < header.mNumPackages; i++) {
+ Node node = Node.fromBytes(reader);
+ packageTable.mNodeMap.put(node.mPackageName, node);
+ }
+ return packageTable;
+ }
+
+ public Node get(String packageName) {
+ return mNodeMap.get(packageName);
+ }
+
+ public Header getHeader() {
+ return mHeader;
+ }
+
+ public static class Header {
+
+ private int mVersion;
+ private String mContainer;
+ private FileType mFileType;
+ private int mFileSize;
+ private int mNumPackages;
+ private int mBucketOffset;
+ private int mNodeOffset;
+
+ public static Header fromBytes(ByteBufferReader reader) {
+ Header header = new Header();
+ header.mVersion = reader.readInt();
+ header.mContainer = reader.readString();
+ header.mFileType = FileType.fromInt(reader.readByte());
+ header.mFileSize = reader.readInt();
+ header.mNumPackages = reader.readInt();
+ header.mBucketOffset = reader.readInt();
+ header.mNodeOffset = reader.readInt();
+
+ if (header.mFileType != FileType.PACKAGE_MAP) {
+ throw new AconfigStorageException("binary file is not a package map");
+ }
+
+ return header;
+ }
+
+ public int getVersion() {
+ return mVersion;
+ }
+
+ public String getContainer() {
+ return mContainer;
+ }
+
+ public FileType getFileType() {
+ return mFileType;
+ }
+
+ public int getFileSize() {
+ return mFileSize;
+ }
+
+ public int getNumPackages() {
+ return mNumPackages;
+ }
+
+ public int getBucketOffset() {
+ return mBucketOffset;
+ }
+
+ public int getNodeOffset() {
+ return mNodeOffset;
+ }
+ }
+
+ public static class Node {
+
+ private String mPackageName;
+ private int mPackageId;
+ private int mBooleanStartIndex;
+ private int mNextOffset;
+
+ public static Node fromBytes(ByteBufferReader reader) {
+ Node node = new Node();
+ node.mPackageName = reader.readString();
+ node.mPackageId = reader.readInt();
+ node.mBooleanStartIndex = reader.readInt();
+ node.mNextOffset = reader.readInt();
+ node.mNextOffset = node.mNextOffset == 0 ? -1 : node.mNextOffset;
+ return node;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPackageName, mPackageId, mBooleanStartIndex, mNextOffset);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || !(obj instanceof Node)) {
+ return false;
+ }
+
+ Node other = (Node) obj;
+ return Objects.equals(mPackageName, other.mPackageName)
+ && mPackageId == other.mPackageId
+ && mBooleanStartIndex == other.mBooleanStartIndex
+ && mNextOffset == other.mNextOffset;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public int getPackageId() {
+ return mPackageId;
+ }
+
+ public int getBooleanStartIndex() {
+ return mBooleanStartIndex;
+ }
+
+ public int getNextOffset() {
+ return mNextOffset;
+ }
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java
new file mode 100644
index 0000000..714b53b
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+public class TableUtils {
+
+ private static final int[] HASH_PRIMES =
+ new int[] {
+ 7,
+ 17,
+ 29,
+ 53,
+ 97,
+ 193,
+ 389,
+ 769,
+ 1543,
+ 3079,
+ 6151,
+ 12289,
+ 24593,
+ 49157,
+ 98317,
+ 196613,
+ 393241,
+ 786433,
+ 1572869,
+ 3145739,
+ 6291469,
+ 12582917,
+ 25165843,
+ 50331653,
+ 100663319,
+ 201326611,
+ 402653189,
+ 805306457,
+ 1610612741
+ };
+
+ public static int getTableSize(int numEntries) {
+ for (int i : HASH_PRIMES) {
+ if (i < 2 * numEntries) continue;
+ return i;
+ }
+ throw new AconfigStorageException("Number of items in a hash table exceeds limit");
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/tests/Android.bp b/tools/aconfig/aconfig_storage_file/tests/Android.bp
index 26b7800..c33127f 100644
--- a/tools/aconfig/aconfig_storage_file/tests/Android.bp
+++ b/tools/aconfig/aconfig_storage_file/tests/Android.bp
@@ -1,4 +1,3 @@
-
cc_test {
name: "aconfig_storage_file.test.cpp",
team: "trendy_team_android_core_experiments",
@@ -21,3 +20,27 @@
"general-tests",
],
}
+
+android_test {
+ name: "aconfig_storage_file.test.java",
+ team: "trendy_team_android_core_experiments",
+ srcs: [
+ "srcs/**/*.java",
+ ],
+ static_libs: [
+ "aconfig_storage_file_java",
+ "androidx.test.runner",
+ "junit",
+ ],
+ sdk_version: "test_current",
+ test_config: "AndroidStorageJaveTest.xml",
+ data: [
+ "package.map",
+ "flag.map",
+ "flag.val",
+ "flag.info",
+ ],
+ test_suites: [
+ "general-tests",
+ ],
+}
diff --git a/tools/aconfig/aconfig_storage_file/tests/AndroidManifest.xml b/tools/aconfig/aconfig_storage_file/tests/AndroidManifest.xml
new file mode 100644
index 0000000..5e01879
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.aconfig.storage.test">
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.aconfig.storage.test" />
+
+</manifest>
diff --git a/tools/aconfig/aconfig_storage_file/tests/AndroidStorageJaveTest.xml b/tools/aconfig/aconfig_storage_file/tests/AndroidStorageJaveTest.xml
new file mode 100644
index 0000000..2d52d44
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/AndroidStorageJaveTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Test aconfig storage java tests">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="aconfig_storage_file.test.java.apk" />
+ </target_preparer>
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="package.map->/data/local/tmp/aconfig_storage_file_test_java/testdata/package.map" />
+ <option name="push" value="flag.map->/data/local/tmp/aconfig_storage_file_test_java/testdata/flag.map" />
+ <option name="push" value="flag.val->/data/local/tmp/aconfig_storage_file_test_java/testdata/flag.val" />
+ <option name="push" value="flag.info->/data/local/tmp/aconfig_storage_file_test_java/testdata/flag.info" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.aconfig.storage.test" />
+ <option name="runtime-hint" value="1m" />
+ </test>
+</configuration>
\ No newline at end of file
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/ByteBufferReaderTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/ByteBufferReaderTest.java
new file mode 100644
index 0000000..66a8166
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/ByteBufferReaderTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage.test;
+
+import static org.junit.Assert.assertEquals;
+
+import android.aconfig.storage.ByteBufferReader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+
+@RunWith(JUnit4.class)
+public class ByteBufferReaderTest {
+
+ @Test
+ public void testReadByte() {
+ ByteBuffer buffer = ByteBuffer.allocate(1);
+ byte expect = 10;
+ buffer.put(expect).rewind();
+
+ ByteBufferReader reader = new ByteBufferReader(buffer);
+ assertEquals(expect, reader.readByte());
+ }
+
+ @Test
+ public void testReadShort() {
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ short expect = Short.MAX_VALUE;
+ buffer.putShort(expect).rewind();
+
+ ByteBufferReader reader = new ByteBufferReader(buffer);
+ assertEquals(expect, reader.readShort());
+ }
+
+ @Test
+ public void testReadInt() {
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ int expect = 10000;
+ buffer.putInt(expect).rewind();
+
+ ByteBufferReader reader = new ByteBufferReader(buffer);
+ assertEquals(expect, reader.readInt());
+ }
+
+ @Test
+ public void testReadString() {
+ String expect = "test read string";
+ byte[] bytes = expect.getBytes(StandardCharsets.UTF_8);
+
+ ByteBuffer buffer = ByteBuffer.allocate(expect.length() * 2 + 4);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ buffer.putInt(expect.length()).put(bytes).rewind();
+
+ ByteBufferReader reader = new ByteBufferReader(buffer);
+
+ assertEquals(expect, reader.readString());
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java
new file mode 100644
index 0000000..fd40d4c
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagTableTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage.test;
+
+import static org.junit.Assert.assertEquals;
+
+import android.aconfig.storage.FileType;
+import android.aconfig.storage.FlagTable;
+import android.aconfig.storage.FlagType;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class FlagTableTest {
+
+ @Test
+ public void testFlagTable_rightHeader() throws Exception {
+ FlagTable flagTable = FlagTable.fromBytes(TestDataUtils.getTestFlagMapByteBuffer());
+ FlagTable.Header header = flagTable.getHeader();
+ assertEquals(1, header.getVersion());
+ assertEquals("mockup", header.getContainer());
+ assertEquals(FileType.FLAG_MAP, header.getFileType());
+ assertEquals(321, header.getFileSize());
+ assertEquals(8, header.getNumFlags());
+ assertEquals(31, header.getBucketOffset());
+ assertEquals(99, header.getNodeOffset());
+ }
+
+ @Test
+ public void testFlagTable_rightNode() throws Exception {
+ FlagTable flagTable = FlagTable.fromBytes(TestDataUtils.getTestFlagMapByteBuffer());
+
+ FlagTable.Node node1 = flagTable.get(0, "enabled_ro");
+ FlagTable.Node node2 = flagTable.get(0, "enabled_rw");
+ FlagTable.Node node3 = flagTable.get(2, "enabled_rw");
+ FlagTable.Node node4 = flagTable.get(1, "disabled_rw");
+ FlagTable.Node node5 = flagTable.get(1, "enabled_fixed_ro");
+ FlagTable.Node node6 = flagTable.get(1, "enabled_ro");
+ FlagTable.Node node7 = flagTable.get(2, "enabled_fixed_ro");
+ FlagTable.Node node8 = flagTable.get(0, "disabled_rw");
+
+ assertEquals("enabled_ro", node1.getFlagName());
+ assertEquals("enabled_rw", node2.getFlagName());
+ assertEquals("enabled_rw", node3.getFlagName());
+ assertEquals("disabled_rw", node4.getFlagName());
+ assertEquals("enabled_fixed_ro", node5.getFlagName());
+ assertEquals("enabled_ro", node6.getFlagName());
+ assertEquals("enabled_fixed_ro", node7.getFlagName());
+ assertEquals("disabled_rw", node8.getFlagName());
+
+ assertEquals(0, node1.getPackageId());
+ assertEquals(0, node2.getPackageId());
+ assertEquals(2, node3.getPackageId());
+ assertEquals(1, node4.getPackageId());
+ assertEquals(1, node5.getPackageId());
+ assertEquals(1, node6.getPackageId());
+ assertEquals(2, node7.getPackageId());
+ assertEquals(0, node8.getPackageId());
+
+ assertEquals(FlagType.ReadOnlyBoolean, node1.getFlagType());
+ assertEquals(FlagType.ReadWriteBoolean, node2.getFlagType());
+ assertEquals(FlagType.ReadWriteBoolean, node3.getFlagType());
+ assertEquals(FlagType.ReadWriteBoolean, node4.getFlagType());
+ assertEquals(FlagType.FixedReadOnlyBoolean, node5.getFlagType());
+ assertEquals(FlagType.ReadOnlyBoolean, node6.getFlagType());
+ assertEquals(FlagType.FixedReadOnlyBoolean, node7.getFlagType());
+ assertEquals(FlagType.ReadWriteBoolean, node8.getFlagType());
+
+ assertEquals(1, node1.getFlagIndex());
+ assertEquals(2, node2.getFlagIndex());
+ assertEquals(1, node3.getFlagIndex());
+ assertEquals(0, node4.getFlagIndex());
+ assertEquals(1, node5.getFlagIndex());
+ assertEquals(2, node6.getFlagIndex());
+ assertEquals(0, node7.getFlagIndex());
+ assertEquals(0, node8.getFlagIndex());
+
+ assertEquals(-1, node1.getNextOffset());
+ assertEquals(151, node2.getNextOffset());
+ assertEquals(-1, node3.getNextOffset());
+ assertEquals(-1, node4.getNextOffset());
+ assertEquals(236, node5.getNextOffset());
+ assertEquals(-1, node6.getNextOffset());
+ assertEquals(-1, node7.getNextOffset());
+ assertEquals(-1, node8.getNextOffset());
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java
new file mode 100644
index 0000000..c18590a
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/FlagValueListTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.aconfig.storage.FileType;
+import android.aconfig.storage.FlagTable;
+import android.aconfig.storage.FlagValueList;
+import android.aconfig.storage.PackageTable;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class FlagValueListTest {
+
+ @Test
+ public void testFlagValueList_rightHeader() throws Exception {
+ FlagValueList flagValueList =
+ FlagValueList.fromBytes(TestDataUtils.getTestFlagValByteBuffer());
+ FlagValueList.Header header = flagValueList.getHeader();
+ assertEquals(1, header.getVersion());
+ assertEquals("mockup", header.getContainer());
+ assertEquals(FileType.FLAG_VAL, header.getFileType());
+ assertEquals(35, header.getFileSize());
+ assertEquals(8, header.getNumFlags());
+ assertEquals(27, header.getBooleanValueOffset());
+ }
+
+ @Test
+ public void testFlagValueList_rightNode() throws Exception {
+ FlagValueList flagValueList =
+ FlagValueList.fromBytes(TestDataUtils.getTestFlagValByteBuffer());
+
+ boolean[] expected = new boolean[] {false, true, true, false, true, true, true, true};
+ assertEquals(expected.length, flagValueList.size());
+
+ for (int i = 0; i < flagValueList.size(); i++) {
+ assertEquals(expected[i], flagValueList.get(i));
+ }
+ }
+
+ @Test
+ public void testFlagValueList_getValue() throws Exception {
+ PackageTable packageTable =
+ PackageTable.fromBytes(TestDataUtils.getTestPackageMapByteBuffer());
+ FlagTable flagTable = FlagTable.fromBytes(TestDataUtils.getTestFlagMapByteBuffer());
+
+ FlagValueList flagValueList =
+ FlagValueList.fromBytes(TestDataUtils.getTestFlagValByteBuffer());
+
+ PackageTable.Node pNode = packageTable.get("com.android.aconfig.storage.test_1");
+ FlagTable.Node fNode = flagTable.get(pNode.getPackageId(), "enabled_rw");
+ assertTrue(flagValueList.get(pNode.getBooleanStartIndex() + fNode.getFlagIndex()));
+
+ pNode = packageTable.get("com.android.aconfig.storage.test_4");
+ fNode = flagTable.get(pNode.getPackageId(), "enabled_fixed_ro");
+ assertTrue(flagValueList.get(pNode.getBooleanStartIndex() + fNode.getFlagIndex()));
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
new file mode 100644
index 0000000..e7e19d8
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage.test;
+
+import static org.junit.Assert.assertEquals;
+
+import android.aconfig.storage.FileType;
+import android.aconfig.storage.PackageTable;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PackageTableTest {
+
+ @Test
+ public void testPackageTable_rightHeader() throws Exception {
+ PackageTable packageTable =
+ PackageTable.fromBytes(TestDataUtils.getTestPackageMapByteBuffer());
+ PackageTable.Header header = packageTable.getHeader();
+ assertEquals(1, header.getVersion());
+ assertEquals("mockup", header.getContainer());
+ assertEquals(FileType.PACKAGE_MAP, header.getFileType());
+ assertEquals(209, header.getFileSize());
+ assertEquals(3, header.getNumPackages());
+ assertEquals(31, header.getBucketOffset());
+ assertEquals(59, header.getNodeOffset());
+ }
+
+ @Test
+ public void testPackageTable_rightNode() throws Exception {
+ PackageTable packageTable =
+ PackageTable.fromBytes(TestDataUtils.getTestPackageMapByteBuffer());
+
+ PackageTable.Node node1 = packageTable.get("com.android.aconfig.storage.test_1");
+ PackageTable.Node node2 = packageTable.get("com.android.aconfig.storage.test_2");
+ PackageTable.Node node4 = packageTable.get("com.android.aconfig.storage.test_4");
+
+ assertEquals("com.android.aconfig.storage.test_1", node1.getPackageName());
+ assertEquals("com.android.aconfig.storage.test_2", node2.getPackageName());
+ assertEquals("com.android.aconfig.storage.test_4", node4.getPackageName());
+
+ assertEquals(0, node1.getPackageId());
+ assertEquals(1, node2.getPackageId());
+ assertEquals(2, node4.getPackageId());
+
+ assertEquals(0, node1.getBooleanStartIndex());
+ assertEquals(3, node2.getBooleanStartIndex());
+ assertEquals(6, node4.getBooleanStartIndex());
+
+ assertEquals(159, node1.getNextOffset());
+ assertEquals(-1, node2.getNextOffset());
+ assertEquals(-1, node4.getNextOffset());
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/TestDataUtils.java b/tools/aconfig/aconfig_storage_file/tests/srcs/TestDataUtils.java
new file mode 100644
index 0000000..f35952d
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/TestDataUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage.test;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public final class TestDataUtils {
+ private static final String TEST_PACKAGE_MAP_PATH = "package.map";
+ private static final String TEST_FLAG_MAP_PATH = "flag.map";
+ private static final String TEST_FLAG_VAL_PATH = "flag.val";
+ private static final String TEST_FLAG_INFO_PATH = "flag.info";
+
+ private static final String TESTDATA_PATH =
+ "/data/local/tmp/aconfig_storage_file_test_java/testdata/";
+
+ public static ByteBuffer getTestPackageMapByteBuffer() throws Exception {
+ return readFile(TESTDATA_PATH + TEST_PACKAGE_MAP_PATH);
+ }
+
+ public static ByteBuffer getTestFlagMapByteBuffer() throws Exception {
+ return readFile(TESTDATA_PATH + TEST_FLAG_MAP_PATH);
+ }
+
+ public static ByteBuffer getTestFlagValByteBuffer() throws Exception {
+ return readFile(TESTDATA_PATH + TEST_FLAG_VAL_PATH);
+ }
+
+ public static ByteBuffer getTestFlagInfoByteBuffer() throws Exception {
+ return readFile(TESTDATA_PATH + TEST_FLAG_INFO_PATH);
+ }
+
+ private static ByteBuffer readFile(String fileName) throws Exception {
+ InputStream input = new FileInputStream(fileName);
+ return ByteBuffer.wrap(input.readAllBytes());
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp
index 5e9eb54..c2f4c18 100644
--- a/tools/aconfig/aconfig_storage_read_api/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/Android.bp
@@ -154,7 +154,9 @@
java_library {
name: "libaconfig_storage_read_api_java",
srcs: [
- "srcs/**/*.java",
+ "srcs/android/aconfig/storage/AconfigStorageReadAPI.java",
+ "srcs/android/aconfig/storage/FlagReadContext.java",
+ "srcs/android/aconfig/storage/PackageReadContext.java",
],
required: ["libaconfig_storage_read_api_rust_jni"],
min_sdk_version: "UpsideDownCake",
@@ -163,3 +165,14 @@
"//apex_available:platform",
],
}
+
+java_library {
+ name: "aconfig_storage_reader_java",
+ srcs: [
+ "srcs/android/aconfig/storage/StorageInternalReader.java",
+ ],
+ static_libs: [
+ "aconfig_storage_file_java",
+ ],
+ sdk_version: "core_current",
+}
diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java
new file mode 100644
index 0000000..5f31017
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage;
+
+import java.io.FileInputStream;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+
+public class StorageInternalReader {
+
+ private static final String MAP_PATH = "/metadata/aconfig/maps/";
+ private static final String BOOT_PATH = "/metadata/aconfig/boot/";
+
+ private PackageTable mPackageTable;
+ private FlagValueList mFlagValueList;
+
+ private int mPackageBooleanStartOffset;
+
+ public StorageInternalReader(String container, String packageName) {
+ this(packageName, MAP_PATH + container + ".package.map", BOOT_PATH + container + ".val");
+ }
+
+ public StorageInternalReader(String packageName, String packageMapFile, String flagValueFile) {
+ mPackageTable = PackageTable.fromBytes(mapStorageFile(packageMapFile));
+ mFlagValueList = FlagValueList.fromBytes(mapStorageFile(flagValueFile));
+ mPackageBooleanStartOffset = getPackageBooleanStartOffset(packageName);
+ }
+
+ public boolean getBooleanFlagValue(int index) {
+ index += mPackageBooleanStartOffset;
+ if (index >= mFlagValueList.size()) {
+ throw new AconfigStorageException("Fail to get boolean flag value");
+ }
+ return mFlagValueList.get(index);
+ }
+
+ private int getPackageBooleanStartOffset(String packageName) {
+ PackageTable.Node pNode = mPackageTable.get(packageName);
+ if (pNode == null) {
+ PackageTable.Header header = mPackageTable.getHeader();
+ throw new AconfigStorageException(
+ String.format(
+ "Fail to get package %s from container %s",
+ packageName, header.getContainer()));
+ }
+ return pNode.getBooleanStartIndex();
+ }
+
+ // Map a storage file given file path
+ private static MappedByteBuffer mapStorageFile(String file) {
+ try {
+ FileInputStream stream = new FileInputStream(file);
+ FileChannel channel = stream.getChannel();
+ return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
+ } catch (Exception e) {
+ throw new AconfigStorageException(
+ String.format("Fail to mmap storage file %s", file), e);
+ }
+ }
+}
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp b/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp
index d94b2b4..11b3824 100644
--- a/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp
+++ b/tools/aconfig/aconfig_storage_read_api/tests/java/Android.bp
@@ -1,7 +1,8 @@
android_test {
name: "aconfig_storage_read_api.test.java",
- srcs: ["AconfigStorageReadAPITest.java"],
+ srcs: ["./**/*.java"],
static_libs: [
+ "aconfig_storage_reader_java",
"androidx.test.rules",
"libaconfig_storage_read_api_java",
"junit",
diff --git a/tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java b/tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java
new file mode 100644
index 0000000..3a1bba0
--- /dev/null
+++ b/tools/aconfig/aconfig_storage_read_api/tests/java/StorageInternalReaderTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.aconfig.storage.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.aconfig.storage.StorageInternalReader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class StorageInternalReaderTest {
+
+ private String mStorageDir = "/data/local/tmp/aconfig_java_api_test";
+
+ @Test
+ public void testStorageInternalReader_getFlag() {
+
+ String packageMapFile = mStorageDir + "/maps/mockup.package.map";
+ String flagValueFile = mStorageDir + "/boot/mockup.val";
+
+ StorageInternalReader reader =
+ new StorageInternalReader(
+ "com.android.aconfig.storage.test_1", packageMapFile, flagValueFile);
+ assertFalse(reader.getBooleanFlagValue(0));
+ assertTrue(reader.getBooleanFlagValue(1));
+ }
+}
diff --git a/tools/aconfig/aflags/src/aconfig_storage_source.rs b/tools/aconfig/aflags/src/aconfig_storage_source.rs
index 04140c7..d9dc15f 100644
--- a/tools/aconfig/aflags/src/aconfig_storage_source.rs
+++ b/tools/aconfig/aflags/src/aconfig_storage_source.rs
@@ -1,14 +1,91 @@
use crate::{Flag, FlagPermission, FlagSource, FlagValue, ValuePickedFrom};
use anyhow::{anyhow, Result};
+use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
pub struct AconfigStorageSource {}
+use aconfig_storage_file::protos::ProtoStorageFileInfo;
use aconfig_storage_file::protos::ProtoStorageFiles;
+use aconfig_storage_file::FlagValueAndInfoSummary;
-static STORAGE_INFO_FILE_PATH: &str = "/metadata/aconfig/persistent_storage_file_records.pb";
+static STORAGE_INFO_FILE_PATH: &str = "/metadata/aconfig/storage_records.pb";
+
+fn read_default_values(file_info: ProtoStorageFileInfo) -> Result<HashMap<String, FlagValue>> {
+ let package_map =
+ file_info.package_map.ok_or(anyhow!("storage file is missing package map"))?;
+ let flag_map = file_info.flag_map.ok_or(anyhow!("storage file is missing flag map"))?;
+ let flag_val = file_info.flag_val.ok_or(anyhow!("storage file is missing flag val"))?;
+
+ let mut result = HashMap::new();
+ for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)? {
+ let value = FlagValue::try_from(listed_flag.flag_value.as_str())?;
+ result.insert(listed_flag.package_name + &listed_flag.flag_name, value);
+ }
+ Ok(result)
+}
+
+fn read_next_boot_values(
+ listed_flags: &[FlagValueAndInfoSummary],
+) -> Result<HashMap<String, FlagValue>> {
+ let mut result = HashMap::new();
+ for flag in listed_flags {
+ result.insert(
+ flag.package_name.clone() + &flag.flag_name,
+ FlagValue::try_from(flag.flag_value.as_str())?,
+ );
+ }
+ Ok(result)
+}
+
+fn reconcile(
+ default_values: HashMap<String, FlagValue>,
+ next_boot_values: HashMap<String, FlagValue>,
+ flags_current_boot: &[FlagValueAndInfoSummary],
+ container: &str,
+) -> Result<Vec<Flag>> {
+ let mut result = Vec::new();
+ for listed_flag in flags_current_boot {
+ let default_value = default_values
+ .get(&(listed_flag.package_name.clone() + &listed_flag.flag_name))
+ .copied();
+
+ let name = listed_flag.flag_name.clone();
+ let package = listed_flag.package_name.clone();
+ let value = FlagValue::try_from(listed_flag.flag_value.as_str())?;
+ let container = container.to_string();
+ let staged_value = next_boot_values
+ .get(&(listed_flag.package_name.clone() + &listed_flag.flag_name))
+ .filter(|&v| value != *v)
+ .copied();
+ let permission = if listed_flag.is_readwrite {
+ FlagPermission::ReadWrite
+ } else {
+ FlagPermission::ReadOnly
+ };
+ let value_picked_from = if Some(value) == default_value {
+ ValuePickedFrom::Default
+ } else {
+ ValuePickedFrom::Server
+ };
+
+ result.push(Flag {
+ name,
+ package,
+ value,
+ container,
+ staged_value,
+ permission,
+ value_picked_from,
+
+ // TODO(b/324436145): delete namespace field once DeviceConfig isn't in CLI.
+ namespace: "-".to_string(),
+ });
+ }
+ Ok(result)
+}
impl FlagSource for AconfigStorageSource {
fn list_flags() -> Result<Vec<Flag>> {
@@ -20,30 +97,35 @@
let storage_file_info: ProtoStorageFiles = protobuf::Message::parse_from_bytes(&bytes)?;
for file_info in storage_file_info.files {
- let package_map =
- file_info.package_map.ok_or(anyhow!("storage file is missing package map"))?;
- let flag_map = file_info.flag_map.ok_or(anyhow!("storage file is missing flag map"))?;
- let flag_val = file_info.flag_val.ok_or(anyhow!("storage file is missing flag val"))?;
+ let default_values = read_default_values(file_info.clone())?;
+
let container =
file_info.container.ok_or(anyhow!("storage file is missing container"))?;
+ let package_map = format!("/metadata/aconfig/maps/{container}.package.map");
+ let flag_map = format!("/metadata/aconfig/maps/{container}.flag.map");
+ let flag_info = format!("/metadata/aconfig/boot/{container}.info");
- for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)?
- {
- result.push(Flag {
- name: listed_flag.flag_name,
- package: listed_flag.package_name,
- value: FlagValue::try_from(listed_flag.flag_value.as_str())?,
- container: container.to_string(),
+ let flag_val_current_boot = format!("/metadata/aconfig/boot/{container}.val");
+ let flag_val_next_boot = format!("/metadata/aconfig/flags/{container}.val");
- // TODO(b/324436145): delete namespace field once DeviceConfig isn't in CLI.
- namespace: "-".to_string(),
+ let flags_next_boot = aconfig_storage_file::list_flags_with_info(
+ &package_map,
+ &flag_map,
+ &flag_val_next_boot,
+ &flag_info,
+ )?;
+ let flags_current_boot = aconfig_storage_file::list_flags_with_info(
+ &package_map,
+ &flag_map,
+ &flag_val_current_boot,
+ &flag_info,
+ )?;
- // TODO(b/324436145): Populate with real values once API is available.
- staged_value: None,
- permission: FlagPermission::ReadOnly,
- value_picked_from: ValuePickedFrom::Default,
- });
- }
+ let next_boot_values = read_next_boot_values(&flags_next_boot)?;
+ let processed_flags =
+ reconcile(default_values, next_boot_values, &flags_current_boot, &container)?;
+
+ result.extend(processed_flags);
}
Ok(result)
diff --git a/tools/aconfig/aflags/src/main.rs b/tools/aconfig/aflags/src/main.rs
index 810f2e3..6d76fd0 100644
--- a/tools/aconfig/aflags/src/main.rs
+++ b/tools/aconfig/aflags/src/main.rs
@@ -286,7 +286,9 @@
let cli = Cli::parse();
let output = match cli.command {
Command::List { use_new_storage: true, container } => {
- list(FlagSourceType::AconfigStorage, container).map(Some)
+ list(FlagSourceType::AconfigStorage, container)
+ .map_err(|_| anyhow!("storage may not be enabled"))
+ .map(Some)
}
Command::List { use_new_storage: false, container } => {
list(FlagSourceType::DeviceConfig, container).map(Some)
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
index 1125d39..d323c20 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -19,10 +19,10 @@
import android.aconfig.Aconfig
import com.android.tools.metalava.model.BaseItemVisitor
+import com.android.tools.metalava.model.CallableItem
import com.android.tools.metalava.model.ClassItem
import com.android.tools.metalava.model.FieldItem
import com.android.tools.metalava.model.Item
-import com.android.tools.metalava.model.MethodItem
import com.android.tools.metalava.model.text.ApiFile
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.ProgramResult
@@ -274,15 +274,15 @@
}
}
- override fun visitMethod(method: MethodItem) {
- getFlagOrNull(method)?.let { flag ->
- val methodName = buildString {
- append(method.name())
+ override fun visitCallable(callable: CallableItem) {
+ getFlagOrNull(callable)?.let { flag ->
+ val callableSignature = buildString {
+ append(callable.name())
append("(")
- method.parameters().joinTo(this, separator = "") { it.type().internalName() }
+ callable.parameters().joinTo(this, separator = "") { it.type().internalName() }
append(")")
}
- val symbol = Symbol.createMethod(method.containingClass().qualifiedName(), methodName)
+ val symbol = Symbol.createMethod(callable.containingClass().qualifiedName(), callableSignature)
output.add(Pair(symbol, flag))
}
}
diff --git a/tools/filelistdiff/allowlist b/tools/filelistdiff/allowlist
index 0a51d0e..943f955 100644
--- a/tools/filelistdiff/allowlist
+++ b/tools/filelistdiff/allowlist
@@ -78,6 +78,10 @@
lib/libwfds.so
lib/libyuv.so
+# b/351258461
+adb_keys
+init.environ.rc
+
# Known diffs only in the Soong system image
lib/libhidcommand_jni.so
lib/libuinputcommand_jni.so
\ No newline at end of file
diff --git a/tools/ide_query/cc_analyzer/Android.bp b/tools/ide_query/cc_analyzer/Android.bp
index 3cbbb05..e85d445 100644
--- a/tools/ide_query/cc_analyzer/Android.bp
+++ b/tools/ide_query/cc_analyzer/Android.bp
@@ -58,7 +58,7 @@
shared_libs: ["libclang-cpp_host"],
static_libs: [
"include_scanner",
- "ide_query_proto",
+ "cc_analyzer_proto",
],
defaults: ["ide_query_cc_analyzer_defaults"],
}
@@ -72,7 +72,7 @@
"libprotobuf-cpp-full",
],
static_libs: [
- "ide_query_proto",
+ "cc_analyzer_proto",
"builtin_headers",
"include_scanner",
"analyzer",
diff --git a/tools/ide_query/cc_analyzer/analyzer.cc b/tools/ide_query/cc_analyzer/analyzer.cc
index bb7ca0b..4ccec54 100644
--- a/tools/ide_query/cc_analyzer/analyzer.cc
+++ b/tools/ide_query/cc_analyzer/analyzer.cc
@@ -20,9 +20,9 @@
#include <utility>
#include <vector>
+#include "cc_analyzer.pb.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/JSONCompilationDatabase.h"
-#include "ide_query.pb.h"
#include "include_scanner.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@@ -48,11 +48,11 @@
}
} // namespace
-::ide_query::DepsResponse GetDeps(::ide_query::RepoState state) {
- ::ide_query::DepsResponse results;
+::cc_analyzer::DepsResponse GetDeps(::cc_analyzer::RepoState state) {
+ ::cc_analyzer::DepsResponse results;
auto db = LoadCompDB(state.comp_db_path());
if (!db) {
- results.mutable_status()->set_code(::ide_query::Status::FAILURE);
+ results.mutable_status()->set_code(::cc_analyzer::Status::FAILURE);
results.mutable_status()->set_message(llvm::toString(db.takeError()));
return results;
}
@@ -63,7 +63,7 @@
llvm::sys::path::append(abs_file, active_file);
auto cmds = db->get()->getCompileCommands(active_file);
if (cmds.empty()) {
- result.mutable_status()->set_code(::ide_query::Status::FAILURE);
+ result.mutable_status()->set_code(::cc_analyzer::Status::FAILURE);
result.mutable_status()->set_message(
llvm::Twine("Can't find compile flags for file: ", abs_file).str());
continue;
@@ -80,11 +80,11 @@
return results;
}
-::ide_query::IdeAnalysis GetBuildInputs(::ide_query::RepoState state) {
+::cc_analyzer::IdeAnalysis GetBuildInputs(::cc_analyzer::RepoState state) {
auto db = LoadCompDB(state.comp_db_path());
- ::ide_query::IdeAnalysis results;
+ ::cc_analyzer::IdeAnalysis results;
if (!db) {
- results.mutable_status()->set_code(::ide_query::Status::FAILURE);
+ results.mutable_status()->set_code(::cc_analyzer::Status::FAILURE);
results.mutable_status()->set_message(llvm::toString(db.takeError()));
return results;
}
@@ -97,7 +97,6 @@
genfile_root_abs.push_back('/');
}
- results.set_build_artifact_root(state.out_dir());
for (llvm::StringRef active_file : state.active_file_path()) {
auto& result = *results.add_sources();
result.set_path(active_file.str());
@@ -106,7 +105,7 @@
llvm::sys::path::append(abs_file, active_file);
auto cmds = db->get()->getCompileCommands(abs_file);
if (cmds.empty()) {
- result.mutable_status()->set_code(::ide_query::Status::FAILURE);
+ result.mutable_status()->set_code(::cc_analyzer::Status::FAILURE);
result.mutable_status()->set_message(
llvm::Twine("Can't find compile flags for file: ", abs_file).str());
continue;
@@ -114,7 +113,7 @@
const auto& cmd = cmds.front();
llvm::StringRef working_dir = cmd.Directory;
if (!working_dir.consume_front(repo_dir)) {
- result.mutable_status()->set_code(::ide_query::Status::FAILURE);
+ result.mutable_status()->set_code(::cc_analyzer::Status::FAILURE);
result.mutable_status()->set_message("Command working dir " +
working_dir.str() +
" outside repository " + repo_dir);
@@ -127,7 +126,7 @@
auto includes =
ScanIncludes(cmds.front(), llvm::vfs::createPhysicalFileSystem());
if (!includes) {
- result.mutable_status()->set_code(::ide_query::Status::FAILURE);
+ result.mutable_status()->set_code(::cc_analyzer::Status::FAILURE);
result.mutable_status()->set_message(
llvm::toString(includes.takeError()));
continue;
diff --git a/tools/ide_query/cc_analyzer/analyzer.h b/tools/ide_query/cc_analyzer/analyzer.h
index 3133795..fd19082 100644
--- a/tools/ide_query/cc_analyzer/analyzer.h
+++ b/tools/ide_query/cc_analyzer/analyzer.h
@@ -17,17 +17,17 @@
#ifndef _TOOLS_IDE_QUERY_CC_ANALYZER_ANALYZER_H_
#define _TOOLS_IDE_QUERY_CC_ANALYZER_ANALYZER_H_
-#include "ide_query.pb.h"
+#include "cc_analyzer.pb.h"
namespace tools::ide_query::cc_analyzer {
// Scans the build graph and returns target names from the build graph to
// generate all the dependencies for the active files.
-::ide_query::DepsResponse GetDeps(::ide_query::RepoState state);
+::cc_analyzer::DepsResponse GetDeps(::cc_analyzer::RepoState state);
// Scans the sources and returns all the source files required for analyzing the
// active files.
-::ide_query::IdeAnalysis GetBuildInputs(::ide_query::RepoState state);
+::cc_analyzer::IdeAnalysis GetBuildInputs(::cc_analyzer::RepoState state);
} // namespace tools::ide_query::cc_analyzer
diff --git a/tools/ide_query/cc_analyzer/main.cc b/tools/ide_query/cc_analyzer/main.cc
index 8e00c63..d86fc8c 100644
--- a/tools/ide_query/cc_analyzer/main.cc
+++ b/tools/ide_query/cc_analyzer/main.cc
@@ -28,7 +28,7 @@
#include "analyzer.h"
#include "google/protobuf/message.h"
-#include "ide_query.pb.h"
+#include "cc_analyzer.pb.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetSelect.h"
@@ -48,9 +48,9 @@
llvm::cl::desc("Print the list of headers to insert and remove"),
};
-ide_query::IdeAnalysis ReturnError(llvm::StringRef message) {
- ide_query::IdeAnalysis result;
- result.mutable_status()->set_code(ide_query::Status::FAILURE);
+cc_analyzer::IdeAnalysis ReturnError(llvm::StringRef message) {
+ cc_analyzer::IdeAnalysis result;
+ result.mutable_status()->set_code(cc_analyzer::Status::FAILURE);
result.mutable_status()->set_message(message.str());
return result;
}
@@ -61,7 +61,7 @@
llvm::InitializeAllTargetInfos();
llvm::cl::ParseCommandLineOptions(argc, argv);
- ide_query::RepoState state;
+ cc_analyzer::RepoState state;
if (!state.ParseFromFileDescriptor(STDIN_FILENO)) {
llvm::errs() << "Failed to parse input!\n";
return 1;
@@ -70,12 +70,12 @@
std::unique_ptr<google::protobuf::Message> result;
switch (mode) {
case OpMode::DEPS: {
- result = std::make_unique<ide_query::DepsResponse>(
+ result = std::make_unique<cc_analyzer::DepsResponse>(
tools::ide_query::cc_analyzer::GetDeps(std::move(state)));
break;
}
case OpMode::INPUTS: {
- result = std::make_unique<ide_query::IdeAnalysis>(
+ result = std::make_unique<cc_analyzer::IdeAnalysis>(
tools::ide_query::cc_analyzer::GetBuildInputs(std::move(state)));
break;
}
diff --git a/tools/ide_query/ide_query_proto/Android.bp b/tools/ide_query/cc_analyzer_proto/Android.bp
similarity index 93%
rename from tools/ide_query/ide_query_proto/Android.bp
rename to tools/ide_query/cc_analyzer_proto/Android.bp
index 70f15cd..0ed07b4 100644
--- a/tools/ide_query/ide_query_proto/Android.bp
+++ b/tools/ide_query/cc_analyzer_proto/Android.bp
@@ -19,9 +19,9 @@
}
cc_library_host_static {
- name: "ide_query_proto",
+ name: "cc_analyzer_proto",
srcs: [
- "ide_query.proto",
+ "cc_analyzer.proto",
],
proto: {
export_proto_headers: true,
diff --git a/tools/ide_query/cc_analyzer_proto/cc_analyzer.pb.go b/tools/ide_query/cc_analyzer_proto/cc_analyzer.pb.go
new file mode 100644
index 0000000..debe5c0
--- /dev/null
+++ b/tools/ide_query/cc_analyzer_proto/cc_analyzer.pb.go
@@ -0,0 +1,789 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.30.0
+// protoc v3.21.12
+// source: cc_analyzer.proto
+
+package cc_analyzer_proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Status_Code int32
+
+const (
+ Status_OK Status_Code = 0
+ Status_FAILURE Status_Code = 1
+)
+
+// Enum value maps for Status_Code.
+var (
+ Status_Code_name = map[int32]string{
+ 0: "OK",
+ 1: "FAILURE",
+ }
+ Status_Code_value = map[string]int32{
+ "OK": 0,
+ "FAILURE": 1,
+ }
+)
+
+func (x Status_Code) Enum() *Status_Code {
+ p := new(Status_Code)
+ *p = x
+ return p
+}
+
+func (x Status_Code) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Status_Code) Descriptor() protoreflect.EnumDescriptor {
+ return file_cc_analyzer_proto_enumTypes[0].Descriptor()
+}
+
+func (Status_Code) Type() protoreflect.EnumType {
+ return &file_cc_analyzer_proto_enumTypes[0]
+}
+
+func (x Status_Code) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Status_Code.Descriptor instead.
+func (Status_Code) EnumDescriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{0, 0}
+}
+
+// Indicates the success/failure for analysis.
+type Status struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Code Status_Code `protobuf:"varint,1,opt,name=code,proto3,enum=cc_analyzer.Status_Code" json:"code,omitempty"`
+ // Details about the status, might be displayed to user.
+ Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"`
+}
+
+func (x *Status) Reset() {
+ *x = Status{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status) ProtoMessage() {}
+
+func (x *Status) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status.ProtoReflect.Descriptor instead.
+func (*Status) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Status) GetCode() Status_Code {
+ if x != nil {
+ return x.Code
+ }
+ return Status_OK
+}
+
+func (x *Status) GetMessage() string {
+ if x != nil && x.Message != nil {
+ return *x.Message
+ }
+ return ""
+}
+
+// Represents an Android checkout on user's workstation.
+type RepoState struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Absolute path for the checkout in the workstation.
+ // e.g. /home/user/work/android/
+ RepoDir string `protobuf:"bytes,1,opt,name=repo_dir,json=repoDir,proto3" json:"repo_dir,omitempty"`
+ // Relative to repo_dir.
+ ActiveFilePath []string `protobuf:"bytes,2,rep,name=active_file_path,json=activeFilePath,proto3" json:"active_file_path,omitempty"`
+ // Repository relative path to output directory in workstation.
+ OutDir string `protobuf:"bytes,3,opt,name=out_dir,json=outDir,proto3" json:"out_dir,omitempty"`
+ // Repository relative path to compile_commands.json in workstation.
+ CompDbPath string `protobuf:"bytes,4,opt,name=comp_db_path,json=compDbPath,proto3" json:"comp_db_path,omitempty"`
+}
+
+func (x *RepoState) Reset() {
+ *x = RepoState{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RepoState) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RepoState) ProtoMessage() {}
+
+func (x *RepoState) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RepoState.ProtoReflect.Descriptor instead.
+func (*RepoState) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *RepoState) GetRepoDir() string {
+ if x != nil {
+ return x.RepoDir
+ }
+ return ""
+}
+
+func (x *RepoState) GetActiveFilePath() []string {
+ if x != nil {
+ return x.ActiveFilePath
+ }
+ return nil
+}
+
+func (x *RepoState) GetOutDir() string {
+ if x != nil {
+ return x.OutDir
+ }
+ return ""
+}
+
+func (x *RepoState) GetCompDbPath() string {
+ if x != nil {
+ return x.CompDbPath
+ }
+ return ""
+}
+
+// Provides all the targets that are pre-requisities for running language
+// services on active_file_paths.
+type DepsResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Deps []*DepsResponse_Deps `protobuf:"bytes,1,rep,name=deps,proto3" json:"deps,omitempty"`
+ Status *Status `protobuf:"bytes,2,opt,name=status,proto3,oneof" json:"status,omitempty"`
+}
+
+func (x *DepsResponse) Reset() {
+ *x = DepsResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DepsResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DepsResponse) ProtoMessage() {}
+
+func (x *DepsResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DepsResponse.ProtoReflect.Descriptor instead.
+func (*DepsResponse) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *DepsResponse) GetDeps() []*DepsResponse_Deps {
+ if x != nil {
+ return x.Deps
+ }
+ return nil
+}
+
+func (x *DepsResponse) GetStatus() *Status {
+ if x != nil {
+ return x.Status
+ }
+ return nil
+}
+
+// Returns all the information necessary for providing language services for the
+// active files.
+type GeneratedFile struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Path to the file relative to repository root.
+ Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
+ // The text of the generated file, if not provided contents will be read
+ // from the path above in user's workstation.
+ Contents []byte `protobuf:"bytes,2,opt,name=contents,proto3,oneof" json:"contents,omitempty"`
+}
+
+func (x *GeneratedFile) Reset() {
+ *x = GeneratedFile{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GeneratedFile) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GeneratedFile) ProtoMessage() {}
+
+func (x *GeneratedFile) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GeneratedFile.ProtoReflect.Descriptor instead.
+func (*GeneratedFile) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GeneratedFile) GetPath() string {
+ if x != nil {
+ return x.Path
+ }
+ return ""
+}
+
+func (x *GeneratedFile) GetContents() []byte {
+ if x != nil {
+ return x.Contents
+ }
+ return nil
+}
+
+type SourceFile struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Path to the source file relative to repository root.
+ Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
+ // Working directory used by the build system. All the relative
+ // paths in compiler_arguments should be relative to this path.
+ // Relative to repository root.
+ WorkingDir string `protobuf:"bytes,2,opt,name=working_dir,json=workingDir,proto3" json:"working_dir,omitempty"`
+ // Compiler arguments to compile the source file. If multiple variants
+ // of the module being compiled are possible, the query script will choose
+ // one.
+ CompilerArguments []string `protobuf:"bytes,3,rep,name=compiler_arguments,json=compilerArguments,proto3" json:"compiler_arguments,omitempty"`
+ // Any generated files that are used in compiling the file.
+ Generated []*GeneratedFile `protobuf:"bytes,4,rep,name=generated,proto3" json:"generated,omitempty"`
+ // Paths to all of the sources, like build files, code generators,
+ // proto files etc. that were used during analysis. Used to figure
+ // out when a set of build artifacts are stale and the query tool
+ // must be re-run.
+ // Relative to repository root.
+ Deps []string `protobuf:"bytes,5,rep,name=deps,proto3" json:"deps,omitempty"`
+ // Represents analysis status for this particular file. e.g. not part
+ // of the build graph.
+ Status *Status `protobuf:"bytes,6,opt,name=status,proto3,oneof" json:"status,omitempty"`
+}
+
+func (x *SourceFile) Reset() {
+ *x = SourceFile{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SourceFile) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SourceFile) ProtoMessage() {}
+
+func (x *SourceFile) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SourceFile.ProtoReflect.Descriptor instead.
+func (*SourceFile) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *SourceFile) GetPath() string {
+ if x != nil {
+ return x.Path
+ }
+ return ""
+}
+
+func (x *SourceFile) GetWorkingDir() string {
+ if x != nil {
+ return x.WorkingDir
+ }
+ return ""
+}
+
+func (x *SourceFile) GetCompilerArguments() []string {
+ if x != nil {
+ return x.CompilerArguments
+ }
+ return nil
+}
+
+func (x *SourceFile) GetGenerated() []*GeneratedFile {
+ if x != nil {
+ return x.Generated
+ }
+ return nil
+}
+
+func (x *SourceFile) GetDeps() []string {
+ if x != nil {
+ return x.Deps
+ }
+ return nil
+}
+
+func (x *SourceFile) GetStatus() *Status {
+ if x != nil {
+ return x.Status
+ }
+ return nil
+}
+
+type IdeAnalysis struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Sources []*SourceFile `protobuf:"bytes,2,rep,name=sources,proto3" json:"sources,omitempty"`
+ // Status representing overall analysis.
+ // Should fail only when no analysis can be performed.
+ Status *Status `protobuf:"bytes,3,opt,name=status,proto3,oneof" json:"status,omitempty"`
+}
+
+func (x *IdeAnalysis) Reset() {
+ *x = IdeAnalysis{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *IdeAnalysis) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*IdeAnalysis) ProtoMessage() {}
+
+func (x *IdeAnalysis) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use IdeAnalysis.ProtoReflect.Descriptor instead.
+func (*IdeAnalysis) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *IdeAnalysis) GetSources() []*SourceFile {
+ if x != nil {
+ return x.Sources
+ }
+ return nil
+}
+
+func (x *IdeAnalysis) GetStatus() *Status {
+ if x != nil {
+ return x.Status
+ }
+ return nil
+}
+
+// Build dependencies of a source file for providing language services.
+type DepsResponse_Deps struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Relative to repo_dir.
+ SourceFile string `protobuf:"bytes,1,opt,name=source_file,json=sourceFile,proto3" json:"source_file,omitempty"`
+ // Build target to execute for generating dep.
+ BuildTarget []string `protobuf:"bytes,2,rep,name=build_target,json=buildTarget,proto3" json:"build_target,omitempty"`
+ Status *Status `protobuf:"bytes,3,opt,name=status,proto3,oneof" json:"status,omitempty"`
+}
+
+func (x *DepsResponse_Deps) Reset() {
+ *x = DepsResponse_Deps{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_cc_analyzer_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DepsResponse_Deps) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DepsResponse_Deps) ProtoMessage() {}
+
+func (x *DepsResponse_Deps) ProtoReflect() protoreflect.Message {
+ mi := &file_cc_analyzer_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DepsResponse_Deps.ProtoReflect.Descriptor instead.
+func (*DepsResponse_Deps) Descriptor() ([]byte, []int) {
+ return file_cc_analyzer_proto_rawDescGZIP(), []int{2, 0}
+}
+
+func (x *DepsResponse_Deps) GetSourceFile() string {
+ if x != nil {
+ return x.SourceFile
+ }
+ return ""
+}
+
+func (x *DepsResponse_Deps) GetBuildTarget() []string {
+ if x != nil {
+ return x.BuildTarget
+ }
+ return nil
+}
+
+func (x *DepsResponse_Deps) GetStatus() *Status {
+ if x != nil {
+ return x.Status
+ }
+ return nil
+}
+
+var File_cc_analyzer_proto protoreflect.FileDescriptor
+
+var file_cc_analyzer_proto_rawDesc = []byte{
+ 0x0a, 0x11, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72,
+ 0x22, 0x7e, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x04, 0x63, 0x6f,
+ 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x63, 0x63, 0x5f, 0x61, 0x6e,
+ 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x43, 0x6f,
+ 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x22, 0x1b, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12,
+ 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x55,
+ 0x52, 0x45, 0x10, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x70, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x19,
+ 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x44, 0x69, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x63, 0x74,
+ 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x50,
+ 0x61, 0x74, 0x68, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x44, 0x69, 0x72, 0x12, 0x20, 0x0a, 0x0c,
+ 0x63, 0x6f, 0x6d, 0x70, 0x5f, 0x64, 0x62, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x44, 0x62, 0x50, 0x61, 0x74, 0x68, 0x22, 0x89,
+ 0x02, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+ 0x32, 0x0a, 0x04, 0x64, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
+ 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x73,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x70, 0x73, 0x52, 0x04, 0x64,
+ 0x65, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65,
+ 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x87, 0x01, 0x0a, 0x04, 0x44, 0x65, 0x70, 0x73, 0x12, 0x1f,
+ 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12,
+ 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
+ 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72,
+ 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42,
+ 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x51, 0x0a, 0x0d, 0x47, 0x65,
+ 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70,
+ 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12,
+ 0x1f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0c, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x88, 0x01, 0x01,
+ 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xfb, 0x01,
+ 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04,
+ 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68,
+ 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x72, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69,
+ 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x61, 0x72,
+ 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x63,
+ 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+ 0x12, 0x38, 0x0a, 0x09, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65,
+ 0x72, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52,
+ 0x09, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65,
+ 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x70, 0x73, 0x12, 0x30,
+ 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
+ 0x2e, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01,
+ 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x0b,
+ 0x49, 0x64, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x12, 0x31, 0x0a, 0x07, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63,
+ 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x30,
+ 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
+ 0x2e, 0x63, 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01,
+ 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10,
+ 0x02, 0x42, 0x1d, 0x5a, 0x1b, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x63,
+ 0x63, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_cc_analyzer_proto_rawDescOnce sync.Once
+ file_cc_analyzer_proto_rawDescData = file_cc_analyzer_proto_rawDesc
+)
+
+func file_cc_analyzer_proto_rawDescGZIP() []byte {
+ file_cc_analyzer_proto_rawDescOnce.Do(func() {
+ file_cc_analyzer_proto_rawDescData = protoimpl.X.CompressGZIP(file_cc_analyzer_proto_rawDescData)
+ })
+ return file_cc_analyzer_proto_rawDescData
+}
+
+var file_cc_analyzer_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_cc_analyzer_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_cc_analyzer_proto_goTypes = []interface{}{
+ (Status_Code)(0), // 0: cc_analyzer.Status.Code
+ (*Status)(nil), // 1: cc_analyzer.Status
+ (*RepoState)(nil), // 2: cc_analyzer.RepoState
+ (*DepsResponse)(nil), // 3: cc_analyzer.DepsResponse
+ (*GeneratedFile)(nil), // 4: cc_analyzer.GeneratedFile
+ (*SourceFile)(nil), // 5: cc_analyzer.SourceFile
+ (*IdeAnalysis)(nil), // 6: cc_analyzer.IdeAnalysis
+ (*DepsResponse_Deps)(nil), // 7: cc_analyzer.DepsResponse.Deps
+}
+var file_cc_analyzer_proto_depIdxs = []int32{
+ 0, // 0: cc_analyzer.Status.code:type_name -> cc_analyzer.Status.Code
+ 7, // 1: cc_analyzer.DepsResponse.deps:type_name -> cc_analyzer.DepsResponse.Deps
+ 1, // 2: cc_analyzer.DepsResponse.status:type_name -> cc_analyzer.Status
+ 4, // 3: cc_analyzer.SourceFile.generated:type_name -> cc_analyzer.GeneratedFile
+ 1, // 4: cc_analyzer.SourceFile.status:type_name -> cc_analyzer.Status
+ 5, // 5: cc_analyzer.IdeAnalysis.sources:type_name -> cc_analyzer.SourceFile
+ 1, // 6: cc_analyzer.IdeAnalysis.status:type_name -> cc_analyzer.Status
+ 1, // 7: cc_analyzer.DepsResponse.Deps.status:type_name -> cc_analyzer.Status
+ 8, // [8:8] is the sub-list for method output_type
+ 8, // [8:8] is the sub-list for method input_type
+ 8, // [8:8] is the sub-list for extension type_name
+ 8, // [8:8] is the sub-list for extension extendee
+ 0, // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_cc_analyzer_proto_init() }
+func file_cc_analyzer_proto_init() {
+ if File_cc_analyzer_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_cc_analyzer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RepoState); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DepsResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GeneratedFile); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SourceFile); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*IdeAnalysis); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DepsResponse_Deps); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_cc_analyzer_proto_msgTypes[0].OneofWrappers = []interface{}{}
+ file_cc_analyzer_proto_msgTypes[2].OneofWrappers = []interface{}{}
+ file_cc_analyzer_proto_msgTypes[3].OneofWrappers = []interface{}{}
+ file_cc_analyzer_proto_msgTypes[4].OneofWrappers = []interface{}{}
+ file_cc_analyzer_proto_msgTypes[5].OneofWrappers = []interface{}{}
+ file_cc_analyzer_proto_msgTypes[6].OneofWrappers = []interface{}{}
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_cc_analyzer_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 7,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_cc_analyzer_proto_goTypes,
+ DependencyIndexes: file_cc_analyzer_proto_depIdxs,
+ EnumInfos: file_cc_analyzer_proto_enumTypes,
+ MessageInfos: file_cc_analyzer_proto_msgTypes,
+ }.Build()
+ File_cc_analyzer_proto = out.File
+ file_cc_analyzer_proto_rawDesc = nil
+ file_cc_analyzer_proto_goTypes = nil
+ file_cc_analyzer_proto_depIdxs = nil
+}
diff --git a/tools/ide_query/cc_analyzer_proto/cc_analyzer.proto b/tools/ide_query/cc_analyzer_proto/cc_analyzer.proto
new file mode 100644
index 0000000..094eb49
--- /dev/null
+++ b/tools/ide_query/cc_analyzer_proto/cc_analyzer.proto
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto3";
+
+package cc_analyzer;
+
+option go_package = "ide_query/cc_analyzer_proto";
+
+// Indicates the success/failure for analysis.
+message Status {
+ enum Code {
+ OK = 0;
+ FAILURE = 1;
+ }
+ Code code = 1;
+ // Details about the status, might be displayed to user.
+ optional string message = 2;
+}
+
+// Represents an Android checkout on user's workstation.
+message RepoState {
+ // Absolute path for the checkout in the workstation.
+ // e.g. /home/user/work/android/
+ string repo_dir = 1;
+ // Relative to repo_dir.
+ repeated string active_file_path = 2;
+ // Repository relative path to output directory in workstation.
+ string out_dir = 3;
+ // Repository relative path to compile_commands.json in workstation.
+ string comp_db_path = 4;
+}
+
+// Provides all the targets that are pre-requisities for running language
+// services on active_file_paths.
+message DepsResponse {
+ // Build dependencies of a source file for providing language services.
+ message Deps {
+ // Relative to repo_dir.
+ string source_file = 1;
+ // Build target to execute for generating dep.
+ repeated string build_target = 2;
+ optional Status status = 3;
+ }
+ repeated Deps deps = 1;
+ optional Status status = 2;
+}
+
+// Returns all the information necessary for providing language services for the
+// active files.
+message GeneratedFile {
+ // Path to the file relative to repository root.
+ string path = 1;
+
+ // The text of the generated file, if not provided contents will be read
+ // from the path above in user's workstation.
+ optional bytes contents = 2;
+}
+
+message SourceFile {
+ // Path to the source file relative to repository root.
+ string path = 1;
+
+ // Working directory used by the build system. All the relative
+ // paths in compiler_arguments should be relative to this path.
+ // Relative to repository root.
+ string working_dir = 2;
+
+ // Compiler arguments to compile the source file. If multiple variants
+ // of the module being compiled are possible, the query script will choose
+ // one.
+ repeated string compiler_arguments = 3;
+
+ // Any generated files that are used in compiling the file.
+ repeated GeneratedFile generated = 4;
+
+ // Paths to all of the sources, like build files, code generators,
+ // proto files etc. that were used during analysis. Used to figure
+ // out when a set of build artifacts are stale and the query tool
+ // must be re-run.
+ // Relative to repository root.
+ repeated string deps = 5;
+
+ // Represents analysis status for this particular file. e.g. not part
+ // of the build graph.
+ optional Status status = 6;
+}
+
+message IdeAnalysis {
+ repeated SourceFile sources = 2;
+
+ // Status representing overall analysis.
+ // Should fail only when no analysis can be performed.
+ optional Status status = 3;
+
+ reserved 1;
+}
diff --git a/tools/ide_query/cc_analyzer_proto/regen.sh b/tools/ide_query/cc_analyzer_proto/regen.sh
new file mode 100755
index 0000000..ef44f88
--- /dev/null
+++ b/tools/ide_query/cc_analyzer_proto/regen.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+aprotoc --go_out=paths=source_relative:. cc_analyzer.proto
diff --git a/tools/ide_query/ide_query.go b/tools/ide_query/ide_query.go
index de84fbe..23c7abd 100644
--- a/tools/ide_query/ide_query.go
+++ b/tools/ide_query/ide_query.go
@@ -33,6 +33,7 @@
"strings"
"google.golang.org/protobuf/proto"
+ apb "ide_query/cc_analyzer_proto"
pb "ide_query/ide_query_proto"
)
@@ -42,9 +43,6 @@
RepoDir string
OutDir string
ClangToolsRoot string
-
- CcFiles []string
- JavaFiles []string
}
// LunchTarget is a parsed Android lunch target.
@@ -83,7 +81,7 @@
func main() {
var env Env
- env.OutDir = os.Getenv("OUT_DIR")
+ env.OutDir = strings.TrimSuffix(os.Getenv("OUT_DIR"), "/")
env.RepoDir = os.Getenv("ANDROID_BUILD_TOP")
env.ClangToolsRoot = os.Getenv("PREBUILTS_CLANG_TOOLS_ROOT")
flag.Var(&env.LunchTarget, "lunch_target", "The lunch target to query")
@@ -95,12 +93,13 @@
return
}
+ var ccFiles, javaFiles []string
for _, f := range files {
switch {
case strings.HasSuffix(f, ".java") || strings.HasSuffix(f, ".kt"):
- env.JavaFiles = append(env.JavaFiles, f)
+ javaFiles = append(javaFiles, f)
case strings.HasSuffix(f, ".cc") || strings.HasSuffix(f, ".cpp") || strings.HasSuffix(f, ".h"):
- env.CcFiles = append(env.CcFiles, f)
+ ccFiles = append(ccFiles, f)
default:
log.Printf("File %q is supported - will be skipped.", f)
}
@@ -110,28 +109,54 @@
// TODO(michaelmerg): Figure out if module_bp_java_deps.json and compile_commands.json is outdated.
runMake(ctx, env, "nothing")
- javaModules, javaFileToModuleMap, err := loadJavaModules(&env)
+ javaModules, err := loadJavaModules(env)
if err != nil {
log.Printf("Failed to load java modules: %v", err)
}
- toMake := getJavaTargets(javaFileToModuleMap)
- ccTargets, status := getCCTargets(ctx, &env)
- if status != nil && status.Code != pb.Status_OK {
- log.Fatalf("Failed to query cc targets: %v", *status.Message)
- }
- toMake = append(toMake, ccTargets...)
- fmt.Fprintf(os.Stderr, "Running make for modules: %v\n", strings.Join(toMake, ", "))
- if err := runMake(ctx, env, toMake...); err != nil {
- log.Printf("Building deps failed: %v", err)
+ var targets []string
+ javaTargetsByFile := findJavaModules(javaFiles, javaModules)
+ for _, t := range javaTargetsByFile {
+ targets = append(targets, t)
}
- res := getJavaInputs(&env, javaModules, javaFileToModuleMap)
- ccAnalysis := getCCInputs(ctx, &env)
- proto.Merge(res, ccAnalysis)
+ ccTargets, err := getCCTargets(ctx, env, ccFiles)
+ if err != nil {
+ log.Fatalf("Failed to query cc targets: %v", err)
+ }
+ targets = append(targets, ccTargets...)
+ if len(targets) == 0 {
+ fmt.Println("No targets found.")
+ os.Exit(1)
+ return
+ }
- res.BuildArtifactRoot = env.OutDir
- data, err := proto.Marshal(res)
+ fmt.Fprintf(os.Stderr, "Running make for modules: %v\n", strings.Join(targets, ", "))
+ if err := runMake(ctx, env, targets...); err != nil {
+ log.Printf("Building modules failed: %v", err)
+ }
+
+ var analysis pb.IdeAnalysis
+ results, units := getJavaInputs(env, javaTargetsByFile, javaModules)
+ analysis.Results = results
+ analysis.Units = units
+ if err != nil && analysis.Error == nil {
+ analysis.Error = &pb.AnalysisError{
+ ErrorMessage: err.Error(),
+ }
+ }
+
+ results, units, err = getCCInputs(ctx, env, ccFiles)
+ analysis.Results = append(analysis.Results, results...)
+ analysis.Units = append(analysis.Units, units...)
+ if err != nil && analysis.Error == nil {
+ analysis.Error = &pb.AnalysisError{
+ ErrorMessage: err.Error(),
+ }
+ }
+
+ analysis.BuildOutDir = env.OutDir
+ data, err := proto.Marshal(&analysis)
if err != nil {
log.Fatalf("Failed to marshal result proto: %v", err)
}
@@ -141,22 +166,22 @@
log.Fatalf("Failed to write result proto: %v", err)
}
- for _, s := range res.Sources {
- fmt.Fprintf(os.Stderr, "%s: %v (Deps: %d, Generated: %d)\n", s.GetPath(), s.GetStatus(), len(s.GetDeps()), len(s.GetGenerated()))
+ for _, r := range analysis.Results {
+ fmt.Fprintf(os.Stderr, "%s: %+v\n", r.GetSourceFilePath(), r.GetStatus())
}
}
-func repoState(env *Env) *pb.RepoState {
+func repoState(env Env, filePaths []string) *apb.RepoState {
const compDbPath = "soong/development/ide/compdb/compile_commands.json"
- return &pb.RepoState{
+ return &apb.RepoState{
RepoDir: env.RepoDir,
- ActiveFilePath: env.CcFiles,
+ ActiveFilePath: filePaths,
OutDir: env.OutDir,
CompDbPath: path.Join(env.OutDir, compDbPath),
}
}
-func runCCanalyzer(ctx context.Context, env *Env, mode string, in []byte) ([]byte, error) {
+func runCCanalyzer(ctx context.Context, env Env, mode string, in []byte) ([]byte, error) {
ccAnalyzerPath := path.Join(env.ClangToolsRoot, "bin/ide_query_cc_analyzer")
outBuffer := new(bytes.Buffer)
@@ -176,127 +201,205 @@
}
// Execute cc_analyzer and get all the targets that needs to be build for analyzing files.
-func getCCTargets(ctx context.Context, env *Env) ([]string, *pb.Status) {
- state := repoState(env)
- bytes, err := proto.Marshal(state)
+func getCCTargets(ctx context.Context, env Env, filePaths []string) ([]string, error) {
+ state, err := proto.Marshal(repoState(env, filePaths))
if err != nil {
log.Fatalln("Failed to serialize state:", err)
}
- resp := new(pb.DepsResponse)
- result, err := runCCanalyzer(ctx, env, "deps", bytes)
- if marshal_err := proto.Unmarshal(result, resp); marshal_err != nil {
- return nil, &pb.Status{
- Code: pb.Status_FAILURE,
- Message: proto.String("Malformed response from cc_analyzer: " + marshal_err.Error()),
- }
+ resp := new(apb.DepsResponse)
+ result, err := runCCanalyzer(ctx, env, "deps", state)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := proto.Unmarshal(result, resp); err != nil {
+ return nil, fmt.Errorf("malformed response from cc_analyzer: %v", err)
}
var targets []string
- if resp.Status != nil && resp.Status.Code != pb.Status_OK {
- return targets, resp.Status
+ if resp.Status != nil && resp.Status.Code != apb.Status_OK {
+ return targets, fmt.Errorf("cc_analyzer failed: %v", resp.Status.Message)
}
+
for _, deps := range resp.Deps {
targets = append(targets, deps.BuildTarget...)
}
-
- status := &pb.Status{Code: pb.Status_OK}
- if err != nil {
- status = &pb.Status{
- Code: pb.Status_FAILURE,
- Message: proto.String(err.Error()),
- }
- }
- return targets, status
+ return targets, nil
}
-func getCCInputs(ctx context.Context, env *Env) *pb.IdeAnalysis {
- state := repoState(env)
- bytes, err := proto.Marshal(state)
+func getCCInputs(ctx context.Context, env Env, filePaths []string) ([]*pb.AnalysisResult, []*pb.BuildableUnit, error) {
+ state, err := proto.Marshal(repoState(env, filePaths))
if err != nil {
log.Fatalln("Failed to serialize state:", err)
}
- resp := new(pb.IdeAnalysis)
- result, err := runCCanalyzer(ctx, env, "inputs", bytes)
- if marshal_err := proto.Unmarshal(result, resp); marshal_err != nil {
- resp.Status = &pb.Status{
- Code: pb.Status_FAILURE,
- Message: proto.String("Malformed response from cc_analyzer: " + marshal_err.Error()),
- }
- return resp
+ resp := new(apb.IdeAnalysis)
+ result, err := runCCanalyzer(ctx, env, "inputs", state)
+ if err != nil {
+ return nil, nil, fmt.Errorf("cc_analyzer failed:", err)
+ }
+ if err := proto.Unmarshal(result, resp); err != nil {
+ return nil, nil, fmt.Errorf("malformed response from cc_analyzer: %v", err)
+ }
+ if resp.Status != nil && resp.Status.Code != apb.Status_OK {
+ return nil, nil, fmt.Errorf("cc_analyzer failed: %v", resp.Status.Message)
}
- if err != nil && (resp.Status == nil || resp.Status.Code == pb.Status_OK) {
- resp.Status = &pb.Status{
- Code: pb.Status_FAILURE,
- Message: proto.String(err.Error()),
+ var results []*pb.AnalysisResult
+ var units []*pb.BuildableUnit
+ for _, s := range resp.Sources {
+ status := &pb.AnalysisResult_Status{
+ Code: pb.AnalysisResult_Status_CODE_OK,
}
- }
- return resp
-}
-
-func getJavaTargets(javaFileToModuleMap map[string]*javaModule) []string {
- var targets []string
- for _, m := range javaFileToModuleMap {
- targets = append(targets, m.Name)
- }
- return targets
-}
-
-func getJavaInputs(env *Env, javaModules map[string]*javaModule, javaFileToModuleMap map[string]*javaModule) *pb.IdeAnalysis {
- var sources []*pb.SourceFile
- type depsAndGenerated struct {
- Deps []string
- Generated []*pb.GeneratedFile
- }
- moduleToDeps := make(map[string]*depsAndGenerated)
- for _, f := range env.JavaFiles {
- file := &pb.SourceFile{
- Path: f,
- }
- sources = append(sources, file)
-
- m := javaFileToModuleMap[f]
- if m == nil {
- file.Status = &pb.Status{
- Code: pb.Status_FAILURE,
- Message: proto.String("File not found in any module."),
- }
- continue
+ if s.GetStatus().GetCode() != apb.Status_OK {
+ status.Code = pb.AnalysisResult_Status_CODE_BUILD_FAILED
+ status.StatusMessage = proto.String(s.GetStatus().GetMessage())
}
- file.Status = &pb.Status{Code: pb.Status_OK}
- if moduleToDeps[m.Name] != nil {
- file.Generated = moduleToDeps[m.Name].Generated
- file.Deps = moduleToDeps[m.Name].Deps
- continue
+ result := &pb.AnalysisResult{
+ SourceFilePath: s.GetPath(),
+ UnitId: s.GetPath(),
+ Status: status,
}
+ results = append(results, result)
- deps := transitiveDeps(m, javaModules)
var generated []*pb.GeneratedFile
- outPrefix := env.OutDir + "/"
- for _, d := range deps {
- if relPath, ok := strings.CutPrefix(d, outPrefix); ok {
- contents, err := os.ReadFile(d)
- if err != nil {
- fmt.Printf("Generated file %q not found - will be skipped.\n", d)
- continue
- }
+ for _, f := range s.Generated {
+ generated = append(generated, &pb.GeneratedFile{
+ Path: f.GetPath(),
+ Contents: f.GetContents(),
+ })
+ }
+ genUnit := &pb.BuildableUnit{
+ Id: "genfiles_for_" + s.GetPath(),
+ SourceFilePaths: s.GetDeps(),
+ GeneratedFiles: generated,
+ }
- generated = append(generated, &pb.GeneratedFile{
- Path: relPath,
- Contents: contents,
- })
+ unit := &pb.BuildableUnit{
+ Id: s.GetPath(),
+ Language: pb.Language_LANGUAGE_CPP,
+ SourceFilePaths: []string{s.GetPath()},
+ CompilerArguments: s.GetCompilerArguments(),
+ DependencyIds: []string{genUnit.GetId()},
+ }
+ units = append(units, unit, genUnit)
+ }
+ return results, units, nil
+}
+
+// findJavaModules tries to find the modules that cover the given file paths.
+// If a file is covered by multiple modules, the first module is returned.
+func findJavaModules(paths []string, modules map[string]*javaModule) map[string]string {
+ ret := make(map[string]string)
+ for name, module := range modules {
+ if strings.HasSuffix(name, ".impl") {
+ continue
+ }
+
+ for i, p := range paths {
+ if slices.Contains(module.Srcs, p) {
+ ret[p] = name
+ paths = append(paths[:i], paths[i+1:]...)
+ break
}
}
- moduleToDeps[m.Name] = &depsAndGenerated{deps, generated}
- file.Generated = generated
- file.Deps = deps
+ if len(paths) == 0 {
+ break
+ }
}
- return &pb.IdeAnalysis{
- Sources: sources,
+ return ret
+}
+
+func getJavaInputs(env Env, modulesByPath map[string]string, modules map[string]*javaModule) ([]*pb.AnalysisResult, []*pb.BuildableUnit) {
+ var results []*pb.AnalysisResult
+ unitsById := make(map[string]*pb.BuildableUnit)
+ for p, moduleName := range modulesByPath {
+ r := &pb.AnalysisResult{
+ SourceFilePath: p,
+ }
+ results = append(results, r)
+
+ m := modules[moduleName]
+ if m == nil {
+ r.Status = &pb.AnalysisResult_Status{
+ Code: pb.AnalysisResult_Status_CODE_NOT_FOUND,
+ StatusMessage: proto.String("File not found in any module."),
+ }
+ continue
+ }
+
+ r.UnitId = moduleName
+ r.Status = &pb.AnalysisResult_Status{Code: pb.AnalysisResult_Status_CODE_OK}
+ if unitsById[r.UnitId] != nil {
+ // File is covered by an already created unit.
+ continue
+ }
+
+ u := &pb.BuildableUnit{
+ Id: moduleName,
+ Language: pb.Language_LANGUAGE_JAVA,
+ SourceFilePaths: m.Srcs,
+ }
+ unitsById[u.Id] = u
+
+ q := list.New()
+ for _, d := range m.Deps {
+ q.PushBack(d)
+ }
+ for q.Len() > 0 {
+ name := q.Remove(q.Front()).(string)
+ mod := modules[name]
+ if mod == nil || unitsById[name] != nil {
+ continue
+ }
+
+ var paths []string
+ paths = append(paths, mod.Srcs...)
+ paths = append(paths, mod.SrcJars...)
+ paths = append(paths, mod.Jars...)
+ unitsById[name] = &pb.BuildableUnit{
+ Id: name,
+ SourceFilePaths: mod.Srcs,
+ GeneratedFiles: genFiles(env, paths),
+ }
+
+ for _, d := range mod.Deps {
+ q.PushBack(d)
+ }
+ }
}
+
+ units := make([]*pb.BuildableUnit, 0, len(unitsById))
+ for _, u := range unitsById {
+ units = append(units, u)
+ }
+ return results, units
+}
+
+// genFiles returns the generated files (paths that start with outDir/) for the
+// given paths. Generated files that do not exist are ignored.
+func genFiles(env Env, paths []string) []*pb.GeneratedFile {
+ prefix := env.OutDir + "/"
+ var ret []*pb.GeneratedFile
+ for _, p := range paths {
+ relPath, ok := strings.CutPrefix(p, prefix)
+ if !ok {
+ continue
+ }
+
+ contents, err := os.ReadFile(path.Join(env.RepoDir, p))
+ if err != nil {
+ continue
+ }
+
+ ret = append(ret, &pb.GeneratedFile{
+ Path: relPath,
+ Contents: contents,
+ })
+ }
+ return ret
}
// runMake runs Soong build for the given modules.
@@ -308,6 +411,7 @@
"TARGET_PRODUCT=" + env.LunchTarget.Product,
"TARGET_RELEASE=" + env.LunchTarget.Release,
"TARGET_BUILD_VARIANT=" + env.LunchTarget.Variant,
+ "TARGET_BUILD_TYPE=release",
"-k",
}
args = append(args, modules...)
@@ -319,7 +423,6 @@
}
type javaModule struct {
- Name string
Path []string `json:"path,omitempty"`
Deps []string `json:"dependencies,omitempty"`
Srcs []string `json:"srcs,omitempty"`
@@ -327,66 +430,23 @@
SrcJars []string `json:"srcjars,omitempty"`
}
-func loadJavaModules(env *Env) (map[string]*javaModule, map[string]*javaModule, error) {
+func loadJavaModules(env Env) (map[string]*javaModule, error) {
javaDepsPath := path.Join(env.RepoDir, env.OutDir, "soong/module_bp_java_deps.json")
data, err := os.ReadFile(javaDepsPath)
if err != nil {
- return nil, nil, err
+ return nil, err
}
- var moduleMapping map[string]*javaModule // module name -> module
- if err = json.Unmarshal(data, &moduleMapping); err != nil {
- return nil, nil, err
+ var ret map[string]*javaModule // module name -> module
+ if err = json.Unmarshal(data, &ret); err != nil {
+ return nil, err
}
- javaModules := make(map[string]*javaModule)
- javaFileToModuleMap := make(map[string]*javaModule)
- for name, module := range moduleMapping {
- if strings.HasSuffix(name, "-jarjar") || strings.HasSuffix(name, ".impl") {
- continue
- }
- module.Name = name
- javaModules[name] = module
- for _, src := range module.Srcs {
- if !slices.Contains(env.JavaFiles, src) {
- // We are only interested in active files.
- continue
- }
- if javaFileToModuleMap[src] != nil {
- // TODO(michaelmerg): Handle the case where a file is covered by multiple modules.
- log.Printf("File %q found in module %q but is already covered by module %q", src, module.Name, javaFileToModuleMap[src].Name)
- continue
- }
- javaFileToModuleMap[src] = module
+ // Add top level java_sdk_library for .impl modules.
+ for name, module := range ret {
+ if striped := strings.TrimSuffix(name, ".impl"); striped != name {
+ ret[striped] = module
}
}
- return javaModules, javaFileToModuleMap, nil
-}
-
-func transitiveDeps(m *javaModule, modules map[string]*javaModule) []string {
- var ret []string
- q := list.New()
- q.PushBack(m.Name)
- seen := make(map[string]bool) // module names -> true
- for q.Len() > 0 {
- name := q.Remove(q.Front()).(string)
- mod := modules[name]
- if mod == nil {
- continue
- }
-
- ret = append(ret, mod.Srcs...)
- ret = append(ret, mod.SrcJars...)
- ret = append(ret, mod.Jars...)
- for _, d := range mod.Deps {
- if seen[d] {
- continue
- }
- seen[d] = true
- q.PushBack(d)
- }
- }
- slices.Sort(ret)
- ret = slices.Compact(ret)
- return ret
+ return ret, nil
}
diff --git a/tools/ide_query/ide_query.sh b/tools/ide_query/ide_query.sh
index 2df48d0..6f9b0c4 100755
--- a/tools/ide_query/ide_query.sh
+++ b/tools/ide_query/ide_query.sh
@@ -32,6 +32,7 @@
;;
esac
+export BUILD_ENV_SEQUENCE_NUMBER=13
export ANDROID_BUILD_TOP=$TOP
export OUT_DIR=${OUT_DIR}
exec "${PREBUILTS_GO_ROOT}/bin/go" "run" "ide_query" "$@"
diff --git a/tools/ide_query/ide_query_proto/ide_query.pb.go b/tools/ide_query/ide_query_proto/ide_query.pb.go
index f3a016d..a190223 100644
--- a/tools/ide_query/ide_query_proto/ide_query.pb.go
+++ b/tools/ide_query/ide_query_proto/ide_query.pb.go
@@ -1,6 +1,21 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.25.0-devel
+// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: ide_query.proto
@@ -20,251 +35,113 @@
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
-type Status_Code int32
+type Language int32
const (
- Status_OK Status_Code = 0
- Status_FAILURE Status_Code = 1
+ Language_LANGUAGE_UNSPECIFIED Language = 0
+ Language_LANGUAGE_JAVA Language = 1 // also includes Kotlin
+ Language_LANGUAGE_CPP Language = 2
)
-// Enum value maps for Status_Code.
+// Enum value maps for Language.
var (
- Status_Code_name = map[int32]string{
- 0: "OK",
- 1: "FAILURE",
+ Language_name = map[int32]string{
+ 0: "LANGUAGE_UNSPECIFIED",
+ 1: "LANGUAGE_JAVA",
+ 2: "LANGUAGE_CPP",
}
- Status_Code_value = map[string]int32{
- "OK": 0,
- "FAILURE": 1,
+ Language_value = map[string]int32{
+ "LANGUAGE_UNSPECIFIED": 0,
+ "LANGUAGE_JAVA": 1,
+ "LANGUAGE_CPP": 2,
}
)
-func (x Status_Code) Enum() *Status_Code {
- p := new(Status_Code)
+func (x Language) Enum() *Language {
+ p := new(Language)
*p = x
return p
}
-func (x Status_Code) String() string {
+func (x Language) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
-func (Status_Code) Descriptor() protoreflect.EnumDescriptor {
+func (Language) Descriptor() protoreflect.EnumDescriptor {
return file_ide_query_proto_enumTypes[0].Descriptor()
}
-func (Status_Code) Type() protoreflect.EnumType {
+func (Language) Type() protoreflect.EnumType {
return &file_ide_query_proto_enumTypes[0]
}
-func (x Status_Code) Number() protoreflect.EnumNumber {
+func (x Language) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
-// Deprecated: Use Status_Code.Descriptor instead.
-func (Status_Code) EnumDescriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{0, 0}
-}
-
-// Indicates the success/failure for analysis.
-type Status struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Code Status_Code `protobuf:"varint,1,opt,name=code,proto3,enum=ide_query.Status_Code" json:"code,omitempty"`
- // Details about the status, might be displayed to user.
- Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"`
-}
-
-func (x *Status) Reset() {
- *x = Status{}
- if protoimpl.UnsafeEnabled {
- mi := &file_ide_query_proto_msgTypes[0]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *Status) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Status) ProtoMessage() {}
-
-func (x *Status) ProtoReflect() protoreflect.Message {
- mi := &file_ide_query_proto_msgTypes[0]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Status.ProtoReflect.Descriptor instead.
-func (*Status) Descriptor() ([]byte, []int) {
+// Deprecated: Use Language.Descriptor instead.
+func (Language) EnumDescriptor() ([]byte, []int) {
return file_ide_query_proto_rawDescGZIP(), []int{0}
}
-func (x *Status) GetCode() Status_Code {
- if x != nil {
- return x.Code
+type AnalysisResult_Status_Code int32
+
+const (
+ AnalysisResult_Status_CODE_UNSPECIFIED AnalysisResult_Status_Code = 0
+ AnalysisResult_Status_CODE_OK AnalysisResult_Status_Code = 1
+ AnalysisResult_Status_CODE_NOT_FOUND AnalysisResult_Status_Code = 2 // no target or module found for the source file.
+ AnalysisResult_Status_CODE_BUILD_FAILED AnalysisResult_Status_Code = 3
+)
+
+// Enum value maps for AnalysisResult_Status_Code.
+var (
+ AnalysisResult_Status_Code_name = map[int32]string{
+ 0: "CODE_UNSPECIFIED",
+ 1: "CODE_OK",
+ 2: "CODE_NOT_FOUND",
+ 3: "CODE_BUILD_FAILED",
}
- return Status_OK
-}
-
-func (x *Status) GetMessage() string {
- if x != nil && x.Message != nil {
- return *x.Message
+ AnalysisResult_Status_Code_value = map[string]int32{
+ "CODE_UNSPECIFIED": 0,
+ "CODE_OK": 1,
+ "CODE_NOT_FOUND": 2,
+ "CODE_BUILD_FAILED": 3,
}
- return ""
+)
+
+func (x AnalysisResult_Status_Code) Enum() *AnalysisResult_Status_Code {
+ p := new(AnalysisResult_Status_Code)
+ *p = x
+ return p
}
-// Represents an Android checkout on user's workstation.
-type RepoState struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- // Absolute path for the checkout in the workstation.
- // e.g. /home/user/work/android/
- RepoDir string `protobuf:"bytes,1,opt,name=repo_dir,json=repoDir,proto3" json:"repo_dir,omitempty"`
- // Relative to repo_dir.
- ActiveFilePath []string `protobuf:"bytes,2,rep,name=active_file_path,json=activeFilePath,proto3" json:"active_file_path,omitempty"`
- // Repository relative path to output directory in workstation.
- OutDir string `protobuf:"bytes,3,opt,name=out_dir,json=outDir,proto3" json:"out_dir,omitempty"`
- // Repository relative path to compile_commands.json in workstation.
- CompDbPath string `protobuf:"bytes,4,opt,name=comp_db_path,json=compDbPath,proto3" json:"comp_db_path,omitempty"`
+func (x AnalysisResult_Status_Code) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
-func (x *RepoState) Reset() {
- *x = RepoState{}
- if protoimpl.UnsafeEnabled {
- mi := &file_ide_query_proto_msgTypes[1]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
+func (AnalysisResult_Status_Code) Descriptor() protoreflect.EnumDescriptor {
+ return file_ide_query_proto_enumTypes[1].Descriptor()
}
-func (x *RepoState) String() string {
- return protoimpl.X.MessageStringOf(x)
+func (AnalysisResult_Status_Code) Type() protoreflect.EnumType {
+ return &file_ide_query_proto_enumTypes[1]
}
-func (*RepoState) ProtoMessage() {}
-
-func (x *RepoState) ProtoReflect() protoreflect.Message {
- mi := &file_ide_query_proto_msgTypes[1]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
+func (x AnalysisResult_Status_Code) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
}
-// Deprecated: Use RepoState.ProtoReflect.Descriptor instead.
-func (*RepoState) Descriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{1}
+// Deprecated: Use AnalysisResult_Status_Code.Descriptor instead.
+func (AnalysisResult_Status_Code) EnumDescriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{3, 0, 0}
}
-func (x *RepoState) GetRepoDir() string {
- if x != nil {
- return x.RepoDir
- }
- return ""
-}
-
-func (x *RepoState) GetActiveFilePath() []string {
- if x != nil {
- return x.ActiveFilePath
- }
- return nil
-}
-
-func (x *RepoState) GetOutDir() string {
- if x != nil {
- return x.OutDir
- }
- return ""
-}
-
-func (x *RepoState) GetCompDbPath() string {
- if x != nil {
- return x.CompDbPath
- }
- return ""
-}
-
-// Provides all the targets that are pre-requisities for running language
-// services on active_file_paths.
-type DepsResponse struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Deps []*DepsResponse_Deps `protobuf:"bytes,1,rep,name=deps,proto3" json:"deps,omitempty"`
- Status *Status `protobuf:"bytes,2,opt,name=status,proto3,oneof" json:"status,omitempty"`
-}
-
-func (x *DepsResponse) Reset() {
- *x = DepsResponse{}
- if protoimpl.UnsafeEnabled {
- mi := &file_ide_query_proto_msgTypes[2]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *DepsResponse) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*DepsResponse) ProtoMessage() {}
-
-func (x *DepsResponse) ProtoReflect() protoreflect.Message {
- mi := &file_ide_query_proto_msgTypes[2]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use DepsResponse.ProtoReflect.Descriptor instead.
-func (*DepsResponse) Descriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *DepsResponse) GetDeps() []*DepsResponse_Deps {
- if x != nil {
- return x.Deps
- }
- return nil
-}
-
-func (x *DepsResponse) GetStatus() *Status {
- if x != nil {
- return x.Status
- }
- return nil
-}
-
-// Returns all the information necessary for providing language services for the
-// active files.
type GeneratedFile struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // Path to the file relative to IdeAnalysis.build_artifact_root.
+ // Path to the file relative to build_out_dir.
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
// The text of the generated file, if not provided contents will be read
// from the path above in user's workstation.
@@ -274,7 +151,7 @@
func (x *GeneratedFile) Reset() {
*x = GeneratedFile{}
if protoimpl.UnsafeEnabled {
- mi := &file_ide_query_proto_msgTypes[3]
+ mi := &file_ide_query_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -287,7 +164,7 @@
func (*GeneratedFile) ProtoMessage() {}
func (x *GeneratedFile) ProtoReflect() protoreflect.Message {
- mi := &file_ide_query_proto_msgTypes[3]
+ mi := &file_ide_query_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -300,7 +177,7 @@
// Deprecated: Use GeneratedFile.ProtoReflect.Descriptor instead.
func (*GeneratedFile) Descriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{3}
+ return file_ide_query_proto_rawDescGZIP(), []int{0}
}
func (x *GeneratedFile) GetPath() string {
@@ -317,127 +194,29 @@
return nil
}
-type SourceFile struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- // Path to the source file relative to repository root.
- Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
- // Working directory used by the build system. All the relative
- // paths in compiler_arguments should be relative to this path.
- // Relative to repository root.
- WorkingDir string `protobuf:"bytes,2,opt,name=working_dir,json=workingDir,proto3" json:"working_dir,omitempty"`
- // Compiler arguments to compile the source file. If multiple variants
- // of the module being compiled are possible, the query script will choose
- // one.
- CompilerArguments []string `protobuf:"bytes,3,rep,name=compiler_arguments,json=compilerArguments,proto3" json:"compiler_arguments,omitempty"`
- // Any generated files that are used in compiling the file.
- Generated []*GeneratedFile `protobuf:"bytes,4,rep,name=generated,proto3" json:"generated,omitempty"`
- // Paths to all of the sources, like build files, code generators,
- // proto files etc. that were used during analysis. Used to figure
- // out when a set of build artifacts are stale and the query tool
- // must be re-run.
- // Relative to repository root.
- Deps []string `protobuf:"bytes,5,rep,name=deps,proto3" json:"deps,omitempty"`
- // Represents analysis status for this particular file. e.g. not part
- // of the build graph.
- Status *Status `protobuf:"bytes,6,opt,name=status,proto3,oneof" json:"status,omitempty"`
-}
-
-func (x *SourceFile) Reset() {
- *x = SourceFile{}
- if protoimpl.UnsafeEnabled {
- mi := &file_ide_query_proto_msgTypes[4]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *SourceFile) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*SourceFile) ProtoMessage() {}
-
-func (x *SourceFile) ProtoReflect() protoreflect.Message {
- mi := &file_ide_query_proto_msgTypes[4]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use SourceFile.ProtoReflect.Descriptor instead.
-func (*SourceFile) Descriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{4}
-}
-
-func (x *SourceFile) GetPath() string {
- if x != nil {
- return x.Path
- }
- return ""
-}
-
-func (x *SourceFile) GetWorkingDir() string {
- if x != nil {
- return x.WorkingDir
- }
- return ""
-}
-
-func (x *SourceFile) GetCompilerArguments() []string {
- if x != nil {
- return x.CompilerArguments
- }
- return nil
-}
-
-func (x *SourceFile) GetGenerated() []*GeneratedFile {
- if x != nil {
- return x.Generated
- }
- return nil
-}
-
-func (x *SourceFile) GetDeps() []string {
- if x != nil {
- return x.Deps
- }
- return nil
-}
-
-func (x *SourceFile) GetStatus() *Status {
- if x != nil {
- return x.Status
- }
- return nil
-}
-
type IdeAnalysis struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // Path relative to repository root, containing all the artifacts
- // generated by the build system. GeneratedFile.path are always
- // relative to this directory.
- BuildArtifactRoot string `protobuf:"bytes,1,opt,name=build_artifact_root,json=buildArtifactRoot,proto3" json:"build_artifact_root,omitempty"`
- Sources []*SourceFile `protobuf:"bytes,2,rep,name=sources,proto3" json:"sources,omitempty"`
- // Status representing overall analysis.
- // Should fail only when no analysis can be performed.
- Status *Status `protobuf:"bytes,3,opt,name=status,proto3,oneof" json:"status,omitempty"`
+ // Directory that contains build outputs generated by the build system.
+ // Relative to repository root.
+ BuildOutDir string `protobuf:"bytes,1,opt,name=build_out_dir,json=buildOutDir,proto3" json:"build_out_dir,omitempty"`
+ // Working directory used by the build system.
+ // Relative to repository root.
+ WorkingDir string `protobuf:"bytes,4,opt,name=working_dir,json=workingDir,proto3" json:"working_dir,omitempty"`
+ // Only set if the whole query failed.
+ Error *AnalysisError `protobuf:"bytes,5,opt,name=error,proto3,oneof" json:"error,omitempty"`
+ // List of results, one per queried file.
+ Results []*AnalysisResult `protobuf:"bytes,6,rep,name=results,proto3" json:"results,omitempty"`
+ // List of buildable units directly or indirectly references by the results.
+ Units []*BuildableUnit `protobuf:"bytes,7,rep,name=units,proto3" json:"units,omitempty"`
}
func (x *IdeAnalysis) Reset() {
*x = IdeAnalysis{}
if protoimpl.UnsafeEnabled {
- mi := &file_ide_query_proto_msgTypes[5]
+ mi := &file_ide_query_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -450,7 +229,7 @@
func (*IdeAnalysis) ProtoMessage() {}
func (x *IdeAnalysis) ProtoReflect() protoreflect.Message {
- mi := &file_ide_query_proto_msgTypes[5]
+ mi := &file_ide_query_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -463,45 +242,345 @@
// Deprecated: Use IdeAnalysis.ProtoReflect.Descriptor instead.
func (*IdeAnalysis) Descriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{5}
+ return file_ide_query_proto_rawDescGZIP(), []int{1}
}
-func (x *IdeAnalysis) GetBuildArtifactRoot() string {
+func (x *IdeAnalysis) GetBuildOutDir() string {
if x != nil {
- return x.BuildArtifactRoot
+ return x.BuildOutDir
}
return ""
}
-func (x *IdeAnalysis) GetSources() []*SourceFile {
+func (x *IdeAnalysis) GetWorkingDir() string {
if x != nil {
- return x.Sources
+ return x.WorkingDir
+ }
+ return ""
+}
+
+func (x *IdeAnalysis) GetError() *AnalysisError {
+ if x != nil {
+ return x.Error
}
return nil
}
-func (x *IdeAnalysis) GetStatus() *Status {
+func (x *IdeAnalysis) GetResults() []*AnalysisResult {
+ if x != nil {
+ return x.Results
+ }
+ return nil
+}
+
+func (x *IdeAnalysis) GetUnits() []*BuildableUnit {
+ if x != nil {
+ return x.Units
+ }
+ return nil
+}
+
+type AnalysisError struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Human readable error message.
+ ErrorMessage string `protobuf:"bytes,1,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
+}
+
+func (x *AnalysisError) Reset() {
+ *x = AnalysisError{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ide_query_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AnalysisError) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AnalysisError) ProtoMessage() {}
+
+func (x *AnalysisError) ProtoReflect() protoreflect.Message {
+ mi := &file_ide_query_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AnalysisError.ProtoReflect.Descriptor instead.
+func (*AnalysisError) Descriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *AnalysisError) GetErrorMessage() string {
+ if x != nil {
+ return x.ErrorMessage
+ }
+ return ""
+}
+
+type AnalysisResult struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Path to the source file that was queried, relative to repository root.
+ SourceFilePath string `protobuf:"bytes,1,opt,name=source_file_path,json=sourceFilePath,proto3" json:"source_file_path,omitempty"`
+ // Represents status for this result. e.g. not part of the build graph.
+ Status *AnalysisResult_Status `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
+ // ID of buildable unit that contains the source file.
+ // The ide_query script can choose the most relevant unit from multiple
+ // options.
+ UnitId string `protobuf:"bytes,3,opt,name=unit_id,json=unitId,proto3" json:"unit_id,omitempty"`
+ // Invalidation rule to check if the result is still valid.
+ Invalidation *Invalidation `protobuf:"bytes,4,opt,name=invalidation,proto3" json:"invalidation,omitempty"`
+}
+
+func (x *AnalysisResult) Reset() {
+ *x = AnalysisResult{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ide_query_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AnalysisResult) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AnalysisResult) ProtoMessage() {}
+
+func (x *AnalysisResult) ProtoReflect() protoreflect.Message {
+ mi := &file_ide_query_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AnalysisResult.ProtoReflect.Descriptor instead.
+func (*AnalysisResult) Descriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *AnalysisResult) GetSourceFilePath() string {
+ if x != nil {
+ return x.SourceFilePath
+ }
+ return ""
+}
+
+func (x *AnalysisResult) GetStatus() *AnalysisResult_Status {
if x != nil {
return x.Status
}
return nil
}
-// Build dependencies of a source file for providing language services.
-type DepsResponse_Deps struct {
+func (x *AnalysisResult) GetUnitId() string {
+ if x != nil {
+ return x.UnitId
+ }
+ return ""
+}
+
+func (x *AnalysisResult) GetInvalidation() *Invalidation {
+ if x != nil {
+ return x.Invalidation
+ }
+ return nil
+}
+
+type BuildableUnit struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // Relative to repo_dir.
- SourceFile string `protobuf:"bytes,1,opt,name=source_file,json=sourceFile,proto3" json:"source_file,omitempty"`
- // Build target to execute for generating dep.
- BuildTarget []string `protobuf:"bytes,2,rep,name=build_target,json=buildTarget,proto3" json:"build_target,omitempty"`
- Status *Status `protobuf:"bytes,3,opt,name=status,proto3,oneof" json:"status,omitempty"`
+ // Unique identifier of the buildable unit.
+ //
+ // Examples:
+ // - Java: module or target name, e.g. "framework-bluetooth" or
+ // "//third_party/hamcrest:hamcrest_java"
+ // - C++: source file, e.g. "path/to/file.cc"
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+ // Language of the unit.
+ // Required for buildable units directly referenced by the AnalysisResult,
+ // e.g. the unit associated with the compilation stage for the source file.
+ Language Language `protobuf:"varint,2,opt,name=language,proto3,enum=ide_query.Language" json:"language,omitempty"`
+ // Source files that are part of this unit.
+ // Path to the file relative to working_dir.
+ SourceFilePaths []string `protobuf:"bytes,3,rep,name=source_file_paths,json=sourceFilePaths,proto3" json:"source_file_paths,omitempty"`
+ // Compiler arguments to compile the source files.
+ CompilerArguments []string `protobuf:"bytes,4,rep,name=compiler_arguments,json=compilerArguments,proto3" json:"compiler_arguments,omitempty"`
+ // List of generated files produced by this unit.
+ GeneratedFiles []*GeneratedFile `protobuf:"bytes,5,rep,name=generated_files,json=generatedFiles,proto3" json:"generated_files,omitempty"`
+ // List of other BuildableUnits this unit depend on.
+ DependencyIds []string `protobuf:"bytes,6,rep,name=dependency_ids,json=dependencyIds,proto3" json:"dependency_ids,omitempty"`
}
-func (x *DepsResponse_Deps) Reset() {
- *x = DepsResponse_Deps{}
+func (x *BuildableUnit) Reset() {
+ *x = BuildableUnit{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ide_query_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BuildableUnit) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BuildableUnit) ProtoMessage() {}
+
+func (x *BuildableUnit) ProtoReflect() protoreflect.Message {
+ mi := &file_ide_query_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BuildableUnit.ProtoReflect.Descriptor instead.
+func (*BuildableUnit) Descriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *BuildableUnit) GetId() string {
+ if x != nil {
+ return x.Id
+ }
+ return ""
+}
+
+func (x *BuildableUnit) GetLanguage() Language {
+ if x != nil {
+ return x.Language
+ }
+ return Language_LANGUAGE_UNSPECIFIED
+}
+
+func (x *BuildableUnit) GetSourceFilePaths() []string {
+ if x != nil {
+ return x.SourceFilePaths
+ }
+ return nil
+}
+
+func (x *BuildableUnit) GetCompilerArguments() []string {
+ if x != nil {
+ return x.CompilerArguments
+ }
+ return nil
+}
+
+func (x *BuildableUnit) GetGeneratedFiles() []*GeneratedFile {
+ if x != nil {
+ return x.GeneratedFiles
+ }
+ return nil
+}
+
+func (x *BuildableUnit) GetDependencyIds() []string {
+ if x != nil {
+ return x.DependencyIds
+ }
+ return nil
+}
+
+// Invalidation rule to check if the result is still valid.
+// This should contain files/dirs that are not directly part of the build graph
+// but still affect the result. For example BUILD files, directory to the
+// toolchain or config files etc.
+type Invalidation struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // If any of these files change the result may become invalid.
+ // Path to the file relative to repository root.
+ FilePaths []string `protobuf:"bytes,1,rep,name=file_paths,json=filePaths,proto3" json:"file_paths,omitempty"`
+ // If any of these rules match a changed file the result may become invalid.
+ Wildcards []*Invalidation_Wildcard `protobuf:"bytes,4,rep,name=wildcards,proto3" json:"wildcards,omitempty"`
+}
+
+func (x *Invalidation) Reset() {
+ *x = Invalidation{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ide_query_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Invalidation) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Invalidation) ProtoMessage() {}
+
+func (x *Invalidation) ProtoReflect() protoreflect.Message {
+ mi := &file_ide_query_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Invalidation.ProtoReflect.Descriptor instead.
+func (*Invalidation) Descriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *Invalidation) GetFilePaths() []string {
+ if x != nil {
+ return x.FilePaths
+ }
+ return nil
+}
+
+func (x *Invalidation) GetWildcards() []*Invalidation_Wildcard {
+ if x != nil {
+ return x.Wildcards
+ }
+ return nil
+}
+
+// Indicates the success/failure for the query.
+type AnalysisResult_Status struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Code AnalysisResult_Status_Code `protobuf:"varint,1,opt,name=code,proto3,enum=ide_query.AnalysisResult_Status_Code" json:"code,omitempty"`
+ // Details about the status, might be displayed to user.
+ StatusMessage *string `protobuf:"bytes,2,opt,name=status_message,json=statusMessage,proto3,oneof" json:"status_message,omitempty"`
+}
+
+func (x *AnalysisResult_Status) Reset() {
+ *x = AnalysisResult_Status{}
if protoimpl.UnsafeEnabled {
mi := &file_ide_query_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -509,13 +588,13 @@
}
}
-func (x *DepsResponse_Deps) String() string {
+func (x *AnalysisResult_Status) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*DepsResponse_Deps) ProtoMessage() {}
+func (*AnalysisResult_Status) ProtoMessage() {}
-func (x *DepsResponse_Deps) ProtoReflect() protoreflect.Message {
+func (x *AnalysisResult_Status) ProtoReflect() protoreflect.Message {
mi := &file_ide_query_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -527,104 +606,190 @@
return mi.MessageOf(x)
}
-// Deprecated: Use DepsResponse_Deps.ProtoReflect.Descriptor instead.
-func (*DepsResponse_Deps) Descriptor() ([]byte, []int) {
- return file_ide_query_proto_rawDescGZIP(), []int{2, 0}
+// Deprecated: Use AnalysisResult_Status.ProtoReflect.Descriptor instead.
+func (*AnalysisResult_Status) Descriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{3, 0}
}
-func (x *DepsResponse_Deps) GetSourceFile() string {
+func (x *AnalysisResult_Status) GetCode() AnalysisResult_Status_Code {
if x != nil {
- return x.SourceFile
+ return x.Code
+ }
+ return AnalysisResult_Status_CODE_UNSPECIFIED
+}
+
+func (x *AnalysisResult_Status) GetStatusMessage() string {
+ if x != nil && x.StatusMessage != nil {
+ return *x.StatusMessage
}
return ""
}
-func (x *DepsResponse_Deps) GetBuildTarget() []string {
- if x != nil {
- return x.BuildTarget
- }
- return nil
+type Invalidation_Wildcard struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Prefix of the file path (e.g. "path/to/")
+ Prefix *string `protobuf:"bytes,1,opt,name=prefix,proto3,oneof" json:"prefix,omitempty"`
+ // Suffix of the file path (e.g. "Android.bp")
+ Suffix *string `protobuf:"bytes,2,opt,name=suffix,proto3,oneof" json:"suffix,omitempty"`
+ // If false, the part of the path between the given `prefix` and `suffix`
+ // should not contain directory separators ('/').
+ CanCrossFolder *bool `protobuf:"varint,3,opt,name=can_cross_folder,json=canCrossFolder,proto3,oneof" json:"can_cross_folder,omitempty"`
}
-func (x *DepsResponse_Deps) GetStatus() *Status {
- if x != nil {
- return x.Status
+func (x *Invalidation_Wildcard) Reset() {
+ *x = Invalidation_Wildcard{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ide_query_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
}
- return nil
+}
+
+func (x *Invalidation_Wildcard) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Invalidation_Wildcard) ProtoMessage() {}
+
+func (x *Invalidation_Wildcard) ProtoReflect() protoreflect.Message {
+ mi := &file_ide_query_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Invalidation_Wildcard.ProtoReflect.Descriptor instead.
+func (*Invalidation_Wildcard) Descriptor() ([]byte, []int) {
+ return file_ide_query_proto_rawDescGZIP(), []int{5, 0}
+}
+
+func (x *Invalidation_Wildcard) GetPrefix() string {
+ if x != nil && x.Prefix != nil {
+ return *x.Prefix
+ }
+ return ""
+}
+
+func (x *Invalidation_Wildcard) GetSuffix() string {
+ if x != nil && x.Suffix != nil {
+ return *x.Suffix
+ }
+ return ""
+}
+
+func (x *Invalidation_Wildcard) GetCanCrossFolder() bool {
+ if x != nil && x.CanCrossFolder != nil {
+ return *x.CanCrossFolder
+ }
+ return false
}
var File_ide_query_proto protoreflect.FileDescriptor
var file_ide_query_proto_rawDesc = []byte{
0x0a, 0x0f, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x12, 0x09, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x7c, 0x0a, 0x06,
- 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79,
- 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
- 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01,
- 0x01, 0x22, 0x1b, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10,
- 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x42, 0x0a,
- 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x52,
- 0x65, 0x70, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f,
- 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f,
- 0x44, 0x69, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69,
- 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61,
- 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x17, 0x0a,
- 0x07, 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
- 0x6f, 0x75, 0x74, 0x44, 0x69, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x5f, 0x64,
- 0x62, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
- 0x6d, 0x70, 0x44, 0x62, 0x50, 0x61, 0x74, 0x68, 0x22, 0x83, 0x02, 0x0a, 0x0c, 0x44, 0x65, 0x70,
- 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x64, 0x65, 0x70,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75,
- 0x65, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x2e, 0x44, 0x65, 0x70, 0x73, 0x52, 0x04, 0x64, 0x65, 0x70, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x73,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x69, 0x64,
- 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00,
- 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x85, 0x01, 0x0a, 0x04,
- 0x44, 0x65, 0x70, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66,
- 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74,
- 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x69,
- 0x6c, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71,
- 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x51,
- 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12,
- 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70,
- 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
- 0x73, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
- 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65,
- 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x5f,
- 0x64, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69,
- 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
- 0x72, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
- 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x41, 0x72, 0x67, 0x75, 0x6d,
- 0x65, 0x6e, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
- 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75,
- 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c,
- 0x65, 0x52, 0x09, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04,
- 0x64, 0x65, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x70, 0x73,
- 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x11, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01,
- 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x0b,
- 0x49, 0x64, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x62,
- 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x72, 0x6f,
- 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x41,
- 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x69,
- 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46,
- 0x69, 0x6c, 0x65, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x06,
- 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x69,
- 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48,
- 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07,
- 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x1b, 0x5a, 0x19, 0x69, 0x64, 0x65, 0x5f, 0x71,
- 0x75, 0x65, 0x72, 0x79, 0x2f, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x6f, 0x12, 0x09, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x51, 0x0a, 0x0d,
+ 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a,
+ 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
+ 0x68, 0x12, 0x1f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x88,
+ 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22,
+ 0x82, 0x02, 0x0a, 0x0b, 0x49, 0x64, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x12,
+ 0x22, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x72,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4f, 0x75, 0x74,
+ 0x44, 0x69, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x64,
+ 0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e,
+ 0x67, 0x44, 0x69, 0x72, 0x12, 0x33, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e,
+ 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52,
+ 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x07, 0x72, 0x65, 0x73,
+ 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x69, 0x64, 0x65,
+ 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52,
+ 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2e,
+ 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e,
+ 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x61,
+ 0x62, 0x6c, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x42, 0x08,
+ 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04,
+ 0x08, 0x03, 0x10, 0x04, 0x22, 0x34, 0x0a, 0x0d, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
+ 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72,
+ 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa5, 0x03, 0x0a, 0x0e, 0x41,
+ 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x28, 0x0a,
+ 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74,
+ 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46,
+ 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75,
+ 0x65, 0x72, 0x79, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x75,
+ 0x6c, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x6e, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x06, 0x75, 0x6e, 0x69, 0x74, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0c, 0x69, 0x6e,
+ 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x17, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x76,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c,
+ 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xd8, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x12, 0x39, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x25, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x41, 0x6e, 0x61,
+ 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a,
+ 0x0e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x22, 0x54, 0x0a, 0x04, 0x43, 0x6f, 0x64,
+ 0x65, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+ 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x44, 0x45, 0x5f,
+ 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x54,
+ 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x44, 0x45,
+ 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x42,
+ 0x11, 0x0a, 0x0f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x22, 0x95, 0x02, 0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x61, 0x62, 0x6c, 0x65,
+ 0x55, 0x6e, 0x69, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65,
+ 0x72, 0x79, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6c, 0x61, 0x6e,
+ 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
+ 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09,
+ 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68,
+ 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x61, 0x72,
+ 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x63,
+ 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+ 0x12, 0x41, 0x0a, 0x0f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69,
+ 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, 0x64, 0x65, 0x5f,
+ 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46,
+ 0x69, 0x6c, 0x65, 0x52, 0x0e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69,
+ 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63,
+ 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x65, 0x70,
+ 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x49, 0x64, 0x73, 0x22, 0x8e, 0x02, 0x0a, 0x0c, 0x49,
+ 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x66,
+ 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x09, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x3e, 0x0a, 0x09, 0x77, 0x69,
+ 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e,
+ 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69,
+ 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x57, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x52,
+ 0x09, 0x77, 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x73, 0x1a, 0x9e, 0x01, 0x0a, 0x08, 0x57,
+ 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x12, 0x1b, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69,
+ 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69,
+ 0x78, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x88, 0x01,
+ 0x01, 0x12, 0x2d, 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x66,
+ 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x0e, 0x63,
+ 0x61, 0x6e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x46, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01,
+ 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x42, 0x09, 0x0a, 0x07, 0x5f,
+ 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x63,
+ 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x2a, 0x49, 0x0a, 0x08, 0x4c,
+ 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x41, 0x4e, 0x47, 0x55,
+ 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+ 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x41, 0x4e, 0x47, 0x55, 0x41, 0x47, 0x45, 0x5f, 0x4a, 0x41,
+ 0x56, 0x41, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x41, 0x4e, 0x47, 0x55, 0x41, 0x47, 0x45,
+ 0x5f, 0x43, 0x50, 0x50, 0x10, 0x02, 0x42, 0x1b, 0x5a, 0x19, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75,
+ 0x65, 0x72, 0x79, 0x2f, 0x69, 0x64, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -639,32 +804,35 @@
return file_ide_query_proto_rawDescData
}
-var file_ide_query_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_ide_query_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_ide_query_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_ide_query_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_ide_query_proto_goTypes = []interface{}{
- (Status_Code)(0), // 0: ide_query.Status.Code
- (*Status)(nil), // 1: ide_query.Status
- (*RepoState)(nil), // 2: ide_query.RepoState
- (*DepsResponse)(nil), // 3: ide_query.DepsResponse
- (*GeneratedFile)(nil), // 4: ide_query.GeneratedFile
- (*SourceFile)(nil), // 5: ide_query.SourceFile
- (*IdeAnalysis)(nil), // 6: ide_query.IdeAnalysis
- (*DepsResponse_Deps)(nil), // 7: ide_query.DepsResponse.Deps
+ (Language)(0), // 0: ide_query.Language
+ (AnalysisResult_Status_Code)(0), // 1: ide_query.AnalysisResult.Status.Code
+ (*GeneratedFile)(nil), // 2: ide_query.GeneratedFile
+ (*IdeAnalysis)(nil), // 3: ide_query.IdeAnalysis
+ (*AnalysisError)(nil), // 4: ide_query.AnalysisError
+ (*AnalysisResult)(nil), // 5: ide_query.AnalysisResult
+ (*BuildableUnit)(nil), // 6: ide_query.BuildableUnit
+ (*Invalidation)(nil), // 7: ide_query.Invalidation
+ (*AnalysisResult_Status)(nil), // 8: ide_query.AnalysisResult.Status
+ (*Invalidation_Wildcard)(nil), // 9: ide_query.Invalidation.Wildcard
}
var file_ide_query_proto_depIdxs = []int32{
- 0, // 0: ide_query.Status.code:type_name -> ide_query.Status.Code
- 7, // 1: ide_query.DepsResponse.deps:type_name -> ide_query.DepsResponse.Deps
- 1, // 2: ide_query.DepsResponse.status:type_name -> ide_query.Status
- 4, // 3: ide_query.SourceFile.generated:type_name -> ide_query.GeneratedFile
- 1, // 4: ide_query.SourceFile.status:type_name -> ide_query.Status
- 5, // 5: ide_query.IdeAnalysis.sources:type_name -> ide_query.SourceFile
- 1, // 6: ide_query.IdeAnalysis.status:type_name -> ide_query.Status
- 1, // 7: ide_query.DepsResponse.Deps.status:type_name -> ide_query.Status
- 8, // [8:8] is the sub-list for method output_type
- 8, // [8:8] is the sub-list for method input_type
- 8, // [8:8] is the sub-list for extension type_name
- 8, // [8:8] is the sub-list for extension extendee
- 0, // [0:8] is the sub-list for field type_name
+ 4, // 0: ide_query.IdeAnalysis.error:type_name -> ide_query.AnalysisError
+ 5, // 1: ide_query.IdeAnalysis.results:type_name -> ide_query.AnalysisResult
+ 6, // 2: ide_query.IdeAnalysis.units:type_name -> ide_query.BuildableUnit
+ 8, // 3: ide_query.AnalysisResult.status:type_name -> ide_query.AnalysisResult.Status
+ 7, // 4: ide_query.AnalysisResult.invalidation:type_name -> ide_query.Invalidation
+ 0, // 5: ide_query.BuildableUnit.language:type_name -> ide_query.Language
+ 2, // 6: ide_query.BuildableUnit.generated_files:type_name -> ide_query.GeneratedFile
+ 9, // 7: ide_query.Invalidation.wildcards:type_name -> ide_query.Invalidation.Wildcard
+ 1, // 8: ide_query.AnalysisResult.Status.code:type_name -> ide_query.AnalysisResult.Status.Code
+ 9, // [9:9] is the sub-list for method output_type
+ 9, // [9:9] is the sub-list for method input_type
+ 9, // [9:9] is the sub-list for extension type_name
+ 9, // [9:9] is the sub-list for extension extendee
+ 0, // [0:9] is the sub-list for field type_name
}
func init() { file_ide_query_proto_init() }
@@ -674,42 +842,6 @@
}
if !protoimpl.UnsafeEnabled {
file_ide_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Status); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_ide_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*RepoState); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_ide_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DepsResponse); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_ide_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GeneratedFile); i {
case 0:
return &v.state
@@ -721,19 +853,7 @@
return nil
}
}
- file_ide_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*SourceFile); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_ide_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ file_ide_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IdeAnalysis); i {
case 0:
return &v.state
@@ -745,8 +865,68 @@
return nil
}
}
+ file_ide_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AnalysisError); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ide_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AnalysisResult); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ide_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BuildableUnit); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ide_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Invalidation); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
file_ide_query_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DepsResponse_Deps); i {
+ switch v := v.(*AnalysisResult_Status); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ide_query_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Invalidation_Wildcard); i {
case 0:
return &v.state
case 1:
@@ -759,18 +939,16 @@
}
}
file_ide_query_proto_msgTypes[0].OneofWrappers = []interface{}{}
- file_ide_query_proto_msgTypes[2].OneofWrappers = []interface{}{}
- file_ide_query_proto_msgTypes[3].OneofWrappers = []interface{}{}
- file_ide_query_proto_msgTypes[4].OneofWrappers = []interface{}{}
- file_ide_query_proto_msgTypes[5].OneofWrappers = []interface{}{}
+ file_ide_query_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_ide_query_proto_msgTypes[6].OneofWrappers = []interface{}{}
+ file_ide_query_proto_msgTypes[7].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ide_query_proto_rawDesc,
- NumEnums: 1,
- NumMessages: 7,
+ NumEnums: 2,
+ NumMessages: 8,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/tools/ide_query/ide_query_proto/ide_query.proto b/tools/ide_query/ide_query_proto/ide_query.proto
index 3d7a8e7..13f349c 100644
--- a/tools/ide_query/ide_query_proto/ide_query.proto
+++ b/tools/ide_query/ide_query_proto/ide_query.proto
@@ -16,51 +16,11 @@
syntax = "proto3";
package ide_query;
+
option go_package = "ide_query/ide_query_proto";
-// Indicates the success/failure for analysis.
-message Status {
- enum Code {
- OK = 0;
- FAILURE = 1;
- }
- Code code = 1;
- // Details about the status, might be displayed to user.
- optional string message = 2;
-}
-
-// Represents an Android checkout on user's workstation.
-message RepoState {
- // Absolute path for the checkout in the workstation.
- // e.g. /home/user/work/android/
- string repo_dir = 1;
- // Relative to repo_dir.
- repeated string active_file_path = 2;
- // Repository relative path to output directory in workstation.
- string out_dir = 3;
- // Repository relative path to compile_commands.json in workstation.
- string comp_db_path = 4;
-}
-
-// Provides all the targets that are pre-requisities for running language
-// services on active_file_paths.
-message DepsResponse {
- // Build dependencies of a source file for providing language services.
- message Deps {
- // Relative to repo_dir.
- string source_file = 1;
- // Build target to execute for generating dep.
- repeated string build_target = 2;
- optional Status status = 3;
- }
- repeated Deps deps = 1;
- optional Status status = 2;
-}
-
-// Returns all the information necessary for providing language services for the
-// active files.
message GeneratedFile {
- // Path to the file relative to IdeAnalysis.build_artifact_root.
+ // Path to the file relative to build_out_dir.
string path = 1;
// The text of the generated file, if not provided contents will be read
@@ -68,44 +28,100 @@
optional bytes contents = 2;
}
-message SourceFile {
- // Path to the source file relative to repository root.
- string path = 1;
-
- // Working directory used by the build system. All the relative
- // paths in compiler_arguments should be relative to this path.
- // Relative to repository root.
- string working_dir = 2;
-
- // Compiler arguments to compile the source file. If multiple variants
- // of the module being compiled are possible, the query script will choose
- // one.
- repeated string compiler_arguments = 3;
-
- // Any generated files that are used in compiling the file.
- repeated GeneratedFile generated = 4;
-
- // Paths to all of the sources, like build files, code generators,
- // proto files etc. that were used during analysis. Used to figure
- // out when a set of build artifacts are stale and the query tool
- // must be re-run.
- // Relative to repository root.
- repeated string deps = 5;
-
- // Represents analysis status for this particular file. e.g. not part
- // of the build graph.
- optional Status status = 6;
-}
-
message IdeAnalysis {
- // Path relative to repository root, containing all the artifacts
- // generated by the build system. GeneratedFile.path are always
- // relative to this directory.
- string build_artifact_root = 1;
+ // Directory that contains build outputs generated by the build system.
+ // Relative to repository root.
+ string build_out_dir = 1;
+ // Working directory used by the build system.
+ // Relative to repository root.
+ string working_dir = 4;
+ // Only set if the whole query failed.
+ optional AnalysisError error = 5;
+ // List of results, one per queried file.
+ repeated AnalysisResult results = 6;
+ // List of buildable units directly or indirectly references by the results.
+ repeated BuildableUnit units = 7;
- repeated SourceFile sources = 2;
-
- // Status representing overall analysis.
- // Should fail only when no analysis can be performed.
- optional Status status = 3;
+ reserved 2, 3;
}
+
+message AnalysisError {
+ // Human readable error message.
+ string error_message = 1;
+}
+
+message AnalysisResult {
+ // Path to the source file that was queried, relative to repository root.
+ string source_file_path = 1;
+ // Indicates the success/failure for the query.
+ message Status {
+ enum Code {
+ CODE_UNSPECIFIED = 0;
+ CODE_OK = 1;
+ CODE_NOT_FOUND = 2; // no target or module found for the source file.
+ CODE_BUILD_FAILED = 3;
+ }
+ Code code = 1;
+ // Details about the status, might be displayed to user.
+ optional string status_message = 2;
+ }
+ // Represents status for this result. e.g. not part of the build graph.
+ Status status = 2;
+ // ID of buildable unit that contains the source file.
+ // The ide_query script can choose the most relevant unit from multiple
+ // options.
+ string unit_id = 3;
+ // Invalidation rule to check if the result is still valid.
+ Invalidation invalidation = 4;
+}
+
+enum Language {
+ LANGUAGE_UNSPECIFIED = 0;
+ LANGUAGE_JAVA = 1; // also includes Kotlin
+ LANGUAGE_CPP = 2;
+}
+
+message BuildableUnit {
+ // Unique identifier of the buildable unit.
+ //
+ // Examples:
+ // - Java: module or target name, e.g. "framework-bluetooth" or
+ // "//third_party/hamcrest:hamcrest_java"
+ // - C++: source file, e.g. "path/to/file.cc"
+ string id = 1;
+ // Language of the unit.
+ // Required for buildable units directly referenced by the AnalysisResult,
+ // e.g. the unit associated with the compilation stage for the source file.
+ Language language = 2;
+ // Source files that are part of this unit.
+ // Path to the file relative to working_dir.
+ repeated string source_file_paths = 3;
+ // Compiler arguments to compile the source files.
+ repeated string compiler_arguments = 4;
+ // List of generated files produced by this unit.
+ repeated GeneratedFile generated_files = 5;
+ // List of other BuildableUnits this unit depend on.
+ repeated string dependency_ids = 6;
+}
+
+// Invalidation rule to check if the result is still valid.
+// This should contain files/dirs that are not directly part of the build graph
+// but still affect the result. For example BUILD files, directory to the
+// toolchain or config files etc.
+message Invalidation {
+ // If any of these files change the result may become invalid.
+ // Path to the file relative to repository root.
+ repeated string file_paths = 1;
+
+ message Wildcard {
+ // Prefix of the file path (e.g. "path/to/")
+ optional string prefix = 1;
+ // Suffix of the file path (e.g. "Android.bp")
+ optional string suffix = 2;
+ // If false, the part of the path between the given `prefix` and `suffix`
+ // should not contain directory separators ('/').
+ optional bool can_cross_folder = 3;
+ }
+ // If any of these rules match a changed file the result may become invalid.
+ repeated Wildcard wildcards = 4;
+}
\ No newline at end of file