19b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Copyright (C) 2012 The Libphonenumber Authors
29b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com//
39b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Licensed under the Apache License, Version 2.0 (the "License");
49b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// you may not use this file except in compliance with the License.
59b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// You may obtain a copy of the License at
69b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com//
79b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// http://www.apache.org/licenses/LICENSE-2.0
89b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com//
99b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Unless required by applicable law or agreed to in writing, software
109b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// distributed under the License is distributed on an "AS IS" BASIS,
119b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// See the License for the specific language governing permissions and
139b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// limitations under the License.
149b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
159b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Author: Patrick Mezard
169b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
179b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include "phonenumbers/geocoding/phonenumber_offline_geocoder.h"
189b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
199b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include <algorithm>
209b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include <map>
219b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include <string>
229b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
239b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include <unicode/unistr.h>  // NOLINT(build/include_order)
249b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
259b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include "phonenumbers/geocoding/area_code_map.h"
269b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include "phonenumbers/geocoding/geocoding_data.h"
279b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include "phonenumbers/geocoding/mapping_file_provider.h"
289b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include "phonenumbers/phonenumberutil.h"
299b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com#include "phonenumbers/stl_util.h"
309b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
319b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace i18n {
329b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace phonenumbers {
339b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
349b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comusing icu::UnicodeString;
359b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comusing std::map;
369b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comusing std::string;
379b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
389b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace {
399b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
409b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Returns true if s1 comes strictly before s2 in lexicographic order.
419b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.combool IsLowerThan(const char* s1, const char* s2) {
429b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return strcmp(s1, s2) < 0;
439b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
449b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
459b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}  // namespace
469b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
479b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comPhoneNumberOfflineGeocoder::PhoneNumberOfflineGeocoder() {
489b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  Init(get_country_calling_codes(), get_country_calling_codes_size(),
499b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com       get_country_languages, get_prefix_language_code_pairs(),
509b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com       get_prefix_language_code_pairs_size(), get_prefix_descriptions);
519b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
529b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
539b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comPhoneNumberOfflineGeocoder::PhoneNumberOfflineGeocoder(
549b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const int* country_calling_codes, int country_calling_codes_size,
559b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    country_languages_getter get_country_languages,
569b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const char** prefix_language_code_pairs,
579b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    int prefix_language_code_pairs_size,
589b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    prefix_descriptions_getter get_prefix_descriptions) {
599b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  Init(country_calling_codes, country_calling_codes_size,
609b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com       get_country_languages, prefix_language_code_pairs,
619b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com       prefix_language_code_pairs_size, get_prefix_descriptions);
629b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
639b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
649b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comvoid PhoneNumberOfflineGeocoder::Init(
659b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const int* country_calling_codes, int country_calling_codes_size,
669b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    country_languages_getter get_country_languages,
679b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const char** prefix_language_code_pairs,
689b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    int prefix_language_code_pairs_size,
699b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    prefix_descriptions_getter get_prefix_descriptions) {
709b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  phone_util_ = PhoneNumberUtil::GetInstance();
719b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  provider_.reset(new MappingFileProvider(country_calling_codes,
729b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com                                          country_calling_codes_size,
739b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com                                          get_country_languages));
749b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  prefix_language_code_pairs_ = prefix_language_code_pairs;
759b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  prefix_language_code_pairs_size_ = prefix_language_code_pairs_size;
769b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  get_prefix_descriptions_ = get_prefix_descriptions;
779b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
789b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
799b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comPhoneNumberOfflineGeocoder::~PhoneNumberOfflineGeocoder() {
809b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  STLDeleteContainerPairSecondPointers(
819b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      available_maps_.begin(), available_maps_.end());
829b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
839b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
849b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comconst AreaCodeMap* PhoneNumberOfflineGeocoder::GetPhonePrefixDescriptions(
859b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    int prefix, const string& language, const string& script,
869b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string& region) const {
879b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  string filename;
889b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  provider_->GetFileName(prefix, language, script, region, &filename);
899b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (filename.empty()) {
909b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    return NULL;
919b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
929b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  AreaCodeMaps::const_iterator it = available_maps_.find(filename);
939b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (it == available_maps_.end()) {
949b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    it = LoadAreaCodeMapFromFile(filename);
959b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    if (it == available_maps_.end()) {
969b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      return NULL;
979b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    }
989b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
999b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return it->second;
1009b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1019b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1029b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comPhoneNumberOfflineGeocoder::AreaCodeMaps::const_iterator
1039b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comPhoneNumberOfflineGeocoder::LoadAreaCodeMapFromFile(
1049b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string& filename) const {
1059b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const char** const prefix_language_code_pairs_end =
1069b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      prefix_language_code_pairs_ + prefix_language_code_pairs_size_;
1079b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const char** const prefix_language_code_pair =
1089b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      std::lower_bound(prefix_language_code_pairs_,
1099b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com                       prefix_language_code_pairs_end,
1109b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com                       filename.c_str(), IsLowerThan);
1119b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (prefix_language_code_pair != prefix_language_code_pairs_end &&
1129b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      filename.compare(*prefix_language_code_pair) == 0) {
1139b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    AreaCodeMap* const m = new AreaCodeMap();
1149b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    m->ReadAreaCodeMap(get_prefix_descriptions_(
1159b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com            prefix_language_code_pair - prefix_language_code_pairs_));
1169b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    return available_maps_.insert(AreaCodeMaps::value_type(filename, m)).first;
1179b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
1189b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return available_maps_.end();
1199b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1209b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1219b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstring PhoneNumberOfflineGeocoder::GetCountryNameForNumber(
1229b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const PhoneNumber& number, const Locale& language) const {
1239b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  string region_code;
1249b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  phone_util_->GetRegionCodeForNumber(number, &region_code);
1259b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return GetRegionDisplayName(&region_code, language);
1269b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1279b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1289b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstring PhoneNumberOfflineGeocoder::GetRegionDisplayName(
1299b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string* region_code, const Locale& language) const {
1309b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (region_code == NULL || region_code->compare("ZZ") == 0 ||
1319b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      region_code->compare(
1329b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com         PhoneNumberUtil::kRegionCodeForNonGeoEntity) == 0) {
1339b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    return "";
1349b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
1359b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  UnicodeString udisplay_country;
1369b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  icu::Locale("", region_code->c_str()).getDisplayCountry(
1379b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      language, udisplay_country);
1389b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  string display_country;
1399b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  udisplay_country.toUTF8String(display_country);
1409b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return display_country;
1419b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1429b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1439b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstring PhoneNumberOfflineGeocoder::GetDescriptionForValidNumber(
1449b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const PhoneNumber& number, const Locale& language) const {
1459b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const char* const description = GetAreaDescription(
1469b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      number, language.getLanguage(), "", language.getCountry());
1479b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return *description != '\0'
1489b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com        ? description
1499b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com        : GetCountryNameForNumber(number, language);
1509b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1519b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1529b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstring PhoneNumberOfflineGeocoder::GetDescriptionForValidNumber(
1539b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const PhoneNumber& number, const Locale& language,
1549b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string& user_region) const {
1559b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // If the user region matches the number's region, then we just show the
1569b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // lower-level description, if one exists - if no description exists, we will
1579b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // show the region(country) name for the number.
1589b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  string region_code;
1599b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  phone_util_->GetRegionCodeForNumber(number, &region_code);
1609b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (user_region.compare(region_code) == 0) {
1619b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    return GetDescriptionForValidNumber(number, language);
1629b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
1639b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // Otherwise, we just show the region(country) name for now.
1649b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return GetRegionDisplayName(&region_code, language);
1659b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1669b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1679b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstring PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
1689b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const PhoneNumber& number, const Locale& locale) const {
1699b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (!phone_util_->IsValidNumber(number)) {
1709b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    return "";
1719b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
1729b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return GetDescriptionForValidNumber(number, locale);
1739b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1749b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1759b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstring PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
1769b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const PhoneNumber& number, const Locale& language,
1779b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string& user_region) const {
1789b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if (!phone_util_->IsValidNumber(number)) {
1799b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    return "";
1809b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
1819b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return GetDescriptionForValidNumber(number, language, user_region);
1829b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1839b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1849b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comconst char* PhoneNumberOfflineGeocoder::GetAreaDescription(
1859b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const PhoneNumber& number, const string& lang, const string& script,
1869b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string& region) const {
1879b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const int country_calling_code = number.country_code();
1889b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // NANPA area is not split in C++ code.
1899b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const int phone_prefix = country_calling_code;
1909b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const AreaCodeMap* const descriptions = GetPhonePrefixDescriptions(
1919b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      phone_prefix, lang, script, region);
1929b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  const char* description = descriptions ? descriptions->Lookup(number) : NULL;
1939b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // When a location is not available in the requested language, fall back to
1949b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // English.
1959b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  if ((!description || *description == '\0') && MayFallBackToEnglish(lang)) {
1969b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const AreaCodeMap* default_descriptions = GetPhonePrefixDescriptions(
1979b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com        phone_prefix, "en", "", "");
1989b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    if (!default_descriptions) {
1999b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com      return "";
2009b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    }
2019b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    description = default_descriptions->Lookup(number);
2029b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  }
2039b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return description ? description : "";
2049b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
2059b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
2069b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Don't fall back to English if the requested language is among the following:
2079b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// - Chinese
2089b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// - Japanese
2099b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// - Korean
2109b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.combool PhoneNumberOfflineGeocoder::MayFallBackToEnglish(
2119b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const string& lang) const {
2129b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  return lang.compare("zh") && lang.compare("ja") && lang.compare("ko");
2139b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
2149b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
2159b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}  // namespace phonenumbers
2169b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}  // namespace i18n
217