1 // Copyright (C) 2009 The Libphonenumber Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "phonenumbers/phonenumberutil.h"
16
17 #include <algorithm>
18 #include <cctype>
19 #include <cstring>
20 #include <iterator>
21 #include <map>
22 #include <utility>
23 #include <vector>
24
25 #include <unicode/uchar.h>
26 #include <unicode/utf8.h>
27
28 #include "phonenumbers/asyoutypeformatter.h"
29 #include "phonenumbers/base/basictypes.h"
30 #include "phonenumbers/base/logging.h"
31 #include "phonenumbers/base/memory/singleton.h"
32 #include "phonenumbers/default_logger.h"
33 #include "phonenumbers/encoding_utils.h"
34 #include "phonenumbers/matcher_api.h"
35 #include "phonenumbers/metadata.h"
36 #include "phonenumbers/normalize_utf8.h"
37 #include "phonenumbers/phonemetadata.pb.h"
38 #include "phonenumbers/phonenumber.h"
39 #include "phonenumbers/phonenumber.pb.h"
40 #include "phonenumbers/regex_based_matcher.h"
41 #include "phonenumbers/regexp_adapter.h"
42 #include "phonenumbers/regexp_cache.h"
43 #include "phonenumbers/regexp_factory.h"
44 #include "phonenumbers/region_code.h"
45 #include "phonenumbers/stl_util.h"
46 #include "phonenumbers/stringutil.h"
47 #include "phonenumbers/utf/unicodetext.h"
48 #include "phonenumbers/utf/utf.h"
49
50 namespace i18n {
51 namespace phonenumbers {
52
53 using google::protobuf::RepeatedField;
54 using gtl::OrderByFirst;
55
56 // static constants
57 const size_t PhoneNumberUtil::kMinLengthForNsn;
58 const size_t PhoneNumberUtil::kMaxLengthForNsn;
59 const size_t PhoneNumberUtil::kMaxLengthCountryCode;
60 const int PhoneNumberUtil::kNanpaCountryCode;
61
62 // static
63 const char PhoneNumberUtil::kPlusChars[] = "+\xEF\xBC\x8B"; /* "++" */
64 // Regular expression of acceptable punctuation found in phone numbers, used to
65 // find numbers in text and to decide what is a viable phone number. This
66 // excludes diallable characters.
67 // This consists of dash characters, white space characters, full stops,
68 // slashes, square brackets, parentheses and tildes. It also includes the letter
69 // 'x' as that is found as a placeholder for carrier information in some phone
70 // numbers. Full-width variants are also present.
71 // To find out the unicode code-point of the characters below in vim, highlight
72 // the character and type 'ga'. Note that the - is used to express ranges of
73 // full-width punctuation below, as well as being present in the expression
74 // itself. In emacs, you can use M-x unicode-what to query information about the
75 // unicode character.
76 // static
77 const char PhoneNumberUtil::kValidPunctuation[] =
78 /* "-x‐-―−ー--/ <U+200B><U+2060> ()()[].\\[\\]/~⁓∼" */
79 "-x\xE2\x80\x90-\xE2\x80\x95\xE2\x88\x92\xE3\x83\xBC\xEF\xBC\x8D-\xEF\xBC"
80 "\x8F \xC2\xA0\xC2\xAD\xE2\x80\x8B\xE2\x81\xA0\xE3\x80\x80()\xEF\xBC\x88"
81 "\xEF\xBC\x89\xEF\xBC\xBB\xEF\xBC\xBD.\\[\\]/~\xE2\x81\x93\xE2\x88\xBC";
82
83 // static
84 const char PhoneNumberUtil::kCaptureUpToSecondNumberStart[] = "(.*)[\\\\/] *x";
85
86 // static
87 const char PhoneNumberUtil::kRegionCodeForNonGeoEntity[] = "001";
88
89 namespace {
90
91 // The prefix that needs to be inserted in front of a Colombian landline
92 // number when dialed from a mobile phone in Colombia.
93 const char kColombiaMobileToFixedLinePrefix[] = "3";
94
95 // The kPlusSign signifies the international prefix.
96 const char kPlusSign[] = "+";
97
98 const char kStarSign[] = "*";
99
100 const char kRfc3966ExtnPrefix[] = ";ext=";
101 const char kRfc3966Prefix[] = "tel:";
102 const char kRfc3966PhoneContext[] = ";phone-context=";
103 const char kRfc3966IsdnSubaddress[] = ";isub=";
104
105 const char kDigits[] = "\\p{Nd}";
106 // We accept alpha characters in phone numbers, ASCII only. We store lower-case
107 // here only since our regular expressions are case-insensitive.
108 const char kValidAlpha[] = "a-z";
109
110 // Default extension prefix to use when formatting. This will be put in front of
111 // any extension component of the number, after the main national number is
112 // formatted. For example, if you wish the default extension formatting to be "
113 // extn: 3456", then you should specify " extn: " here as the default extension
114 // prefix. This can be overridden by region-specific preferences.
115 const char kDefaultExtnPrefix[] = " ext. ";
116
117 // One-character symbols that can be used to indicate an extension.
118 const char kSingleExtnSymbolsForMatching[] =
119 "x\xEF\xBD\x98#\xEF\xBC\x83~\xEF\xBD\x9E";
120
LoadCompiledInMetadata(PhoneMetadataCollection * metadata)121 bool LoadCompiledInMetadata(PhoneMetadataCollection* metadata) {
122 if (!metadata->ParseFromArray(metadata_get(), metadata_size())) {
123 LOG(ERROR) << "Could not parse binary data.";
124 return false;
125 }
126 return true;
127 }
128
129 // Returns a pointer to the description inside the metadata of the appropriate
130 // type.
GetNumberDescByType(const PhoneMetadata & metadata,PhoneNumberUtil::PhoneNumberType type)131 const PhoneNumberDesc* GetNumberDescByType(
132 const PhoneMetadata& metadata,
133 PhoneNumberUtil::PhoneNumberType type) {
134 switch (type) {
135 case PhoneNumberUtil::PREMIUM_RATE:
136 return &metadata.premium_rate();
137 case PhoneNumberUtil::TOLL_FREE:
138 return &metadata.toll_free();
139 case PhoneNumberUtil::MOBILE:
140 return &metadata.mobile();
141 case PhoneNumberUtil::FIXED_LINE:
142 case PhoneNumberUtil::FIXED_LINE_OR_MOBILE:
143 return &metadata.fixed_line();
144 case PhoneNumberUtil::SHARED_COST:
145 return &metadata.shared_cost();
146 case PhoneNumberUtil::VOIP:
147 return &metadata.voip();
148 case PhoneNumberUtil::PERSONAL_NUMBER:
149 return &metadata.personal_number();
150 case PhoneNumberUtil::PAGER:
151 return &metadata.pager();
152 case PhoneNumberUtil::UAN:
153 return &metadata.uan();
154 case PhoneNumberUtil::VOICEMAIL:
155 return &metadata.voicemail();
156 default:
157 return &metadata.general_desc();
158 }
159 }
160
161 // A helper function that is used by Format and FormatByPattern.
PrefixNumberWithCountryCallingCode(int country_calling_code,PhoneNumberUtil::PhoneNumberFormat number_format,string * formatted_number)162 void PrefixNumberWithCountryCallingCode(
163 int country_calling_code,
164 PhoneNumberUtil::PhoneNumberFormat number_format,
165 string* formatted_number) {
166 switch (number_format) {
167 case PhoneNumberUtil::E164:
168 formatted_number->insert(0, StrCat(kPlusSign, country_calling_code));
169 return;
170 case PhoneNumberUtil::INTERNATIONAL:
171 formatted_number->insert(0, StrCat(kPlusSign, country_calling_code, " "));
172 return;
173 case PhoneNumberUtil::RFC3966:
174 formatted_number->insert(0, StrCat(kRfc3966Prefix, kPlusSign,
175 country_calling_code, "-"));
176 return;
177 case PhoneNumberUtil::NATIONAL:
178 default:
179 // Do nothing.
180 return;
181 }
182 }
183
184 // Returns true when one national number is the suffix of the other or both are
185 // the same.
IsNationalNumberSuffixOfTheOther(const PhoneNumber & first_number,const PhoneNumber & second_number)186 bool IsNationalNumberSuffixOfTheOther(const PhoneNumber& first_number,
187 const PhoneNumber& second_number) {
188 const string& first_number_national_number =
189 SimpleItoa(static_cast<uint64>(first_number.national_number()));
190 const string& second_number_national_number =
191 SimpleItoa(static_cast<uint64>(second_number.national_number()));
192 // Note that HasSuffixString returns true if the numbers are equal.
193 return HasSuffixString(first_number_national_number,
194 second_number_national_number) ||
195 HasSuffixString(second_number_national_number,
196 first_number_national_number);
197 }
198
ToUnicodeCodepoint(const char * unicode_char)199 char32 ToUnicodeCodepoint(const char* unicode_char) {
200 char32 codepoint;
201 EncodingUtils::DecodeUTF8Char(unicode_char, &codepoint);
202 return codepoint;
203 }
204
205 // Helper initialiser method to create the regular-expression pattern to match
206 // extensions, allowing the one-codepoint extension symbols provided by
207 // single_extn_symbols.
208 // Note that there are currently three capturing groups for the extension itself
209 // - if this number is changed, MaybeStripExtension needs to be updated.
CreateExtnPattern(const string & single_extn_symbols)210 string CreateExtnPattern(const string& single_extn_symbols) {
211 static const string capturing_extn_digits = StrCat("([", kDigits, "]{1,7})");
212 // The first regular expression covers RFC 3966 format, where the extension is
213 // added using ";ext=". The second more generic one starts with optional white
214 // space and ends with an optional full stop (.), followed by zero or more
215 // spaces/tabs/commas and then the numbers themselves. The third one covers
216 // the special case of American numbers where the extension is written with a
217 // hash at the end, such as "- 503#".
218 // Note that the only capturing groups should be around the digits that you
219 // want to capture as part of the extension, or else parsing will fail!
220 // Canonical-equivalence doesn't seem to be an option with RE2, so we allow
221 // two options for representing the ó - the character itself, and one in the
222 // unicode decomposed form with the combining acute accent.
223 return (StrCat(
224 kRfc3966ExtnPrefix, capturing_extn_digits, "|"
225 /* "[ \\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|single_extn_symbols|"
226 "int|int|anexo)"
227 "[:\\..]?[ \\t,-]*", capturing_extn_digits, "#?|" */
228 "[ \xC2\xA0\\t,]*(?:e?xt(?:ensi(?:o\xCC\x81?|\xC3\xB3))?n?|"
229 "(?:\xEF\xBD\x85)?\xEF\xBD\x98\xEF\xBD\x94(?:\xEF\xBD\x8E)?|"
230 "\xD0\xB4\xD0\xBE\xD0\xB1|[", single_extn_symbols, "]|int|"
231 "\xEF\xBD\x89\xEF\xBD\x8E\xEF\xBD\x94|anexo)"
232 "[:\\.\xEF\xBC\x8E]?[ \xC2\xA0\\t,-]*", capturing_extn_digits,
233 "#?|[- ]+([", kDigits, "]{1,5})#"));
234 }
235
236 // Normalizes a string of characters representing a phone number by replacing
237 // all characters found in the accompanying map with the values therein, and
238 // stripping all other characters if remove_non_matches is true.
239 // Parameters:
240 // number - a pointer to a string of characters representing a phone number to
241 // be normalized.
242 // normalization_replacements - a mapping of characters to what they should be
243 // replaced by in the normalized version of the phone number
244 // remove_non_matches - indicates whether characters that are not able to be
245 // replaced should be stripped from the number. If this is false, they will be
246 // left unchanged in the number.
NormalizeHelper(const std::map<char32,char> & normalization_replacements,bool remove_non_matches,string * number)247 void NormalizeHelper(const std::map<char32, char>& normalization_replacements,
248 bool remove_non_matches,
249 string* number) {
250 DCHECK(number);
251 UnicodeText number_as_unicode;
252 number_as_unicode.PointToUTF8(number->data(), number->size());
253 string normalized_number;
254 char unicode_char[5];
255 for (UnicodeText::const_iterator it = number_as_unicode.begin();
256 it != number_as_unicode.end();
257 ++it) {
258 std::map<char32, char>::const_iterator found_glyph_pair =
259 normalization_replacements.find(*it);
260 if (found_glyph_pair != normalization_replacements.end()) {
261 normalized_number.push_back(found_glyph_pair->second);
262 } else if (!remove_non_matches) {
263 // Find out how long this unicode char is so we can append it all.
264 int char_len = it.get_utf8(unicode_char);
265 normalized_number.append(unicode_char, char_len);
266 }
267 // If neither of the above are true, we remove this character.
268 }
269 number->assign(normalized_number);
270 }
271
272 // Returns true if there is any possible number data set for a particular
273 // PhoneNumberDesc.
DescHasPossibleNumberData(const PhoneNumberDesc & desc)274 bool DescHasPossibleNumberData(const PhoneNumberDesc& desc) {
275 // If this is empty, it means numbers of this type inherit from the "general
276 // desc" -> the value "-1" means that no numbers exist for this type.
277 return desc.possible_length_size() != 1 || desc.possible_length(0) != -1;
278 }
279
280 // Note: DescHasData must account for any of MetadataFilter's
281 // excludableChildFields potentially being absent from the metadata. It must
282 // check them all. For any changes in DescHasData, ensure that all the
283 // excludableChildFields are still being checked. If your change is safe simply
284 // mention why during a review without needing to change MetadataFilter.
285 // Returns true if there is any data set for a particular PhoneNumberDesc.
DescHasData(const PhoneNumberDesc & desc)286 bool DescHasData(const PhoneNumberDesc& desc) {
287 // Checking most properties since we don't know what's present, since a custom
288 // build may have stripped just one of them (e.g. USE_METADATA_LITE strips
289 // exampleNumber). We don't bother checking the PossibleLengthsLocalOnly,
290 // since if this is the only thing that's present we don't really support the
291 // type at all: no type-specific methods will work with only this data.
292 return desc.has_example_number() || DescHasPossibleNumberData(desc) ||
293 desc.has_national_number_pattern();
294 }
295
296 // Returns the types we have metadata for based on the PhoneMetadata object
297 // passed in.
GetSupportedTypesForMetadata(const PhoneMetadata & metadata,std::set<PhoneNumberUtil::PhoneNumberType> * types)298 void GetSupportedTypesForMetadata(
299 const PhoneMetadata& metadata,
300 std::set<PhoneNumberUtil::PhoneNumberType>* types) {
301 DCHECK(types);
302 for (int i = 0; i <= static_cast<int>(PhoneNumberUtil::kMaxNumberType); ++i) {
303 PhoneNumberUtil::PhoneNumberType type =
304 static_cast<PhoneNumberUtil::PhoneNumberType>(i);
305 if (type == PhoneNumberUtil::FIXED_LINE_OR_MOBILE ||
306 type == PhoneNumberUtil::UNKNOWN) {
307 // Never return FIXED_LINE_OR_MOBILE (it is a convenience type, and
308 // represents that a particular number type can't be
309 // determined) or UNKNOWN (the non-type).
310 continue;
311 }
312 if (DescHasData(*GetNumberDescByType(metadata, type))) {
313 types->insert(type);
314 }
315 }
316 }
317
318 // Helper method to check a number against possible lengths for this number
319 // type, and determine whether it matches, or is too short or too long.
TestNumberLength(const string & number,const PhoneMetadata & metadata,PhoneNumberUtil::PhoneNumberType type)320 PhoneNumberUtil::ValidationResult TestNumberLength(
321 const string& number, const PhoneMetadata& metadata,
322 PhoneNumberUtil::PhoneNumberType type) {
323 const PhoneNumberDesc* desc_for_type = GetNumberDescByType(metadata, type);
324 // There should always be "possibleLengths" set for every element. This is
325 // declared in the XML schema which is verified by
326 // PhoneNumberMetadataSchemaTest. For size efficiency, where a
327 // sub-description (e.g. fixed-line) has the same possibleLengths as the
328 // parent, this is missing, so we fall back to the general desc (where no
329 // numbers of the type exist at all, there is one possible length (-1) which
330 // is guaranteed not to match the length of any real phone number).
331 RepeatedField<int> possible_lengths =
332 desc_for_type->possible_length_size() == 0
333 ? metadata.general_desc().possible_length()
334 : desc_for_type->possible_length();
335 RepeatedField<int> local_lengths =
336 desc_for_type->possible_length_local_only();
337 if (type == PhoneNumberUtil::FIXED_LINE_OR_MOBILE) {
338 const PhoneNumberDesc* fixed_line_desc =
339 GetNumberDescByType(metadata, PhoneNumberUtil::FIXED_LINE);
340 if (!DescHasPossibleNumberData(*fixed_line_desc)) {
341 // The rare case has been encountered where no fixedLine data is available
342 // (true for some non-geographical entities), so we just check mobile.
343 return TestNumberLength(number, metadata, PhoneNumberUtil::MOBILE);
344 } else {
345 const PhoneNumberDesc* mobile_desc =
346 GetNumberDescByType(metadata, PhoneNumberUtil::MOBILE);
347 if (DescHasPossibleNumberData(*mobile_desc)) {
348 // Merge the mobile data in if there was any. Note that when adding the
349 // possible lengths from mobile, we have to again check they aren't
350 // empty since if they are this indicates they are the same as the
351 // general desc and should be obtained from there.
352 possible_lengths.MergeFrom(
353 mobile_desc->possible_length_size() == 0
354 ? metadata.general_desc().possible_length()
355 : mobile_desc->possible_length());
356 std::sort(possible_lengths.begin(), possible_lengths.end());
357
358 if (local_lengths.size() == 0) {
359 local_lengths = mobile_desc->possible_length_local_only();
360 } else {
361 local_lengths.MergeFrom(mobile_desc->possible_length_local_only());
362 std::sort(local_lengths.begin(), local_lengths.end());
363 }
364 }
365 }
366 }
367
368 // If the type is not suported at all (indicated by the possible lengths
369 // containing -1 at this point) we return invalid length.
370 if (possible_lengths.Get(0) == -1) {
371 return PhoneNumberUtil::INVALID_LENGTH;
372 }
373
374 int actual_length = number.length();
375 // This is safe because there is never an overlap beween the possible lengths
376 // and the local-only lengths; this is checked at build time.
377 if (std::find(local_lengths.begin(), local_lengths.end(), actual_length) !=
378 local_lengths.end()) {
379 return PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY;
380 }
381 int minimum_length = possible_lengths.Get(0);
382 if (minimum_length == actual_length) {
383 return PhoneNumberUtil::IS_POSSIBLE;
384 } else if (minimum_length > actual_length) {
385 return PhoneNumberUtil::TOO_SHORT;
386 } else if (*(possible_lengths.end() - 1) < actual_length) {
387 return PhoneNumberUtil::TOO_LONG;
388 }
389 // We skip the first element; we've already checked it.
390 return std::find(possible_lengths.begin() + 1, possible_lengths.end(),
391 actual_length) != possible_lengths.end()
392 ? PhoneNumberUtil::IS_POSSIBLE
393 : PhoneNumberUtil::INVALID_LENGTH;
394 }
395
396 // Helper method to check a number against possible lengths for this region,
397 // based on the metadata being passed in, and determine whether it matches, or
398 // is too short or too long.
TestNumberLength(const string & number,const PhoneMetadata & metadata)399 PhoneNumberUtil::ValidationResult TestNumberLength(
400 const string& number, const PhoneMetadata& metadata) {
401 return TestNumberLength(number, metadata, PhoneNumberUtil::UNKNOWN);
402 }
403
404 // Returns a new phone number containing only the fields needed to uniquely
405 // identify a phone number, rather than any fields that capture the context in
406 // which the phone number was created.
407 // These fields correspond to those set in Parse() rather than
408 // ParseAndKeepRawInput().
CopyCoreFieldsOnly(const PhoneNumber & number,PhoneNumber * pruned_number)409 void CopyCoreFieldsOnly(const PhoneNumber& number, PhoneNumber* pruned_number) {
410 pruned_number->set_country_code(number.country_code());
411 pruned_number->set_national_number(number.national_number());
412 if (!number.extension().empty()) {
413 pruned_number->set_extension(number.extension());
414 }
415 if (number.italian_leading_zero()) {
416 pruned_number->set_italian_leading_zero(true);
417 // This field is only relevant if there are leading zeros at all.
418 pruned_number->set_number_of_leading_zeros(
419 number.number_of_leading_zeros());
420 }
421 }
422
423 // Determines whether the given number is a national number match for the given
424 // PhoneNumberDesc. Does not check against possible lengths!
IsMatch(const MatcherApi & matcher_api,const string & number,const PhoneNumberDesc & desc)425 bool IsMatch(const MatcherApi& matcher_api,
426 const string& number, const PhoneNumberDesc& desc) {
427 return matcher_api.MatchNationalNumber(number, desc, false);
428 }
429
430 } // namespace
431
SetLogger(Logger * logger)432 void PhoneNumberUtil::SetLogger(Logger* logger) {
433 logger_.reset(logger);
434 Logger::set_logger_impl(logger_.get());
435 }
436
437 class PhoneNumberRegExpsAndMappings {
438 private:
InitializeMapsAndSets()439 void InitializeMapsAndSets() {
440 diallable_char_mappings_.insert(std::make_pair('+', '+'));
441 diallable_char_mappings_.insert(std::make_pair('*', '*'));
442 diallable_char_mappings_.insert(std::make_pair('#', '#'));
443 // Here we insert all punctuation symbols that we wish to respect when
444 // formatting alpha numbers, as they show the intended number groupings.
445 all_plus_number_grouping_symbols_.insert(
446 std::make_pair(ToUnicodeCodepoint("-"), '-'));
447 all_plus_number_grouping_symbols_.insert(
448 std::make_pair(ToUnicodeCodepoint("\xEF\xBC\x8D" /* "-" */), '-'));
449 all_plus_number_grouping_symbols_.insert(
450 std::make_pair(ToUnicodeCodepoint("\xE2\x80\x90" /* "‐" */), '-'));
451 all_plus_number_grouping_symbols_.insert(
452 std::make_pair(ToUnicodeCodepoint("\xE2\x80\x91" /* "‑" */), '-'));
453 all_plus_number_grouping_symbols_.insert(
454 std::make_pair(ToUnicodeCodepoint("\xE2\x80\x92" /* "‒" */), '-'));
455 all_plus_number_grouping_symbols_.insert(
456 std::make_pair(ToUnicodeCodepoint("\xE2\x80\x93" /* "–" */), '-'));
457 all_plus_number_grouping_symbols_.insert(
458 std::make_pair(ToUnicodeCodepoint("\xE2\x80\x94" /* "—" */), '-'));
459 all_plus_number_grouping_symbols_.insert(
460 std::make_pair(ToUnicodeCodepoint("\xE2\x80\x95" /* "―" */), '-'));
461 all_plus_number_grouping_symbols_.insert(
462 std::make_pair(ToUnicodeCodepoint("\xE2\x88\x92" /* "−" */), '-'));
463 all_plus_number_grouping_symbols_.insert(
464 std::make_pair(ToUnicodeCodepoint("/"), '/'));
465 all_plus_number_grouping_symbols_.insert(
466 std::make_pair(ToUnicodeCodepoint("\xEF\xBC\x8F" /* "/" */), '/'));
467 all_plus_number_grouping_symbols_.insert(
468 std::make_pair(ToUnicodeCodepoint(" "), ' '));
469 all_plus_number_grouping_symbols_.insert(
470 std::make_pair(ToUnicodeCodepoint("\xE3\x80\x80" /* " " */), ' '));
471 all_plus_number_grouping_symbols_.insert(
472 std::make_pair(ToUnicodeCodepoint("\xE2\x81\xA0"), ' '));
473 all_plus_number_grouping_symbols_.insert(
474 std::make_pair(ToUnicodeCodepoint("."), '.'));
475 all_plus_number_grouping_symbols_.insert(
476 std::make_pair(ToUnicodeCodepoint("\xEF\xBC\x8E" /* "." */), '.'));
477 // Only the upper-case letters are added here - the lower-case versions are
478 // added programmatically.
479 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("A"), '2'));
480 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("B"), '2'));
481 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("C"), '2'));
482 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("D"), '3'));
483 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("E"), '3'));
484 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("F"), '3'));
485 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("G"), '4'));
486 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("H"), '4'));
487 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("I"), '4'));
488 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("J"), '5'));
489 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("K"), '5'));
490 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("L"), '5'));
491 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("M"), '6'));
492 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("N"), '6'));
493 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("O"), '6'));
494 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("P"), '7'));
495 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("Q"), '7'));
496 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("R"), '7'));
497 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("S"), '7'));
498 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("T"), '8'));
499 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("U"), '8'));
500 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("V"), '8'));
501 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("W"), '9'));
502 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("X"), '9'));
503 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("Y"), '9'));
504 alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("Z"), '9'));
505 std::map<char32, char> lower_case_mappings;
506 std::map<char32, char> alpha_letters;
507 for (std::map<char32, char>::const_iterator it = alpha_mappings_.begin();
508 it != alpha_mappings_.end();
509 ++it) {
510 // Convert all the upper-case ASCII letters to lower-case.
511 if (it->first < 128) {
512 char letter_as_upper = static_cast<char>(it->first);
513 char32 letter_as_lower = static_cast<char32>(tolower(letter_as_upper));
514 lower_case_mappings.insert(std::make_pair(letter_as_lower, it->second));
515 // Add the letters in both variants to the alpha_letters map. This just
516 // pairs each letter with its upper-case representation so that it can
517 // be retained when normalising alpha numbers.
518 alpha_letters.insert(std::make_pair(letter_as_lower, letter_as_upper));
519 alpha_letters.insert(std::make_pair(it->first, letter_as_upper));
520 }
521 }
522 // In the Java version we don't insert the lower-case mappings in the map,
523 // because we convert to upper case on the fly. Doing this here would
524 // involve pulling in all of ICU, which we don't want to do if we don't have
525 // to.
526 alpha_mappings_.insert(lower_case_mappings.begin(),
527 lower_case_mappings.end());
528 alpha_phone_mappings_.insert(alpha_mappings_.begin(),
529 alpha_mappings_.end());
530 all_plus_number_grouping_symbols_.insert(alpha_letters.begin(),
531 alpha_letters.end());
532 // Add the ASCII digits so that they don't get deleted by NormalizeHelper().
533 for (char c = '0'; c <= '9'; ++c) {
534 diallable_char_mappings_.insert(std::make_pair(c, c));
535 alpha_phone_mappings_.insert(std::make_pair(c, c));
536 all_plus_number_grouping_symbols_.insert(std::make_pair(c, c));
537 }
538
539 mobile_token_mappings_.insert(std::make_pair(54, '9'));
540 geo_mobile_countries_without_mobile_area_codes_.insert(86); // China
541 geo_mobile_countries_.insert(52); // Mexico
542 geo_mobile_countries_.insert(54); // Argentina
543 geo_mobile_countries_.insert(55); // Brazil
544 // Indonesia: some prefixes only (fixed CMDA wireless)
545 geo_mobile_countries_.insert(62);
546 geo_mobile_countries_.insert(
547 geo_mobile_countries_without_mobile_area_codes_.begin(),
548 geo_mobile_countries_without_mobile_area_codes_.end());
549 }
550
551 // Regular expression of viable phone numbers. This is location independent.
552 // Checks we have at least three leading digits, and only valid punctuation,
553 // alpha characters and digits in the phone number. Does not include extension
554 // data. The symbol 'x' is allowed here as valid punctuation since it is often
555 // used as a placeholder for carrier codes, for example in Brazilian phone
556 // numbers. We also allow multiple plus-signs at the start.
557 // Corresponds to the following:
558 // [digits]{minLengthNsn}|
559 // plus_sign*(([punctuation]|[star])*[digits]){3,}
560 // ([punctuation]|[star]|[digits]|[alpha])*
561 //
562 // The first reg-ex is to allow short numbers (two digits long) to be parsed
563 // if they are entered as "15" etc, but only if there is no punctuation in
564 // them. The second expression restricts the number of digits to three or
565 // more, but then allows them to be in international form, and to have
566 // alpha-characters and punctuation.
567 const string valid_phone_number_;
568
569 // Regexp of all possible ways to write extensions, for use when parsing. This
570 // will be run as a case-insensitive regexp match. Wide character versions are
571 // also provided after each ASCII version.
572 // For parsing, we are slightly more lenient in our interpretation than for
573 // matching. Here we allow "comma" and "semicolon" as possible extension
574 // indicators. When matching, these are hardly ever used to indicate this.
575 const string extn_patterns_for_parsing_;
576
577 public:
578 scoped_ptr<const AbstractRegExpFactory> regexp_factory_;
579 scoped_ptr<RegExpCache> regexp_cache_;
580
581 // A map that contains characters that are essential when dialling. That means
582 // any of the characters in this map must not be removed from a number when
583 // dialing, otherwise the call will not reach the intended destination.
584 std::map<char32, char> diallable_char_mappings_;
585 // These mappings map a character (key) to a specific digit that should
586 // replace it for normalization purposes.
587 std::map<char32, char> alpha_mappings_;
588 // For performance reasons, store a map of combining alpha_mappings with ASCII
589 // digits.
590 std::map<char32, char> alpha_phone_mappings_;
591
592 // Separate map of all symbols that we wish to retain when formatting alpha
593 // numbers. This includes digits, ascii letters and number grouping symbols
594 // such as "-" and " ".
595 std::map<char32, char> all_plus_number_grouping_symbols_;
596
597 // Map of country calling codes that use a mobile token before the area code.
598 // One example of when this is relevant is when determining the length of the
599 // national destination code, which should be the length of the area code plus
600 // the length of the mobile token.
601 std::map<int, char> mobile_token_mappings_;
602
603 // Set of country codes that have geographically assigned mobile numbers (see
604 // geo_mobile_countries_ below) which are not based on *area codes*. For
605 // example, in China mobile numbers start with a carrier indicator, and beyond
606 // that are geographically assigned: this carrier indicator is not considered
607 // to be an area code.
608 std::set<int> geo_mobile_countries_without_mobile_area_codes_;
609
610 // Set of country calling codes that have geographically assigned mobile
611 // numbers. This may not be complete; we add calling codes case by case, as we
612 // find geographical mobile numbers or hear from user reports.
613 std::set<int> geo_mobile_countries_;
614
615 // Pattern that makes it easy to distinguish whether a region has a single
616 // international dialing prefix or not. If a region has a single international
617 // prefix (e.g. 011 in USA), it will be represented as a string that contains
618 // a sequence of ASCII digits, and possibly a tilde, which signals waiting for
619 // the tone. If there are multiple available international prefixes in a
620 // region, they will be represented as a regex string that always contains one
621 // or more characters that are not ASCII digits or a tilde.
622 scoped_ptr<const RegExp> single_international_prefix_;
623
624 scoped_ptr<const RegExp> digits_pattern_;
625 scoped_ptr<const RegExp> capturing_digit_pattern_;
626 scoped_ptr<const RegExp> capturing_ascii_digits_pattern_;
627
628 // Regular expression of acceptable characters that may start a phone number
629 // for the purposes of parsing. This allows us to strip away meaningless
630 // prefixes to phone numbers that may be mistakenly given to us. This consists
631 // of digits, the plus symbol and arabic-indic digits. This does not contain
632 // alpha characters, although they may be used later in the number. It also
633 // does not include other punctuation, as this will be stripped later during
634 // parsing and is of no information value when parsing a number. The string
635 // starting with this valid character is captured.
636 // This corresponds to VALID_START_CHAR in the java version.
637 scoped_ptr<const RegExp> valid_start_char_pattern_;
638
639 // Regular expression of valid characters before a marker that might indicate
640 // a second number.
641 scoped_ptr<const RegExp> capture_up_to_second_number_start_pattern_;
642
643 // Regular expression of trailing characters that we want to remove. We remove
644 // all characters that are not alpha or numerical characters. The hash
645 // character is retained here, as it may signify the previous block was an
646 // extension. Note the capturing block at the start to capture the rest of the
647 // number if this was a match.
648 // This corresponds to UNWANTED_END_CHAR_PATTERN in the java version.
649 scoped_ptr<const RegExp> unwanted_end_char_pattern_;
650
651 // Regular expression of groups of valid punctuation characters.
652 scoped_ptr<const RegExp> separator_pattern_;
653
654 // Regexp of all possible ways to write extensions, for use when finding phone
655 // numbers in text. This will be run as a case-insensitive regexp match. Wide
656 // character versions are also provided after each ASCII version.
657 const string extn_patterns_for_matching_;
658
659 // Regexp of all known extension prefixes used by different regions followed
660 // by 1 or more valid digits, for use when parsing.
661 scoped_ptr<const RegExp> extn_pattern_;
662
663 // We append optionally the extension pattern to the end here, as a valid
664 // phone number may have an extension prefix appended, followed by 1 or more
665 // digits.
666 scoped_ptr<const RegExp> valid_phone_number_pattern_;
667
668 // We use this pattern to check if the phone number has at least three letters
669 // in it - if so, then we treat it as a number where some phone-number digits
670 // are represented by letters.
671 scoped_ptr<const RegExp> valid_alpha_phone_pattern_;
672
673 scoped_ptr<const RegExp> first_group_capturing_pattern_;
674
675 scoped_ptr<const RegExp> carrier_code_pattern_;
676
677 scoped_ptr<const RegExp> plus_chars_pattern_;
678
PhoneNumberRegExpsAndMappings()679 PhoneNumberRegExpsAndMappings()
680 : valid_phone_number_(
681 StrCat(kDigits, "{", PhoneNumberUtil::kMinLengthForNsn, "}|[",
682 PhoneNumberUtil::kPlusChars, "]*(?:[",
683 PhoneNumberUtil::kValidPunctuation, kStarSign, "]*",
684 kDigits, "){3,}[", PhoneNumberUtil::kValidPunctuation,
685 kStarSign, kValidAlpha, kDigits, "]*")),
686 extn_patterns_for_parsing_(
687 CreateExtnPattern(StrCat(",;", kSingleExtnSymbolsForMatching))),
688 regexp_factory_(new RegExpFactory()),
689 regexp_cache_(new RegExpCache(*regexp_factory_.get(), 128)),
690 diallable_char_mappings_(),
691 alpha_mappings_(),
692 alpha_phone_mappings_(),
693 all_plus_number_grouping_symbols_(),
694 mobile_token_mappings_(),
695 geo_mobile_countries_without_mobile_area_codes_(),
696 geo_mobile_countries_(),
697 single_international_prefix_(regexp_factory_->CreateRegExp(
698 /* "[\\d]+(?:[~⁓∼~][\\d]+)?" */
699 "[\\d]+(?:[~\xE2\x81\x93\xE2\x88\xBC\xEF\xBD\x9E][\\d]+)?")),
700 digits_pattern_(
701 regexp_factory_->CreateRegExp(StrCat("[", kDigits, "]*"))),
702 capturing_digit_pattern_(
703 regexp_factory_->CreateRegExp(StrCat("([", kDigits, "])"))),
704 capturing_ascii_digits_pattern_(
705 regexp_factory_->CreateRegExp("(\\d+)")),
706 valid_start_char_pattern_(regexp_factory_->CreateRegExp(
707 StrCat("[", PhoneNumberUtil::kPlusChars, kDigits, "]"))),
708 capture_up_to_second_number_start_pattern_(
709 regexp_factory_->CreateRegExp(
710 PhoneNumberUtil::kCaptureUpToSecondNumberStart)),
711 unwanted_end_char_pattern_(
712 regexp_factory_->CreateRegExp("[^\\p{N}\\p{L}#]")),
713 separator_pattern_(
714 regexp_factory_->CreateRegExp(
715 StrCat("[", PhoneNumberUtil::kValidPunctuation, "]+"))),
716 extn_patterns_for_matching_(
717 CreateExtnPattern(kSingleExtnSymbolsForMatching)),
718 extn_pattern_(regexp_factory_->CreateRegExp(
719 StrCat("(?i)(?:", extn_patterns_for_parsing_, ")$"))),
720 valid_phone_number_pattern_(regexp_factory_->CreateRegExp(
721 StrCat("(?i)", valid_phone_number_,
722 "(?:", extn_patterns_for_parsing_, ")?"))),
723 valid_alpha_phone_pattern_(regexp_factory_->CreateRegExp(
724 StrCat("(?i)(?:.*?[", kValidAlpha, "]){3}"))),
725 // The first_group_capturing_pattern was originally set to $1 but there
726 // are some countries for which the first group is not used in the
727 // national pattern (e.g. Argentina) so the $1 group does not match
728 // correctly. Therefore, we use \d, so that the first group actually
729 // used in the pattern will be matched.
730 first_group_capturing_pattern_(
731 regexp_factory_->CreateRegExp("(\\$\\d)")),
732 carrier_code_pattern_(regexp_factory_->CreateRegExp("\\$CC")),
733 plus_chars_pattern_(
734 regexp_factory_->CreateRegExp(
735 StrCat("[", PhoneNumberUtil::kPlusChars, "]+"))) {
736 InitializeMapsAndSets();
737 }
738
739 private:
740 DISALLOW_COPY_AND_ASSIGN(PhoneNumberRegExpsAndMappings);
741 };
742
743 // Private constructor. Also takes care of initialisation.
PhoneNumberUtil()744 PhoneNumberUtil::PhoneNumberUtil()
745 : logger_(Logger::set_logger_impl(new NullLogger())),
746 matcher_api_(new RegexBasedMatcher()),
747 reg_exps_(new PhoneNumberRegExpsAndMappings),
748 country_calling_code_to_region_code_map_(
749 new std::vector<IntRegionsPair>()),
750 nanpa_regions_(new std::set<string>()),
751 region_to_metadata_map_(new std::map<string, PhoneMetadata>()),
752 country_code_to_non_geographical_metadata_map_(
753 new std::map<int, PhoneMetadata>) {
754 Logger::set_logger_impl(logger_.get());
755 // TODO: Update the java version to put the contents of the init
756 // method inside the constructor as well to keep both in sync.
757 PhoneMetadataCollection metadata_collection;
758 if (!LoadCompiledInMetadata(&metadata_collection)) {
759 LOG(DFATAL) << "Could not parse compiled-in metadata.";
760 return;
761 }
762 // Storing data in a temporary map to make it easier to find other regions
763 // that share a country calling code when inserting data.
764 std::map<int, std::list<string>* > country_calling_code_to_region_map;
765 for (RepeatedPtrField<PhoneMetadata>::const_iterator it =
766 metadata_collection.metadata().begin();
767 it != metadata_collection.metadata().end();
768 ++it) {
769 const string& region_code = it->id();
770 if (region_code == RegionCode::GetUnknown()) {
771 continue;
772 }
773
774 int country_calling_code = it->country_code();
775 if (kRegionCodeForNonGeoEntity == region_code) {
776 country_code_to_non_geographical_metadata_map_->insert(
777 std::make_pair(country_calling_code, *it));
778 } else {
779 region_to_metadata_map_->insert(std::make_pair(region_code, *it));
780 }
781 std::map<int, std::list<string>* >::iterator calling_code_in_map =
782 country_calling_code_to_region_map.find(country_calling_code);
783 if (calling_code_in_map != country_calling_code_to_region_map.end()) {
784 if (it->main_country_for_code()) {
785 calling_code_in_map->second->push_front(region_code);
786 } else {
787 calling_code_in_map->second->push_back(region_code);
788 }
789 } else {
790 // For most country calling codes, there will be only one region code.
791 std::list<string>* list_with_region_code = new std::list<string>();
792 list_with_region_code->push_back(region_code);
793 country_calling_code_to_region_map.insert(
794 std::make_pair(country_calling_code, list_with_region_code));
795 }
796 if (country_calling_code == kNanpaCountryCode) {
797 nanpa_regions_->insert(region_code);
798 }
799 }
800
801 country_calling_code_to_region_code_map_->insert(
802 country_calling_code_to_region_code_map_->begin(),
803 country_calling_code_to_region_map.begin(),
804 country_calling_code_to_region_map.end());
805 // Sort all the pairs in ascending order according to country calling code.
806 std::sort(country_calling_code_to_region_code_map_->begin(),
807 country_calling_code_to_region_code_map_->end(), OrderByFirst());
808 }
809
~PhoneNumberUtil()810 PhoneNumberUtil::~PhoneNumberUtil() {
811 gtl::STLDeleteContainerPairSecondPointers(
812 country_calling_code_to_region_code_map_->begin(),
813 country_calling_code_to_region_code_map_->end());
814 }
815
GetSupportedRegions(std::set<string> * regions) const816 void PhoneNumberUtil::GetSupportedRegions(std::set<string>* regions) const {
817 DCHECK(regions);
818 for (std::map<string, PhoneMetadata>::const_iterator it =
819 region_to_metadata_map_->begin(); it != region_to_metadata_map_->end();
820 ++it) {
821 regions->insert(it->first);
822 }
823 }
824
GetSupportedGlobalNetworkCallingCodes(std::set<int> * calling_codes) const825 void PhoneNumberUtil::GetSupportedGlobalNetworkCallingCodes(
826 std::set<int>* calling_codes) const {
827 DCHECK(calling_codes);
828 for (std::map<int, PhoneMetadata>::const_iterator it =
829 country_code_to_non_geographical_metadata_map_->begin();
830 it != country_code_to_non_geographical_metadata_map_->end(); ++it) {
831 calling_codes->insert(it->first);
832 }
833 }
834
GetSupportedCallingCodes(std::set<int> * calling_codes) const835 void PhoneNumberUtil::GetSupportedCallingCodes(
836 std::set<int>* calling_codes) const {
837 DCHECK(calling_codes);
838 for (std::vector<IntRegionsPair>::const_iterator it =
839 country_calling_code_to_region_code_map_->begin();
840 it != country_calling_code_to_region_code_map_->end(); ++it) {
841 calling_codes->insert(it->first);
842 }
843 }
844
GetSupportedTypesForRegion(const string & region_code,std::set<PhoneNumberType> * types) const845 void PhoneNumberUtil::GetSupportedTypesForRegion(
846 const string& region_code,
847 std::set<PhoneNumberType>* types) const {
848 DCHECK(types);
849 if (!IsValidRegionCode(region_code)) {
850 LOG(WARNING) << "Invalid or unknown region code provided: " << region_code;
851 return;
852 }
853 const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
854 GetSupportedTypesForMetadata(*metadata, types);
855 }
856
GetSupportedTypesForNonGeoEntity(int country_calling_code,std::set<PhoneNumberType> * types) const857 void PhoneNumberUtil::GetSupportedTypesForNonGeoEntity(
858 int country_calling_code,
859 std::set<PhoneNumberType>* types) const {
860 DCHECK(types);
861 const PhoneMetadata* metadata =
862 GetMetadataForNonGeographicalRegion(country_calling_code);
863 if (metadata == NULL) {
864 LOG(WARNING) << "Unknown country calling code for a non-geographical "
865 << "entity provided: "
866 << country_calling_code;
867 return;
868 }
869 GetSupportedTypesForMetadata(*metadata, types);
870 }
871
872 // Public wrapper function to get a PhoneNumberUtil instance with the default
873 // metadata file.
874 // static
GetInstance()875 PhoneNumberUtil* PhoneNumberUtil::GetInstance() {
876 return Singleton<PhoneNumberUtil>::GetInstance();
877 }
878
GetExtnPatternsForMatching() const879 const string& PhoneNumberUtil::GetExtnPatternsForMatching() const {
880 return reg_exps_->extn_patterns_for_matching_;
881 }
882
StartsWithPlusCharsPattern(const string & number) const883 bool PhoneNumberUtil::StartsWithPlusCharsPattern(const string& number)
884 const {
885 const scoped_ptr<RegExpInput> number_string_piece(
886 reg_exps_->regexp_factory_->CreateInput(number));
887 return reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get());
888 }
889
ContainsOnlyValidDigits(const string & s) const890 bool PhoneNumberUtil::ContainsOnlyValidDigits(const string& s) const {
891 return reg_exps_->digits_pattern_->FullMatch(s);
892 }
893
TrimUnwantedEndChars(string * number) const894 void PhoneNumberUtil::TrimUnwantedEndChars(string* number) const {
895 DCHECK(number);
896 UnicodeText number_as_unicode;
897 number_as_unicode.PointToUTF8(number->data(), number->size());
898 char current_char[5];
899 int len;
900 UnicodeText::const_reverse_iterator reverse_it(number_as_unicode.end());
901 for (; reverse_it.base() != number_as_unicode.begin(); ++reverse_it) {
902 len = reverse_it.get_utf8(current_char);
903 current_char[len] = '\0';
904 if (!reg_exps_->unwanted_end_char_pattern_->FullMatch(current_char)) {
905 break;
906 }
907 }
908
909 number->assign(UnicodeText::UTF8Substring(number_as_unicode.begin(),
910 reverse_it.base()));
911 }
912
IsFormatEligibleForAsYouTypeFormatter(const string & format) const913 bool PhoneNumberUtil::IsFormatEligibleForAsYouTypeFormatter(
914 const string& format) const {
915 // A pattern that is used to determine if a numberFormat under
916 // availableFormats is eligible to be used by the AYTF. It is eligible when
917 // the format element under numberFormat contains groups of the dollar sign
918 // followed by a single digit, separated by valid phone number punctuation.
919 // This prevents invalid punctuation (such as the star sign in Israeli star
920 // numbers) getting into the output of the AYTF.
921 const RegExp& eligible_format_pattern = reg_exps_->regexp_cache_->GetRegExp(
922 StrCat("[", kValidPunctuation, "]*", "(\\$\\d", "[",
923 kValidPunctuation, "]*)+"));
924 return eligible_format_pattern.FullMatch(format);
925 }
926
FormattingRuleHasFirstGroupOnly(const string & national_prefix_formatting_rule) const927 bool PhoneNumberUtil::FormattingRuleHasFirstGroupOnly(
928 const string& national_prefix_formatting_rule) const {
929 // A pattern that is used to determine if the national prefix formatting rule
930 // has the first group only, i.e., does not start with the national prefix.
931 // Note that the pattern explicitly allows for unbalanced parentheses.
932 const RegExp& first_group_only_prefix_pattern =
933 reg_exps_->regexp_cache_->GetRegExp("\\(?\\$1\\)?");
934 return national_prefix_formatting_rule.empty() ||
935 first_group_only_prefix_pattern.FullMatch(
936 national_prefix_formatting_rule);
937 }
938
GetNddPrefixForRegion(const string & region_code,bool strip_non_digits,string * national_prefix) const939 void PhoneNumberUtil::GetNddPrefixForRegion(const string& region_code,
940 bool strip_non_digits,
941 string* national_prefix) const {
942 DCHECK(national_prefix);
943 const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
944 if (!metadata) {
945 LOG(WARNING) << "Invalid or unknown region code (" << region_code
946 << ") provided.";
947 return;
948 }
949 national_prefix->assign(metadata->national_prefix());
950 if (strip_non_digits) {
951 // Note: if any other non-numeric symbols are ever used in national
952 // prefixes, these would have to be removed here as well.
953 strrmm(national_prefix, "~");
954 }
955 }
956
IsValidRegionCode(const string & region_code) const957 bool PhoneNumberUtil::IsValidRegionCode(const string& region_code) const {
958 return (region_to_metadata_map_->find(region_code) !=
959 region_to_metadata_map_->end());
960 }
961
HasValidCountryCallingCode(int country_calling_code) const962 bool PhoneNumberUtil::HasValidCountryCallingCode(
963 int country_calling_code) const {
964 // Create an IntRegionsPair with the country_code passed in, and use it to
965 // locate the pair with the same country_code in the sorted vector.
966 IntRegionsPair target_pair;
967 target_pair.first = country_calling_code;
968 return (std::binary_search(country_calling_code_to_region_code_map_->begin(),
969 country_calling_code_to_region_code_map_->end(),
970 target_pair, OrderByFirst()));
971 }
972
973 // Returns a pointer to the phone metadata for the appropriate region or NULL
974 // if the region code is invalid or unknown.
GetMetadataForRegion(const string & region_code) const975 const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegion(
976 const string& region_code) const {
977 std::map<string, PhoneMetadata>::const_iterator it =
978 region_to_metadata_map_->find(region_code);
979 if (it != region_to_metadata_map_->end()) {
980 return &it->second;
981 }
982 return NULL;
983 }
984
GetMetadataForNonGeographicalRegion(int country_calling_code) const985 const PhoneMetadata* PhoneNumberUtil::GetMetadataForNonGeographicalRegion(
986 int country_calling_code) const {
987 std::map<int, PhoneMetadata>::const_iterator it =
988 country_code_to_non_geographical_metadata_map_->find(
989 country_calling_code);
990 if (it != country_code_to_non_geographical_metadata_map_->end()) {
991 return &it->second;
992 }
993 return NULL;
994 }
995
Format(const PhoneNumber & number,PhoneNumberFormat number_format,string * formatted_number) const996 void PhoneNumberUtil::Format(const PhoneNumber& number,
997 PhoneNumberFormat number_format,
998 string* formatted_number) const {
999 DCHECK(formatted_number);
1000 if (number.national_number() == 0) {
1001 const string& raw_input = number.raw_input();
1002 if (!raw_input.empty()) {
1003 // Unparseable numbers that kept their raw input just use that.
1004 // This is the only case where a number can be formatted as E164 without a
1005 // leading '+' symbol (but the original number wasn't parseable anyway).
1006 // TODO: Consider removing the 'if' above so that unparseable
1007 // strings without raw input format to the empty string instead of "+00".
1008 formatted_number->assign(raw_input);
1009 return;
1010 }
1011 }
1012 int country_calling_code = number.country_code();
1013 string national_significant_number;
1014 GetNationalSignificantNumber(number, &national_significant_number);
1015 if (number_format == E164) {
1016 // Early exit for E164 case (even if the country calling code is invalid)
1017 // since no formatting of the national number needs to be applied.
1018 // Extensions are not formatted.
1019 formatted_number->assign(national_significant_number);
1020 PrefixNumberWithCountryCallingCode(country_calling_code, E164,
1021 formatted_number);
1022 return;
1023 }
1024 if (!HasValidCountryCallingCode(country_calling_code)) {
1025 formatted_number->assign(national_significant_number);
1026 return;
1027 }
1028 // Note here that all NANPA formatting rules are contained by US, so we use
1029 // that to format NANPA numbers. The same applies to Russian Fed regions -
1030 // rules are contained by Russia. French Indian Ocean country rules are
1031 // contained by Réunion.
1032 string region_code;
1033 GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
1034 // Metadata cannot be NULL because the country calling code is valid (which
1035 // means that the region code cannot be ZZ and must be one of our supported
1036 // region codes).
1037 const PhoneMetadata* metadata =
1038 GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
1039 FormatNsn(national_significant_number, *metadata, number_format,
1040 formatted_number);
1041 MaybeAppendFormattedExtension(number, *metadata, number_format,
1042 formatted_number);
1043 PrefixNumberWithCountryCallingCode(country_calling_code, number_format,
1044 formatted_number);
1045 }
1046
FormatByPattern(const PhoneNumber & number,PhoneNumberFormat number_format,const RepeatedPtrField<NumberFormat> & user_defined_formats,string * formatted_number) const1047 void PhoneNumberUtil::FormatByPattern(
1048 const PhoneNumber& number,
1049 PhoneNumberFormat number_format,
1050 const RepeatedPtrField<NumberFormat>& user_defined_formats,
1051 string* formatted_number) const {
1052 DCHECK(formatted_number);
1053 int country_calling_code = number.country_code();
1054 // Note GetRegionCodeForCountryCode() is used because formatting information
1055 // for regions which share a country calling code is contained by only one
1056 // region for performance reasons. For example, for NANPA regions it will be
1057 // contained in the metadata for US.
1058 string national_significant_number;
1059 GetNationalSignificantNumber(number, &national_significant_number);
1060 if (!HasValidCountryCallingCode(country_calling_code)) {
1061 formatted_number->assign(national_significant_number);
1062 return;
1063 }
1064 string region_code;
1065 GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
1066 // Metadata cannot be NULL because the country calling code is valid.
1067 const PhoneMetadata* metadata =
1068 GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
1069 const NumberFormat* formatting_pattern =
1070 ChooseFormattingPatternForNumber(user_defined_formats,
1071 national_significant_number);
1072 if (!formatting_pattern) {
1073 // If no pattern above is matched, we format the number as a whole.
1074 formatted_number->assign(national_significant_number);
1075 } else {
1076 NumberFormat num_format_copy;
1077 // Before we do a replacement of the national prefix pattern $NP with the
1078 // national prefix, we need to copy the rule so that subsequent replacements
1079 // for different numbers have the appropriate national prefix.
1080 num_format_copy.MergeFrom(*formatting_pattern);
1081 string national_prefix_formatting_rule(
1082 formatting_pattern->national_prefix_formatting_rule());
1083 if (!national_prefix_formatting_rule.empty()) {
1084 const string& national_prefix = metadata->national_prefix();
1085 if (!national_prefix.empty()) {
1086 // Replace $NP with national prefix and $FG with the first group ($1).
1087 GlobalReplaceSubstring("$NP", national_prefix,
1088 &national_prefix_formatting_rule);
1089 GlobalReplaceSubstring("$FG", "$1",
1090 &national_prefix_formatting_rule);
1091 num_format_copy.set_national_prefix_formatting_rule(
1092 national_prefix_formatting_rule);
1093 } else {
1094 // We don't want to have a rule for how to format the national prefix if
1095 // there isn't one.
1096 num_format_copy.clear_national_prefix_formatting_rule();
1097 }
1098 }
1099 FormatNsnUsingPattern(national_significant_number, num_format_copy,
1100 number_format, formatted_number);
1101 }
1102 MaybeAppendFormattedExtension(number, *metadata, NATIONAL, formatted_number);
1103 PrefixNumberWithCountryCallingCode(country_calling_code, number_format,
1104 formatted_number);
1105 }
1106
FormatNationalNumberWithCarrierCode(const PhoneNumber & number,const string & carrier_code,string * formatted_number) const1107 void PhoneNumberUtil::FormatNationalNumberWithCarrierCode(
1108 const PhoneNumber& number,
1109 const string& carrier_code,
1110 string* formatted_number) const {
1111 int country_calling_code = number.country_code();
1112 string national_significant_number;
1113 GetNationalSignificantNumber(number, &national_significant_number);
1114 if (!HasValidCountryCallingCode(country_calling_code)) {
1115 formatted_number->assign(national_significant_number);
1116 return;
1117 }
1118
1119 // Note GetRegionCodeForCountryCode() is used because formatting information
1120 // for regions which share a country calling code is contained by only one
1121 // region for performance reasons. For example, for NANPA regions it will be
1122 // contained in the metadata for US.
1123 string region_code;
1124 GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
1125 // Metadata cannot be NULL because the country calling code is valid.
1126 const PhoneMetadata* metadata =
1127 GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
1128 FormatNsnWithCarrier(national_significant_number, *metadata, NATIONAL,
1129 carrier_code, formatted_number);
1130 MaybeAppendFormattedExtension(number, *metadata, NATIONAL, formatted_number);
1131 PrefixNumberWithCountryCallingCode(country_calling_code, NATIONAL,
1132 formatted_number);
1133 }
1134
GetMetadataForRegionOrCallingCode(int country_calling_code,const string & region_code) const1135 const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegionOrCallingCode(
1136 int country_calling_code, const string& region_code) const {
1137 return kRegionCodeForNonGeoEntity == region_code
1138 ? GetMetadataForNonGeographicalRegion(country_calling_code)
1139 : GetMetadataForRegion(region_code);
1140 }
1141
FormatNationalNumberWithPreferredCarrierCode(const PhoneNumber & number,const string & fallback_carrier_code,string * formatted_number) const1142 void PhoneNumberUtil::FormatNationalNumberWithPreferredCarrierCode(
1143 const PhoneNumber& number,
1144 const string& fallback_carrier_code,
1145 string* formatted_number) const {
1146 FormatNationalNumberWithCarrierCode(
1147 number,
1148 // Historically, we set this to an empty string when parsing with raw
1149 // input if none was found in the input string. However, this doesn't
1150 // result in a number we can dial. For this reason, we treat the empty
1151 // string the same as if it isn't set at all.
1152 !number.preferred_domestic_carrier_code().empty()
1153 ? number.preferred_domestic_carrier_code()
1154 : fallback_carrier_code,
1155 formatted_number);
1156 }
1157
FormatNumberForMobileDialing(const PhoneNumber & number,const string & calling_from,bool with_formatting,string * formatted_number) const1158 void PhoneNumberUtil::FormatNumberForMobileDialing(
1159 const PhoneNumber& number,
1160 const string& calling_from,
1161 bool with_formatting,
1162 string* formatted_number) const {
1163 int country_calling_code = number.country_code();
1164 if (!HasValidCountryCallingCode(country_calling_code)) {
1165 formatted_number->assign(number.has_raw_input() ? number.raw_input() : "");
1166 return;
1167 }
1168
1169 formatted_number->assign("");
1170 // Clear the extension, as that part cannot normally be dialed together with
1171 // the main number.
1172 PhoneNumber number_no_extension(number);
1173 number_no_extension.clear_extension();
1174 string region_code;
1175 GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
1176 PhoneNumberType number_type = GetNumberType(number_no_extension);
1177 bool is_valid_number = (number_type != UNKNOWN);
1178 if (calling_from == region_code) {
1179 bool is_fixed_line_or_mobile =
1180 (number_type == FIXED_LINE) || (number_type == MOBILE) ||
1181 (number_type == FIXED_LINE_OR_MOBILE);
1182 // Carrier codes may be needed in some countries. We handle this here.
1183 if ((region_code == "CO") && (number_type == FIXED_LINE)) {
1184 FormatNationalNumberWithCarrierCode(
1185 number_no_extension, kColombiaMobileToFixedLinePrefix,
1186 formatted_number);
1187 } else if ((region_code == "BR") && (is_fixed_line_or_mobile)) {
1188 // Historically, we set this to an empty string when parsing with raw
1189 // input if none was found in the input string. However, this doesn't
1190 // result in a number we can dial. For this reason, we treat the empty
1191 // string the same as if it isn't set at all.
1192 if (!number_no_extension.preferred_domestic_carrier_code().empty()) {
1193 FormatNationalNumberWithPreferredCarrierCode(number_no_extension, "",
1194 formatted_number);
1195 } else {
1196 // Brazilian fixed line and mobile numbers need to be dialed with a
1197 // carrier code when called within Brazil. Without that, most of the
1198 // carriers won't connect the call. Because of that, we return an empty
1199 // string here.
1200 formatted_number->assign("");
1201 }
1202 } else if (country_calling_code == kNanpaCountryCode) {
1203 // For NANPA countries, we output international format for numbers that
1204 // can be dialed internationally, since that always works, except for
1205 // numbers which might potentially be short numbers, which are always
1206 // dialled in national format.
1207 const PhoneMetadata* region_metadata = GetMetadataForRegion(calling_from);
1208 string national_number;
1209 GetNationalSignificantNumber(number_no_extension, &national_number);
1210 if (CanBeInternationallyDialled(number_no_extension) &&
1211 TestNumberLength(national_number, *region_metadata) != TOO_SHORT) {
1212 Format(number_no_extension, INTERNATIONAL, formatted_number);
1213 } else {
1214 Format(number_no_extension, NATIONAL, formatted_number);
1215 }
1216 } else {
1217 // For non-geographical countries, and Mexican, Chilean and Uzbek fixed
1218 // line and mobile numbers, we output international format for numbers
1219 // that can be dialed internationally as that always works.
1220 if ((region_code == kRegionCodeForNonGeoEntity ||
1221 // MX fixed line and mobile numbers should always be formatted in
1222 // international format, even when dialed within MX. For national
1223 // format to work, a carrier code needs to be used, and the correct
1224 // carrier code depends on if the caller and callee are from the same
1225 // local area. It is trickier to get that to work correctly than
1226 // using international format, which is tested to work fine on all
1227 // carriers.
1228 // CL fixed line numbers need the national prefix when dialing in the
1229 // national format, but don't have it when used for display. The
1230 // reverse is true for mobile numbers. As a result, we output them in
1231 // the international format to make it work.
1232 // UZ mobile and fixed-line numbers have to be formatted in
1233 // international format or prefixed with special codes like 03, 04
1234 // (for fixed-line) and 05 (for mobile) for dialling successfully
1235 // from mobile devices. As we do not have complete information on
1236 // special codes and to be consistent with formatting across all
1237 // phone types we return the number in international format here.
1238 ((region_code == "MX" ||
1239 region_code == "CL" ||
1240 region_code == "UZ") &&
1241 is_fixed_line_or_mobile)) &&
1242 CanBeInternationallyDialled(number_no_extension)) {
1243 Format(number_no_extension, INTERNATIONAL, formatted_number);
1244 } else {
1245 Format(number_no_extension, NATIONAL, formatted_number);
1246 }
1247 }
1248 } else if (is_valid_number &&
1249 CanBeInternationallyDialled(number_no_extension)) {
1250 // We assume that short numbers are not diallable from outside their
1251 // region, so if a number is not a valid regular length phone number, we
1252 // treat it as if it cannot be internationally dialled.
1253 with_formatting
1254 ? Format(number_no_extension, INTERNATIONAL, formatted_number)
1255 : Format(number_no_extension, E164, formatted_number);
1256 return;
1257 }
1258 if (!with_formatting) {
1259 NormalizeDiallableCharsOnly(formatted_number);
1260 }
1261 }
1262
FormatOutOfCountryCallingNumber(const PhoneNumber & number,const string & calling_from,string * formatted_number) const1263 void PhoneNumberUtil::FormatOutOfCountryCallingNumber(
1264 const PhoneNumber& number,
1265 const string& calling_from,
1266 string* formatted_number) const {
1267 DCHECK(formatted_number);
1268 if (!IsValidRegionCode(calling_from)) {
1269 VLOG(1) << "Trying to format number from invalid region " << calling_from
1270 << ". International formatting applied.";
1271 Format(number, INTERNATIONAL, formatted_number);
1272 return;
1273 }
1274 int country_code = number.country_code();
1275 string national_significant_number;
1276 GetNationalSignificantNumber(number, &national_significant_number);
1277 if (!HasValidCountryCallingCode(country_code)) {
1278 formatted_number->assign(national_significant_number);
1279 return;
1280 }
1281 if (country_code == kNanpaCountryCode) {
1282 if (IsNANPACountry(calling_from)) {
1283 // For NANPA regions, return the national format for these regions but
1284 // prefix it with the country calling code.
1285 Format(number, NATIONAL, formatted_number);
1286 formatted_number->insert(0, StrCat(country_code, " "));
1287 return;
1288 }
1289 } else if (country_code == GetCountryCodeForValidRegion(calling_from)) {
1290 // If neither region is a NANPA region, then we check to see if the
1291 // country calling code of the number and the country calling code of the
1292 // region we are calling from are the same.
1293 // For regions that share a country calling code, the country calling code
1294 // need not be dialled. This also applies when dialling within a region, so
1295 // this if clause covers both these cases.
1296 // Technically this is the case for dialling from la Réunion to other
1297 // overseas departments of France (French Guiana, Martinique, Guadeloupe),
1298 // but not vice versa - so we don't cover this edge case for now and for
1299 // those cases return the version including country calling code.
1300 // Details here:
1301 // http://www.petitfute.com/voyage/225-info-pratiques-reunion
1302 Format(number, NATIONAL, formatted_number);
1303 return;
1304 }
1305 // Metadata cannot be NULL because we checked 'IsValidRegionCode()' above.
1306 const PhoneMetadata* metadata_calling_from =
1307 GetMetadataForRegion(calling_from);
1308 const string& international_prefix =
1309 metadata_calling_from->international_prefix();
1310
1311 // For regions that have multiple international prefixes, the international
1312 // format of the number is returned, unless there is a preferred international
1313 // prefix.
1314 const string international_prefix_for_formatting(
1315 reg_exps_->single_international_prefix_->FullMatch(international_prefix)
1316 ? international_prefix
1317 : metadata_calling_from->preferred_international_prefix());
1318
1319 string region_code;
1320 GetRegionCodeForCountryCode(country_code, ®ion_code);
1321 // Metadata cannot be NULL because the country_code is valid.
1322 const PhoneMetadata* metadata_for_region =
1323 GetMetadataForRegionOrCallingCode(country_code, region_code);
1324 FormatNsn(national_significant_number, *metadata_for_region, INTERNATIONAL,
1325 formatted_number);
1326 MaybeAppendFormattedExtension(number, *metadata_for_region, INTERNATIONAL,
1327 formatted_number);
1328 if (!international_prefix_for_formatting.empty()) {
1329 formatted_number->insert(
1330 0, StrCat(international_prefix_for_formatting, " ", country_code, " "));
1331 } else {
1332 PrefixNumberWithCountryCallingCode(country_code, INTERNATIONAL,
1333 formatted_number);
1334 }
1335 }
1336
FormatInOriginalFormat(const PhoneNumber & number,const string & region_calling_from,string * formatted_number) const1337 void PhoneNumberUtil::FormatInOriginalFormat(const PhoneNumber& number,
1338 const string& region_calling_from,
1339 string* formatted_number) const {
1340 DCHECK(formatted_number);
1341
1342 if (number.has_raw_input() && !HasFormattingPatternForNumber(number)) {
1343 // We check if we have the formatting pattern because without that, we might
1344 // format the number as a group without national prefix.
1345 formatted_number->assign(number.raw_input());
1346 return;
1347 }
1348 if (!number.has_country_code_source()) {
1349 Format(number, NATIONAL, formatted_number);
1350 return;
1351 }
1352 switch (number.country_code_source()) {
1353 case PhoneNumber::FROM_NUMBER_WITH_PLUS_SIGN:
1354 Format(number, INTERNATIONAL, formatted_number);
1355 break;
1356 case PhoneNumber::FROM_NUMBER_WITH_IDD:
1357 FormatOutOfCountryCallingNumber(number, region_calling_from,
1358 formatted_number);
1359 break;
1360 case PhoneNumber::FROM_NUMBER_WITHOUT_PLUS_SIGN:
1361 Format(number, INTERNATIONAL, formatted_number);
1362 formatted_number->erase(formatted_number->begin());
1363 break;
1364 case PhoneNumber::FROM_DEFAULT_COUNTRY:
1365 // Fall-through to default case.
1366 default:
1367 string region_code;
1368 GetRegionCodeForCountryCode(number.country_code(), ®ion_code);
1369 // We strip non-digits from the NDD here, and from the raw input later, so
1370 // that we can compare them easily.
1371 string national_prefix;
1372 GetNddPrefixForRegion(region_code, true /* strip non-digits */,
1373 &national_prefix);
1374 if (national_prefix.empty()) {
1375 // If the region doesn't have a national prefix at all, we can safely
1376 // return the national format without worrying about a national prefix
1377 // being added.
1378 Format(number, NATIONAL, formatted_number);
1379 break;
1380 }
1381 // Otherwise, we check if the original number was entered with a national
1382 // prefix.
1383 if (RawInputContainsNationalPrefix(number.raw_input(), national_prefix,
1384 region_code)) {
1385 // If so, we can safely return the national format.
1386 Format(number, NATIONAL, formatted_number);
1387 break;
1388 }
1389 // Metadata cannot be NULL here because GetNddPrefixForRegion() (above)
1390 // leaves the prefix empty if there is no metadata for the region.
1391 const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
1392 string national_number;
1393 GetNationalSignificantNumber(number, &national_number);
1394 // This shouldn't be NULL, because we have checked that above with
1395 // HasFormattingPatternForNumber.
1396 const NumberFormat* format_rule =
1397 ChooseFormattingPatternForNumber(metadata->number_format(),
1398 national_number);
1399 // The format rule could still be NULL here if the national number was 0
1400 // and there was no raw input (this should not be possible for numbers
1401 // generated by the phonenumber library as they would also not have a
1402 // country calling code and we would have exited earlier).
1403 if (!format_rule) {
1404 Format(number, NATIONAL, formatted_number);
1405 break;
1406 }
1407 // When the format we apply to this number doesn't contain national
1408 // prefix, we can just return the national format.
1409 // TODO: Refactor the code below with the code in
1410 // IsNationalPrefixPresentIfRequired.
1411 string candidate_national_prefix_rule(
1412 format_rule->national_prefix_formatting_rule());
1413 // We assume that the first-group symbol will never be _before_ the
1414 // national prefix.
1415 if (!candidate_national_prefix_rule.empty()) {
1416 size_t index_of_first_group = candidate_national_prefix_rule.find("$1");
1417 if (index_of_first_group == string::npos) {
1418 LOG(ERROR) << "First group missing in national prefix rule: "
1419 << candidate_national_prefix_rule;
1420 Format(number, NATIONAL, formatted_number);
1421 break;
1422 }
1423 candidate_national_prefix_rule.erase(index_of_first_group);
1424 NormalizeDigitsOnly(&candidate_national_prefix_rule);
1425 }
1426 if (candidate_national_prefix_rule.empty()) {
1427 // National prefix not used when formatting this number.
1428 Format(number, NATIONAL, formatted_number);
1429 break;
1430 }
1431 // Otherwise, we need to remove the national prefix from our output.
1432 RepeatedPtrField<NumberFormat> number_formats;
1433 NumberFormat* number_format = number_formats.Add();
1434 number_format->MergeFrom(*format_rule);
1435 number_format->clear_national_prefix_formatting_rule();
1436 FormatByPattern(number, NATIONAL, number_formats, formatted_number);
1437 break;
1438 }
1439 // If no digit is inserted/removed/modified as a result of our formatting, we
1440 // return the formatted phone number; otherwise we return the raw input the
1441 // user entered.
1442 if (!formatted_number->empty() && !number.raw_input().empty()) {
1443 string normalized_formatted_number(*formatted_number);
1444 NormalizeDiallableCharsOnly(&normalized_formatted_number);
1445 string normalized_raw_input(number.raw_input());
1446 NormalizeDiallableCharsOnly(&normalized_raw_input);
1447 if (normalized_formatted_number != normalized_raw_input) {
1448 formatted_number->assign(number.raw_input());
1449 }
1450 }
1451 }
1452
1453 // Check if raw_input, which is assumed to be in the national format, has a
1454 // national prefix. The national prefix is assumed to be in digits-only form.
RawInputContainsNationalPrefix(const string & raw_input,const string & national_prefix,const string & region_code) const1455 bool PhoneNumberUtil::RawInputContainsNationalPrefix(
1456 const string& raw_input,
1457 const string& national_prefix,
1458 const string& region_code) const {
1459 string normalized_national_number(raw_input);
1460 NormalizeDigitsOnly(&normalized_national_number);
1461 if (HasPrefixString(normalized_national_number, national_prefix)) {
1462 // Some Japanese numbers (e.g. 00777123) might be mistaken to contain
1463 // the national prefix when written without it (e.g. 0777123) if we just
1464 // do prefix matching. To tackle that, we check the validity of the
1465 // number if the assumed national prefix is removed (777123 won't be
1466 // valid in Japan).
1467 PhoneNumber number_without_national_prefix;
1468 if (Parse(normalized_national_number.substr(national_prefix.length()),
1469 region_code, &number_without_national_prefix)
1470 == NO_PARSING_ERROR) {
1471 return IsValidNumber(number_without_national_prefix);
1472 }
1473 }
1474 return false;
1475 }
1476
HasFormattingPatternForNumber(const PhoneNumber & number) const1477 bool PhoneNumberUtil::HasFormattingPatternForNumber(
1478 const PhoneNumber& number) const {
1479 int country_calling_code = number.country_code();
1480 string region_code;
1481 GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
1482 const PhoneMetadata* metadata =
1483 GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
1484 if (!metadata) {
1485 return false;
1486 }
1487 string national_number;
1488 GetNationalSignificantNumber(number, &national_number);
1489 const NumberFormat* format_rule =
1490 ChooseFormattingPatternForNumber(metadata->number_format(),
1491 national_number);
1492 return format_rule;
1493 }
1494
FormatOutOfCountryKeepingAlphaChars(const PhoneNumber & number,const string & calling_from,string * formatted_number) const1495 void PhoneNumberUtil::FormatOutOfCountryKeepingAlphaChars(
1496 const PhoneNumber& number,
1497 const string& calling_from,
1498 string* formatted_number) const {
1499 // If there is no raw input, then we can't keep alpha characters because there
1500 // aren't any. In this case, we return FormatOutOfCountryCallingNumber.
1501 if (number.raw_input().empty()) {
1502 FormatOutOfCountryCallingNumber(number, calling_from, formatted_number);
1503 return;
1504 }
1505 int country_code = number.country_code();
1506 if (!HasValidCountryCallingCode(country_code)) {
1507 formatted_number->assign(number.raw_input());
1508 return;
1509 }
1510 // Strip any prefix such as country calling code, IDD, that was present. We do
1511 // this by comparing the number in raw_input with the parsed number.
1512 string raw_input_copy(number.raw_input());
1513 // Normalize punctuation. We retain number grouping symbols such as " " only.
1514 NormalizeHelper(reg_exps_->all_plus_number_grouping_symbols_, true,
1515 &raw_input_copy);
1516 // Now we trim everything before the first three digits in the parsed number.
1517 // We choose three because all valid alpha numbers have 3 digits at the start
1518 // - if it does not, then we don't trim anything at all. Similarly, if the
1519 // national number was less than three digits, we don't trim anything at all.
1520 string national_number;
1521 GetNationalSignificantNumber(number, &national_number);
1522 if (national_number.length() > 3) {
1523 size_t first_national_number_digit =
1524 raw_input_copy.find(national_number.substr(0, 3));
1525 if (first_national_number_digit != string::npos) {
1526 raw_input_copy = raw_input_copy.substr(first_national_number_digit);
1527 }
1528 }
1529 const PhoneMetadata* metadata = GetMetadataForRegion(calling_from);
1530 if (country_code == kNanpaCountryCode) {
1531 if (IsNANPACountry(calling_from)) {
1532 StrAppend(formatted_number, country_code, " ", raw_input_copy);
1533 return;
1534 }
1535 } else if (metadata &&
1536 country_code == GetCountryCodeForValidRegion(calling_from)) {
1537 const NumberFormat* formatting_pattern =
1538 ChooseFormattingPatternForNumber(metadata->number_format(),
1539 national_number);
1540 if (!formatting_pattern) {
1541 // If no pattern above is matched, we format the original input.
1542 formatted_number->assign(raw_input_copy);
1543 return;
1544 }
1545 NumberFormat new_format;
1546 new_format.MergeFrom(*formatting_pattern);
1547 // The first group is the first group of digits that the user wrote
1548 // together.
1549 new_format.set_pattern("(\\d+)(.*)");
1550 // Here we just concatenate them back together after the national prefix
1551 // has been fixed.
1552 new_format.set_format("$1$2");
1553 // Now we format using this pattern instead of the default pattern, but
1554 // with the national prefix prefixed if necessary.
1555 // This will not work in the cases where the pattern (and not the
1556 // leading digits) decide whether a national prefix needs to be used, since
1557 // we have overridden the pattern to match anything, but that is not the
1558 // case in the metadata to date.
1559 FormatNsnUsingPattern(raw_input_copy, new_format, NATIONAL,
1560 formatted_number);
1561 return;
1562 }
1563
1564 string international_prefix_for_formatting;
1565 // If an unsupported region-calling-from is entered, or a country with
1566 // multiple international prefixes, the international format of the number is
1567 // returned, unless there is a preferred international prefix.
1568 if (metadata) {
1569 const string& international_prefix = metadata->international_prefix();
1570 international_prefix_for_formatting =
1571 reg_exps_->single_international_prefix_->FullMatch(international_prefix)
1572 ? international_prefix
1573 : metadata->preferred_international_prefix();
1574 }
1575 if (!international_prefix_for_formatting.empty()) {
1576 StrAppend(formatted_number, international_prefix_for_formatting, " ",
1577 country_code, " ", raw_input_copy);
1578 } else {
1579 // Invalid region entered as country-calling-from (so no metadata was found
1580 // for it) or the region chosen has multiple international dialling
1581 // prefixes.
1582 if (!IsValidRegionCode(calling_from)) {
1583 VLOG(1) << "Trying to format number from invalid region " << calling_from
1584 << ". International formatting applied.";
1585 }
1586 formatted_number->assign(raw_input_copy);
1587 PrefixNumberWithCountryCallingCode(country_code, INTERNATIONAL,
1588 formatted_number);
1589 }
1590 }
1591
ChooseFormattingPatternForNumber(const RepeatedPtrField<NumberFormat> & available_formats,const string & national_number) const1592 const NumberFormat* PhoneNumberUtil::ChooseFormattingPatternForNumber(
1593 const RepeatedPtrField<NumberFormat>& available_formats,
1594 const string& national_number) const {
1595 for (RepeatedPtrField<NumberFormat>::const_iterator
1596 it = available_formats.begin(); it != available_formats.end(); ++it) {
1597 int size = it->leading_digits_pattern_size();
1598 if (size > 0) {
1599 const scoped_ptr<RegExpInput> number_copy(
1600 reg_exps_->regexp_factory_->CreateInput(national_number));
1601 // We always use the last leading_digits_pattern, as it is the most
1602 // detailed.
1603 if (!reg_exps_->regexp_cache_->GetRegExp(
1604 it->leading_digits_pattern(size - 1)).Consume(
1605 number_copy.get())) {
1606 continue;
1607 }
1608 }
1609 const RegExp& pattern_to_match(
1610 reg_exps_->regexp_cache_->GetRegExp(it->pattern()));
1611 if (pattern_to_match.FullMatch(national_number)) {
1612 return &(*it);
1613 }
1614 }
1615 return NULL;
1616 }
1617
1618 // Note that carrier_code is optional - if an empty string, no carrier code
1619 // replacement will take place.
FormatNsnUsingPatternWithCarrier(const string & national_number,const NumberFormat & formatting_pattern,PhoneNumberUtil::PhoneNumberFormat number_format,const string & carrier_code,string * formatted_number) const1620 void PhoneNumberUtil::FormatNsnUsingPatternWithCarrier(
1621 const string& national_number,
1622 const NumberFormat& formatting_pattern,
1623 PhoneNumberUtil::PhoneNumberFormat number_format,
1624 const string& carrier_code,
1625 string* formatted_number) const {
1626 DCHECK(formatted_number);
1627 string number_format_rule(formatting_pattern.format());
1628 if (number_format == PhoneNumberUtil::NATIONAL &&
1629 carrier_code.length() > 0 &&
1630 formatting_pattern.domestic_carrier_code_formatting_rule().length() > 0) {
1631 // Replace the $CC in the formatting rule with the desired carrier code.
1632 string carrier_code_formatting_rule =
1633 formatting_pattern.domestic_carrier_code_formatting_rule();
1634 reg_exps_->carrier_code_pattern_->Replace(&carrier_code_formatting_rule,
1635 carrier_code);
1636 reg_exps_->first_group_capturing_pattern_->
1637 Replace(&number_format_rule, carrier_code_formatting_rule);
1638 } else {
1639 // Use the national prefix formatting rule instead.
1640 string national_prefix_formatting_rule =
1641 formatting_pattern.national_prefix_formatting_rule();
1642 if (number_format == PhoneNumberUtil::NATIONAL &&
1643 national_prefix_formatting_rule.length() > 0) {
1644 // Apply the national_prefix_formatting_rule as the formatting_pattern
1645 // contains only information on how the national significant number
1646 // should be formatted at this point.
1647 reg_exps_->first_group_capturing_pattern_->Replace(
1648 &number_format_rule, national_prefix_formatting_rule);
1649 }
1650 }
1651 formatted_number->assign(national_number);
1652
1653 const RegExp& pattern_to_match(
1654 reg_exps_->regexp_cache_->GetRegExp(formatting_pattern.pattern()));
1655 pattern_to_match.GlobalReplace(formatted_number, number_format_rule);
1656
1657 if (number_format == RFC3966) {
1658 // First consume any leading punctuation, if any was present.
1659 const scoped_ptr<RegExpInput> number(
1660 reg_exps_->regexp_factory_->CreateInput(*formatted_number));
1661 if (reg_exps_->separator_pattern_->Consume(number.get())) {
1662 formatted_number->assign(number->ToString());
1663 }
1664 // Then replace all separators with a "-".
1665 reg_exps_->separator_pattern_->GlobalReplace(formatted_number, "-");
1666 }
1667 }
1668
1669 // Simple wrapper of FormatNsnUsingPatternWithCarrier for the common case of
1670 // no carrier code.
FormatNsnUsingPattern(const string & national_number,const NumberFormat & formatting_pattern,PhoneNumberUtil::PhoneNumberFormat number_format,string * formatted_number) const1671 void PhoneNumberUtil::FormatNsnUsingPattern(
1672 const string& national_number,
1673 const NumberFormat& formatting_pattern,
1674 PhoneNumberUtil::PhoneNumberFormat number_format,
1675 string* formatted_number) const {
1676 DCHECK(formatted_number);
1677 FormatNsnUsingPatternWithCarrier(national_number, formatting_pattern,
1678 number_format, "", formatted_number);
1679 }
1680
FormatNsn(const string & number,const PhoneMetadata & metadata,PhoneNumberFormat number_format,string * formatted_number) const1681 void PhoneNumberUtil::FormatNsn(const string& number,
1682 const PhoneMetadata& metadata,
1683 PhoneNumberFormat number_format,
1684 string* formatted_number) const {
1685 DCHECK(formatted_number);
1686 FormatNsnWithCarrier(number, metadata, number_format, "", formatted_number);
1687 }
1688
1689 // Note in some regions, the national number can be written in two completely
1690 // different ways depending on whether it forms part of the NATIONAL format or
1691 // INTERNATIONAL format. The number_format parameter here is used to specify
1692 // which format to use for those cases. If a carrier_code is specified, this
1693 // will be inserted into the formatted string to replace $CC.
FormatNsnWithCarrier(const string & number,const PhoneMetadata & metadata,PhoneNumberFormat number_format,const string & carrier_code,string * formatted_number) const1694 void PhoneNumberUtil::FormatNsnWithCarrier(const string& number,
1695 const PhoneMetadata& metadata,
1696 PhoneNumberFormat number_format,
1697 const string& carrier_code,
1698 string* formatted_number) const {
1699 DCHECK(formatted_number);
1700 // When the intl_number_formats exists, we use that to format national number
1701 // for the INTERNATIONAL format instead of using the number_formats.
1702 const RepeatedPtrField<NumberFormat> available_formats =
1703 (metadata.intl_number_format_size() == 0 || number_format == NATIONAL)
1704 ? metadata.number_format()
1705 : metadata.intl_number_format();
1706 const NumberFormat* formatting_pattern =
1707 ChooseFormattingPatternForNumber(available_formats, number);
1708 if (!formatting_pattern) {
1709 formatted_number->assign(number);
1710 } else {
1711 FormatNsnUsingPatternWithCarrier(number, *formatting_pattern, number_format,
1712 carrier_code, formatted_number);
1713 }
1714 }
1715
1716 // Appends the formatted extension of a phone number, if the phone number had an
1717 // extension specified.
MaybeAppendFormattedExtension(const PhoneNumber & number,const PhoneMetadata & metadata,PhoneNumberFormat number_format,string * formatted_number) const1718 void PhoneNumberUtil::MaybeAppendFormattedExtension(
1719 const PhoneNumber& number,
1720 const PhoneMetadata& metadata,
1721 PhoneNumberFormat number_format,
1722 string* formatted_number) const {
1723 DCHECK(formatted_number);
1724 if (number.has_extension() && number.extension().length() > 0) {
1725 if (number_format == RFC3966) {
1726 StrAppend(formatted_number, kRfc3966ExtnPrefix, number.extension());
1727 } else {
1728 if (metadata.has_preferred_extn_prefix()) {
1729 StrAppend(formatted_number, metadata.preferred_extn_prefix(),
1730 number.extension());
1731 } else {
1732 StrAppend(formatted_number, kDefaultExtnPrefix, number.extension());
1733 }
1734 }
1735 }
1736 }
1737
IsNANPACountry(const string & region_code) const1738 bool PhoneNumberUtil::IsNANPACountry(const string& region_code) const {
1739 return nanpa_regions_->find(region_code) != nanpa_regions_->end();
1740 }
1741
1742 // Returns the region codes that matches the specific country calling code. In
1743 // the case of no region code being found, region_codes will be left empty.
GetRegionCodesForCountryCallingCode(int country_calling_code,std::list<string> * region_codes) const1744 void PhoneNumberUtil::GetRegionCodesForCountryCallingCode(
1745 int country_calling_code,
1746 std::list<string>* region_codes) const {
1747 DCHECK(region_codes);
1748 // Create a IntRegionsPair with the country_code passed in, and use it to
1749 // locate the pair with the same country_code in the sorted vector.
1750 IntRegionsPair target_pair;
1751 target_pair.first = country_calling_code;
1752 typedef std::vector<IntRegionsPair>::const_iterator ConstIterator;
1753 std::pair<ConstIterator, ConstIterator> range =
1754 std::equal_range(country_calling_code_to_region_code_map_->begin(),
1755 country_calling_code_to_region_code_map_->end(),
1756 target_pair, OrderByFirst());
1757 if (range.first != range.second) {
1758 region_codes->insert(region_codes->begin(),
1759 range.first->second->begin(),
1760 range.first->second->end());
1761 }
1762 }
1763
1764 // Returns the region code that matches the specific country calling code. In
1765 // the case of no region code being found, the unknown region code will be
1766 // returned.
GetRegionCodeForCountryCode(int country_calling_code,string * region_code) const1767 void PhoneNumberUtil::GetRegionCodeForCountryCode(
1768 int country_calling_code,
1769 string* region_code) const {
1770 DCHECK(region_code);
1771 std::list<string> region_codes;
1772
1773 GetRegionCodesForCountryCallingCode(country_calling_code, ®ion_codes);
1774 *region_code = (region_codes.size() > 0) ?
1775 region_codes.front() : RegionCode::GetUnknown();
1776 }
1777
GetRegionCodeForNumber(const PhoneNumber & number,string * region_code) const1778 void PhoneNumberUtil::GetRegionCodeForNumber(const PhoneNumber& number,
1779 string* region_code) const {
1780 DCHECK(region_code);
1781 int country_calling_code = number.country_code();
1782 std::list<string> region_codes;
1783 GetRegionCodesForCountryCallingCode(country_calling_code, ®ion_codes);
1784 if (region_codes.size() == 0) {
1785 VLOG(1) << "Missing/invalid country calling code ("
1786 << country_calling_code << ")";
1787 *region_code = RegionCode::GetUnknown();
1788 return;
1789 }
1790 if (region_codes.size() == 1) {
1791 *region_code = region_codes.front();
1792 } else {
1793 GetRegionCodeForNumberFromRegionList(number, region_codes, region_code);
1794 }
1795 }
1796
GetRegionCodeForNumberFromRegionList(const PhoneNumber & number,const std::list<string> & region_codes,string * region_code) const1797 void PhoneNumberUtil::GetRegionCodeForNumberFromRegionList(
1798 const PhoneNumber& number, const std::list<string>& region_codes,
1799 string* region_code) const {
1800 DCHECK(region_code);
1801 string national_number;
1802 GetNationalSignificantNumber(number, &national_number);
1803 for (std::list<string>::const_iterator it = region_codes.begin();
1804 it != region_codes.end(); ++it) {
1805 // Metadata cannot be NULL because the region codes come from the country
1806 // calling code map.
1807 const PhoneMetadata* metadata = GetMetadataForRegion(*it);
1808 if (metadata->has_leading_digits()) {
1809 const scoped_ptr<RegExpInput> number(
1810 reg_exps_->regexp_factory_->CreateInput(national_number));
1811 if (reg_exps_->regexp_cache_->
1812 GetRegExp(metadata->leading_digits()).Consume(number.get())) {
1813 *region_code = *it;
1814 return;
1815 }
1816 } else if (GetNumberTypeHelper(national_number, *metadata) != UNKNOWN) {
1817 *region_code = *it;
1818 return;
1819 }
1820 }
1821 *region_code = RegionCode::GetUnknown();
1822 }
1823
GetCountryCodeForRegion(const string & region_code) const1824 int PhoneNumberUtil::GetCountryCodeForRegion(const string& region_code) const {
1825 if (!IsValidRegionCode(region_code)) {
1826 LOG(WARNING) << "Invalid or unknown region code (" << region_code
1827 << ") provided.";
1828 return 0;
1829 }
1830 return GetCountryCodeForValidRegion(region_code);
1831 }
1832
GetCountryCodeForValidRegion(const string & region_code) const1833 int PhoneNumberUtil::GetCountryCodeForValidRegion(
1834 const string& region_code) const {
1835 const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
1836 return metadata->country_code();
1837 }
1838
1839 // Gets a valid fixed-line number for the specified region_code. Returns false
1840 // if the region was unknown or 001 (representing non-geographical regions), or
1841 // if no number exists.
GetExampleNumber(const string & region_code,PhoneNumber * number) const1842 bool PhoneNumberUtil::GetExampleNumber(const string& region_code,
1843 PhoneNumber* number) const {
1844 DCHECK(number);
1845 return GetExampleNumberForType(region_code, FIXED_LINE, number);
1846 }
1847
GetInvalidExampleNumber(const string & region_code,PhoneNumber * number) const1848 bool PhoneNumberUtil::GetInvalidExampleNumber(const string& region_code,
1849 PhoneNumber* number) const {
1850 DCHECK(number);
1851 if (!IsValidRegionCode(region_code)) {
1852 LOG(WARNING) << "Invalid or unknown region code (" << region_code
1853 << ") provided.";
1854 return false;
1855 }
1856 // We start off with a valid fixed-line number since every country supports
1857 // this. Alternatively we could start with a different number type, since
1858 // fixed-line numbers typically have a wide breadth of valid number lengths
1859 // and we may have to make it very short before we get an invalid number.
1860 const PhoneMetadata* region_metadata = GetMetadataForRegion(region_code);
1861 const PhoneNumberDesc* desc =
1862 GetNumberDescByType(*region_metadata, FIXED_LINE);
1863 if (!desc->has_example_number()) {
1864 // This shouldn't happen - we have a test for this.
1865 return false;
1866 }
1867 const string& example_number = desc->example_number();
1868 // Try and make the number invalid. We do this by changing the length. We try
1869 // reducing the length of the number, since currently no region has a number
1870 // that is the same length as kMinLengthForNsn. This is probably quicker than
1871 // making the number longer, which is another alternative. We could also use
1872 // the possible number pattern to extract the possible lengths of the number
1873 // to make this faster, but this method is only for unit-testing so simplicity
1874 // is preferred to performance.
1875 // We don't want to return a number that can't be parsed, so we check the
1876 // number is long enough. We try all possible lengths because phone number
1877 // plans often have overlapping prefixes so the number 123456 might be valid
1878 // as a fixed-line number, and 12345 as a mobile number. It would be faster to
1879 // loop in a different order, but we prefer numbers that look closer to real
1880 // numbers (and it gives us a variety of different lengths for the resulting
1881 // phone numbers - otherwise they would all be kMinLengthForNsn digits long.)
1882 for (size_t phone_number_length = example_number.length() - 1;
1883 phone_number_length >= kMinLengthForNsn;
1884 phone_number_length--) {
1885 string number_to_try = example_number.substr(0, phone_number_length);
1886 PhoneNumber possibly_valid_number;
1887 Parse(number_to_try, region_code, &possibly_valid_number);
1888 // We don't check the return value since we have already checked the
1889 // length, we know example numbers have only valid digits, and we know the
1890 // region code is fine.
1891 if (!IsValidNumber(possibly_valid_number)) {
1892 number->MergeFrom(possibly_valid_number);
1893 return true;
1894 }
1895 }
1896 // We have a test to check that this doesn't happen for any of our supported
1897 // regions.
1898 return false;
1899 }
1900
1901 // Gets a valid number for the specified region_code and type. Returns false if
1902 // the country was unknown or 001 (representing non-geographical regions), or if
1903 // no number exists.
GetExampleNumberForType(const string & region_code,PhoneNumberUtil::PhoneNumberType type,PhoneNumber * number) const1904 bool PhoneNumberUtil::GetExampleNumberForType(
1905 const string& region_code,
1906 PhoneNumberUtil::PhoneNumberType type,
1907 PhoneNumber* number) const {
1908 DCHECK(number);
1909 if (!IsValidRegionCode(region_code)) {
1910 LOG(WARNING) << "Invalid or unknown region code (" << region_code
1911 << ") provided.";
1912 return false;
1913 }
1914 const PhoneMetadata* region_metadata = GetMetadataForRegion(region_code);
1915 const PhoneNumberDesc* desc = GetNumberDescByType(*region_metadata, type);
1916 if (desc && desc->has_example_number()) {
1917 ErrorType success = Parse(desc->example_number(), region_code, number);
1918 if (success == NO_PARSING_ERROR) {
1919 return true;
1920 } else {
1921 LOG(ERROR) << "Error parsing example number ("
1922 << static_cast<int>(success) << ")";
1923 }
1924 }
1925 return false;
1926 }
1927
GetExampleNumberForType(PhoneNumberUtil::PhoneNumberType type,PhoneNumber * number) const1928 bool PhoneNumberUtil::GetExampleNumberForType(
1929 PhoneNumberUtil::PhoneNumberType type,
1930 PhoneNumber* number) const {
1931 DCHECK(number);
1932 std::set<string> regions;
1933 GetSupportedRegions(®ions);
1934 for (std::set<string>::const_iterator it = regions.begin();
1935 it != regions.end(); ++it) {
1936 if (GetExampleNumberForType(*it, type, number)) {
1937 return true;
1938 }
1939 }
1940 // If there wasn't an example number for a region, try the non-geographical
1941 // entities.
1942 std::set<int> global_network_calling_codes;
1943 GetSupportedGlobalNetworkCallingCodes(&global_network_calling_codes);
1944 for (std::set<int>::const_iterator it = global_network_calling_codes.begin();
1945 it != global_network_calling_codes.end(); ++it) {
1946 int country_calling_code = *it;
1947 const PhoneMetadata* metadata =
1948 GetMetadataForNonGeographicalRegion(country_calling_code);
1949 const PhoneNumberDesc* desc = GetNumberDescByType(*metadata, type);
1950 if (desc->has_example_number()) {
1951 ErrorType success = Parse(StrCat(kPlusSign,
1952 country_calling_code,
1953 desc->example_number()),
1954 RegionCode::GetUnknown(), number);
1955 if (success == NO_PARSING_ERROR) {
1956 return true;
1957 } else {
1958 LOG(ERROR) << "Error parsing example number ("
1959 << static_cast<int>(success) << ")";
1960 }
1961 }
1962 }
1963 // There are no example numbers of this type for any country in the library.
1964 return false;
1965 }
1966
GetExampleNumberForNonGeoEntity(int country_calling_code,PhoneNumber * number) const1967 bool PhoneNumberUtil::GetExampleNumberForNonGeoEntity(
1968 int country_calling_code, PhoneNumber* number) const {
1969 DCHECK(number);
1970 const PhoneMetadata* metadata =
1971 GetMetadataForNonGeographicalRegion(country_calling_code);
1972 if (metadata) {
1973 // For geographical entities, fixed-line data is always present. However,
1974 // for non-geographical entities, this is not the case, so we have to go
1975 // through different types to find the example number. We don't check
1976 // fixed-line or personal number since they aren't used by non-geographical
1977 // entities (if this changes, a unit-test will catch this.)
1978 const int kNumberTypes = 7;
1979 PhoneNumberDesc types[kNumberTypes] = {
1980 metadata->mobile(), metadata->toll_free(), metadata->shared_cost(),
1981 metadata->voip(), metadata->voicemail(), metadata->uan(),
1982 metadata->premium_rate()};
1983 for (int i = 0; i < kNumberTypes; ++i) {
1984 if (types[i].has_example_number()) {
1985 ErrorType success = Parse(StrCat(kPlusSign,
1986 SimpleItoa(country_calling_code),
1987 types[i].example_number()),
1988 RegionCode::GetUnknown(), number);
1989 if (success == NO_PARSING_ERROR) {
1990 return true;
1991 } else {
1992 LOG(ERROR) << "Error parsing example number ("
1993 << static_cast<int>(success) << ")";
1994 }
1995 }
1996 }
1997 } else {
1998 LOG(WARNING) << "Invalid or unknown country calling code provided: "
1999 << country_calling_code;
2000 }
2001 return false;
2002 }
2003
Parse(const string & number_to_parse,const string & default_region,PhoneNumber * number) const2004 PhoneNumberUtil::ErrorType PhoneNumberUtil::Parse(const string& number_to_parse,
2005 const string& default_region,
2006 PhoneNumber* number) const {
2007 DCHECK(number);
2008 return ParseHelper(number_to_parse, default_region, false, true, number);
2009 }
2010
ParseAndKeepRawInput(const string & number_to_parse,const string & default_region,PhoneNumber * number) const2011 PhoneNumberUtil::ErrorType PhoneNumberUtil::ParseAndKeepRawInput(
2012 const string& number_to_parse,
2013 const string& default_region,
2014 PhoneNumber* number) const {
2015 DCHECK(number);
2016 return ParseHelper(number_to_parse, default_region, true, true, number);
2017 }
2018
2019 // Checks to see that the region code used is valid, or if it is not valid, that
2020 // the number to parse starts with a + symbol so that we can attempt to infer
2021 // the country from the number. Returns false if it cannot use the region
2022 // provided and the region cannot be inferred.
CheckRegionForParsing(const string & number_to_parse,const string & default_region) const2023 bool PhoneNumberUtil::CheckRegionForParsing(
2024 const string& number_to_parse,
2025 const string& default_region) const {
2026 if (!IsValidRegionCode(default_region) && !number_to_parse.empty()) {
2027 const scoped_ptr<RegExpInput> number(
2028 reg_exps_->regexp_factory_->CreateInput(number_to_parse));
2029 if (!reg_exps_->plus_chars_pattern_->Consume(number.get())) {
2030 return false;
2031 }
2032 }
2033 return true;
2034 }
2035
2036 // Converts number_to_parse to a form that we can parse and write it to
2037 // national_number if it is written in RFC3966; otherwise extract a possible
2038 // number out of it and write to national_number.
BuildNationalNumberForParsing(const string & number_to_parse,string * national_number) const2039 void PhoneNumberUtil::BuildNationalNumberForParsing(
2040 const string& number_to_parse, string* national_number) const {
2041 size_t index_of_phone_context = number_to_parse.find(kRfc3966PhoneContext);
2042 if (index_of_phone_context != string::npos) {
2043 size_t phone_context_start =
2044 index_of_phone_context + strlen(kRfc3966PhoneContext);
2045 // If the phone context contains a phone number prefix, we need to capture
2046 // it, whereas domains will be ignored.
2047 if (phone_context_start < (number_to_parse.length() - 1) &&
2048 number_to_parse.at(phone_context_start) == kPlusSign[0]) {
2049 // Additional parameters might follow the phone context. If so, we will
2050 // remove them here because the parameters after phone context are not
2051 // important for parsing the phone number.
2052 size_t phone_context_end = number_to_parse.find(';', phone_context_start);
2053 if (phone_context_end != string::npos) {
2054 StrAppend(
2055 national_number, number_to_parse.substr(
2056 phone_context_start, phone_context_end - phone_context_start));
2057 } else {
2058 StrAppend(national_number, number_to_parse.substr(phone_context_start));
2059 }
2060 }
2061
2062 // Now append everything between the "tel:" prefix and the phone-context.
2063 // This should include the national number, an optional extension or
2064 // isdn-subaddress component. Note we also handle the case when "tel:" is
2065 // missing, as we have seen in some of the phone number inputs. In that
2066 // case, we append everything from the beginning.
2067 size_t index_of_rfc_prefix = number_to_parse.find(kRfc3966Prefix);
2068 int index_of_national_number = (index_of_rfc_prefix != string::npos) ?
2069 index_of_rfc_prefix + strlen(kRfc3966Prefix) : 0;
2070 StrAppend(
2071 national_number,
2072 number_to_parse.substr(
2073 index_of_national_number,
2074 index_of_phone_context - index_of_national_number));
2075 } else {
2076 // Extract a possible number from the string passed in (this strips leading
2077 // characters that could not be the start of a phone number.)
2078 ExtractPossibleNumber(number_to_parse, national_number);
2079 }
2080
2081 // Delete the isdn-subaddress and everything after it if it is present. Note
2082 // extension won't appear at the same time with isdn-subaddress according to
2083 // paragraph 5.3 of the RFC3966 spec.
2084 size_t index_of_isdn = national_number->find(kRfc3966IsdnSubaddress);
2085 if (index_of_isdn != string::npos) {
2086 national_number->erase(index_of_isdn);
2087 }
2088 // If both phone context and isdn-subaddress are absent but other parameters
2089 // are present, the parameters are left in nationalNumber. This is because
2090 // we are concerned about deleting content from a potential number string
2091 // when there is no strong evidence that the number is actually written in
2092 // RFC3966.
2093 }
2094
2095 // Note if any new field is added to this method that should always be filled
2096 // in, even when keepRawInput is false, it should also be handled in the
2097 // CopyCoreFieldsOnly() method.
ParseHelper(const string & number_to_parse,const string & default_region,bool keep_raw_input,bool check_region,PhoneNumber * phone_number) const2098 PhoneNumberUtil::ErrorType PhoneNumberUtil::ParseHelper(
2099 const string& number_to_parse,
2100 const string& default_region,
2101 bool keep_raw_input,
2102 bool check_region,
2103 PhoneNumber* phone_number) const {
2104 DCHECK(phone_number);
2105
2106 string national_number;
2107 BuildNationalNumberForParsing(number_to_parse, &national_number);
2108
2109 if (!IsViablePhoneNumber(national_number)) {
2110 VLOG(2) << "The string supplied did not seem to be a phone number.";
2111 return NOT_A_NUMBER;
2112 }
2113
2114 if (check_region &&
2115 !CheckRegionForParsing(national_number, default_region)) {
2116 VLOG(1) << "Missing or invalid default country.";
2117 return INVALID_COUNTRY_CODE_ERROR;
2118 }
2119 PhoneNumber temp_number;
2120 if (keep_raw_input) {
2121 temp_number.set_raw_input(number_to_parse);
2122 }
2123 // Attempt to parse extension first, since it doesn't require country-specific
2124 // data and we want to have the non-normalised number here.
2125 string extension;
2126 MaybeStripExtension(&national_number, &extension);
2127 if (!extension.empty()) {
2128 temp_number.set_extension(extension);
2129 }
2130 const PhoneMetadata* country_metadata = GetMetadataForRegion(default_region);
2131 // Check to see if the number is given in international format so we know
2132 // whether this number is from the default country or not.
2133 string normalized_national_number(national_number);
2134 ErrorType country_code_error =
2135 MaybeExtractCountryCode(country_metadata, keep_raw_input,
2136 &normalized_national_number, &temp_number);
2137 if (country_code_error != NO_PARSING_ERROR) {
2138 const scoped_ptr<RegExpInput> number_string_piece(
2139 reg_exps_->regexp_factory_->CreateInput(national_number));
2140 if ((country_code_error == INVALID_COUNTRY_CODE_ERROR) &&
2141 (reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get()))) {
2142 normalized_national_number.assign(number_string_piece->ToString());
2143 // Strip the plus-char, and try again.
2144 MaybeExtractCountryCode(country_metadata,
2145 keep_raw_input,
2146 &normalized_national_number,
2147 &temp_number);
2148 if (temp_number.country_code() == 0) {
2149 return INVALID_COUNTRY_CODE_ERROR;
2150 }
2151 } else {
2152 return country_code_error;
2153 }
2154 }
2155 int country_code = temp_number.country_code();
2156 if (country_code != 0) {
2157 string phone_number_region;
2158 GetRegionCodeForCountryCode(country_code, &phone_number_region);
2159 if (phone_number_region != default_region) {
2160 country_metadata =
2161 GetMetadataForRegionOrCallingCode(country_code, phone_number_region);
2162 }
2163 } else if (country_metadata) {
2164 // If no extracted country calling code, use the region supplied instead.
2165 // Note that the national number was already normalized by
2166 // MaybeExtractCountryCode.
2167 country_code = country_metadata->country_code();
2168 }
2169 if (normalized_national_number.length() < kMinLengthForNsn) {
2170 VLOG(2) << "The string supplied is too short to be a phone number.";
2171 return TOO_SHORT_NSN;
2172 }
2173 if (country_metadata) {
2174 string carrier_code;
2175 string potential_national_number(normalized_national_number);
2176 MaybeStripNationalPrefixAndCarrierCode(*country_metadata,
2177 &potential_national_number,
2178 &carrier_code);
2179 // We require that the NSN remaining after stripping the national prefix
2180 // and carrier code be long enough to be a possible length for the region.
2181 // Otherwise, we don't do the stripping, since the original number could be
2182 // a valid short number.
2183 ValidationResult validation_result =
2184 TestNumberLength(potential_national_number, *country_metadata);
2185 if (validation_result != TOO_SHORT &&
2186 validation_result != IS_POSSIBLE_LOCAL_ONLY &&
2187 validation_result != INVALID_LENGTH) {
2188 normalized_national_number.assign(potential_national_number);
2189 if (keep_raw_input && !carrier_code.empty()) {
2190 temp_number.set_preferred_domestic_carrier_code(carrier_code);
2191 }
2192 }
2193 }
2194 size_t normalized_national_number_length =
2195 normalized_national_number.length();
2196 if (normalized_national_number_length < kMinLengthForNsn) {
2197 VLOG(2) << "The string supplied is too short to be a phone number.";
2198 return TOO_SHORT_NSN;
2199 }
2200 if (normalized_national_number_length > kMaxLengthForNsn) {
2201 VLOG(2) << "The string supplied is too long to be a phone number.";
2202 return TOO_LONG_NSN;
2203 }
2204 temp_number.set_country_code(country_code);
2205 SetItalianLeadingZerosForPhoneNumber(normalized_national_number,
2206 &temp_number);
2207 uint64 number_as_int;
2208 safe_strtou64(normalized_national_number, &number_as_int);
2209 temp_number.set_national_number(number_as_int);
2210 phone_number->Swap(&temp_number);
2211 return NO_PARSING_ERROR;
2212 }
2213
2214 // Attempts to extract a possible number from the string passed in. This
2215 // currently strips all leading characters that could not be used to start a
2216 // phone number. Characters that can be used to start a phone number are
2217 // defined in the valid_start_char_pattern. If none of these characters are
2218 // found in the number passed in, an empty string is returned. This function
2219 // also attempts to strip off any alternative extensions or endings if two or
2220 // more are present, such as in the case of: (530) 583-6985 x302/x2303. The
2221 // second extension here makes this actually two phone numbers, (530) 583-6985
2222 // x302 and (530) 583-6985 x2303. We remove the second extension so that the
2223 // first number is parsed correctly.
ExtractPossibleNumber(const string & number,string * extracted_number) const2224 void PhoneNumberUtil::ExtractPossibleNumber(const string& number,
2225 string* extracted_number) const {
2226 DCHECK(extracted_number);
2227
2228 UnicodeText number_as_unicode;
2229 number_as_unicode.PointToUTF8(number.data(), number.size());
2230 char current_char[5];
2231 int len;
2232 UnicodeText::const_iterator it;
2233 for (it = number_as_unicode.begin(); it != number_as_unicode.end(); ++it) {
2234 len = it.get_utf8(current_char);
2235 current_char[len] = '\0';
2236 if (reg_exps_->valid_start_char_pattern_->FullMatch(current_char)) {
2237 break;
2238 }
2239 }
2240
2241 if (it == number_as_unicode.end()) {
2242 // No valid start character was found. extracted_number should be set to
2243 // empty string.
2244 extracted_number->assign("");
2245 return;
2246 }
2247
2248 extracted_number->assign(
2249 UnicodeText::UTF8Substring(it, number_as_unicode.end()));
2250 TrimUnwantedEndChars(extracted_number);
2251 if (extracted_number->length() == 0) {
2252 return;
2253 }
2254
2255 // Now remove any extra numbers at the end.
2256 reg_exps_->capture_up_to_second_number_start_pattern_->
2257 PartialMatch(*extracted_number, extracted_number);
2258 }
2259
IsPossibleNumber(const PhoneNumber & number) const2260 bool PhoneNumberUtil::IsPossibleNumber(const PhoneNumber& number) const {
2261 ValidationResult result = IsPossibleNumberWithReason(number);
2262 return result == IS_POSSIBLE || result == IS_POSSIBLE_LOCAL_ONLY;
2263 }
2264
IsPossibleNumberForType(const PhoneNumber & number,const PhoneNumberType type) const2265 bool PhoneNumberUtil::IsPossibleNumberForType(
2266 const PhoneNumber& number, const PhoneNumberType type) const {
2267 ValidationResult result = IsPossibleNumberForTypeWithReason(number, type);
2268 return result == IS_POSSIBLE || result == IS_POSSIBLE_LOCAL_ONLY;
2269 }
2270
IsPossibleNumberForString(const string & number,const string & region_dialing_from) const2271 bool PhoneNumberUtil::IsPossibleNumberForString(
2272 const string& number,
2273 const string& region_dialing_from) const {
2274 PhoneNumber number_proto;
2275 if (Parse(number, region_dialing_from, &number_proto) == NO_PARSING_ERROR) {
2276 return IsPossibleNumber(number_proto);
2277 } else {
2278 return false;
2279 }
2280 }
2281
IsPossibleNumberWithReason(const PhoneNumber & number) const2282 PhoneNumberUtil::ValidationResult PhoneNumberUtil::IsPossibleNumberWithReason(
2283 const PhoneNumber& number) const {
2284 return IsPossibleNumberForTypeWithReason(number, PhoneNumberUtil::UNKNOWN);
2285 }
2286
2287 PhoneNumberUtil::ValidationResult
IsPossibleNumberForTypeWithReason(const PhoneNumber & number,PhoneNumberType type) const2288 PhoneNumberUtil::IsPossibleNumberForTypeWithReason(const PhoneNumber& number,
2289 PhoneNumberType type) const {
2290 string national_number;
2291 GetNationalSignificantNumber(number, &national_number);
2292 int country_code = number.country_code();
2293 // Note: For regions that share a country calling code, like NANPA numbers, we
2294 // just use the rules from the default region (US in this case) since the
2295 // GetRegionCodeForNumber will not work if the number is possible but not
2296 // valid. There is in fact one country calling code (290) where the possible
2297 // number pattern differs between various regions (Saint Helena and Tristan da
2298 // Cuñha), but this is handled by putting all possible lengths for any country
2299 // with this country calling code in the metadata for the default region in
2300 // this case.
2301 if (!HasValidCountryCallingCode(country_code)) {
2302 return INVALID_COUNTRY_CODE;
2303 }
2304 string region_code;
2305 GetRegionCodeForCountryCode(country_code, ®ion_code);
2306 // Metadata cannot be NULL because the country calling code is valid.
2307 const PhoneMetadata* metadata =
2308 GetMetadataForRegionOrCallingCode(country_code, region_code);
2309 return TestNumberLength(national_number, *metadata, type);
2310 }
2311
TruncateTooLongNumber(PhoneNumber * number) const2312 bool PhoneNumberUtil::TruncateTooLongNumber(PhoneNumber* number) const {
2313 if (IsValidNumber(*number)) {
2314 return true;
2315 }
2316 PhoneNumber number_copy(*number);
2317 uint64 national_number = number->national_number();
2318 do {
2319 national_number /= 10;
2320 number_copy.set_national_number(national_number);
2321 if (IsPossibleNumberWithReason(number_copy) == TOO_SHORT ||
2322 national_number == 0) {
2323 return false;
2324 }
2325 } while (!IsValidNumber(number_copy));
2326 number->set_national_number(national_number);
2327 return true;
2328 }
2329
GetNumberType(const PhoneNumber & number) const2330 PhoneNumberUtil::PhoneNumberType PhoneNumberUtil::GetNumberType(
2331 const PhoneNumber& number) const {
2332 string region_code;
2333 GetRegionCodeForNumber(number, ®ion_code);
2334 const PhoneMetadata* metadata =
2335 GetMetadataForRegionOrCallingCode(number.country_code(), region_code);
2336 if (!metadata) {
2337 return UNKNOWN;
2338 }
2339 string national_significant_number;
2340 GetNationalSignificantNumber(number, &national_significant_number);
2341 return GetNumberTypeHelper(national_significant_number, *metadata);
2342 }
2343
IsValidNumber(const PhoneNumber & number) const2344 bool PhoneNumberUtil::IsValidNumber(const PhoneNumber& number) const {
2345 string region_code;
2346 GetRegionCodeForNumber(number, ®ion_code);
2347 return IsValidNumberForRegion(number, region_code);
2348 }
2349
IsValidNumberForRegion(const PhoneNumber & number,const string & region_code) const2350 bool PhoneNumberUtil::IsValidNumberForRegion(const PhoneNumber& number,
2351 const string& region_code) const {
2352 int country_code = number.country_code();
2353 const PhoneMetadata* metadata =
2354 GetMetadataForRegionOrCallingCode(country_code, region_code);
2355 if (!metadata ||
2356 ((kRegionCodeForNonGeoEntity != region_code) &&
2357 country_code != GetCountryCodeForValidRegion(region_code))) {
2358 // Either the region code was invalid, or the country calling code for this
2359 // number does not match that of the region code.
2360 return false;
2361 }
2362 string national_number;
2363 GetNationalSignificantNumber(number, &national_number);
2364
2365 return GetNumberTypeHelper(national_number, *metadata) != UNKNOWN;
2366 }
2367
IsNumberGeographical(const PhoneNumber & phone_number) const2368 bool PhoneNumberUtil::IsNumberGeographical(
2369 const PhoneNumber& phone_number) const {
2370 return IsNumberGeographical(GetNumberType(phone_number),
2371 phone_number.country_code());
2372 }
2373
IsNumberGeographical(PhoneNumberType phone_number_type,int country_calling_code) const2374 bool PhoneNumberUtil::IsNumberGeographical(
2375 PhoneNumberType phone_number_type, int country_calling_code) const {
2376 return phone_number_type == PhoneNumberUtil::FIXED_LINE ||
2377 phone_number_type == PhoneNumberUtil::FIXED_LINE_OR_MOBILE ||
2378 (reg_exps_->geo_mobile_countries_.find(country_calling_code)
2379 != reg_exps_->geo_mobile_countries_.end() &&
2380 phone_number_type == PhoneNumberUtil::MOBILE);
2381 }
2382
2383 // A helper function to set the values related to leading zeros in a
2384 // PhoneNumber.
SetItalianLeadingZerosForPhoneNumber(const string & national_number,PhoneNumber * phone_number) const2385 void PhoneNumberUtil::SetItalianLeadingZerosForPhoneNumber(
2386 const string& national_number, PhoneNumber* phone_number) const {
2387 if (national_number.length() > 1 && national_number[0] == '0') {
2388 phone_number->set_italian_leading_zero(true);
2389 size_t number_of_leading_zeros = 1;
2390 // Note that if the national number is all "0"s, the last "0" is not
2391 // counted as a leading zero.
2392 while (number_of_leading_zeros < national_number.length() - 1 &&
2393 national_number[number_of_leading_zeros] == '0') {
2394 number_of_leading_zeros++;
2395 }
2396 if (number_of_leading_zeros != 1) {
2397 phone_number->set_number_of_leading_zeros(number_of_leading_zeros);
2398 }
2399 }
2400 }
2401
IsNumberMatchingDesc(const string & national_number,const PhoneNumberDesc & number_desc) const2402 bool PhoneNumberUtil::IsNumberMatchingDesc(
2403 const string& national_number, const PhoneNumberDesc& number_desc) const {
2404 // Check if any possible number lengths are present; if so, we use them to
2405 // avoid checking the validation pattern if they don't match. If they are
2406 // absent, this means they match the general description, which we have
2407 // already checked before checking a specific number type.
2408 int actual_length = national_number.length();
2409 if (number_desc.possible_length_size() > 0 &&
2410 std::find(number_desc.possible_length().begin(),
2411 number_desc.possible_length().end(),
2412 actual_length) == number_desc.possible_length().end()) {
2413 return false;
2414 }
2415 return IsMatch(*matcher_api_, national_number, number_desc);
2416 }
2417
GetNumberTypeHelper(const string & national_number,const PhoneMetadata & metadata) const2418 PhoneNumberUtil::PhoneNumberType PhoneNumberUtil::GetNumberTypeHelper(
2419 const string& national_number, const PhoneMetadata& metadata) const {
2420 if (!IsNumberMatchingDesc(national_number, metadata.general_desc())) {
2421 VLOG(4) << "Number type unknown - doesn't match general national number"
2422 << " pattern.";
2423 return PhoneNumberUtil::UNKNOWN;
2424 }
2425 if (IsNumberMatchingDesc(national_number, metadata.premium_rate())) {
2426 VLOG(4) << "Number is a premium number.";
2427 return PhoneNumberUtil::PREMIUM_RATE;
2428 }
2429 if (IsNumberMatchingDesc(national_number, metadata.toll_free())) {
2430 VLOG(4) << "Number is a toll-free number.";
2431 return PhoneNumberUtil::TOLL_FREE;
2432 }
2433 if (IsNumberMatchingDesc(national_number, metadata.shared_cost())) {
2434 VLOG(4) << "Number is a shared cost number.";
2435 return PhoneNumberUtil::SHARED_COST;
2436 }
2437 if (IsNumberMatchingDesc(national_number, metadata.voip())) {
2438 VLOG(4) << "Number is a VOIP (Voice over IP) number.";
2439 return PhoneNumberUtil::VOIP;
2440 }
2441 if (IsNumberMatchingDesc(national_number, metadata.personal_number())) {
2442 VLOG(4) << "Number is a personal number.";
2443 return PhoneNumberUtil::PERSONAL_NUMBER;
2444 }
2445 if (IsNumberMatchingDesc(national_number, metadata.pager())) {
2446 VLOG(4) << "Number is a pager number.";
2447 return PhoneNumberUtil::PAGER;
2448 }
2449 if (IsNumberMatchingDesc(national_number, metadata.uan())) {
2450 VLOG(4) << "Number is a UAN.";
2451 return PhoneNumberUtil::UAN;
2452 }
2453 if (IsNumberMatchingDesc(national_number, metadata.voicemail())) {
2454 VLOG(4) << "Number is a voicemail number.";
2455 return PhoneNumberUtil::VOICEMAIL;
2456 }
2457
2458 bool is_fixed_line =
2459 IsNumberMatchingDesc(national_number, metadata.fixed_line());
2460 if (is_fixed_line) {
2461 if (metadata.same_mobile_and_fixed_line_pattern()) {
2462 VLOG(4) << "Fixed-line and mobile patterns equal, number is fixed-line"
2463 << " or mobile";
2464 return PhoneNumberUtil::FIXED_LINE_OR_MOBILE;
2465 } else if (IsNumberMatchingDesc(national_number, metadata.mobile())) {
2466 VLOG(4) << "Fixed-line and mobile patterns differ, but number is "
2467 << "still fixed-line or mobile";
2468 return PhoneNumberUtil::FIXED_LINE_OR_MOBILE;
2469 }
2470 VLOG(4) << "Number is a fixed line number.";
2471 return PhoneNumberUtil::FIXED_LINE;
2472 }
2473 // Otherwise, test to see if the number is mobile. Only do this if certain
2474 // that the patterns for mobile and fixed line aren't the same.
2475 if (!metadata.same_mobile_and_fixed_line_pattern() &&
2476 IsNumberMatchingDesc(national_number, metadata.mobile())) {
2477 VLOG(4) << "Number is a mobile number.";
2478 return PhoneNumberUtil::MOBILE;
2479 }
2480 VLOG(4) << "Number type unknown - doesn\'t match any specific number type"
2481 << " pattern.";
2482 return PhoneNumberUtil::UNKNOWN;
2483 }
2484
GetNationalSignificantNumber(const PhoneNumber & number,string * national_number) const2485 void PhoneNumberUtil::GetNationalSignificantNumber(
2486 const PhoneNumber& number,
2487 string* national_number) const {
2488 DCHECK(national_number);
2489 // If leading zero(s) have been set, we prefix this now. Note this is not a
2490 // national prefix. Ensure the number of leading zeros is at least 0 so we
2491 // don't crash in the case of malicious input.
2492 StrAppend(national_number, number.italian_leading_zero() ?
2493 string(std::max(number.number_of_leading_zeros(), 0), '0') : "");
2494 StrAppend(national_number, number.national_number());
2495 }
2496
GetLengthOfGeographicalAreaCode(const PhoneNumber & number) const2497 int PhoneNumberUtil::GetLengthOfGeographicalAreaCode(
2498 const PhoneNumber& number) const {
2499 string region_code;
2500 GetRegionCodeForNumber(number, ®ion_code);
2501 const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
2502 if (!metadata) {
2503 return 0;
2504 }
2505 // If a country doesn't use a national prefix, and this number doesn't have an
2506 // Italian leading zero, we assume it is a closed dialling plan with no area
2507 // codes.
2508 if (!metadata->has_national_prefix() && !number.italian_leading_zero()) {
2509 return 0;
2510 }
2511
2512 PhoneNumberType type = GetNumberType(number);
2513 int country_calling_code = number.country_code();
2514 if (type == PhoneNumberUtil::MOBILE &&
2515 reg_exps_->geo_mobile_countries_without_mobile_area_codes_.find(
2516 country_calling_code) !=
2517 reg_exps_->geo_mobile_countries_without_mobile_area_codes_.end()) {
2518 return 0;
2519 }
2520
2521 if (!IsNumberGeographical(type, country_calling_code)) {
2522 return 0;
2523 }
2524
2525 return GetLengthOfNationalDestinationCode(number);
2526 }
2527
GetLengthOfNationalDestinationCode(const PhoneNumber & number) const2528 int PhoneNumberUtil::GetLengthOfNationalDestinationCode(
2529 const PhoneNumber& number) const {
2530 PhoneNumber copied_proto(number);
2531 if (number.has_extension()) {
2532 // Clear the extension so it's not included when formatting.
2533 copied_proto.clear_extension();
2534 }
2535
2536 string formatted_number;
2537 Format(copied_proto, INTERNATIONAL, &formatted_number);
2538 const scoped_ptr<RegExpInput> i18n_number(
2539 reg_exps_->regexp_factory_->CreateInput(formatted_number));
2540 string digit_group;
2541 string ndc;
2542 string third_group;
2543 for (int i = 0; i < 3; ++i) {
2544 if (!reg_exps_->capturing_ascii_digits_pattern_->FindAndConsume(
2545 i18n_number.get(), &digit_group)) {
2546 // We should find at least three groups.
2547 return 0;
2548 }
2549 if (i == 1) {
2550 ndc = digit_group;
2551 } else if (i == 2) {
2552 third_group = digit_group;
2553 }
2554 }
2555
2556 if (GetNumberType(number) == MOBILE) {
2557 // For example Argentinian mobile numbers, when formatted in the
2558 // international format, are in the form of +54 9 NDC XXXX.... As a result,
2559 // we take the length of the third group (NDC) and add the length of the
2560 // mobile token, which also forms part of the national significant number.
2561 // This assumes that the mobile token is always formatted separately from
2562 // the rest of the phone number.
2563 string mobile_token;
2564 GetCountryMobileToken(number.country_code(), &mobile_token);
2565 if (!mobile_token.empty()) {
2566 return third_group.size() + mobile_token.size();
2567 }
2568 }
2569 return ndc.size();
2570 }
2571
GetCountryMobileToken(int country_calling_code,string * mobile_token) const2572 void PhoneNumberUtil::GetCountryMobileToken(int country_calling_code,
2573 string* mobile_token) const {
2574 DCHECK(mobile_token);
2575 std::map<int, char>::iterator it = reg_exps_->mobile_token_mappings_.find(
2576 country_calling_code);
2577 if (it != reg_exps_->mobile_token_mappings_.end()) {
2578 *mobile_token = it->second;
2579 } else {
2580 mobile_token->assign("");
2581 }
2582 }
2583
NormalizeDigitsOnly(string * number) const2584 void PhoneNumberUtil::NormalizeDigitsOnly(string* number) const {
2585 DCHECK(number);
2586 const RegExp& non_digits_pattern = reg_exps_->regexp_cache_->GetRegExp(
2587 StrCat("[^", kDigits, "]"));
2588 // Delete everything that isn't valid digits.
2589 non_digits_pattern.GlobalReplace(number, "");
2590 // Normalize all decimal digits to ASCII digits.
2591 number->assign(NormalizeUTF8::NormalizeDecimalDigits(*number));
2592 }
2593
NormalizeDiallableCharsOnly(string * number) const2594 void PhoneNumberUtil::NormalizeDiallableCharsOnly(string* number) const {
2595 DCHECK(number);
2596 NormalizeHelper(reg_exps_->diallable_char_mappings_,
2597 true /* remove non matches */, number);
2598 }
2599
IsAlphaNumber(const string & number) const2600 bool PhoneNumberUtil::IsAlphaNumber(const string& number) const {
2601 if (!IsViablePhoneNumber(number)) {
2602 // Number is too short, or doesn't match the basic phone number pattern.
2603 return false;
2604 }
2605 // Copy the number, since we are going to try and strip the extension from it.
2606 string number_copy(number);
2607 string extension;
2608 MaybeStripExtension(&number_copy, &extension);
2609 return reg_exps_->valid_alpha_phone_pattern_->FullMatch(number_copy);
2610 }
2611
ConvertAlphaCharactersInNumber(string * number) const2612 void PhoneNumberUtil::ConvertAlphaCharactersInNumber(string* number) const {
2613 DCHECK(number);
2614 NormalizeHelper(reg_exps_->alpha_phone_mappings_, false, number);
2615 }
2616
2617 // Normalizes a string of characters representing a phone number. This performs
2618 // the following conversions:
2619 // - Punctuation is stripped.
2620 // For ALPHA/VANITY numbers:
2621 // - Letters are converted to their numeric representation on a telephone
2622 // keypad. The keypad used here is the one defined in ITU Recommendation
2623 // E.161. This is only done if there are 3 or more letters in the number, to
2624 // lessen the risk that such letters are typos.
2625 // For other numbers:
2626 // - Wide-ascii digits are converted to normal ASCII (European) digits.
2627 // - Arabic-Indic numerals are converted to European numerals.
2628 // - Spurious alpha characters are stripped.
Normalize(string * number) const2629 void PhoneNumberUtil::Normalize(string* number) const {
2630 DCHECK(number);
2631 if (reg_exps_->valid_alpha_phone_pattern_->PartialMatch(*number)) {
2632 NormalizeHelper(reg_exps_->alpha_phone_mappings_, true, number);
2633 }
2634 NormalizeDigitsOnly(number);
2635 }
2636
2637 // Checks to see if the string of characters could possibly be a phone number at
2638 // all. At the moment, checks to see that the string begins with at least 3
2639 // digits, ignoring any punctuation commonly found in phone numbers. This
2640 // method does not require the number to be normalized in advance - but does
2641 // assume that leading non-number symbols have been removed, such as by the
2642 // method ExtractPossibleNumber.
IsViablePhoneNumber(const string & number) const2643 bool PhoneNumberUtil::IsViablePhoneNumber(const string& number) const {
2644 if (number.length() < kMinLengthForNsn) {
2645 return false;
2646 }
2647 return reg_exps_->valid_phone_number_pattern_->FullMatch(number);
2648 }
2649
2650 // Strips the IDD from the start of the number if present. Helper function used
2651 // by MaybeStripInternationalPrefixAndNormalize.
ParsePrefixAsIdd(const RegExp & idd_pattern,string * number) const2652 bool PhoneNumberUtil::ParsePrefixAsIdd(const RegExp& idd_pattern,
2653 string* number) const {
2654 DCHECK(number);
2655 const scoped_ptr<RegExpInput> number_copy(
2656 reg_exps_->regexp_factory_->CreateInput(*number));
2657 // First attempt to strip the idd_pattern at the start, if present. We make a
2658 // copy so that we can revert to the original string if necessary.
2659 if (idd_pattern.Consume(number_copy.get())) {
2660 // Only strip this if the first digit after the match is not a 0, since
2661 // country calling codes cannot begin with 0.
2662 string extracted_digit;
2663 if (reg_exps_->capturing_digit_pattern_->PartialMatch(
2664 number_copy->ToString(), &extracted_digit)) {
2665 NormalizeDigitsOnly(&extracted_digit);
2666 if (extracted_digit == "0") {
2667 return false;
2668 }
2669 }
2670 number->assign(number_copy->ToString());
2671 return true;
2672 }
2673 return false;
2674 }
2675
2676 // Strips any international prefix (such as +, 00, 011) present in the number
2677 // provided, normalizes the resulting number, and indicates if an international
2678 // prefix was present.
2679 //
2680 // possible_idd_prefix represents the international direct dialing prefix from
2681 // the region we think this number may be dialed in.
2682 // Returns true if an international dialing prefix could be removed from the
2683 // number, otherwise false if the number did not seem to be in international
2684 // format.
2685 PhoneNumber::CountryCodeSource
MaybeStripInternationalPrefixAndNormalize(const string & possible_idd_prefix,string * number) const2686 PhoneNumberUtil::MaybeStripInternationalPrefixAndNormalize(
2687 const string& possible_idd_prefix,
2688 string* number) const {
2689 DCHECK(number);
2690 if (number->empty()) {
2691 return PhoneNumber::FROM_DEFAULT_COUNTRY;
2692 }
2693 const scoped_ptr<RegExpInput> number_string_piece(
2694 reg_exps_->regexp_factory_->CreateInput(*number));
2695 if (reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get())) {
2696 number->assign(number_string_piece->ToString());
2697 // Can now normalize the rest of the number since we've consumed the "+"
2698 // sign at the start.
2699 Normalize(number);
2700 return PhoneNumber::FROM_NUMBER_WITH_PLUS_SIGN;
2701 }
2702 // Attempt to parse the first digits as an international prefix.
2703 const RegExp& idd_pattern =
2704 reg_exps_->regexp_cache_->GetRegExp(possible_idd_prefix);
2705 Normalize(number);
2706 return ParsePrefixAsIdd(idd_pattern, number)
2707 ? PhoneNumber::FROM_NUMBER_WITH_IDD
2708 : PhoneNumber::FROM_DEFAULT_COUNTRY;
2709 }
2710
2711 // Strips any national prefix (such as 0, 1) present in the number provided.
2712 // The number passed in should be the normalized telephone number that we wish
2713 // to strip any national dialing prefix from. The metadata should be for the
2714 // region that we think this number is from. Returns true if a national prefix
2715 // and/or carrier code was stripped.
MaybeStripNationalPrefixAndCarrierCode(const PhoneMetadata & metadata,string * number,string * carrier_code) const2716 bool PhoneNumberUtil::MaybeStripNationalPrefixAndCarrierCode(
2717 const PhoneMetadata& metadata,
2718 string* number,
2719 string* carrier_code) const {
2720 DCHECK(number);
2721 string carrier_code_temp;
2722 const string& possible_national_prefix =
2723 metadata.national_prefix_for_parsing();
2724 if (number->empty() || possible_national_prefix.empty()) {
2725 // Early return for numbers of zero length or with no national prefix
2726 // possible.
2727 return false;
2728 }
2729 // We use two copies here since Consume modifies the phone number, and if the
2730 // first if-clause fails the number will already be changed.
2731 const scoped_ptr<RegExpInput> number_copy(
2732 reg_exps_->regexp_factory_->CreateInput(*number));
2733 const scoped_ptr<RegExpInput> number_copy_without_transform(
2734 reg_exps_->regexp_factory_->CreateInput(*number));
2735 string number_string_copy(*number);
2736 string captured_part_of_prefix;
2737 const PhoneNumberDesc& general_desc = metadata.general_desc();
2738 // Check if the original number is viable.
2739 bool is_viable_original_number =
2740 IsMatch(*matcher_api_, *number, general_desc);
2741 // Attempt to parse the first digits as a national prefix. We make a
2742 // copy so that we can revert to the original string if necessary.
2743 const string& transform_rule = metadata.national_prefix_transform_rule();
2744 const RegExp& possible_national_prefix_pattern =
2745 reg_exps_->regexp_cache_->GetRegExp(possible_national_prefix);
2746 if (!transform_rule.empty() &&
2747 (possible_national_prefix_pattern.Consume(
2748 number_copy.get(), &carrier_code_temp, &captured_part_of_prefix) ||
2749 possible_national_prefix_pattern.Consume(
2750 number_copy.get(), &captured_part_of_prefix)) &&
2751 !captured_part_of_prefix.empty()) {
2752 // If this succeeded, then we must have had a transform rule and there must
2753 // have been some part of the prefix that we captured.
2754 // We make the transformation and check that the resultant number is still
2755 // viable. If so, replace the number and return.
2756 possible_national_prefix_pattern.Replace(&number_string_copy,
2757 transform_rule);
2758 if (is_viable_original_number &&
2759 !IsMatch(*matcher_api_, number_string_copy, general_desc)) {
2760 return false;
2761 }
2762 number->assign(number_string_copy);
2763 if (carrier_code) {
2764 carrier_code->assign(carrier_code_temp);
2765 }
2766 } else if (possible_national_prefix_pattern.Consume(
2767 number_copy_without_transform.get(), &carrier_code_temp) ||
2768 possible_national_prefix_pattern.Consume(
2769 number_copy_without_transform.get())) {
2770 VLOG(4) << "Parsed the first digits as a national prefix.";
2771 // If captured_part_of_prefix is empty, this implies nothing was captured by
2772 // the capturing groups in possible_national_prefix; therefore, no
2773 // transformation is necessary, and we just remove the national prefix.
2774 const string number_copy_as_string =
2775 number_copy_without_transform->ToString();
2776 if (is_viable_original_number &&
2777 !IsMatch(*matcher_api_, number_copy_as_string, general_desc)) {
2778 return false;
2779 }
2780 number->assign(number_copy_as_string);
2781 if (carrier_code) {
2782 carrier_code->assign(carrier_code_temp);
2783 }
2784 } else {
2785 return false;
2786 VLOG(4) << "The first digits did not match the national prefix.";
2787 }
2788 return true;
2789 }
2790
2791 // Strips any extension (as in, the part of the number dialled after the call is
2792 // connected, usually indicated with extn, ext, x or similar) from the end of
2793 // the number, and returns it. The number passed in should be non-normalized.
MaybeStripExtension(string * number,string * extension) const2794 bool PhoneNumberUtil::MaybeStripExtension(string* number, string* extension)
2795 const {
2796 DCHECK(number);
2797 DCHECK(extension);
2798 // There are three extension capturing groups in the regular expression.
2799 string possible_extension_one;
2800 string possible_extension_two;
2801 string possible_extension_three;
2802 string number_copy(*number);
2803 const scoped_ptr<RegExpInput> number_copy_as_regexp_input(
2804 reg_exps_->regexp_factory_->CreateInput(number_copy));
2805 if (reg_exps_->extn_pattern_->Consume(number_copy_as_regexp_input.get(),
2806 false,
2807 &possible_extension_one,
2808 &possible_extension_two,
2809 &possible_extension_three)) {
2810 // Replace the extensions in the original string here.
2811 reg_exps_->extn_pattern_->Replace(&number_copy, "");
2812 // If we find a potential extension, and the number preceding this is a
2813 // viable number, we assume it is an extension.
2814 if ((!possible_extension_one.empty() || !possible_extension_two.empty() ||
2815 !possible_extension_three.empty()) &&
2816 IsViablePhoneNumber(number_copy)) {
2817 number->assign(number_copy);
2818 if (!possible_extension_one.empty()) {
2819 extension->assign(possible_extension_one);
2820 } else if (!possible_extension_two.empty()) {
2821 extension->assign(possible_extension_two);
2822 } else if (!possible_extension_three.empty()) {
2823 extension->assign(possible_extension_three);
2824 }
2825 return true;
2826 }
2827 }
2828 return false;
2829 }
2830
2831 // Extracts country calling code from national_number, and returns it. It
2832 // assumes that the leading plus sign or IDD has already been removed. Returns 0
2833 // if national_number doesn't start with a valid country calling code, and
2834 // leaves national_number unmodified. Assumes the national_number is at least 3
2835 // characters long.
ExtractCountryCode(string * national_number) const2836 int PhoneNumberUtil::ExtractCountryCode(string* national_number) const {
2837 int potential_country_code;
2838 if (national_number->empty() || (national_number->at(0) == '0')) {
2839 // Country codes do not begin with a '0'.
2840 return 0;
2841 }
2842 for (size_t i = 1; i <= kMaxLengthCountryCode; ++i) {
2843 safe_strto32(national_number->substr(0, i), &potential_country_code);
2844 string region_code;
2845 GetRegionCodeForCountryCode(potential_country_code, ®ion_code);
2846 if (region_code != RegionCode::GetUnknown()) {
2847 national_number->erase(0, i);
2848 return potential_country_code;
2849 }
2850 }
2851 return 0;
2852 }
2853
2854 // Tries to extract a country calling code from a number. Country calling codes
2855 // are extracted in the following ways:
2856 // - by stripping the international dialing prefix of the region the person
2857 // is dialing from, if this is present in the number, and looking at the next
2858 // digits
2859 // - by stripping the '+' sign if present and then looking at the next digits
2860 // - by comparing the start of the number and the country calling code of the
2861 // default region. If the number is not considered possible for the numbering
2862 // plan of the default region initially, but starts with the country calling
2863 // code of this region, validation will be reattempted after stripping this
2864 // country calling code. If this number is considered a possible number, then
2865 // the first digits will be considered the country calling code and removed as
2866 // such.
2867 //
2868 // Returns NO_PARSING_ERROR if a country calling code was successfully
2869 // extracted or none was present, or the appropriate error otherwise, such as
2870 // if a + was present but it was not followed by a valid country calling code.
2871 // If NO_PARSING_ERROR is returned, the national_number without the country
2872 // calling code is populated, and the country_code of the phone_number passed
2873 // in is set to the country calling code if found, otherwise to 0.
MaybeExtractCountryCode(const PhoneMetadata * default_region_metadata,bool keep_raw_input,string * national_number,PhoneNumber * phone_number) const2874 PhoneNumberUtil::ErrorType PhoneNumberUtil::MaybeExtractCountryCode(
2875 const PhoneMetadata* default_region_metadata,
2876 bool keep_raw_input,
2877 string* national_number,
2878 PhoneNumber* phone_number) const {
2879 DCHECK(national_number);
2880 DCHECK(phone_number);
2881 // Set the default prefix to be something that will never match if there is no
2882 // default region.
2883 string possible_country_idd_prefix = default_region_metadata
2884 ? default_region_metadata->international_prefix()
2885 : "NonMatch";
2886 PhoneNumber::CountryCodeSource country_code_source =
2887 MaybeStripInternationalPrefixAndNormalize(possible_country_idd_prefix,
2888 national_number);
2889 if (keep_raw_input) {
2890 phone_number->set_country_code_source(country_code_source);
2891 }
2892 if (country_code_source != PhoneNumber::FROM_DEFAULT_COUNTRY) {
2893 if (national_number->length() <= kMinLengthForNsn) {
2894 VLOG(2) << "Phone number had an IDD, but after this was not "
2895 << "long enough to be a viable phone number.";
2896 return TOO_SHORT_AFTER_IDD;
2897 }
2898 int potential_country_code = ExtractCountryCode(national_number);
2899 if (potential_country_code != 0) {
2900 phone_number->set_country_code(potential_country_code);
2901 return NO_PARSING_ERROR;
2902 }
2903 // If this fails, they must be using a strange country calling code that we
2904 // don't recognize, or that doesn't exist.
2905 return INVALID_COUNTRY_CODE_ERROR;
2906 } else if (default_region_metadata) {
2907 // Check to see if the number starts with the country calling code for the
2908 // default region. If so, we remove the country calling code, and do some
2909 // checks on the validity of the number before and after.
2910 int default_country_code = default_region_metadata->country_code();
2911 string default_country_code_string(SimpleItoa(default_country_code));
2912 VLOG(4) << "Possible country calling code: " << default_country_code_string;
2913 string potential_national_number;
2914 if (TryStripPrefixString(*national_number,
2915 default_country_code_string,
2916 &potential_national_number)) {
2917 const PhoneNumberDesc& general_num_desc =
2918 default_region_metadata->general_desc();
2919 MaybeStripNationalPrefixAndCarrierCode(*default_region_metadata,
2920 &potential_national_number,
2921 NULL);
2922 VLOG(4) << "Number without country calling code prefix";
2923 // If the number was not valid before but is valid now, or if it was too
2924 // long before, we consider the number with the country code stripped to
2925 // be a better result and keep that instead.
2926 if ((!IsMatch(*matcher_api_, *national_number, general_num_desc) &&
2927 IsMatch(
2928 *matcher_api_, potential_national_number, general_num_desc)) ||
2929 TestNumberLength(*national_number, *default_region_metadata) ==
2930 TOO_LONG) {
2931 national_number->assign(potential_national_number);
2932 if (keep_raw_input) {
2933 phone_number->set_country_code_source(
2934 PhoneNumber::FROM_NUMBER_WITHOUT_PLUS_SIGN);
2935 }
2936 phone_number->set_country_code(default_country_code);
2937 return NO_PARSING_ERROR;
2938 }
2939 }
2940 }
2941 // No country calling code present. Set the country_code to 0.
2942 phone_number->set_country_code(0);
2943 return NO_PARSING_ERROR;
2944 }
2945
IsNumberMatch(const PhoneNumber & first_number_in,const PhoneNumber & second_number_in) const2946 PhoneNumberUtil::MatchType PhoneNumberUtil::IsNumberMatch(
2947 const PhoneNumber& first_number_in,
2948 const PhoneNumber& second_number_in) const {
2949 // We only are about the fields that uniquely define a number, so we copy
2950 // these across explicitly.
2951 PhoneNumber first_number;
2952 CopyCoreFieldsOnly(first_number_in, &first_number);
2953 PhoneNumber second_number;
2954 CopyCoreFieldsOnly(second_number_in, &second_number);
2955 // Early exit if both had extensions and these are different.
2956 if (first_number.has_extension() && second_number.has_extension() &&
2957 first_number.extension() != second_number.extension()) {
2958 return NO_MATCH;
2959 }
2960 int first_number_country_code = first_number.country_code();
2961 int second_number_country_code = second_number.country_code();
2962 // Both had country calling code specified.
2963 if (first_number_country_code != 0 && second_number_country_code != 0) {
2964 if (ExactlySameAs(first_number, second_number)) {
2965 return EXACT_MATCH;
2966 } else if (first_number_country_code == second_number_country_code &&
2967 IsNationalNumberSuffixOfTheOther(first_number, second_number)) {
2968 // A SHORT_NSN_MATCH occurs if there is a difference because of the
2969 // presence or absence of an 'Italian leading zero', the presence or
2970 // absence of an extension, or one NSN being a shorter variant of the
2971 // other.
2972 return SHORT_NSN_MATCH;
2973 }
2974 // This is not a match.
2975 return NO_MATCH;
2976 }
2977 // Checks cases where one or both country calling codes were not specified. To
2978 // make equality checks easier, we first set the country_code fields to be
2979 // equal.
2980 first_number.set_country_code(second_number_country_code);
2981 // If all else was the same, then this is an NSN_MATCH.
2982 if (ExactlySameAs(first_number, second_number)) {
2983 return NSN_MATCH;
2984 }
2985 if (IsNationalNumberSuffixOfTheOther(first_number, second_number)) {
2986 return SHORT_NSN_MATCH;
2987 }
2988 return NO_MATCH;
2989 }
2990
IsNumberMatchWithTwoStrings(const string & first_number,const string & second_number) const2991 PhoneNumberUtil::MatchType PhoneNumberUtil::IsNumberMatchWithTwoStrings(
2992 const string& first_number,
2993 const string& second_number) const {
2994 PhoneNumber first_number_as_proto;
2995 ErrorType error_type =
2996 Parse(first_number, RegionCode::GetUnknown(), &first_number_as_proto);
2997 if (error_type == NO_PARSING_ERROR) {
2998 return IsNumberMatchWithOneString(first_number_as_proto, second_number);
2999 }
3000 if (error_type == INVALID_COUNTRY_CODE_ERROR) {
3001 PhoneNumber second_number_as_proto;
3002 ErrorType error_type = Parse(second_number, RegionCode::GetUnknown(),
3003 &second_number_as_proto);
3004 if (error_type == NO_PARSING_ERROR) {
3005 return IsNumberMatchWithOneString(second_number_as_proto, first_number);
3006 }
3007 if (error_type == INVALID_COUNTRY_CODE_ERROR) {
3008 error_type = ParseHelper(first_number, RegionCode::GetUnknown(), false,
3009 false, &first_number_as_proto);
3010 if (error_type == NO_PARSING_ERROR) {
3011 error_type = ParseHelper(second_number, RegionCode::GetUnknown(), false,
3012 false, &second_number_as_proto);
3013 if (error_type == NO_PARSING_ERROR) {
3014 return IsNumberMatch(first_number_as_proto, second_number_as_proto);
3015 }
3016 }
3017 }
3018 }
3019 // One or more of the phone numbers we are trying to match is not a viable
3020 // phone number.
3021 return INVALID_NUMBER;
3022 }
3023
IsNumberMatchWithOneString(const PhoneNumber & first_number,const string & second_number) const3024 PhoneNumberUtil::MatchType PhoneNumberUtil::IsNumberMatchWithOneString(
3025 const PhoneNumber& first_number,
3026 const string& second_number) const {
3027 // First see if the second number has an implicit country calling code, by
3028 // attempting to parse it.
3029 PhoneNumber second_number_as_proto;
3030 ErrorType error_type =
3031 Parse(second_number, RegionCode::GetUnknown(), &second_number_as_proto);
3032 if (error_type == NO_PARSING_ERROR) {
3033 return IsNumberMatch(first_number, second_number_as_proto);
3034 }
3035 if (error_type == INVALID_COUNTRY_CODE_ERROR) {
3036 // The second number has no country calling code. EXACT_MATCH is no longer
3037 // possible. We parse it as if the region was the same as that for the
3038 // first number, and if EXACT_MATCH is returned, we replace this with
3039 // NSN_MATCH.
3040 string first_number_region;
3041 GetRegionCodeForCountryCode(first_number.country_code(),
3042 &first_number_region);
3043 if (first_number_region != RegionCode::GetUnknown()) {
3044 PhoneNumber second_number_with_first_number_region;
3045 Parse(second_number, first_number_region,
3046 &second_number_with_first_number_region);
3047 MatchType match = IsNumberMatch(first_number,
3048 second_number_with_first_number_region);
3049 if (match == EXACT_MATCH) {
3050 return NSN_MATCH;
3051 }
3052 return match;
3053 } else {
3054 // If the first number didn't have a valid country calling code, then we
3055 // parse the second number without one as well.
3056 error_type = ParseHelper(second_number, RegionCode::GetUnknown(), false,
3057 false, &second_number_as_proto);
3058 if (error_type == NO_PARSING_ERROR) {
3059 return IsNumberMatch(first_number, second_number_as_proto);
3060 }
3061 }
3062 }
3063 // One or more of the phone numbers we are trying to match is not a viable
3064 // phone number.
3065 return INVALID_NUMBER;
3066 }
3067
GetAsYouTypeFormatter(const string & region_code) const3068 AsYouTypeFormatter* PhoneNumberUtil::GetAsYouTypeFormatter(
3069 const string& region_code) const {
3070 return new AsYouTypeFormatter(region_code);
3071 }
3072
CanBeInternationallyDialled(const PhoneNumber & number) const3073 bool PhoneNumberUtil::CanBeInternationallyDialled(
3074 const PhoneNumber& number) const {
3075 string region_code;
3076 GetRegionCodeForNumber(number, ®ion_code);
3077 const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
3078 if (!metadata) {
3079 // Note numbers belonging to non-geographical entities (e.g. +800 numbers)
3080 // are always internationally diallable, and will be caught here.
3081 return true;
3082 }
3083 string national_significant_number;
3084 GetNationalSignificantNumber(number, &national_significant_number);
3085 return !IsNumberMatchingDesc(
3086 national_significant_number, metadata->no_international_dialling());
3087 }
3088
3089 } // namespace phonenumbers
3090 } // namespace i18n
3091