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