#include "components/autofill/core/browser/address_suggestion_generator.h"
#include <functional>
#include <string>
#include <vector>
#include "base/check_deref.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/i18n/case_conversion.h"
#include "base/memory/raw_ptr.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/address_data_manager.h"
#include "components/autofill/core/browser/autofill_browser_util.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_granular_filling_utils.h"
#include "components/autofill/core/browser/data_model/autofill_profile.h"
#include "components/autofill/core/browser/data_model/autofill_profile_comparator.h"
#include "components/autofill/core/browser/data_model/borrowed_transliterator.h"
#include "components/autofill/core/browser/field_filling_address_util.h"
#include "components/autofill/core/browser/field_type_utils.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/address_field_parser.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/geo/address_i18n.h"
#include "components/autofill/core/browser/geo/phone_number_i18n.h"
#include "components/autofill/core/browser/metrics/autofill_metrics.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/ui/suggestion.h"
#include "components/autofill/core/browser/ui/suggestion_type.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/grit/components_scaled_resources.h"
#include "components/strings/grit/components_strings.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
#include "ui/native_theme/native_theme.h"
#endif
namespace autofill {
namespace {
constexpr DenseSet<SuggestionType> kGroupFillingSuggestions = …;
Suggestion CreateSeparator() { … }
Suggestion CreateUndoOrClearFormSuggestion() { … }
bool ShouldUseNationalFormatPhoneNumber(FieldType trigger_field_type) { … }
std::u16string GetFormattedPhoneNumber(const AutofillProfile& profile,
const std::string& app_locale,
bool should_use_national_format) { … }
std::pair<size_t, size_t>
GetFirstAddressFieldPositionAndLengthForNonAddressField(
const AutofillProfile& profile,
const std::string& app_locale,
std::u16string_view suggestion_text) { … }
std::u16string GetProfileSuggestionMainTextForNonAddressField(
const AutofillProfile& profile,
const std::string& app_locale) { … }
std::vector<std::u16string> GetProfileSuggestionLabelForNonAddressField(
const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
profiles,
const std::string& app_locale) { … }
std::u16string GetProfileSuggestionMainText(const AutofillProfile& profile,
const std::string& app_locale,
FieldType trigger_field_type) { … }
Suggestion GetEditAddressProfileSuggestion(Suggestion::BackendId backend_id) { … }
Suggestion GetDeleteAddressProfileSuggestion(Suggestion::BackendId backend_id) { … }
Suggestion GetFillFullAddressSuggestion(Suggestion::BackendId backend_id) { … }
Suggestion GetFillFullNameSuggestion(Suggestion::BackendId backend_id) { … }
Suggestion GetFillEverythingFromAddressProfileSuggestion(
Suggestion::BackendId backend_id) { … }
bool AddAddressFieldByFieldSuggestions(
const std::vector<FieldType>& field_types,
const AutofillProfile& profile,
const std::string& app_locale,
std::vector<Suggestion>& suggestions) { … }
bool CheckIfTypeContainsSubtype(FieldType type,
FieldType sub_type,
const AutofillProfile& profile,
const std::string& app_locale) { … }
void AddNameChildSuggestions(FieldTypeGroup trigger_field_type_group,
const AutofillProfile& profile,
const std::string& app_locale,
Suggestion& suggestion) { … }
bool AddAddressLineChildSuggestions(const AutofillProfile& profile,
const std::string& app_locale,
std::vector<Suggestion>& suggestions) { … }
void AddAddressChildSuggestions(FieldTypeGroup trigger_field_type_group,
const AutofillProfile& profile,
const std::string& app_locale,
Suggestion& suggestion) { … }
void AddContactChildSuggestions(FieldType trigger_field_type,
const AutofillProfile& profile,
const std::string& app_locale,
Suggestion& suggestion) { … }
void AddFooterChildSuggestions(const AutofillProfile& profile,
FieldType trigger_field_type,
bool is_off_the_record,
Suggestion& suggestion) { … }
std::u16string GetGranularFillingLabels(SuggestionType suggestion_type) { … }
bool ShouldAddAddressLine1ToSuggestionLabels(FieldType trigger_field_type) { … }
int GetNumberOfMinimalFieldsToShow(FieldType trigger_field_type,
SuggestionType suggestion_type) { … }
std::vector<std::u16string> GetProfileSuggestionLabels(
const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
profiles,
const FieldTypeSet& field_types,
FieldType trigger_field_type,
SuggestionType suggestion_type,
const std::string& app_locale) { … }
std::vector<std::vector<Suggestion::Text>>
CreateSuggestionLabelsWithGranularFillingDetails(
const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
profiles,
const FieldTypeSet& field_types,
SuggestionType suggestion_type,
FieldType trigger_field_type,
const std::string& app_locale) { … }
bool IsValidAddressSuggestionForFieldContents(
std::u16string suggestion_canon,
std::u16string field_contents_canon,
FieldType trigger_field_type) { … }
std::u16string NormalizeForComparisonForType(const std::u16string& text,
FieldType type) { … }
std::optional<Suggestion> GetSuggestionForTestAddresses(
base::span<const AutofillProfile> test_addresses,
const std::string& locale) { … }
std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
DeduplicatedProfilesForSuggestions(
const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
matched_profiles,
FieldType trigger_field_type,
const FieldTypeSet& field_types,
const AutofillProfileComparator& comparator) { … }
std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
GetPrefixMatchedProfiles(const std::vector<const AutofillProfile*>& profiles,
FieldType trigger_field_type,
const std::u16string& raw_field_contents,
const std::u16string& field_contents_canon,
bool field_is_autofilled,
const std::string& app_locale) { … }
void RemoveDisusedSuggestions(
std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>& profiles) { … }
void AddAddressGranularFillingChildSuggestions(FieldType trigger_field_type,
const AutofillProfile& profile,
Suggestion& suggestion,
bool is_off_the_record,
const std::string& app_locale) { … }
std::vector<Suggestion> GetAddressFooterSuggestions(bool is_autofilled) { … }
ProfilesToSuggestOptions GetProfilesToSuggestOptions(
FieldType trigger_field_type,
const std::u16string& trigger_field_contents,
bool trigger_field_is_autofilled,
AutofillSuggestionTriggerSource trigger_source) { … }
std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
GetProfilesToSuggest(const AddressDataManager& address_data,
FieldType trigger_field_type,
const std::u16string& field_contents,
bool field_is_autofilled,
const FieldTypeSet& field_types,
ProfilesToSuggestOptions options) { … }
std::vector<Suggestion> CreateSuggestionsFromProfiles(
const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
profiles,
const FieldTypeSet& field_types,
SuggestionType suggestion_type,
FieldType trigger_field_type,
uint64_t trigger_field_max_length,
bool is_off_the_record,
const std::string& app_locale) { … }
}
std::vector<Suggestion> GetSuggestionsForProfiles(
const AutofillClient& client,
const FieldTypeSet& field_types,
const FormFieldData& trigger_field,
FieldType trigger_field_type,
SuggestionType suggestion_type,
AutofillSuggestionTriggerSource trigger_source) { … }
Suggestion CreateManageAddressesSuggestion() { … }
std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
GetProfilesToSuggestForTest(const AddressDataManager& address_data,
FieldType trigger_field_type,
const std::u16string& field_contents,
bool field_is_autofilled,
const FieldTypeSet& field_types,
AutofillSuggestionTriggerSource trigger_source) { … }
std::vector<Suggestion> CreateSuggestionsFromProfilesForTest(
const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
profiles,
const FieldTypeSet& field_types,
SuggestionType suggestion_type,
FieldType trigger_field_type,
uint64_t trigger_field_max_length,
bool is_off_the_record,
const std::string& app_locale) { … }
}