• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Libphonenumber Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.i18n.phonenumbers;
18 
19 import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat;
20 import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
21 import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
22 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
23 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
24 import com.google.i18n.phonenumbers.internal.MatcherApi;
25 import com.google.i18n.phonenumbers.internal.RegexBasedMatcher;
26 import com.google.i18n.phonenumbers.internal.RegexCache;
27 import com.google.i18n.phonenumbers.metadata.DefaultMetadataDependenciesProvider;
28 import com.google.i18n.phonenumbers.metadata.source.MetadataSource;
29 import com.google.i18n.phonenumbers.metadata.source.MetadataSourceImpl;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.TreeSet;
40 import java.util.logging.Level;
41 import java.util.logging.Logger;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44 
45 /**
46  * Utility for international phone numbers. Functionality includes formatting, parsing and
47  * validation.
48  *
49  * <p>If you use this library, and want to be notified about important changes, please sign up to
50  * our <a href="https://groups.google.com/forum/#!aboutgroup/libphonenumber-discuss">mailing list</a>.
51  *
52  * NOTE: A lot of methods in this class require Region Code strings. These must be provided using
53  * CLDR two-letter region-code format. These should be in upper-case. The list of the codes
54  * can be found here:
55  * http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html
56  */
57 public class PhoneNumberUtil {
58   private static final Logger logger = Logger.getLogger(PhoneNumberUtil.class.getName());
59 
60   /** Flags to use when compiling regular expressions for phone numbers. */
61   static final int REGEX_FLAGS = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE;
62   // The minimum and maximum length of the national significant number.
63   private static final int MIN_LENGTH_FOR_NSN = 2;
64   // The ITU says the maximum length should be 15, but we have found longer numbers in Germany.
65   static final int MAX_LENGTH_FOR_NSN = 17;
66   // The maximum length of the country calling code.
67   static final int MAX_LENGTH_COUNTRY_CODE = 3;
68   // We don't allow input strings for parsing to be longer than 250 chars. This prevents malicious
69   // input from overflowing the regular-expression engine.
70   private static final int MAX_INPUT_STRING_LENGTH = 250;
71 
72   // Region-code for the unknown region.
73   private static final String UNKNOWN_REGION = "ZZ";
74 
75   private static final int NANPA_COUNTRY_CODE = 1;
76 
77   // The prefix that needs to be inserted in front of a Colombian landline number when dialed from
78   // a mobile phone in Colombia.
79   private static final String COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX = "3";
80 
81   // Map of country calling codes that use a mobile token before the area code. One example of when
82   // this is relevant is when determining the length of the national destination code, which should
83   // be the length of the area code plus the length of the mobile token.
84   private static final Map<Integer, String> MOBILE_TOKEN_MAPPINGS;
85 
86   // Set of country codes that have geographically assigned mobile numbers (see GEO_MOBILE_COUNTRIES
87   // below) which are not based on *area codes*. For example, in China mobile numbers start with a
88   // carrier indicator, and beyond that are geographically assigned: this carrier indicator is not
89   // considered to be an area code.
90   private static final Set<Integer> GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES;
91 
92   // Set of country calling codes that have geographically assigned mobile numbers. This may not be
93   // complete; we add calling codes case by case, as we find geographical mobile numbers or hear
94   // from user reports. Note that countries like the US, where we can't distinguish between
95   // fixed-line or mobile numbers, are not listed here, since we consider FIXED_LINE_OR_MOBILE to be
96   // a possibly geographically-related type anyway (like FIXED_LINE).
97   private static final Set<Integer> GEO_MOBILE_COUNTRIES;
98 
99   // The PLUS_SIGN signifies the international prefix.
100   static final char PLUS_SIGN = '+';
101 
102   private static final char STAR_SIGN = '*';
103 
104   private static final String RFC3966_EXTN_PREFIX = ";ext=";
105   private static final String RFC3966_PREFIX = "tel:";
106   private static final String RFC3966_PHONE_CONTEXT = ";phone-context=";
107   private static final String RFC3966_ISDN_SUBADDRESS = ";isub=";
108 
109   // A map that contains characters that are essential when dialling. That means any of the
110   // characters in this map must not be removed from a number when dialling, otherwise the call
111   // will not reach the intended destination.
112   private static final Map<Character, Character> DIALLABLE_CHAR_MAPPINGS;
113 
114   // Only upper-case variants of alpha characters are stored.
115   private static final Map<Character, Character> ALPHA_MAPPINGS;
116 
117   // For performance reasons, amalgamate both into one map.
118   private static final Map<Character, Character> ALPHA_PHONE_MAPPINGS;
119 
120   // Separate map of all symbols that we wish to retain when formatting alpha numbers. This
121   // includes digits, ASCII letters and number grouping symbols such as "-" and " ".
122   private static final Map<Character, Character> ALL_PLUS_NUMBER_GROUPING_SYMBOLS;
123 
124   static {
125     HashMap<Integer, String> mobileTokenMap = new HashMap<>();
126     mobileTokenMap.put(54, "9");
127     MOBILE_TOKEN_MAPPINGS = Collections.unmodifiableMap(mobileTokenMap);
128 
129     HashSet<Integer> geoMobileCountriesWithoutMobileAreaCodes = new HashSet<>();
130     geoMobileCountriesWithoutMobileAreaCodes.add(86);  // China
131     GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES =
132         Collections.unmodifiableSet(geoMobileCountriesWithoutMobileAreaCodes);
133 
134     HashSet<Integer> geoMobileCountries = new HashSet<>();
135     geoMobileCountries.add(52);  // Mexico
136     geoMobileCountries.add(54);  // Argentina
137     geoMobileCountries.add(55);  // Brazil
138     geoMobileCountries.add(62);  // Indonesia: some prefixes only (fixed CMDA wireless)
139     geoMobileCountries.addAll(geoMobileCountriesWithoutMobileAreaCodes);
140     GEO_MOBILE_COUNTRIES = Collections.unmodifiableSet(geoMobileCountries);
141 
142     // Simple ASCII digits map used to populate ALPHA_PHONE_MAPPINGS and
143     // ALL_PLUS_NUMBER_GROUPING_SYMBOLS.
144     HashMap<Character, Character> asciiDigitMappings = new HashMap<>();
145     asciiDigitMappings.put('0', '0');
146     asciiDigitMappings.put('1', '1');
147     asciiDigitMappings.put('2', '2');
148     asciiDigitMappings.put('3', '3');
149     asciiDigitMappings.put('4', '4');
150     asciiDigitMappings.put('5', '5');
151     asciiDigitMappings.put('6', '6');
152     asciiDigitMappings.put('7', '7');
153     asciiDigitMappings.put('8', '8');
154     asciiDigitMappings.put('9', '9');
155 
156     HashMap<Character, Character> alphaMap = new HashMap<>(40);
157     alphaMap.put('A', '2');
158     alphaMap.put('B', '2');
159     alphaMap.put('C', '2');
160     alphaMap.put('D', '3');
161     alphaMap.put('E', '3');
162     alphaMap.put('F', '3');
163     alphaMap.put('G', '4');
164     alphaMap.put('H', '4');
165     alphaMap.put('I', '4');
166     alphaMap.put('J', '5');
167     alphaMap.put('K', '5');
168     alphaMap.put('L', '5');
169     alphaMap.put('M', '6');
170     alphaMap.put('N', '6');
171     alphaMap.put('O', '6');
172     alphaMap.put('P', '7');
173     alphaMap.put('Q', '7');
174     alphaMap.put('R', '7');
175     alphaMap.put('S', '7');
176     alphaMap.put('T', '8');
177     alphaMap.put('U', '8');
178     alphaMap.put('V', '8');
179     alphaMap.put('W', '9');
180     alphaMap.put('X', '9');
181     alphaMap.put('Y', '9');
182     alphaMap.put('Z', '9');
183     ALPHA_MAPPINGS = Collections.unmodifiableMap(alphaMap);
184 
185     HashMap<Character, Character> combinedMap = new HashMap<>(100);
186     combinedMap.putAll(ALPHA_MAPPINGS);
187     combinedMap.putAll(asciiDigitMappings);
188     ALPHA_PHONE_MAPPINGS = Collections.unmodifiableMap(combinedMap);
189 
190     HashMap<Character, Character> diallableCharMap = new HashMap<>();
191     diallableCharMap.putAll(asciiDigitMappings);
diallableCharMap.put(PLUS_SIGN, PLUS_SIGN)192     diallableCharMap.put(PLUS_SIGN, PLUS_SIGN);
193     diallableCharMap.put('*', '*');
194     diallableCharMap.put('#', '#');
195     DIALLABLE_CHAR_MAPPINGS = Collections.unmodifiableMap(diallableCharMap);
196 
197     HashMap<Character, Character> allPlusNumberGroupings = new HashMap<>();
198     // Put (lower letter -> upper letter) and (upper letter -> upper letter) mappings.
199     for (char c : ALPHA_MAPPINGS.keySet()) {
Character.toLowerCase(c)200       allPlusNumberGroupings.put(Character.toLowerCase(c), c);
allPlusNumberGroupings.put(c, c)201       allPlusNumberGroupings.put(c, c);
202     }
203     allPlusNumberGroupings.putAll(asciiDigitMappings);
204     // Put grouping symbols.
205     allPlusNumberGroupings.put('-', '-');
206     allPlusNumberGroupings.put('\uFF0D', '-');
207     allPlusNumberGroupings.put('\u2010', '-');
208     allPlusNumberGroupings.put('\u2011', '-');
209     allPlusNumberGroupings.put('\u2012', '-');
210     allPlusNumberGroupings.put('\u2013', '-');
211     allPlusNumberGroupings.put('\u2014', '-');
212     allPlusNumberGroupings.put('\u2015', '-');
213     allPlusNumberGroupings.put('\u2212', '-');
214     allPlusNumberGroupings.put('/', '/');
215     allPlusNumberGroupings.put('\uFF0F', '/');
216     allPlusNumberGroupings.put(' ', ' ');
217     allPlusNumberGroupings.put('\u3000', ' ');
218     allPlusNumberGroupings.put('\u2060', ' ');
219     allPlusNumberGroupings.put('.', '.');
220     allPlusNumberGroupings.put('\uFF0E', '.');
221     ALL_PLUS_NUMBER_GROUPING_SYMBOLS = Collections.unmodifiableMap(allPlusNumberGroupings);
222   }
223 
224   // Pattern that makes it easy to distinguish whether a region has a single international dialing
225   // prefix or not. If a region has a single international prefix (e.g. 011 in USA), it will be
226   // represented as a string that contains a sequence of ASCII digits, and possibly a tilde, which
227   // signals waiting for the tone. If there are multiple available international prefixes in a
228   // region, they will be represented as a regex string that always contains one or more characters
229   // that are not ASCII digits or a tilde.
230   private static final Pattern SINGLE_INTERNATIONAL_PREFIX =
231       Pattern.compile("[\\d]+(?:[~\u2053\u223C\uFF5E][\\d]+)?");
232 
233   // Regular expression of acceptable punctuation found in phone numbers, used to find numbers in
234   // text and to decide what is a viable phone number. This excludes diallable characters.
235   // This consists of dash characters, white space characters, full stops, slashes,
236   // square brackets, parentheses and tildes. It also includes the letter 'x' as that is found as a
237   // placeholder for carrier information in some phone numbers. Full-width variants are also
238   // present.
239   static final String VALID_PUNCTUATION = "-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F "
240       + "\u00A0\u00AD\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E";
241 
242   private static final String DIGITS = "\\p{Nd}";
243   // We accept alpha characters in phone numbers, ASCII only, upper and lower case.
244   private static final String VALID_ALPHA =
245       Arrays.toString(ALPHA_MAPPINGS.keySet().toArray()).replaceAll("[, \\[\\]]", "")
246       + Arrays.toString(ALPHA_MAPPINGS.keySet().toArray())
247           .toLowerCase().replaceAll("[, \\[\\]]", "");
248   static final String PLUS_CHARS = "+\uFF0B";
249   static final Pattern PLUS_CHARS_PATTERN = Pattern.compile("[" + PLUS_CHARS + "]+");
250   private static final Pattern SEPARATOR_PATTERN = Pattern.compile("[" + VALID_PUNCTUATION + "]+");
251   private static final Pattern CAPTURING_DIGIT_PATTERN = Pattern.compile("(" + DIGITS + ")");
252 
253   // Regular expression of acceptable characters that may start a phone number for the purposes of
254   // parsing. This allows us to strip away meaningless prefixes to phone numbers that may be
255   // mistakenly given to us. This consists of digits, the plus symbol and arabic-indic digits. This
256   // does not contain alpha characters, although they may be used later in the number. It also does
257   // not include other punctuation, as this will be stripped later during parsing and is of no
258   // information value when parsing a number.
259   private static final String VALID_START_CHAR = "[" + PLUS_CHARS + DIGITS + "]";
260   private static final Pattern VALID_START_CHAR_PATTERN = Pattern.compile(VALID_START_CHAR);
261 
262   // Regular expression of characters typically used to start a second phone number for the purposes
263   // of parsing. This allows us to strip off parts of the number that are actually the start of
264   // another number, such as for: (530) 583-6985 x302/x2303 -> the second extension here makes this
265   // actually two phone numbers, (530) 583-6985 x302 and (530) 583-6985 x2303. We remove the second
266   // extension so that the first number is parsed correctly.
267   private static final String SECOND_NUMBER_START = "[\\\\/] *x";
268   static final Pattern SECOND_NUMBER_START_PATTERN = Pattern.compile(SECOND_NUMBER_START);
269 
270   // Regular expression of trailing characters that we want to remove. We remove all characters that
271   // are not alpha or numerical characters. The hash character is retained here, as it may signify
272   // the previous block was an extension.
273   private static final String UNWANTED_END_CHARS = "[[\\P{N}&&\\P{L}]&&[^#]]+$";
274   static final Pattern UNWANTED_END_CHAR_PATTERN = Pattern.compile(UNWANTED_END_CHARS);
275 
276   // We use this pattern to check if the phone number has at least three letters in it - if so, then
277   // we treat it as a number where some phone-number digits are represented by letters.
278   private static final Pattern VALID_ALPHA_PHONE_PATTERN = Pattern.compile("(?:.*?[A-Za-z]){3}.*");
279 
280   // Regular expression of viable phone numbers. This is location independent. Checks we have at
281   // least three leading digits, and only valid punctuation, alpha characters and
282   // digits in the phone number. Does not include extension data.
283   // The symbol 'x' is allowed here as valid punctuation since it is often used as a placeholder for
284   // carrier codes, for example in Brazilian phone numbers. We also allow multiple "+" characters at
285   // the start.
286   // Corresponds to the following:
287   // [digits]{minLengthNsn}|
288   // plus_sign*(([punctuation]|[star])*[digits]){3,}([punctuation]|[star]|[digits]|[alpha])*
289   //
290   // The first reg-ex is to allow short numbers (two digits long) to be parsed if they are entered
291   // as "15" etc, but only if there is no punctuation in them. The second expression restricts the
292   // number of digits to three or more, but then allows them to be in international form, and to
293   // have alpha-characters and punctuation.
294   //
295   // Note VALID_PUNCTUATION starts with a -, so must be the first in the range.
296   private static final String VALID_PHONE_NUMBER =
297       DIGITS + "{" + MIN_LENGTH_FOR_NSN + "}" + "|"
298       + "[" + PLUS_CHARS + "]*+(?:[" + VALID_PUNCTUATION + STAR_SIGN + "]*" + DIGITS + "){3,}["
299       + VALID_PUNCTUATION + STAR_SIGN + VALID_ALPHA + DIGITS + "]*";
300 
301   // Default extension prefix to use when formatting. This will be put in front of any extension
302   // component of the number, after the main national number is formatted. For example, if you wish
303   // the default extension formatting to be " extn: 3456", then you should specify " extn: " here
304   // as the default extension prefix. This can be overridden by region-specific preferences.
305   private static final String DEFAULT_EXTN_PREFIX = " ext. ";
306 
307   // Regexp of all possible ways to write extensions, for use when parsing. This will be run as a
308   // case-insensitive regexp match. Wide character versions are also provided after each ASCII
309   // version.
310   private static final String EXTN_PATTERNS_FOR_PARSING = createExtnPattern(true);
311   static final String EXTN_PATTERNS_FOR_MATCHING = createExtnPattern(false);
312 
313   /**
314    * Helper method for constructing regular expressions for parsing. Creates an expression that
315    * captures up to maxLength digits.
316    */
extnDigits(int maxLength)317   private static String extnDigits(int maxLength) {
318     return "(" + DIGITS + "{1," + maxLength + "})";
319   }
320 
321   /**
322    * Helper initialiser method to create the regular-expression pattern to match extensions.
323    * Note that there are currently six capturing groups for the extension itself. If this number is
324    * changed, MaybeStripExtension needs to be updated.
325    */
createExtnPattern(boolean forParsing)326   private static String createExtnPattern(boolean forParsing) {
327     // We cap the maximum length of an extension based on the ambiguity of the way the extension is
328     // prefixed. As per ITU, the officially allowed length for extensions is actually 40, but we
329     // don't support this since we haven't seen real examples and this introduces many false
330     // interpretations as the extension labels are not standardized.
331     int extLimitAfterExplicitLabel = 20;
332     int extLimitAfterLikelyLabel = 15;
333     int extLimitAfterAmbiguousChar = 9;
334     int extLimitWhenNotSure = 6;
335 
336     String possibleSeparatorsBetweenNumberAndExtLabel = "[ \u00A0\\t,]*";
337     // Optional full stop (.) or colon, followed by zero or more spaces/tabs/commas.
338     String possibleCharsAfterExtLabel = "[:\\.\uFF0E]?[ \u00A0\\t,-]*";
339     String optionalExtnSuffix = "#?";
340 
341     // Here the extension is called out in more explicit way, i.e mentioning it obvious patterns
342     // like "ext.". Canonical-equivalence doesn't seem to be an option with Android java, so we
343     // allow two options for representing the accented o - the character itself, and one in the
344     // unicode decomposed form with the combining acute accent.
345     String explicitExtLabels =
346         "(?:e?xt(?:ensi(?:o\u0301?|\u00F3))?n?|\uFF45?\uFF58\uFF54\uFF4E?|\u0434\u043E\u0431|anexo)";
347     // One-character symbols that can be used to indicate an extension, and less commonly used
348     // or more ambiguous extension labels.
349     String ambiguousExtLabels = "(?:[x\uFF58#\uFF03~\uFF5E]|int|\uFF49\uFF4E\uFF54)";
350     // When extension is not separated clearly.
351     String ambiguousSeparator = "[- ]+";
352 
353     String rfcExtn = RFC3966_EXTN_PREFIX + extnDigits(extLimitAfterExplicitLabel);
354     String explicitExtn = possibleSeparatorsBetweenNumberAndExtLabel + explicitExtLabels
355         + possibleCharsAfterExtLabel + extnDigits(extLimitAfterExplicitLabel)
356         + optionalExtnSuffix;
357     String ambiguousExtn = possibleSeparatorsBetweenNumberAndExtLabel + ambiguousExtLabels
358         + possibleCharsAfterExtLabel + extnDigits(extLimitAfterAmbiguousChar) + optionalExtnSuffix;
359     String americanStyleExtnWithSuffix = ambiguousSeparator + extnDigits(extLimitWhenNotSure) + "#";
360 
361     // The first regular expression covers RFC 3966 format, where the extension is added using
362     // ";ext=". The second more generic where extension is mentioned with explicit labels like
363     // "ext:". In both the above cases we allow more numbers in extension than any other extension
364     // labels. The third one captures when single character extension labels or less commonly used
365     // labels are used. In such cases we capture fewer extension digits in order to reduce the
366     // chance of falsely interpreting two numbers beside each other as a number + extension. The
367     // fourth one covers the special case of American numbers where the extension is written with a
368     // hash at the end, such as "- 503#".
369     String extensionPattern =
370         rfcExtn + "|"
371         + explicitExtn + "|"
372         + ambiguousExtn + "|"
373         + americanStyleExtnWithSuffix;
374     // Additional pattern that is supported when parsing extensions, not when matching.
375     if (forParsing) {
376       // This is same as possibleSeparatorsBetweenNumberAndExtLabel, but not matching comma as
377       // extension label may have it.
378       String possibleSeparatorsNumberExtLabelNoComma = "[ \u00A0\\t]*";
379       // ",," is commonly used for auto dialling the extension when connected. First comma is matched
380       // through possibleSeparatorsBetweenNumberAndExtLabel, so we do not repeat it here. Semi-colon
381       // works in Iphone and Android also to pop up a button with the extension number following.
382       String autoDiallingAndExtLabelsFound = "(?:,{2}|;)";
383 
384       String autoDiallingExtn = possibleSeparatorsNumberExtLabelNoComma
385           + autoDiallingAndExtLabelsFound + possibleCharsAfterExtLabel
386           + extnDigits(extLimitAfterLikelyLabel) +  optionalExtnSuffix;
387       String onlyCommasExtn = possibleSeparatorsNumberExtLabelNoComma
388         + "(?:,)+" + possibleCharsAfterExtLabel + extnDigits(extLimitAfterAmbiguousChar)
389         + optionalExtnSuffix;
390       // Here the first pattern is exclusively for extension autodialling formats which are used
391       // when dialling and in this case we accept longer extensions. However, the second pattern
392       // is more liberal on the number of commas that acts as extension labels, so we have a strict
393       // cap on the number of digits in such extensions.
394       return extensionPattern + "|"
395           + autoDiallingExtn + "|"
396           + onlyCommasExtn;
397     }
398     return extensionPattern;
399   }
400 
401   // Regexp of all known extension prefixes used by different regions followed by 1 or more valid
402   // digits, for use when parsing.
403   private static final Pattern EXTN_PATTERN =
404       Pattern.compile("(?:" + EXTN_PATTERNS_FOR_PARSING + ")$", REGEX_FLAGS);
405 
406   // We append optionally the extension pattern to the end here, as a valid phone number may
407   // have an extension prefix appended, followed by 1 or more digits.
408   private static final Pattern VALID_PHONE_NUMBER_PATTERN =
409       Pattern.compile(VALID_PHONE_NUMBER + "(?:" + EXTN_PATTERNS_FOR_PARSING + ")?", REGEX_FLAGS);
410 
411   static final Pattern NON_DIGITS_PATTERN = Pattern.compile("(\\D+)");
412 
413   // The FIRST_GROUP_PATTERN was originally set to $1 but there are some countries for which the
414   // first group is not used in the national pattern (e.g. Argentina) so the $1 group does not match
415   // correctly.  Therefore, we use \d, so that the first group actually used in the pattern will be
416   // matched.
417   private static final Pattern FIRST_GROUP_PATTERN = Pattern.compile("(\\$\\d)");
418   // Constants used in the formatting rules to represent the national prefix, first group and
419   // carrier code respectively.
420   private static final String NP_STRING = "$NP";
421   private static final String FG_STRING = "$FG";
422   private static final String CC_STRING = "$CC";
423 
424   // A pattern that is used to determine if the national prefix formatting rule has the first group
425   // only, i.e., does not start with the national prefix. Note that the pattern explicitly allows
426   // for unbalanced parentheses.
427   private static final Pattern FIRST_GROUP_ONLY_PREFIX_PATTERN = Pattern.compile("\\(?\\$1\\)?");
428 
429   private static PhoneNumberUtil instance = null;
430 
431   public static final String REGION_CODE_FOR_NON_GEO_ENTITY = "001";
432 
433   /**
434    * INTERNATIONAL and NATIONAL formats are consistent with the definition in ITU-T Recommendation
435    * E.123. However we follow local conventions such as using '-' instead of whitespace as
436    * separators. For example, the number of the Google Switzerland office will be written as
437    * "+41 44 668 1800" in INTERNATIONAL format, and as "044 668 1800" in NATIONAL format. E164
438    * format is as per INTERNATIONAL format but with no formatting applied, e.g. "+41446681800".
439    * RFC3966 is as per INTERNATIONAL format, but with all spaces and other separating symbols
440    * replaced with a hyphen, and with any phone number extension appended with ";ext=". It also
441    * will have a prefix of "tel:" added, e.g. "tel:+41-44-668-1800".
442    *
443    * Note: If you are considering storing the number in a neutral format, you are highly advised to
444    * use the PhoneNumber class.
445    */
446   public enum PhoneNumberFormat {
447     E164,
448     INTERNATIONAL,
449     NATIONAL,
450     RFC3966
451   }
452 
453   /**
454    * Type of phone numbers.
455    */
456   public enum PhoneNumberType {
457     FIXED_LINE,
458     MOBILE,
459     // In some regions (e.g. the USA), it is impossible to distinguish between fixed-line and
460     // mobile numbers by looking at the phone number itself.
461     FIXED_LINE_OR_MOBILE,
462     // Freephone lines
463     TOLL_FREE,
464     PREMIUM_RATE,
465     // The cost of this call is shared between the caller and the recipient, and is hence typically
466     // less than PREMIUM_RATE calls. See // http://en.wikipedia.org/wiki/Shared_Cost_Service for
467     // more information.
468     SHARED_COST,
469     // Voice over IP numbers. This includes TSoIP (Telephony Service over IP).
470     VOIP,
471     // A personal number is associated with a particular person, and may be routed to either a
472     // MOBILE or FIXED_LINE number. Some more information can be found here:
473     // http://en.wikipedia.org/wiki/Personal_Numbers
474     PERSONAL_NUMBER,
475     PAGER,
476     // Used for "Universal Access Numbers" or "Company Numbers". They may be further routed to
477     // specific offices, but allow one number to be used for a company.
478     UAN,
479     // Used for "Voice Mail Access Numbers".
480     VOICEMAIL,
481     // A phone number is of type UNKNOWN when it does not fit any of the known patterns for a
482     // specific region.
483     UNKNOWN
484   }
485 
486   /**
487    * Types of phone number matches. See detailed description beside the isNumberMatch() method.
488    */
489   public enum MatchType {
490     NOT_A_NUMBER,
491     NO_MATCH,
492     SHORT_NSN_MATCH,
493     NSN_MATCH,
494     EXACT_MATCH,
495   }
496 
497   /**
498    * Possible outcomes when testing if a PhoneNumber is possible.
499    */
500   public enum ValidationResult {
501     /** The number length matches that of valid numbers for this region. */
502     IS_POSSIBLE,
503     /**
504      * The number length matches that of local numbers for this region only (i.e. numbers that may
505      * be able to be dialled within an area, but do not have all the information to be dialled from
506      * anywhere inside or outside the country).
507      */
508     IS_POSSIBLE_LOCAL_ONLY,
509     /** The number has an invalid country calling code. */
510     INVALID_COUNTRY_CODE,
511     /** The number is shorter than all valid numbers for this region. */
512     TOO_SHORT,
513     /**
514      * The number is longer than the shortest valid numbers for this region, shorter than the
515      * longest valid numbers for this region, and does not itself have a number length that matches
516      * valid numbers for this region. This can also be returned in the case where
517      * isPossibleNumberForTypeWithReason was called, and there are no numbers of this type at all
518      * for this region.
519      */
520     INVALID_LENGTH,
521     /** The number is longer than all valid numbers for this region. */
522     TOO_LONG,
523   }
524 
525   /**
526    * Leniency when {@linkplain PhoneNumberUtil#findNumbers finding} potential phone numbers in text
527    * segments. The levels here are ordered in increasing strictness.
528    */
529   public enum Leniency {
530     /**
531      * Phone numbers accepted are {@linkplain PhoneNumberUtil#isPossibleNumber(PhoneNumber)
532      * possible}, but not necessarily {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid}.
533      */
534     POSSIBLE {
535       @Override
verify( PhoneNumber number, CharSequence candidate, PhoneNumberUtil util, PhoneNumberMatcher matcher)536       boolean verify(
537           PhoneNumber number,
538           CharSequence candidate,
539           PhoneNumberUtil util,
540           PhoneNumberMatcher matcher) {
541         return util.isPossibleNumber(number);
542       }
543     },
544     /**
545      * Phone numbers accepted are {@linkplain PhoneNumberUtil#isPossibleNumber(PhoneNumber)
546      * possible} and {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid}. Numbers written
547      * in national format must have their national-prefix present if it is usually written for a
548      * number of this type.
549      */
550     VALID {
551       @Override
verify( PhoneNumber number, CharSequence candidate, PhoneNumberUtil util, PhoneNumberMatcher matcher)552       boolean verify(
553           PhoneNumber number,
554           CharSequence candidate,
555           PhoneNumberUtil util,
556           PhoneNumberMatcher matcher) {
557         if (!util.isValidNumber(number)
558             || !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate.toString(), util)) {
559           return false;
560         }
561         return PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util);
562       }
563     },
564     /**
565      * Phone numbers accepted are {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid} and
566      * are grouped in a possible way for this locale. For example, a US number written as
567      * "65 02 53 00 00" and "650253 0000" are not accepted at this leniency level, whereas
568      * "650 253 0000", "650 2530000" or "6502530000" are.
569      * Numbers with more than one '/' symbol in the national significant number are also dropped at
570      * this level.
571      * <p>
572      * Warning: This level might result in lower coverage especially for regions outside of country
573      * code "+1". If you are not sure about which level to use, email the discussion group
574      * libphonenumber-discuss@googlegroups.com.
575      */
576     STRICT_GROUPING {
577       @Override
verify( PhoneNumber number, CharSequence candidate, PhoneNumberUtil util, PhoneNumberMatcher matcher)578       boolean verify(
579           PhoneNumber number,
580           CharSequence candidate,
581           PhoneNumberUtil util,
582           PhoneNumberMatcher matcher) {
583         String candidateString = candidate.toString();
584         if (!util.isValidNumber(number)
585             || !PhoneNumberMatcher.containsOnlyValidXChars(number, candidateString, util)
586             || PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidateString)
587             || !PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util)) {
588           return false;
589         }
590         return matcher.checkNumberGroupingIsValid(
591             number, candidate, util, new PhoneNumberMatcher.NumberGroupingChecker() {
592               @Override
593               public boolean checkGroups(PhoneNumberUtil util, PhoneNumber number,
594                                          StringBuilder normalizedCandidate,
595                                          String[] expectedNumberGroups) {
596                 return PhoneNumberMatcher.allNumberGroupsRemainGrouped(
597                     util, number, normalizedCandidate, expectedNumberGroups);
598               }
599             });
600       }
601     },
602     /**
603      * Phone numbers accepted are {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid} and
604      * are grouped in the same way that we would have formatted it, or as a single block. For
605      * example, a US number written as "650 2530000" is not accepted at this leniency level, whereas
606      * "650 253 0000" or "6502530000" are.
607      * Numbers with more than one '/' symbol are also dropped at this level.
608      * <p>
609      * Warning: This level might result in lower coverage especially for regions outside of country
610      * code "+1". If you are not sure about which level to use, email the discussion group
611      * libphonenumber-discuss@googlegroups.com.
612      */
613     EXACT_GROUPING {
614       @Override
verify( PhoneNumber number, CharSequence candidate, PhoneNumberUtil util, PhoneNumberMatcher matcher)615       boolean verify(
616           PhoneNumber number,
617           CharSequence candidate,
618           PhoneNumberUtil util,
619           PhoneNumberMatcher matcher) {
620         String candidateString = candidate.toString();
621         if (!util.isValidNumber(number)
622             || !PhoneNumberMatcher.containsOnlyValidXChars(number, candidateString, util)
623             || PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidateString)
624             || !PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util)) {
625           return false;
626         }
627         return matcher.checkNumberGroupingIsValid(
628             number, candidate, util, new PhoneNumberMatcher.NumberGroupingChecker() {
629               @Override
630               public boolean checkGroups(PhoneNumberUtil util, PhoneNumber number,
631                                          StringBuilder normalizedCandidate,
632                                          String[] expectedNumberGroups) {
633                 return PhoneNumberMatcher.allNumberGroupsAreExactlyPresent(
634                     util, number, normalizedCandidate, expectedNumberGroups);
635               }
636             });
637       }
638     };
639 
640     /** Returns true if {@code number} is a verified number according to this leniency. */
641     abstract boolean verify(
642         PhoneNumber number,
643         CharSequence candidate,
644         PhoneNumberUtil util,
645         PhoneNumberMatcher matcher);
646   }
647 
648   // A source of metadata for different regions.
649   private final MetadataSource metadataSource;
650 
651   // A mapping from a country calling code to the region codes which denote the region represented
652   // by that country calling code. In the case of multiple regions sharing a calling code, such as
653   // the NANPA regions, the one indicated with "isMainCountryForCode" in the metadata should be
654   // first.
655   private final Map<Integer, List<String>> countryCallingCodeToRegionCodeMap;
656 
657   // An API for validation checking.
658   private final MatcherApi matcherApi = RegexBasedMatcher.create();
659 
660   // The set of regions that share country calling code 1.
661   // There are roughly 26 regions.
662   // We set the initial capacity of the HashSet to 35 to offer a load factor of roughly 0.75.
663   private final Set<String> nanpaRegions = new HashSet<>(35);
664 
665   // A cache for frequently used region-specific regular expressions.
666   // The initial capacity is set to 100 as this seems to be an optimal value for Android, based on
667   // performance measurements.
668   private final RegexCache regexCache = new RegexCache(100);
669 
670   // The set of regions the library supports.
671   // There are roughly 240 of them and we set the initial capacity of the HashSet to 320 to offer a
672   // load factor of roughly 0.75.
673   private final Set<String> supportedRegions = new HashSet<>(320);
674 
675   // The set of country calling codes that map to the non-geo entity region ("001"). This set
676   // currently contains < 12 elements so the default capacity of 16 (load factor=0.75) is fine.
677   private final Set<Integer> countryCodesForNonGeographicalRegion = new HashSet<>();
678 
679   /**
680    * This class implements a singleton, the constructor is only visible to facilitate testing.
681    */
682   // @VisibleForTesting
683   PhoneNumberUtil(MetadataSource metadataSource,
684       Map<Integer, List<String>> countryCallingCodeToRegionCodeMap) {
685     this.metadataSource = metadataSource;
686     this.countryCallingCodeToRegionCodeMap = countryCallingCodeToRegionCodeMap;
687     for (Map.Entry<Integer, List<String>> entry : countryCallingCodeToRegionCodeMap.entrySet()) {
688       List<String> regionCodes = entry.getValue();
689       // We can assume that if the country calling code maps to the non-geo entity region code then
690       // that's the only region code it maps to.
691       if (regionCodes.size() == 1 && REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCodes.get(0))) {
692         // This is the subset of all country codes that map to the non-geo entity region code.
693         countryCodesForNonGeographicalRegion.add(entry.getKey());
694       } else {
695         // The supported regions set does not include the "001" non-geo entity region code.
696         supportedRegions.addAll(regionCodes);
697       }
698     }
699     // If the non-geo entity still got added to the set of supported regions it must be because
700     // there are entries that list the non-geo entity alongside normal regions (which is wrong).
701     // If we discover this, remove the non-geo entity from the set of supported regions and log.
702     if (supportedRegions.remove(REGION_CODE_FOR_NON_GEO_ENTITY)) {
703       logger.log(Level.WARNING, "invalid metadata (country calling code was mapped to the non-geo "
704           + "entity as well as specific region(s))");
705     }
706     nanpaRegions.addAll(countryCallingCodeToRegionCodeMap.get(NANPA_COUNTRY_CODE));
707   }
708 
709   /**
710    * Attempts to extract a possible number from the string passed in. This currently strips all
711    * leading characters that cannot be used to start a phone number. Characters that can be used to
712    * start a phone number are defined in the VALID_START_CHAR_PATTERN. If none of these characters
713    * are found in the number passed in, an empty string is returned. This function also attempts to
714    * strip off any alternative extensions or endings if two or more are present, such as in the case
715    * of: (530) 583-6985 x302/x2303. The second extension here makes this actually two phone numbers,
716    * (530) 583-6985 x302 and (530) 583-6985 x2303. We remove the second extension so that the first
717    * number is parsed correctly.
718    *
719    * @param number  the string that might contain a phone number
720    * @return  the number, stripped of any non-phone-number prefix (such as "Tel:") or an empty
721    *     string if no character used to start phone numbers (such as + or any digit) is found in the
722    *     number
723    */
724   static CharSequence extractPossibleNumber(CharSequence number) {
725     Matcher m = VALID_START_CHAR_PATTERN.matcher(number);
726     if (m.find()) {
727       number = number.subSequence(m.start(), number.length());
728       // Remove trailing non-alpha non-numerical characters.
729       Matcher trailingCharsMatcher = UNWANTED_END_CHAR_PATTERN.matcher(number);
730       if (trailingCharsMatcher.find()) {
731         number = number.subSequence(0, trailingCharsMatcher.start());
732       }
733       // Check for extra numbers at the end.
734       Matcher secondNumber = SECOND_NUMBER_START_PATTERN.matcher(number);
735       if (secondNumber.find()) {
736         number = number.subSequence(0, secondNumber.start());
737       }
738       return number;
739     } else {
740       return "";
741     }
742   }
743 
744   /**
745    * Checks to see if the string of characters could possibly be a phone number at all. At the
746    * moment, checks to see that the string begins with at least 2 digits, ignoring any punctuation
747    * commonly found in phone numbers.
748    * This method does not require the number to be normalized in advance - but does assume that
749    * leading non-number symbols have been removed, such as by the method extractPossibleNumber.
750    *
751    * @param number  string to be checked for viability as a phone number
752    * @return  true if the number could be a phone number of some sort, otherwise false
753    */
754   // @VisibleForTesting
755   static boolean isViablePhoneNumber(CharSequence number) {
756     if (number.length() < MIN_LENGTH_FOR_NSN) {
757       return false;
758     }
759     Matcher m = VALID_PHONE_NUMBER_PATTERN.matcher(number);
760     return m.matches();
761   }
762 
763   /**
764    * Normalizes a string of characters representing a phone number. This performs the following
765    * conversions:
766    *   - Punctuation is stripped.
767    *   For ALPHA/VANITY numbers:
768    *   - Letters are converted to their numeric representation on a telephone keypad. The keypad
769    *     used here is the one defined in ITU Recommendation E.161. This is only done if there are 3
770    *     or more letters in the number, to lessen the risk that such letters are typos.
771    *   For other numbers:
772    *   - Wide-ascii digits are converted to normal ASCII (European) digits.
773    *   - Arabic-Indic numerals are converted to European numerals.
774    *   - Spurious alpha characters are stripped.
775    *
776    * @param number  a StringBuilder of characters representing a phone number that will be
777    *     normalized in place
778    */
779   static StringBuilder normalize(StringBuilder number) {
780     Matcher m = VALID_ALPHA_PHONE_PATTERN.matcher(number);
781     if (m.matches()) {
782       number.replace(0, number.length(), normalizeHelper(number, ALPHA_PHONE_MAPPINGS, true));
783     } else {
784       number.replace(0, number.length(), normalizeDigitsOnly(number));
785     }
786     return number;
787   }
788 
789   /**
790    * Normalizes a string of characters representing a phone number. This converts wide-ascii and
791    * arabic-indic numerals to European numerals, and strips punctuation and alpha characters.
792    *
793    * @param number  a string of characters representing a phone number
794    * @return  the normalized string version of the phone number
795    */
796   public static String normalizeDigitsOnly(CharSequence number) {
797     return normalizeDigits(number, false /* strip non-digits */).toString();
798   }
799 
800   static StringBuilder normalizeDigits(CharSequence number, boolean keepNonDigits) {
801     StringBuilder normalizedDigits = new StringBuilder(number.length());
802     for (int i = 0; i < number.length(); i++) {
803       char c = number.charAt(i);
804       int digit = Character.digit(c, 10);
805       if (digit != -1) {
806         normalizedDigits.append(digit);
807       } else if (keepNonDigits) {
808         normalizedDigits.append(c);
809       }
810     }
811     return normalizedDigits;
812   }
813 
814   /**
815    * Normalizes a string of characters representing a phone number. This strips all characters which
816    * are not diallable on a mobile phone keypad (including all non-ASCII digits).
817    *
818    * @param number  a string of characters representing a phone number
819    * @return  the normalized string version of the phone number
820    */
821   public static String normalizeDiallableCharsOnly(CharSequence number) {
822     return normalizeHelper(number, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */);
823   }
824 
825   /**
826    * Converts all alpha characters in a number to their respective digits on a keypad, but retains
827    * existing formatting.
828    */
829   public static String convertAlphaCharactersInNumber(CharSequence number) {
830     return normalizeHelper(number, ALPHA_PHONE_MAPPINGS, false);
831   }
832 
833   /**
834    * Gets the length of the geographical area code from the
835    * PhoneNumber object passed in, so that clients could use it
836    * to split a national significant number into geographical area code and subscriber number. It
837    * works in such a way that the resultant subscriber number should be diallable, at least on some
838    * devices. An example of how this could be used:
839    *
840    * <pre>{@code
841    * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
842    * PhoneNumber number = phoneUtil.parse("16502530000", "US");
843    * String nationalSignificantNumber = phoneUtil.getNationalSignificantNumber(number);
844    * String areaCode;
845    * String subscriberNumber;
846    *
847    * int areaCodeLength = phoneUtil.getLengthOfGeographicalAreaCode(number);
848    * if (areaCodeLength > 0) {
849    *   areaCode = nationalSignificantNumber.substring(0, areaCodeLength);
850    *   subscriberNumber = nationalSignificantNumber.substring(areaCodeLength);
851    * } else {
852    *   areaCode = "";
853    *   subscriberNumber = nationalSignificantNumber;
854    * }
855    * }</pre>
856    *
857    * N.B.: area code is a very ambiguous concept, so the I18N team generally recommends against
858    * using it for most purposes, but recommends using the more general {@code national_number}
859    * instead. Read the following carefully before deciding to use this method:
860    * <ul>
861    *  <li> geographical area codes change over time, and this method honors those changes;
862    *    therefore, it doesn't guarantee the stability of the result it produces.
863    *  <li> subscriber numbers may not be diallable from all devices (notably mobile devices, which
864    *    typically requires the full national_number to be dialled in most regions).
865    *  <li> most non-geographical numbers have no area codes, including numbers from non-geographical
866    *    entities
867    *  <li> some geographical numbers have no area codes.
868    * </ul>
869    * @param number  the PhoneNumber object for which clients
870    *     want to know the length of the area code
871    * @return  the length of area code of the PhoneNumber object
872    *     passed in
873    */
874   public int getLengthOfGeographicalAreaCode(PhoneNumber number) {
875     PhoneMetadata metadata = getMetadataForRegion(getRegionCodeForNumber(number));
876     if (metadata == null) {
877       return 0;
878     }
879     // If a country doesn't use a national prefix, and this number doesn't have an Italian leading
880     // zero, we assume it is a closed dialling plan with no area codes.
881     if (!metadata.hasNationalPrefix() && !number.isItalianLeadingZero()) {
882       return 0;
883     }
884 
885     PhoneNumberType type = getNumberType(number);
886     int countryCallingCode = number.getCountryCode();
887     if (type == PhoneNumberType.MOBILE
888         // Note this is a rough heuristic; it doesn't cover Indonesia well, for example, where area
889         // codes are present for some mobile phones but not for others. We have no better way of
890         // representing this in the metadata at this point.
891         && GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES.contains(countryCallingCode)) {
892       return 0;
893     }
894 
895     if (!isNumberGeographical(type, countryCallingCode)) {
896       return 0;
897     }
898 
899     return getLengthOfNationalDestinationCode(number);
900   }
901 
902   /**
903    * Gets the length of the national destination code (NDC) from the
904    * PhoneNumber object passed in, so that clients could use it
905    * to split a national significant number into NDC and subscriber number. The NDC of a phone
906    * number is normally the first group of digit(s) right after the country calling code when the
907    * number is formatted in the international format, if there is a subscriber number part that
908    * follows.
909    *
910    * N.B.: similar to an area code, not all numbers have an NDC!
911    *
912    * An example of how this could be used:
913    *
914    * <pre>{@code
915    * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
916    * PhoneNumber number = phoneUtil.parse("18002530000", "US");
917    * String nationalSignificantNumber = phoneUtil.getNationalSignificantNumber(number);
918    * String nationalDestinationCode;
919    * String subscriberNumber;
920    *
921    * int nationalDestinationCodeLength = phoneUtil.getLengthOfNationalDestinationCode(number);
922    * if (nationalDestinationCodeLength > 0) {
923    *   nationalDestinationCode = nationalSignificantNumber.substring(0,
924    *       nationalDestinationCodeLength);
925    *   subscriberNumber = nationalSignificantNumber.substring(nationalDestinationCodeLength);
926    * } else {
927    *   nationalDestinationCode = "";
928    *   subscriberNumber = nationalSignificantNumber;
929    * }
930    * }</pre>
931    *
932    * Refer to the unittests to see the difference between this function and
933    * {@link #getLengthOfGeographicalAreaCode}.
934    *
935    * @param number  the PhoneNumber object for which clients
936    *     want to know the length of the NDC
937    * @return  the length of NDC of the PhoneNumber object
938    *     passed in, which could be zero
939    */
940   public int getLengthOfNationalDestinationCode(PhoneNumber number) {
941     PhoneNumber copiedProto;
942     if (number.hasExtension()) {
943       // We don't want to alter the proto given to us, but we don't want to include the extension
944       // when we format it, so we copy it and clear the extension here.
945       copiedProto = new PhoneNumber();
946       copiedProto.mergeFrom(number);
947       copiedProto.clearExtension();
948     } else {
949       copiedProto = number;
950     }
951 
952     String nationalSignificantNumber = format(copiedProto,
953                                               PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
954     String[] numberGroups = NON_DIGITS_PATTERN.split(nationalSignificantNumber);
955     // The pattern will start with "+COUNTRY_CODE " so the first group will always be the empty
956     // string (before the + symbol) and the second group will be the country calling code. The third
957     // group will be area code if it is not the last group.
958     if (numberGroups.length <= 3) {
959       return 0;
960     }
961 
962     if (getNumberType(number) == PhoneNumberType.MOBILE) {
963       // For example Argentinian mobile numbers, when formatted in the international format, are in
964       // the form of +54 9 NDC XXXX.... As a result, we take the length of the third group (NDC) and
965       // add the length of the second group (which is the mobile token), which also forms part of
966       // the national significant number. This assumes that the mobile token is always formatted
967       // separately from the rest of the phone number.
968       String mobileToken = getCountryMobileToken(number.getCountryCode());
969       if (!mobileToken.equals("")) {
970         return numberGroups[2].length() + numberGroups[3].length();
971       }
972     }
973     return numberGroups[2].length();
974   }
975 
976   /**
977    * Returns the mobile token for the provided country calling code if it has one, otherwise
978    * returns an empty string. A mobile token is a number inserted before the area code when dialing
979    * a mobile number from that country from abroad.
980    *
981    * @param countryCallingCode  the country calling code for which we want the mobile token
982    * @return  the mobile token, as a string, for the given country calling code
983    */
984   public static String getCountryMobileToken(int countryCallingCode) {
985     if (MOBILE_TOKEN_MAPPINGS.containsKey(countryCallingCode)) {
986       return MOBILE_TOKEN_MAPPINGS.get(countryCallingCode);
987     }
988     return "";
989   }
990 
991   /**
992    * Normalizes a string of characters representing a phone number by replacing all characters found
993    * in the accompanying map with the values therein, and stripping all other characters if
994    * removeNonMatches is true.
995    *
996    * @param number  a string of characters representing a phone number
997    * @param normalizationReplacements  a mapping of characters to what they should be replaced by in
998    *     the normalized version of the phone number
999    * @param removeNonMatches  indicates whether characters that are not able to be replaced should
1000    *     be stripped from the number. If this is false, they will be left unchanged in the number.
1001    * @return  the normalized string version of the phone number
1002    */
1003   private static String normalizeHelper(CharSequence number,
1004                                         Map<Character, Character> normalizationReplacements,
1005                                         boolean removeNonMatches) {
1006     StringBuilder normalizedNumber = new StringBuilder(number.length());
1007     for (int i = 0; i < number.length(); i++) {
1008       char character = number.charAt(i);
1009       Character newDigit = normalizationReplacements.get(Character.toUpperCase(character));
1010       if (newDigit != null) {
1011         normalizedNumber.append(newDigit);
1012       } else if (!removeNonMatches) {
1013         normalizedNumber.append(character);
1014       }
1015       // If neither of the above are true, we remove this character.
1016     }
1017     return normalizedNumber.toString();
1018   }
1019 
1020   /**
1021    * Sets or resets the PhoneNumberUtil singleton instance. If set to null, the next call to
1022    * {@code getInstance()} will load (and return) the default instance.
1023    */
1024   // @VisibleForTesting
1025   static synchronized void setInstance(PhoneNumberUtil util) {
1026     instance = util;
1027   }
1028 
1029   /**
1030    * Returns all regions the library has metadata for.
1031    *
1032    * @return  an unordered set of the two-letter region codes for every geographical region the
1033    *     library supports
1034    */
1035   public Set<String> getSupportedRegions() {
1036     return Collections.unmodifiableSet(supportedRegions);
1037   }
1038 
1039   /**
1040    * Returns all global network calling codes the library has metadata for.
1041    *
1042    * @return  an unordered set of the country calling codes for every non-geographical entity the
1043    *     library supports
1044    */
1045   public Set<Integer> getSupportedGlobalNetworkCallingCodes() {
1046     return Collections.unmodifiableSet(countryCodesForNonGeographicalRegion);
1047   }
1048 
1049   /**
1050    * Returns all country calling codes the library has metadata for, covering both non-geographical
1051    * entities (global network calling codes) and those used for geographical entities. This could be
1052    * used to populate a drop-down box of country calling codes for a phone-number widget, for
1053    * instance.
1054    *
1055    * @return  an unordered set of the country calling codes for every geographical and
1056    *     non-geographical entity the library supports
1057    */
1058   public Set<Integer> getSupportedCallingCodes() {
1059     return Collections.unmodifiableSet(countryCallingCodeToRegionCodeMap.keySet());
1060   }
1061 
1062   /**
1063    * Returns true if there is any possible number data set for a particular PhoneNumberDesc.
1064    */
1065   private static boolean descHasPossibleNumberData(PhoneNumberDesc desc) {
1066     // If this is empty, it means numbers of this type inherit from the "general desc" -> the value
1067     // "-1" means that no numbers exist for this type.
1068     return desc.getPossibleLengthCount() != 1 || desc.getPossibleLength(0) != -1;
1069   }
1070 
1071   // Note: descHasData must account for any of MetadataFilter's excludableChildFields potentially
1072   // being absent from the metadata. It must check them all. For any changes in descHasData, ensure
1073   // that all the excludableChildFields are still being checked. If your change is safe simply
1074   // mention why during a review without needing to change MetadataFilter.
1075   /**
1076    * Returns true if there is any data set for a particular PhoneNumberDesc.
1077    */
1078   private static boolean descHasData(PhoneNumberDesc desc) {
1079     // Checking most properties since we don't know what's present, since a custom build may have
1080     // stripped just one of them (e.g. liteBuild strips exampleNumber). We don't bother checking the
1081     // possibleLengthsLocalOnly, since if this is the only thing that's present we don't really
1082     // support the type at all: no type-specific methods will work with only this data.
1083     return desc.hasExampleNumber()
1084         || descHasPossibleNumberData(desc)
1085         || desc.hasNationalNumberPattern();
1086   }
1087 
1088   /**
1089    * Returns the types we have metadata for based on the PhoneMetadata object passed in, which must
1090    * be non-null.
1091    */
1092   private Set<PhoneNumberType> getSupportedTypesForMetadata(PhoneMetadata metadata) {
1093     Set<PhoneNumberType> types = new TreeSet<>();
1094     for (PhoneNumberType type : PhoneNumberType.values()) {
1095       if (type == PhoneNumberType.FIXED_LINE_OR_MOBILE || type == PhoneNumberType.UNKNOWN) {
1096         // Never return FIXED_LINE_OR_MOBILE (it is a convenience type, and represents that a
1097         // particular number type can't be determined) or UNKNOWN (the non-type).
1098         continue;
1099       }
1100       if (descHasData(getNumberDescByType(metadata, type))) {
1101         types.add(type);
1102       }
1103     }
1104     return Collections.unmodifiableSet(types);
1105   }
1106 
1107   /**
1108    * Returns the types for a given region which the library has metadata for. Will not include
1109    * FIXED_LINE_OR_MOBILE (if numbers in this region could be classified as FIXED_LINE_OR_MOBILE,
1110    * both FIXED_LINE and MOBILE would be present) and UNKNOWN.
1111    *
1112    * No types will be returned for invalid or unknown region codes.
1113    */
1114   public Set<PhoneNumberType> getSupportedTypesForRegion(String regionCode) {
1115     if (!isValidRegionCode(regionCode)) {
1116       logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode);
1117       return Collections.unmodifiableSet(new TreeSet<PhoneNumberType>());
1118     }
1119     PhoneMetadata metadata = getMetadataForRegion(regionCode);
1120     return getSupportedTypesForMetadata(metadata);
1121   }
1122 
1123   /**
1124    * Returns the types for a country-code belonging to a non-geographical entity which the library
1125    * has metadata for. Will not include FIXED_LINE_OR_MOBILE (if numbers for this non-geographical
1126    * entity could be classified as FIXED_LINE_OR_MOBILE, both FIXED_LINE and MOBILE would be
1127    * present) and UNKNOWN.
1128    *
1129    * No types will be returned for country calling codes that do not map to a known non-geographical
1130    * entity.
1131    */
1132   public Set<PhoneNumberType> getSupportedTypesForNonGeoEntity(int countryCallingCode) {
1133     PhoneMetadata metadata = getMetadataForNonGeographicalRegion(countryCallingCode);
1134     if (metadata == null) {
1135       logger.log(Level.WARNING, "Unknown country calling code for a non-geographical entity "
1136           + "provided: " + countryCallingCode);
1137       return Collections.unmodifiableSet(new TreeSet<PhoneNumberType>());
1138     }
1139     return getSupportedTypesForMetadata(metadata);
1140   }
1141 
1142   /**
1143    * Gets a {@link PhoneNumberUtil} instance to carry out international phone number formatting,
1144    * parsing, or validation. The instance is loaded with all phone number metadata.
1145    *
1146    * <p>The {@link PhoneNumberUtil} is implemented as a singleton. Therefore, calling getInstance
1147    * multiple times will only result in one instance being created.
1148    *
1149    * @return a PhoneNumberUtil instance
1150    */
1151   public static synchronized PhoneNumberUtil getInstance() {
1152     if (instance == null) {
1153       MetadataLoader metadataLoader = DefaultMetadataDependenciesProvider.getInstance()
1154           .getMetadataLoader();
1155       setInstance(createInstance(metadataLoader));
1156     }
1157     return instance;
1158   }
1159 
1160   /**
1161    * Create a new {@link PhoneNumberUtil} instance to carry out international phone number
1162    * formatting, parsing, or validation. The instance is loaded with all metadata by
1163    * using the metadataLoader specified.
1164    *
1165    * <p>This method should only be used in the rare case in which you want to manage your own
1166    * metadata loading. Calling this method multiple times is very expensive, as each time
1167    * a new instance is created from scratch. When in doubt, use {@link #getInstance}.
1168    *
1169    * @param metadataLoader  customized metadata loader. This should not be null
1170    * @return  a PhoneNumberUtil instance
1171    */
1172   public static PhoneNumberUtil createInstance(MetadataLoader metadataLoader) {
1173     if (metadataLoader == null) {
1174       throw new IllegalArgumentException("metadataLoader could not be null.");
1175     }
1176     return createInstance(new MetadataSourceImpl(
1177         DefaultMetadataDependenciesProvider.getInstance().getPhoneNumberMetadataFileNameProvider(),
1178         metadataLoader,
1179         DefaultMetadataDependenciesProvider.getInstance().getMetadataParser()
1180     ));
1181   }
1182 
1183   /**
1184    * Create a new {@link PhoneNumberUtil} instance to carry out international phone number
1185    * formatting, parsing, or validation. The instance is loaded with all metadata by
1186    * using the metadataSource specified.
1187    *
1188    * <p>This method should only be used in the rare case in which you want to manage your own
1189    * metadata loading. Calling this method multiple times is very expensive, as each time
1190    * a new instance is created from scratch. When in doubt, use {@link #getInstance}.
1191    *
1192    * @param metadataSource  customized metadata source. This should not be null
1193    * @return  a PhoneNumberUtil instance
1194    */
1195   private static PhoneNumberUtil createInstance(MetadataSource metadataSource) {
1196     if (metadataSource == null) {
1197       throw new IllegalArgumentException("metadataSource could not be null.");
1198     }
1199     return new PhoneNumberUtil(metadataSource,
1200         CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap());
1201   }
1202 
1203   /**
1204    * Helper function to check if the national prefix formatting rule has the first group only, i.e.,
1205    * does not start with the national prefix.
1206    */
1207   static boolean formattingRuleHasFirstGroupOnly(String nationalPrefixFormattingRule) {
1208     return nationalPrefixFormattingRule.length() == 0
1209         || FIRST_GROUP_ONLY_PREFIX_PATTERN.matcher(nationalPrefixFormattingRule).matches();
1210   }
1211 
1212   /**
1213    * Tests whether a phone number has a geographical association. It checks if the number is
1214    * associated with a certain region in the country to which it belongs. Note that this doesn't
1215    * verify if the number is actually in use.
1216    */
1217   public boolean isNumberGeographical(PhoneNumber phoneNumber) {
1218     return isNumberGeographical(getNumberType(phoneNumber), phoneNumber.getCountryCode());
1219   }
1220 
1221   /**
1222    * Overload of isNumberGeographical(PhoneNumber), since calculating the phone number type is
1223    * expensive; if we have already done this, we don't want to do it again.
1224    */
1225   public boolean isNumberGeographical(PhoneNumberType phoneNumberType, int countryCallingCode) {
1226     return phoneNumberType == PhoneNumberType.FIXED_LINE
1227         || phoneNumberType == PhoneNumberType.FIXED_LINE_OR_MOBILE
1228         || (GEO_MOBILE_COUNTRIES.contains(countryCallingCode)
1229             && phoneNumberType == PhoneNumberType.MOBILE);
1230   }
1231 
1232   /**
1233    * Helper function to check region code is not unknown or null.
1234    */
1235   private boolean isValidRegionCode(String regionCode) {
1236     return regionCode != null && supportedRegions.contains(regionCode);
1237   }
1238 
1239   /**
1240    * Helper function to check the country calling code is valid.
1241    */
1242   private boolean hasValidCountryCallingCode(int countryCallingCode) {
1243     return countryCallingCodeToRegionCodeMap.containsKey(countryCallingCode);
1244   }
1245 
1246   /**
1247    * Formats a phone number in the specified format using default rules. Note that this does not
1248    * promise to produce a phone number that the user can dial from where they are - although we do
1249    * format in either 'national' or 'international' format depending on what the client asks for, we
1250    * do not currently support a more abbreviated format, such as for users in the same "area" who
1251    * could potentially dial the number without area code. Note that if the phone number has a
1252    * country calling code of 0 or an otherwise invalid country calling code, we cannot work out
1253    * which formatting rules to apply so we return the national significant number with no formatting
1254    * applied.
1255    *
1256    * @param number  the phone number to be formatted
1257    * @param numberFormat  the format the phone number should be formatted into
1258    * @return  the formatted phone number
1259    */
1260   public String format(PhoneNumber number, PhoneNumberFormat numberFormat) {
1261     if (number.getNationalNumber() == 0 && number.hasRawInput()) {
1262       // Unparseable numbers that kept their raw input just use that.
1263       // This is the only case where a number can be formatted as E164 without a
1264       // leading '+' symbol (but the original number wasn't parseable anyway).
1265       // TODO: Consider removing the 'if' above so that unparseable
1266       // strings without raw input format to the empty string instead of "+00".
1267       String rawInput = number.getRawInput();
1268       if (rawInput.length() > 0) {
1269         return rawInput;
1270       }
1271     }
1272     StringBuilder formattedNumber = new StringBuilder(20);
1273     format(number, numberFormat, formattedNumber);
1274     return formattedNumber.toString();
1275   }
1276 
1277   /**
1278    * Same as {@link #format(PhoneNumber, PhoneNumberFormat)}, but accepts a mutable StringBuilder as
1279    * a parameter to decrease object creation when invoked many times.
1280    */
1281   public void format(PhoneNumber number, PhoneNumberFormat numberFormat,
1282                      StringBuilder formattedNumber) {
1283     // Clear the StringBuilder first.
1284     formattedNumber.setLength(0);
1285     int countryCallingCode = number.getCountryCode();
1286     String nationalSignificantNumber = getNationalSignificantNumber(number);
1287 
1288     if (numberFormat == PhoneNumberFormat.E164) {
1289       // Early exit for E164 case (even if the country calling code is invalid) since no formatting
1290       // of the national number needs to be applied. Extensions are not formatted.
1291       formattedNumber.append(nationalSignificantNumber);
1292       prefixNumberWithCountryCallingCode(countryCallingCode, PhoneNumberFormat.E164,
1293                                          formattedNumber);
1294       return;
1295     }
1296     if (!hasValidCountryCallingCode(countryCallingCode)) {
1297       formattedNumber.append(nationalSignificantNumber);
1298       return;
1299     }
1300     // Note getRegionCodeForCountryCode() is used because formatting information for regions which
1301     // share a country calling code is contained by only one region for performance reasons. For
1302     // example, for NANPA regions it will be contained in the metadata for US.
1303     String regionCode = getRegionCodeForCountryCode(countryCallingCode);
1304     // Metadata cannot be null because the country calling code is valid (which means that the
1305     // region code cannot be ZZ and must be one of our supported region codes).
1306     PhoneMetadata metadata =
1307         getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
1308     formattedNumber.append(formatNsn(nationalSignificantNumber, metadata, numberFormat));
1309     maybeAppendFormattedExtension(number, metadata, numberFormat, formattedNumber);
1310     prefixNumberWithCountryCallingCode(countryCallingCode, numberFormat, formattedNumber);
1311   }
1312 
1313   /**
1314    * Formats a phone number in the specified format using client-defined formatting rules. Note that
1315    * if the phone number has a country calling code of zero or an otherwise invalid country calling
1316    * code, we cannot work out things like whether there should be a national prefix applied, or how
1317    * to format extensions, so we return the national significant number with no formatting applied.
1318    *
1319    * @param number  the phone number to be formatted
1320    * @param numberFormat  the format the phone number should be formatted into
1321    * @param userDefinedFormats  formatting rules specified by clients
1322    * @return  the formatted phone number
1323    */
1324   public String formatByPattern(PhoneNumber number,
1325                                 PhoneNumberFormat numberFormat,
1326                                 List<NumberFormat> userDefinedFormats) {
1327     int countryCallingCode = number.getCountryCode();
1328     String nationalSignificantNumber = getNationalSignificantNumber(number);
1329     if (!hasValidCountryCallingCode(countryCallingCode)) {
1330       return nationalSignificantNumber;
1331     }
1332     // Note getRegionCodeForCountryCode() is used because formatting information for regions which
1333     // share a country calling code is contained by only one region for performance reasons. For
1334     // example, for NANPA regions it will be contained in the metadata for US.
1335     String regionCode = getRegionCodeForCountryCode(countryCallingCode);
1336     // Metadata cannot be null because the country calling code is valid.
1337     PhoneMetadata metadata =
1338         getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
1339 
1340     StringBuilder formattedNumber = new StringBuilder(20);
1341 
1342     NumberFormat formattingPattern =
1343         chooseFormattingPatternForNumber(userDefinedFormats, nationalSignificantNumber);
1344     if (formattingPattern == null) {
1345       // If no pattern above is matched, we format the number as a whole.
1346       formattedNumber.append(nationalSignificantNumber);
1347     } else {
1348       NumberFormat.Builder numFormatCopy = NumberFormat.newBuilder();
1349       // Before we do a replacement of the national prefix pattern $NP with the national prefix, we
1350       // need to copy the rule so that subsequent replacements for different numbers have the
1351       // appropriate national prefix.
1352       numFormatCopy.mergeFrom(formattingPattern);
1353       String nationalPrefixFormattingRule = formattingPattern.getNationalPrefixFormattingRule();
1354       if (nationalPrefixFormattingRule.length() > 0) {
1355         String nationalPrefix = metadata.getNationalPrefix();
1356         if (nationalPrefix.length() > 0) {
1357           // Replace $NP with national prefix and $FG with the first group ($1).
1358           nationalPrefixFormattingRule =
1359               nationalPrefixFormattingRule.replace(NP_STRING, nationalPrefix);
1360           nationalPrefixFormattingRule = nationalPrefixFormattingRule.replace(FG_STRING, "$1");
1361           numFormatCopy.setNationalPrefixFormattingRule(nationalPrefixFormattingRule);
1362         } else {
1363           // We don't want to have a rule for how to format the national prefix if there isn't one.
1364           numFormatCopy.clearNationalPrefixFormattingRule();
1365         }
1366       }
1367       formattedNumber.append(
1368           formatNsnUsingPattern(nationalSignificantNumber, numFormatCopy.build(), numberFormat));
1369     }
1370     maybeAppendFormattedExtension(number, metadata, numberFormat, formattedNumber);
1371     prefixNumberWithCountryCallingCode(countryCallingCode, numberFormat, formattedNumber);
1372     return formattedNumber.toString();
1373   }
1374 
1375   /**
1376    * Formats a phone number in national format for dialing using the carrier as specified in the
1377    * {@code carrierCode}. The {@code carrierCode} will always be used regardless of whether the
1378    * phone number already has a preferred domestic carrier code stored. If {@code carrierCode}
1379    * contains an empty string, returns the number in national format without any carrier code.
1380    *
1381    * @param number  the phone number to be formatted
1382    * @param carrierCode  the carrier selection code to be used
1383    * @return  the formatted phone number in national format for dialing using the carrier as
1384    *     specified in the {@code carrierCode}
1385    */
1386   public String formatNationalNumberWithCarrierCode(PhoneNumber number, CharSequence carrierCode) {
1387     int countryCallingCode = number.getCountryCode();
1388     String nationalSignificantNumber = getNationalSignificantNumber(number);
1389     if (!hasValidCountryCallingCode(countryCallingCode)) {
1390       return nationalSignificantNumber;
1391     }
1392 
1393     // Note getRegionCodeForCountryCode() is used because formatting information for regions which
1394     // share a country calling code is contained by only one region for performance reasons. For
1395     // example, for NANPA regions it will be contained in the metadata for US.
1396     String regionCode = getRegionCodeForCountryCode(countryCallingCode);
1397     // Metadata cannot be null because the country calling code is valid.
1398     PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
1399 
1400     StringBuilder formattedNumber = new StringBuilder(20);
1401     formattedNumber.append(formatNsn(nationalSignificantNumber, metadata,
1402                                      PhoneNumberFormat.NATIONAL, carrierCode));
1403     maybeAppendFormattedExtension(number, metadata, PhoneNumberFormat.NATIONAL, formattedNumber);
1404     prefixNumberWithCountryCallingCode(countryCallingCode, PhoneNumberFormat.NATIONAL,
1405                                        formattedNumber);
1406     return formattedNumber.toString();
1407   }
1408 
1409   private PhoneMetadata getMetadataForRegionOrCallingCode(
1410       int countryCallingCode, String regionCode) {
1411     return REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode)
1412         ? getMetadataForNonGeographicalRegion(countryCallingCode)
1413         : getMetadataForRegion(regionCode);
1414   }
1415 
1416   /**
1417    * Formats a phone number in national format for dialing using the carrier as specified in the
1418    * preferredDomesticCarrierCode field of the PhoneNumber object passed in. If that is missing,
1419    * use the {@code fallbackCarrierCode} passed in instead. If there is no
1420    * {@code preferredDomesticCarrierCode}, and the {@code fallbackCarrierCode} contains an empty
1421    * string, return the number in national format without any carrier code.
1422    *
1423    * <p>Use {@link #formatNationalNumberWithCarrierCode} instead if the carrier code passed in
1424    * should take precedence over the number's {@code preferredDomesticCarrierCode} when formatting.
1425    *
1426    * @param number  the phone number to be formatted
1427    * @param fallbackCarrierCode  the carrier selection code to be used, if none is found in the
1428    *     phone number itself
1429    * @return  the formatted phone number in national format for dialing using the number's
1430    *     {@code preferredDomesticCarrierCode}, or the {@code fallbackCarrierCode} passed in if
1431    *     none is found
1432    */
1433   public String formatNationalNumberWithPreferredCarrierCode(PhoneNumber number,
1434                                                              CharSequence fallbackCarrierCode) {
1435     return formatNationalNumberWithCarrierCode(number,
1436         // Historically, we set this to an empty string when parsing with raw input if none was
1437         // found in the input string. However, this doesn't result in a number we can dial. For this
1438         // reason, we treat the empty string the same as if it isn't set at all.
1439         number.getPreferredDomesticCarrierCode().length() > 0
1440         ? number.getPreferredDomesticCarrierCode()
1441         : fallbackCarrierCode);
1442   }
1443 
1444   /**
1445    * Returns a number formatted in such a way that it can be dialed from a mobile phone in a
1446    * specific region. If the number cannot be reached from the region (e.g. some countries block
1447    * toll-free numbers from being called outside of the country), the method returns an empty
1448    * string.
1449    *
1450    * @param number  the phone number to be formatted
1451    * @param regionCallingFrom  the region where the call is being placed
1452    * @param withFormatting  whether the number should be returned with formatting symbols, such as
1453    *     spaces and dashes.
1454    * @return  the formatted phone number
1455    */
1456   public String formatNumberForMobileDialing(PhoneNumber number, String regionCallingFrom,
1457                                              boolean withFormatting) {
1458     int countryCallingCode = number.getCountryCode();
1459     if (!hasValidCountryCallingCode(countryCallingCode)) {
1460       return number.hasRawInput() ? number.getRawInput() : "";
1461     }
1462 
1463     String formattedNumber = "";
1464     // Clear the extension, as that part cannot normally be dialed together with the main number.
1465     PhoneNumber numberNoExt = new PhoneNumber().mergeFrom(number).clearExtension();
1466     String regionCode = getRegionCodeForCountryCode(countryCallingCode);
1467     PhoneNumberType numberType = getNumberType(numberNoExt);
1468     boolean isValidNumber = (numberType != PhoneNumberType.UNKNOWN);
1469     if (regionCallingFrom.equals(regionCode)) {
1470       boolean isFixedLineOrMobile =
1471           (numberType == PhoneNumberType.FIXED_LINE) || (numberType == PhoneNumberType.MOBILE)
1472           || (numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE);
1473       // Carrier codes may be needed in some countries. We handle this here.
1474       if (regionCode.equals("CO") && numberType == PhoneNumberType.FIXED_LINE) {
1475         formattedNumber =
1476             formatNationalNumberWithCarrierCode(numberNoExt, COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX);
1477       } else if (regionCode.equals("BR") && isFixedLineOrMobile) {
1478         // Historically, we set this to an empty string when parsing with raw input if none was
1479         // found in the input string. However, this doesn't result in a number we can dial. For this
1480         // reason, we treat the empty string the same as if it isn't set at all.
1481         formattedNumber = numberNoExt.getPreferredDomesticCarrierCode().length() > 0
1482             ? formattedNumber = formatNationalNumberWithPreferredCarrierCode(numberNoExt, "")
1483             // Brazilian fixed line and mobile numbers need to be dialed with a carrier code when
1484             // called within Brazil. Without that, most of the carriers won't connect the call.
1485             // Because of that, we return an empty string here.
1486             : "";
1487       } else if (countryCallingCode == NANPA_COUNTRY_CODE) {
1488         // For NANPA countries, we output international format for numbers that can be dialed
1489         // internationally, since that always works, except for numbers which might potentially be
1490         // short numbers, which are always dialled in national format.
1491         PhoneMetadata regionMetadata = getMetadataForRegion(regionCallingFrom);
1492         if (canBeInternationallyDialled(numberNoExt)
1493             && testNumberLength(getNationalSignificantNumber(numberNoExt), regionMetadata)
1494                 != ValidationResult.TOO_SHORT) {
1495           formattedNumber = format(numberNoExt, PhoneNumberFormat.INTERNATIONAL);
1496         } else {
1497           formattedNumber = format(numberNoExt, PhoneNumberFormat.NATIONAL);
1498         }
1499       } else {
1500         // For non-geographical countries, and Mexican, Chilean, and Uzbek fixed line and mobile
1501         // numbers, we output international format for numbers that can be dialed internationally as
1502         // that always works.
1503         if ((regionCode.equals(REGION_CODE_FOR_NON_GEO_ENTITY)
1504              // MX fixed line and mobile numbers should always be formatted in international format,
1505              // even when dialed within MX. For national format to work, a carrier code needs to be
1506              // used, and the correct carrier code depends on if the caller and callee are from the
1507              // same local area. It is trickier to get that to work correctly than using
1508              // international format, which is tested to work fine on all carriers.
1509              // CL fixed line numbers need the national prefix when dialing in the national format,
1510              // but don't have it when used for display. The reverse is true for mobile numbers.  As
1511              // a result, we output them in the international format to make it work.
1512              // UZ mobile and fixed-line numbers have to be formatted in international format or
1513              // prefixed with special codes like 03, 04 (for fixed-line) and 05 (for mobile) for
1514              // dialling successfully from mobile devices. As we do not have complete information on
1515              // special codes and to be consistent with formatting across all phone types we return
1516              // the number in international format here.
1517              || ((regionCode.equals("MX") || regionCode.equals("CL")
1518                  || regionCode.equals("UZ")) && isFixedLineOrMobile))
1519             && canBeInternationallyDialled(numberNoExt)) {
1520           formattedNumber = format(numberNoExt, PhoneNumberFormat.INTERNATIONAL);
1521         } else {
1522           formattedNumber = format(numberNoExt, PhoneNumberFormat.NATIONAL);
1523         }
1524       }
1525     } else if (isValidNumber && canBeInternationallyDialled(numberNoExt)) {
1526       // We assume that short numbers are not diallable from outside their region, so if a number
1527       // is not a valid regular length phone number, we treat it as if it cannot be internationally
1528       // dialled.
1529       return withFormatting ? format(numberNoExt, PhoneNumberFormat.INTERNATIONAL)
1530                             : format(numberNoExt, PhoneNumberFormat.E164);
1531     }
1532     return withFormatting ? formattedNumber
1533                           : normalizeDiallableCharsOnly(formattedNumber);
1534   }
1535 
1536   /**
1537    * Formats a phone number for out-of-country dialing purposes. If no regionCallingFrom is
1538    * supplied, we format the number in its INTERNATIONAL format. If the country calling code is the
1539    * same as that of the region where the number is from, then NATIONAL formatting will be applied.
1540    *
1541    * <p>If the number itself has a country calling code of zero or an otherwise invalid country
1542    * calling code, then we return the number with no formatting applied.
1543    *
1544    * <p>Note this function takes care of the case for calling inside of NANPA and between Russia and
1545    * Kazakhstan (who share the same country calling code). In those cases, no international prefix
1546    * is used. For regions which have multiple international prefixes, the number in its
1547    * INTERNATIONAL format will be returned instead.
1548    *
1549    * @param number  the phone number to be formatted
1550    * @param regionCallingFrom  the region where the call is being placed
1551    * @return  the formatted phone number
1552    */
1553   public String formatOutOfCountryCallingNumber(PhoneNumber number,
1554                                                 String regionCallingFrom) {
1555     if (!isValidRegionCode(regionCallingFrom)) {
1556       logger.log(Level.WARNING,
1557                  "Trying to format number from invalid region "
1558                  + regionCallingFrom
1559                  + ". International formatting applied.");
1560       return format(number, PhoneNumberFormat.INTERNATIONAL);
1561     }
1562     int countryCallingCode = number.getCountryCode();
1563     String nationalSignificantNumber = getNationalSignificantNumber(number);
1564     if (!hasValidCountryCallingCode(countryCallingCode)) {
1565       return nationalSignificantNumber;
1566     }
1567     if (countryCallingCode == NANPA_COUNTRY_CODE) {
1568       if (isNANPACountry(regionCallingFrom)) {
1569         // For NANPA regions, return the national format for these regions but prefix it with the
1570         // country calling code.
1571         return countryCallingCode + " " + format(number, PhoneNumberFormat.NATIONAL);
1572       }
1573     } else if (countryCallingCode == getCountryCodeForValidRegion(regionCallingFrom)) {
1574       // If regions share a country calling code, the country calling code need not be dialled.
1575       // This also applies when dialling within a region, so this if clause covers both these cases.
1576       // Technically this is the case for dialling from La Reunion to other overseas departments of
1577       // France (French Guiana, Martinique, Guadeloupe), but not vice versa - so we don't cover this
1578       // edge case for now and for those cases return the version including country calling code.
1579       // Details here: http://www.petitfute.com/voyage/225-info-pratiques-reunion
1580       return format(number, PhoneNumberFormat.NATIONAL);
1581     }
1582     // Metadata cannot be null because we checked 'isValidRegionCode()' above.
1583     PhoneMetadata metadataForRegionCallingFrom = getMetadataForRegion(regionCallingFrom);
1584     String internationalPrefix = metadataForRegionCallingFrom.getInternationalPrefix();
1585 
1586     // In general, if there is a preferred international prefix, use that. Otherwise, for regions
1587     // that have multiple international prefixes, the international format of the number is
1588     // returned since we would not know which one to use.
1589     String internationalPrefixForFormatting = "";
1590     if (metadataForRegionCallingFrom.hasPreferredInternationalPrefix()) {
1591       internationalPrefixForFormatting =
1592           metadataForRegionCallingFrom.getPreferredInternationalPrefix();
1593     } else if (SINGLE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches()) {
1594       internationalPrefixForFormatting = internationalPrefix;
1595     }
1596 
1597     String regionCode = getRegionCodeForCountryCode(countryCallingCode);
1598     // Metadata cannot be null because the country calling code is valid.
1599     PhoneMetadata metadataForRegion =
1600         getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
1601     String formattedNationalNumber =
1602         formatNsn(nationalSignificantNumber, metadataForRegion, PhoneNumberFormat.INTERNATIONAL);
1603     StringBuilder formattedNumber = new StringBuilder(formattedNationalNumber);
1604     maybeAppendFormattedExtension(number, metadataForRegion, PhoneNumberFormat.INTERNATIONAL,
1605                                   formattedNumber);
1606     if (internationalPrefixForFormatting.length() > 0) {
1607       formattedNumber.insert(0, " ").insert(0, countryCallingCode).insert(0, " ")
1608           .insert(0, internationalPrefixForFormatting);
1609     } else {
1610       prefixNumberWithCountryCallingCode(countryCallingCode,
1611                                          PhoneNumberFormat.INTERNATIONAL,
1612                                          formattedNumber);
1613     }
1614     return formattedNumber.toString();
1615   }
1616 
1617   /**
1618    * Formats a phone number using the original phone number format that the number is parsed from.
1619    * The original format is embedded in the country_code_source field of the PhoneNumber object
1620    * passed in. If such information is missing, the number will be formatted into the NATIONAL
1621    * format by default. When we don't have a formatting pattern for the number, the method returns
1622    * the raw input when it is available.
1623    *
1624    * Note this method guarantees no digit will be inserted, removed or modified as a result of
1625    * formatting.
1626    *
1627    * @param number  the phone number that needs to be formatted in its original number format
1628    * @param regionCallingFrom  the region whose IDD needs to be prefixed if the original number
1629    *     has one
1630    * @return  the formatted phone number in its original number format
1631    */
1632   public String formatInOriginalFormat(PhoneNumber number, String regionCallingFrom) {
1633     if (number.hasRawInput() && !hasFormattingPatternForNumber(number)) {
1634       // We check if we have the formatting pattern because without that, we might format the number
1635       // as a group without national prefix.
1636       return number.getRawInput();
1637     }
1638     if (!number.hasCountryCodeSource()) {
1639       return format(number, PhoneNumberFormat.NATIONAL);
1640     }
1641     String formattedNumber;
1642     switch (number.getCountryCodeSource()) {
1643       case FROM_NUMBER_WITH_PLUS_SIGN:
1644         formattedNumber = format(number, PhoneNumberFormat.INTERNATIONAL);
1645         break;
1646       case FROM_NUMBER_WITH_IDD:
1647         formattedNumber = formatOutOfCountryCallingNumber(number, regionCallingFrom);
1648         break;
1649       case FROM_NUMBER_WITHOUT_PLUS_SIGN:
1650         formattedNumber = format(number, PhoneNumberFormat.INTERNATIONAL).substring(1);
1651         break;
1652       case FROM_DEFAULT_COUNTRY:
1653         // Fall-through to default case.
1654       default:
1655         String regionCode = getRegionCodeForCountryCode(number.getCountryCode());
1656         // We strip non-digits from the NDD here, and from the raw input later, so that we can
1657         // compare them easily.
1658         String nationalPrefix = getNddPrefixForRegion(regionCode, true /* strip non-digits */);
1659         String nationalFormat = format(number, PhoneNumberFormat.NATIONAL);
1660         if (nationalPrefix == null || nationalPrefix.length() == 0) {
1661           // If the region doesn't have a national prefix at all, we can safely return the national
1662           // format without worrying about a national prefix being added.
1663           formattedNumber = nationalFormat;
1664           break;
1665         }
1666         // Otherwise, we check if the original number was entered with a national prefix.
1667         if (rawInputContainsNationalPrefix(
1668             number.getRawInput(), nationalPrefix, regionCode)) {
1669           // If so, we can safely return the national format.
1670           formattedNumber = nationalFormat;
1671           break;
1672         }
1673         // Metadata cannot be null here because getNddPrefixForRegion() (above) returns null if
1674         // there is no metadata for the region.
1675         PhoneMetadata metadata = getMetadataForRegion(regionCode);
1676         String nationalNumber = getNationalSignificantNumber(number);
1677         NumberFormat formatRule =
1678             chooseFormattingPatternForNumber(metadata.getNumberFormatList(), nationalNumber);
1679         // The format rule could still be null here if the national number was 0 and there was no
1680         // raw input (this should not be possible for numbers generated by the phonenumber library
1681         // as they would also not have a country calling code and we would have exited earlier).
1682         if (formatRule == null) {
1683           formattedNumber = nationalFormat;
1684           break;
1685         }
1686         // When the format we apply to this number doesn't contain national prefix, we can just
1687         // return the national format.
1688         // TODO: Refactor the code below with the code in
1689         // isNationalPrefixPresentIfRequired.
1690         String candidateNationalPrefixRule = formatRule.getNationalPrefixFormattingRule();
1691         // We assume that the first-group symbol will never be _before_ the national prefix.
1692         int indexOfFirstGroup = candidateNationalPrefixRule.indexOf("$1");
1693         if (indexOfFirstGroup <= 0) {
1694           formattedNumber = nationalFormat;
1695           break;
1696         }
1697         candidateNationalPrefixRule =
1698             candidateNationalPrefixRule.substring(0, indexOfFirstGroup);
1699         candidateNationalPrefixRule = normalizeDigitsOnly(candidateNationalPrefixRule);
1700         if (candidateNationalPrefixRule.length() == 0) {
1701           // National prefix not used when formatting this number.
1702           formattedNumber = nationalFormat;
1703           break;
1704         }
1705         // Otherwise, we need to remove the national prefix from our output.
1706         NumberFormat.Builder numFormatCopy =  NumberFormat.newBuilder();
1707         numFormatCopy.mergeFrom(formatRule);
1708         numFormatCopy.clearNationalPrefixFormattingRule();
1709         List<NumberFormat> numberFormats = new ArrayList<>(1);
1710         numberFormats.add(numFormatCopy.build());
1711         formattedNumber = formatByPattern(number, PhoneNumberFormat.NATIONAL, numberFormats);
1712         break;
1713     }
1714     String rawInput = number.getRawInput();
1715     // If no digit is inserted/removed/modified as a result of our formatting, we return the
1716     // formatted phone number; otherwise we return the raw input the user entered.
1717     if (formattedNumber != null && rawInput.length() > 0) {
1718       String normalizedFormattedNumber = normalizeDiallableCharsOnly(formattedNumber);
1719       String normalizedRawInput = normalizeDiallableCharsOnly(rawInput);
1720       if (!normalizedFormattedNumber.equals(normalizedRawInput)) {
1721         formattedNumber = rawInput;
1722       }
1723     }
1724     return formattedNumber;
1725   }
1726 
1727   // Check if rawInput, which is assumed to be in the national format, has a national prefix. The
1728   // national prefix is assumed to be in digits-only form.
1729   private boolean rawInputContainsNationalPrefix(String rawInput, String nationalPrefix,
1730       String regionCode) {
1731     String normalizedNationalNumber = normalizeDigitsOnly(rawInput);
1732     if (normalizedNationalNumber.startsWith(nationalPrefix)) {
1733       try {
1734         // Some Japanese numbers (e.g. 00777123) might be mistaken to contain the national prefix
1735         // when written without it (e.g. 0777123) if we just do prefix matching. To tackle that, we
1736         // check the validity of the number if the assumed national prefix is removed (777123 won't
1737         // be valid in Japan).
1738         return isValidNumber(
1739             parse(normalizedNationalNumber.substring(nationalPrefix.length()), regionCode));
1740       } catch (NumberParseException e) {
1741         return false;
1742       }
1743     }
1744     return false;
1745   }
1746 
1747   private boolean hasFormattingPatternForNumber(PhoneNumber number) {
1748     int countryCallingCode = number.getCountryCode();
1749     String phoneNumberRegion = getRegionCodeForCountryCode(countryCallingCode);
1750     PhoneMetadata metadata =
1751         getMetadataForRegionOrCallingCode(countryCallingCode, phoneNumberRegion);
1752     if (metadata == null) {
1753       return false;
1754     }
1755     String nationalNumber = getNationalSignificantNumber(number);
1756     NumberFormat formatRule =
1757         chooseFormattingPatternForNumber(metadata.getNumberFormatList(), nationalNumber);
1758     return formatRule != null;
1759   }
1760 
1761   /**
1762    * Formats a phone number for out-of-country dialing purposes.
1763    *
1764    * Note that in this version, if the number was entered originally using alpha characters and
1765    * this version of the number is stored in raw_input, this representation of the number will be
1766    * used rather than the digit representation. Grouping information, as specified by characters
1767    * such as "-" and " ", will be retained.
1768    *
1769    * <p><b>Caveats:</b></p>
1770    * <ul>
1771    *  <li> This will not produce good results if the country calling code is both present in the raw
1772    *       input _and_ is the start of the national number. This is not a problem in the regions
1773    *       which typically use alpha numbers.
1774    *  <li> This will also not produce good results if the raw input has any grouping information
1775    *       within the first three digits of the national number, and if the function needs to strip
1776    *       preceding digits/words in the raw input before these digits. Normally people group the
1777    *       first three digits together so this is not a huge problem - and will be fixed if it
1778    *       proves to be so.
1779    * </ul>
1780    *
1781    * @param number  the phone number that needs to be formatted
1782    * @param regionCallingFrom  the region where the call is being placed
1783    * @return  the formatted phone number
1784    */
1785   public String formatOutOfCountryKeepingAlphaChars(PhoneNumber number,
1786                                                     String regionCallingFrom) {
1787     String rawInput = number.getRawInput();
1788     // If there is no raw input, then we can't keep alpha characters because there aren't any.
1789     // In this case, we return formatOutOfCountryCallingNumber.
1790     if (rawInput.length() == 0) {
1791       return formatOutOfCountryCallingNumber(number, regionCallingFrom);
1792     }
1793     int countryCode = number.getCountryCode();
1794     if (!hasValidCountryCallingCode(countryCode)) {
1795       return rawInput;
1796     }
1797     // Strip any prefix such as country calling code, IDD, that was present. We do this by comparing
1798     // the number in raw_input with the parsed number.
1799     // To do this, first we normalize punctuation. We retain number grouping symbols such as " "
1800     // only.
1801     rawInput = normalizeHelper(rawInput, ALL_PLUS_NUMBER_GROUPING_SYMBOLS, true);
1802     // Now we trim everything before the first three digits in the parsed number. We choose three
1803     // because all valid alpha numbers have 3 digits at the start - if it does not, then we don't
1804     // trim anything at all. Similarly, if the national number was less than three digits, we don't
1805     // trim anything at all.
1806     String nationalNumber = getNationalSignificantNumber(number);
1807     if (nationalNumber.length() > 3) {
1808       int firstNationalNumberDigit = rawInput.indexOf(nationalNumber.substring(0, 3));
1809       if (firstNationalNumberDigit != -1) {
1810         rawInput = rawInput.substring(firstNationalNumberDigit);
1811       }
1812     }
1813     PhoneMetadata metadataForRegionCallingFrom = getMetadataForRegion(regionCallingFrom);
1814     if (countryCode == NANPA_COUNTRY_CODE) {
1815       if (isNANPACountry(regionCallingFrom)) {
1816         return countryCode + " " + rawInput;
1817       }
1818     } else if (metadataForRegionCallingFrom != null
1819         && countryCode == getCountryCodeForValidRegion(regionCallingFrom)) {
1820       NumberFormat formattingPattern =
1821           chooseFormattingPatternForNumber(metadataForRegionCallingFrom.getNumberFormatList(),
1822                                            nationalNumber);
1823       if (formattingPattern == null) {
1824         // If no pattern above is matched, we format the original input.
1825         return rawInput;
1826       }
1827       NumberFormat.Builder newFormat = NumberFormat.newBuilder();
1828       newFormat.mergeFrom(formattingPattern);
1829       // The first group is the first group of digits that the user wrote together.
1830       newFormat.setPattern("(\\d+)(.*)");
1831       // Here we just concatenate them back together after the national prefix has been fixed.
1832       newFormat.setFormat("$1$2");
1833       // Now we format using this pattern instead of the default pattern, but with the national
1834       // prefix prefixed if necessary.
1835       // This will not work in the cases where the pattern (and not the leading digits) decide
1836       // whether a national prefix needs to be used, since we have overridden the pattern to match
1837       // anything, but that is not the case in the metadata to date.
1838       return formatNsnUsingPattern(rawInput, newFormat.build(), PhoneNumberFormat.NATIONAL);
1839     }
1840     String internationalPrefixForFormatting = "";
1841     // If an unsupported region-calling-from is entered, or a country with multiple international
1842     // prefixes, the international format of the number is returned, unless there is a preferred
1843     // international prefix.
1844     if (metadataForRegionCallingFrom != null) {
1845       String internationalPrefix = metadataForRegionCallingFrom.getInternationalPrefix();
1846       internationalPrefixForFormatting =
1847           SINGLE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches()
1848           ? internationalPrefix
1849           : metadataForRegionCallingFrom.getPreferredInternationalPrefix();
1850     }
1851     StringBuilder formattedNumber = new StringBuilder(rawInput);
1852     String regionCode = getRegionCodeForCountryCode(countryCode);
1853     // Metadata cannot be null because the country calling code is valid.
1854     PhoneMetadata metadataForRegion = getMetadataForRegionOrCallingCode(countryCode, regionCode);
1855     maybeAppendFormattedExtension(number, metadataForRegion,
1856                                   PhoneNumberFormat.INTERNATIONAL, formattedNumber);
1857     if (internationalPrefixForFormatting.length() > 0) {
1858       formattedNumber.insert(0, " ").insert(0, countryCode).insert(0, " ")
1859           .insert(0, internationalPrefixForFormatting);
1860     } else {
1861       // Invalid region entered as country-calling-from (so no metadata was found for it) or the
1862       // region chosen has multiple international dialling prefixes.
1863       if (!isValidRegionCode(regionCallingFrom)) {
1864         logger.log(Level.WARNING,
1865                    "Trying to format number from invalid region "
1866                    + regionCallingFrom
1867                    + ". International formatting applied.");
1868       }
1869       prefixNumberWithCountryCallingCode(countryCode,
1870                                          PhoneNumberFormat.INTERNATIONAL,
1871                                          formattedNumber);
1872     }
1873     return formattedNumber.toString();
1874   }
1875 
1876   /**
1877    * Gets the national significant number of a phone number. Note a national significant number
1878    * doesn't contain a national prefix or any formatting.
1879    *
1880    * @param number  the phone number for which the national significant number is needed
1881    * @return  the national significant number of the PhoneNumber object passed in
1882    */
1883   public String getNationalSignificantNumber(PhoneNumber number) {
1884     // If leading zero(s) have been set, we prefix this now. Note this is not a national prefix.
1885     StringBuilder nationalNumber = new StringBuilder();
1886     if (number.isItalianLeadingZero() && number.getNumberOfLeadingZeros() > 0) {
1887       char[] zeros = new char[number.getNumberOfLeadingZeros()];
1888       Arrays.fill(zeros, '0');
1889       nationalNumber.append(new String(zeros));
1890     }
1891     nationalNumber.append(number.getNationalNumber());
1892     return nationalNumber.toString();
1893   }
1894 
1895   /**
1896    * A helper function that is used by format and formatByPattern.
1897    */
1898   private void prefixNumberWithCountryCallingCode(int countryCallingCode,
1899                                                   PhoneNumberFormat numberFormat,
1900                                                   StringBuilder formattedNumber) {
1901     switch (numberFormat) {
1902       case E164:
1903         formattedNumber.insert(0, countryCallingCode).insert(0, PLUS_SIGN);
1904         return;
1905       case INTERNATIONAL:
1906         formattedNumber.insert(0, " ").insert(0, countryCallingCode).insert(0, PLUS_SIGN);
1907         return;
1908       case RFC3966:
1909         formattedNumber.insert(0, "-").insert(0, countryCallingCode).insert(0, PLUS_SIGN)
1910             .insert(0, RFC3966_PREFIX);
1911         return;
1912       case NATIONAL:
1913       default:
1914         return;
1915     }
1916   }
1917 
1918   // Simple wrapper of formatNsn for the common case of no carrier code.
1919   private String formatNsn(String number, PhoneMetadata metadata, PhoneNumberFormat numberFormat) {
1920     return formatNsn(number, metadata, numberFormat, null);
1921   }
1922 
1923   // Note in some regions, the national number can be written in two completely different ways
1924   // depending on whether it forms part of the NATIONAL format or INTERNATIONAL format. The
1925   // numberFormat parameter here is used to specify which format to use for those cases. If a
1926   // carrierCode is specified, this will be inserted into the formatted string to replace $CC.
1927   private String formatNsn(String number,
1928                            PhoneMetadata metadata,
1929                            PhoneNumberFormat numberFormat,
1930                            CharSequence carrierCode) {
1931     List<NumberFormat> intlNumberFormats = metadata.getIntlNumberFormatList();
1932     // When the intlNumberFormats exists, we use that to format national number for the
1933     // INTERNATIONAL format instead of using the numberDesc.numberFormats.
1934     List<NumberFormat> availableFormats =
1935         (intlNumberFormats.size() == 0 || numberFormat == PhoneNumberFormat.NATIONAL)
1936         ? metadata.getNumberFormatList()
1937         : metadata.getIntlNumberFormatList();
1938     NumberFormat formattingPattern = chooseFormattingPatternForNumber(availableFormats, number);
1939     return (formattingPattern == null)
1940         ? number
1941         : formatNsnUsingPattern(number, formattingPattern, numberFormat, carrierCode);
1942   }
1943 
1944   NumberFormat chooseFormattingPatternForNumber(List<NumberFormat> availableFormats,
1945                                                 String nationalNumber) {
1946     for (NumberFormat numFormat : availableFormats) {
1947       int size = numFormat.getLeadingDigitsPatternCount();
1948       if (size == 0 || regexCache.getPatternForRegex(
1949               // We always use the last leading_digits_pattern, as it is the most detailed.
1950               numFormat.getLeadingDigitsPattern(size - 1)).matcher(nationalNumber).lookingAt()) {
1951         Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber);
1952         if (m.matches()) {
1953           return numFormat;
1954         }
1955       }
1956     }
1957     return null;
1958   }
1959 
1960   // Simple wrapper of formatNsnUsingPattern for the common case of no carrier code.
1961   String formatNsnUsingPattern(String nationalNumber,
1962                                NumberFormat formattingPattern,
1963                                PhoneNumberFormat numberFormat) {
1964     return formatNsnUsingPattern(nationalNumber, formattingPattern, numberFormat, null);
1965   }
1966 
1967   // Note that carrierCode is optional - if null or an empty string, no carrier code replacement
1968   // will take place.
1969   private String formatNsnUsingPattern(String nationalNumber,
1970                                        NumberFormat formattingPattern,
1971                                        PhoneNumberFormat numberFormat,
1972                                        CharSequence carrierCode) {
1973     String numberFormatRule = formattingPattern.getFormat();
1974     Matcher m =
1975         regexCache.getPatternForRegex(formattingPattern.getPattern()).matcher(nationalNumber);
1976     String formattedNationalNumber = "";
1977     if (numberFormat == PhoneNumberFormat.NATIONAL
1978         && carrierCode != null && carrierCode.length() > 0
1979         && formattingPattern.getDomesticCarrierCodeFormattingRule().length() > 0) {
1980       // Replace the $CC in the formatting rule with the desired carrier code.
1981       String carrierCodeFormattingRule = formattingPattern.getDomesticCarrierCodeFormattingRule();
1982       carrierCodeFormattingRule = carrierCodeFormattingRule.replace(CC_STRING, carrierCode);
1983       // Now replace the $FG in the formatting rule with the first group and the carrier code
1984       // combined in the appropriate way.
1985       numberFormatRule = FIRST_GROUP_PATTERN.matcher(numberFormatRule)
1986           .replaceFirst(carrierCodeFormattingRule);
1987       formattedNationalNumber = m.replaceAll(numberFormatRule);
1988     } else {
1989       // Use the national prefix formatting rule instead.
1990       String nationalPrefixFormattingRule = formattingPattern.getNationalPrefixFormattingRule();
1991       if (numberFormat == PhoneNumberFormat.NATIONAL
1992           && nationalPrefixFormattingRule != null
1993           && nationalPrefixFormattingRule.length() > 0) {
1994         Matcher firstGroupMatcher = FIRST_GROUP_PATTERN.matcher(numberFormatRule);
1995         formattedNationalNumber =
1996             m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule));
1997       } else {
1998         formattedNationalNumber = m.replaceAll(numberFormatRule);
1999       }
2000     }
2001     if (numberFormat == PhoneNumberFormat.RFC3966) {
2002       // Strip any leading punctuation.
2003       Matcher matcher = SEPARATOR_PATTERN.matcher(formattedNationalNumber);
2004       if (matcher.lookingAt()) {
2005         formattedNationalNumber = matcher.replaceFirst("");
2006       }
2007       // Replace the rest with a dash between each number group.
2008       formattedNationalNumber = matcher.reset(formattedNationalNumber).replaceAll("-");
2009     }
2010     return formattedNationalNumber;
2011   }
2012 
2013   /**
2014    * Gets a valid number for the specified region.
2015    *
2016    * @param regionCode  the region for which an example number is needed
2017    * @return  a valid fixed-line number for the specified region. Returns null when the metadata
2018    *    does not contain such information, or the region 001 is passed in. For 001 (representing
2019    *    non-geographical numbers), call {@link #getExampleNumberForNonGeoEntity} instead.
2020    */
2021   public PhoneNumber getExampleNumber(String regionCode) {
2022     return getExampleNumberForType(regionCode, PhoneNumberType.FIXED_LINE);
2023   }
2024 
2025   /**
2026    * Gets an invalid number for the specified region. This is useful for unit-testing purposes,
2027    * where you want to test what will happen with an invalid number. Note that the number that is
2028    * returned will always be able to be parsed and will have the correct country code. It may also
2029    * be a valid *short* number/code for this region. Validity checking such numbers is handled with
2030    * {@link com.google.i18n.phonenumbers.ShortNumberInfo}.
2031    *
2032    * @param regionCode  the region for which an example number is needed
2033    * @return  an invalid number for the specified region. Returns null when an unsupported region or
2034    *     the region 001 (Earth) is passed in.
2035    */
2036   public PhoneNumber getInvalidExampleNumber(String regionCode) {
2037     if (!isValidRegionCode(regionCode)) {
2038       logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode);
2039       return null;
2040     }
2041     // We start off with a valid fixed-line number since every country supports this. Alternatively
2042     // we could start with a different number type, since fixed-line numbers typically have a wide
2043     // breadth of valid number lengths and we may have to make it very short before we get an
2044     // invalid number.
2045     PhoneNumberDesc desc = getNumberDescByType(getMetadataForRegion(regionCode),
2046         PhoneNumberType.FIXED_LINE);
2047     if (!desc.hasExampleNumber()) {
2048       // This shouldn't happen; we have a test for this.
2049       return null;
2050     }
2051     String exampleNumber = desc.getExampleNumber();
2052     // Try and make the number invalid. We do this by changing the length. We try reducing the
2053     // length of the number, since currently no region has a number that is the same length as
2054     // MIN_LENGTH_FOR_NSN. This is probably quicker than making the number longer, which is another
2055     // alternative. We could also use the possible number pattern to extract the possible lengths of
2056     // the number to make this faster, but this method is only for unit-testing so simplicity is
2057     // preferred to performance.  We don't want to return a number that can't be parsed, so we check
2058     // the number is long enough. We try all possible lengths because phone number plans often have
2059     // overlapping prefixes so the number 123456 might be valid as a fixed-line number, and 12345 as
2060     // a mobile number. It would be faster to loop in a different order, but we prefer numbers that
2061     // look closer to real numbers (and it gives us a variety of different lengths for the resulting
2062     // phone numbers - otherwise they would all be MIN_LENGTH_FOR_NSN digits long.)
2063     for (int phoneNumberLength = exampleNumber.length() - 1;
2064          phoneNumberLength >= MIN_LENGTH_FOR_NSN;
2065          phoneNumberLength--) {
2066       String numberToTry = exampleNumber.substring(0, phoneNumberLength);
2067       try {
2068         PhoneNumber possiblyValidNumber = parse(numberToTry, regionCode);
2069         if (!isValidNumber(possiblyValidNumber)) {
2070           return possiblyValidNumber;
2071         }
2072       } catch (NumberParseException e) {
2073         // Shouldn't happen: we have already checked the length, we know example numbers have
2074         // only valid digits, and we know the region code is fine.
2075       }
2076     }
2077     // We have a test to check that this doesn't happen for any of our supported regions.
2078     return null;
2079   }
2080 
2081   /**
2082    * Gets a valid number for the specified region and number type.
2083    *
2084    * @param regionCode  the region for which an example number is needed
2085    * @param type  the type of number that is needed
2086    * @return  a valid number for the specified region and type. Returns null when the metadata
2087    *     does not contain such information or if an invalid region or region 001 was entered.
2088    *     For 001 (representing non-geographical numbers), call
2089    *     {@link #getExampleNumberForNonGeoEntity} instead.
2090    */
2091   public PhoneNumber getExampleNumberForType(String regionCode, PhoneNumberType type) {
2092     // Check the region code is valid.
2093     if (!isValidRegionCode(regionCode)) {
2094       logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode);
2095       return null;
2096     }
2097     PhoneNumberDesc desc = getNumberDescByType(getMetadataForRegion(regionCode), type);
2098     try {
2099       if (desc.hasExampleNumber()) {
2100         return parse(desc.getExampleNumber(), regionCode);
2101       }
2102     } catch (NumberParseException e) {
2103       logger.log(Level.SEVERE, e.toString());
2104     }
2105     return null;
2106   }
2107 
2108   /**
2109    * Gets a valid number for the specified number type (it may belong to any country).
2110    *
2111    * @param type  the type of number that is needed
2112    * @return  a valid number for the specified type. Returns null when the metadata
2113    *     does not contain such information. This should only happen when no numbers of this type are
2114    *     allocated anywhere in the world anymore.
2115    */
2116   public PhoneNumber getExampleNumberForType(PhoneNumberType type) {
2117     for (String regionCode : getSupportedRegions()) {
2118       PhoneNumber exampleNumber = getExampleNumberForType(regionCode, type);
2119       if (exampleNumber != null) {
2120         return exampleNumber;
2121       }
2122     }
2123     // If there wasn't an example number for a region, try the non-geographical entities.
2124     for (int countryCallingCode : getSupportedGlobalNetworkCallingCodes()) {
2125       PhoneNumberDesc desc = getNumberDescByType(
2126           getMetadataForNonGeographicalRegion(countryCallingCode), type);
2127       try {
2128         if (desc.hasExampleNumber()) {
2129           return parse("+" + countryCallingCode + desc.getExampleNumber(), UNKNOWN_REGION);
2130         }
2131       } catch (NumberParseException e) {
2132         logger.log(Level.SEVERE, e.toString());
2133       }
2134     }
2135     // There are no example numbers of this type for any country in the library.
2136     return null;
2137   }
2138 
2139   /**
2140    * Gets a valid number for the specified country calling code for a non-geographical entity.
2141    *
2142    * @param countryCallingCode  the country calling code for a non-geographical entity
2143    * @return  a valid number for the non-geographical entity. Returns null when the metadata
2144    *    does not contain such information, or the country calling code passed in does not belong
2145    *    to a non-geographical entity.
2146    */
2147   public PhoneNumber getExampleNumberForNonGeoEntity(int countryCallingCode) {
2148     PhoneMetadata metadata = getMetadataForNonGeographicalRegion(countryCallingCode);
2149     if (metadata != null) {
2150       // For geographical entities, fixed-line data is always present. However, for non-geographical
2151       // entities, this is not the case, so we have to go through different types to find the
2152       // example number. We don't check fixed-line or personal number since they aren't used by
2153       // non-geographical entities (if this changes, a unit-test will catch this.)
2154       for (PhoneNumberDesc desc : Arrays.asList(metadata.getMobile(), metadata.getTollFree(),
2155                metadata.getSharedCost(), metadata.getVoip(), metadata.getVoicemail(),
2156                metadata.getUan(), metadata.getPremiumRate())) {
2157         try {
2158           if (desc != null && desc.hasExampleNumber()) {
2159             return parse("+" + countryCallingCode + desc.getExampleNumber(), UNKNOWN_REGION);
2160           }
2161         } catch (NumberParseException e) {
2162           logger.log(Level.SEVERE, e.toString());
2163         }
2164       }
2165     } else {
2166       logger.log(Level.WARNING,
2167                  "Invalid or unknown country calling code provided: " + countryCallingCode);
2168     }
2169     return null;
2170   }
2171 
2172   /**
2173    * Appends the formatted extension of a phone number to formattedNumber, if the phone number had
2174    * an extension specified.
2175    */
2176   private void maybeAppendFormattedExtension(PhoneNumber number, PhoneMetadata metadata,
2177                                              PhoneNumberFormat numberFormat,
2178                                              StringBuilder formattedNumber) {
2179     if (number.hasExtension() && number.getExtension().length() > 0) {
2180       if (numberFormat == PhoneNumberFormat.RFC3966) {
2181         formattedNumber.append(RFC3966_EXTN_PREFIX).append(number.getExtension());
2182       } else {
2183         if (metadata.hasPreferredExtnPrefix()) {
2184           formattedNumber.append(metadata.getPreferredExtnPrefix()).append(number.getExtension());
2185         } else {
2186           formattedNumber.append(DEFAULT_EXTN_PREFIX).append(number.getExtension());
2187         }
2188       }
2189     }
2190   }
2191 
2192   PhoneNumberDesc getNumberDescByType(PhoneMetadata metadata, PhoneNumberType type) {
2193     switch (type) {
2194       case PREMIUM_RATE:
2195         return metadata.getPremiumRate();
2196       case TOLL_FREE:
2197         return metadata.getTollFree();
2198       case MOBILE:
2199         return metadata.getMobile();
2200       case FIXED_LINE:
2201       case FIXED_LINE_OR_MOBILE:
2202         return metadata.getFixedLine();
2203       case SHARED_COST:
2204         return metadata.getSharedCost();
2205       case VOIP:
2206         return metadata.getVoip();
2207       case PERSONAL_NUMBER:
2208         return metadata.getPersonalNumber();
2209       case PAGER:
2210         return metadata.getPager();
2211       case UAN:
2212         return metadata.getUan();
2213       case VOICEMAIL:
2214         return metadata.getVoicemail();
2215       default:
2216         return metadata.getGeneralDesc();
2217     }
2218   }
2219 
2220   /**
2221    * Gets the type of a valid phone number.
2222    *
2223    * @param number  the phone number that we want to know the type
2224    * @return  the type of the phone number, or UNKNOWN if it is invalid
2225    */
2226   public PhoneNumberType getNumberType(PhoneNumber number) {
2227     String regionCode = getRegionCodeForNumber(number);
2228     PhoneMetadata metadata = getMetadataForRegionOrCallingCode(number.getCountryCode(), regionCode);
2229     if (metadata == null) {
2230       return PhoneNumberType.UNKNOWN;
2231     }
2232     String nationalSignificantNumber = getNationalSignificantNumber(number);
2233     return getNumberTypeHelper(nationalSignificantNumber, metadata);
2234   }
2235 
2236   private PhoneNumberType getNumberTypeHelper(String nationalNumber, PhoneMetadata metadata) {
2237     if (!isNumberMatchingDesc(nationalNumber, metadata.getGeneralDesc())) {
2238       return PhoneNumberType.UNKNOWN;
2239     }
2240 
2241     if (isNumberMatchingDesc(nationalNumber, metadata.getPremiumRate())) {
2242       return PhoneNumberType.PREMIUM_RATE;
2243     }
2244     if (isNumberMatchingDesc(nationalNumber, metadata.getTollFree())) {
2245       return PhoneNumberType.TOLL_FREE;
2246     }
2247     if (isNumberMatchingDesc(nationalNumber, metadata.getSharedCost())) {
2248       return PhoneNumberType.SHARED_COST;
2249     }
2250     if (isNumberMatchingDesc(nationalNumber, metadata.getVoip())) {
2251       return PhoneNumberType.VOIP;
2252     }
2253     if (isNumberMatchingDesc(nationalNumber, metadata.getPersonalNumber())) {
2254       return PhoneNumberType.PERSONAL_NUMBER;
2255     }
2256     if (isNumberMatchingDesc(nationalNumber, metadata.getPager())) {
2257       return PhoneNumberType.PAGER;
2258     }
2259     if (isNumberMatchingDesc(nationalNumber, metadata.getUan())) {
2260       return PhoneNumberType.UAN;
2261     }
2262     if (isNumberMatchingDesc(nationalNumber, metadata.getVoicemail())) {
2263       return PhoneNumberType.VOICEMAIL;
2264     }
2265 
2266     boolean isFixedLine = isNumberMatchingDesc(nationalNumber, metadata.getFixedLine());
2267     if (isFixedLine) {
2268       if (metadata.getSameMobileAndFixedLinePattern()) {
2269         return PhoneNumberType.FIXED_LINE_OR_MOBILE;
2270       } else if (isNumberMatchingDesc(nationalNumber, metadata.getMobile())) {
2271         return PhoneNumberType.FIXED_LINE_OR_MOBILE;
2272       }
2273       return PhoneNumberType.FIXED_LINE;
2274     }
2275     // Otherwise, test to see if the number is mobile. Only do this if certain that the patterns for
2276     // mobile and fixed line aren't the same.
2277     if (!metadata.getSameMobileAndFixedLinePattern()
2278         && isNumberMatchingDesc(nationalNumber, metadata.getMobile())) {
2279       return PhoneNumberType.MOBILE;
2280     }
2281     return PhoneNumberType.UNKNOWN;
2282   }
2283 
2284   /**
2285    * Returns the metadata for the given region code or {@code null} if the region code is invalid or
2286    * unknown.
2287    *
2288    * @throws MissingMetadataException if the region code is valid, but metadata cannot be found.
2289    */
2290   PhoneMetadata getMetadataForRegion(String regionCode) {
2291     if (!isValidRegionCode(regionCode)) {
2292       return null;
2293     }
2294     PhoneMetadata phoneMetadata = metadataSource.getMetadataForRegion(regionCode);
2295     ensureMetadataIsNonNull(phoneMetadata, "Missing metadata for region code " + regionCode);
2296     return phoneMetadata;
2297   }
2298 
2299   /**
2300    * Returns the metadata for the given country calling code or {@code null} if the country calling
2301    * code is invalid or unknown.
2302    *
2303    * @throws MissingMetadataException if the country calling code is valid, but metadata cannot be
2304    *     found.
2305    */
2306   PhoneMetadata getMetadataForNonGeographicalRegion(int countryCallingCode) {
2307     if (!countryCodesForNonGeographicalRegion.contains(countryCallingCode)) {
2308       return null;
2309     }
2310     PhoneMetadata phoneMetadata = metadataSource.getMetadataForNonGeographicalRegion(
2311         countryCallingCode);
2312     ensureMetadataIsNonNull(phoneMetadata,
2313         "Missing metadata for country code " + countryCallingCode);
2314     return phoneMetadata;
2315   }
2316 
2317   private static void ensureMetadataIsNonNull(PhoneMetadata phoneMetadata, String message) {
2318     if (phoneMetadata == null) {
2319       throw new MissingMetadataException(message);
2320     }
2321   }
2322 
2323   boolean isNumberMatchingDesc(String nationalNumber, PhoneNumberDesc numberDesc) {
2324     // Check if any possible number lengths are present; if so, we use them to avoid checking the
2325     // validation pattern if they don't match. If they are absent, this means they match the general
2326     // description, which we have already checked before checking a specific number type.
2327     int actualLength = nationalNumber.length();
2328     List<Integer> possibleLengths = numberDesc.getPossibleLengthList();
2329     if (possibleLengths.size() > 0 && !possibleLengths.contains(actualLength)) {
2330       return false;
2331     }
2332     return matcherApi.matchNationalNumber(nationalNumber, numberDesc, false);
2333   }
2334 
2335   /**
2336    * Tests whether a phone number matches a valid pattern. Note this doesn't verify the number
2337    * is actually in use, which is impossible to tell by just looking at a number itself. It only
2338    * verifies whether the parsed, canonicalised number is valid: not whether a particular series of
2339    * digits entered by the user is diallable from the region provided when parsing. For example, the
2340    * number +41 (0) 78 927 2696 can be parsed into a number with country code "41" and national
2341    * significant number "789272696". This is valid, while the original string is not diallable.
2342    *
2343    * @param number  the phone number that we want to validate
2344    * @return  a boolean that indicates whether the number is of a valid pattern
2345    */
2346   public boolean isValidNumber(PhoneNumber number) {
2347     String regionCode = getRegionCodeForNumber(number);
2348     return isValidNumberForRegion(number, regionCode);
2349   }
2350 
2351   /**
2352    * Tests whether a phone number is valid for a certain region. Note this doesn't verify the number
2353    * is actually in use, which is impossible to tell by just looking at a number itself. If the
2354    * country calling code is not the same as the country calling code for the region, this
2355    * immediately exits with false. After this, the specific number pattern rules for the region are
2356    * examined. This is useful for determining for example whether a particular number is valid for
2357    * Canada, rather than just a valid NANPA number.
2358    * Warning: In most cases, you want to use {@link #isValidNumber} instead. For example, this
2359    * method will mark numbers from British Crown dependencies such as the Isle of Man as invalid for
2360    * the region "GB" (United Kingdom), since it has its own region code, "IM", which may be
2361    * undesirable.
2362    *
2363    * @param number  the phone number that we want to validate
2364    * @param regionCode  the region that we want to validate the phone number for
2365    * @return  a boolean that indicates whether the number is of a valid pattern
2366    */
2367   public boolean isValidNumberForRegion(PhoneNumber number, String regionCode) {
2368     int countryCode = number.getCountryCode();
2369     PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode);
2370     if ((metadata == null)
2371         || (!REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode)
2372          && countryCode != getCountryCodeForValidRegion(regionCode))) {
2373       // Either the region code was invalid, or the country calling code for this number does not
2374       // match that of the region code.
2375       return false;
2376     }
2377     String nationalSignificantNumber = getNationalSignificantNumber(number);
2378     return getNumberTypeHelper(nationalSignificantNumber, metadata) != PhoneNumberType.UNKNOWN;
2379   }
2380 
2381   /**
2382    * Returns the region where a phone number is from. This could be used for geocoding at the region
2383    * level. Only guarantees correct results for valid, full numbers (not short-codes, or invalid
2384    * numbers).
2385    *
2386    * @param number  the phone number whose origin we want to know
2387    * @return  the region where the phone number is from, or null if no region matches this calling
2388    *     code
2389    */
2390   public String getRegionCodeForNumber(PhoneNumber number) {
2391     int countryCode = number.getCountryCode();
2392     List<String> regions = countryCallingCodeToRegionCodeMap.get(countryCode);
2393     if (regions == null) {
2394       logger.log(Level.INFO, "Missing/invalid country_code (" + countryCode + ")");
2395       return null;
2396     }
2397     if (regions.size() == 1) {
2398       return regions.get(0);
2399     } else {
2400       return getRegionCodeForNumberFromRegionList(number, regions);
2401     }
2402   }
2403 
2404   private String getRegionCodeForNumberFromRegionList(PhoneNumber number,
2405                                                       List<String> regionCodes) {
2406     String nationalNumber = getNationalSignificantNumber(number);
2407     for (String regionCode : regionCodes) {
2408       // If leadingDigits is present, use this. Otherwise, do full validation.
2409       // Metadata cannot be null because the region codes come from the country calling code map.
2410       PhoneMetadata metadata = getMetadataForRegion(regionCode);
2411       if (metadata.hasLeadingDigits()) {
2412         if (regexCache.getPatternForRegex(metadata.getLeadingDigits())
2413                 .matcher(nationalNumber).lookingAt()) {
2414           return regionCode;
2415         }
2416       } else if (getNumberTypeHelper(nationalNumber, metadata) != PhoneNumberType.UNKNOWN) {
2417         return regionCode;
2418       }
2419     }
2420     return null;
2421   }
2422 
2423   /**
2424    * Returns the region code that matches the specific country calling code. In the case of no
2425    * region code being found, ZZ will be returned. In the case of multiple regions, the one
2426    * designated in the metadata as the "main" region for this calling code will be returned. If the
2427    * countryCallingCode entered is valid but doesn't match a specific region (such as in the case of
2428    * non-geographical calling codes like 800) the value "001" will be returned (corresponding to
2429    * the value for World in the UN M.49 schema).
2430    */
2431   public String getRegionCodeForCountryCode(int countryCallingCode) {
2432     List<String> regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode);
2433     return regionCodes == null ? UNKNOWN_REGION : regionCodes.get(0);
2434   }
2435 
2436   /**
2437    * Returns a list with the region codes that match the specific country calling code. For
2438    * non-geographical country calling codes, the region code 001 is returned. Also, in the case
2439    * of no region code being found, an empty list is returned.
2440    */
2441   public List<String> getRegionCodesForCountryCode(int countryCallingCode) {
2442     List<String> regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode);
2443     return Collections.unmodifiableList(regionCodes == null ? new ArrayList<String>(0)
2444                                                             : regionCodes);
2445   }
2446 
2447   /**
2448    * Returns the country calling code for a specific region. For example, this would be 1 for the
2449    * United States, and 64 for New Zealand.
2450    *
2451    * @param regionCode  the region that we want to get the country calling code for
2452    * @return  the country calling code for the region denoted by regionCode
2453    */
2454   public int getCountryCodeForRegion(String regionCode) {
2455     if (!isValidRegionCode(regionCode)) {
2456       logger.log(Level.WARNING,
2457                  "Invalid or missing region code ("
2458                   + ((regionCode == null) ? "null" : regionCode)
2459                   + ") provided.");
2460       return 0;
2461     }
2462     return getCountryCodeForValidRegion(regionCode);
2463   }
2464 
2465   /**
2466    * Returns the country calling code for a specific region. For example, this would be 1 for the
2467    * United States, and 64 for New Zealand. Assumes the region is already valid.
2468    *
2469    * @param regionCode  the region that we want to get the country calling code for
2470    * @return  the country calling code for the region denoted by regionCode
2471    * @throws IllegalArgumentException if the region is invalid
2472    */
2473   private int getCountryCodeForValidRegion(String regionCode) {
2474     PhoneMetadata metadata = getMetadataForRegion(regionCode);
2475     if (metadata == null) {
2476       throw new IllegalArgumentException("Invalid region code: " + regionCode);
2477     }
2478     return metadata.getCountryCode();
2479   }
2480 
2481   /**
2482    * Returns the national dialling prefix for a specific region. For example, this would be 1 for
2483    * the United States, and 0 for New Zealand. Set stripNonDigits to true to strip symbols like "~"
2484    * (which indicates a wait for a dialling tone) from the prefix returned. If no national prefix is
2485    * present, we return null.
2486    *
2487    * <p>Warning: Do not use this method for do-your-own formatting - for some regions, the
2488    * national dialling prefix is used only for certain types of numbers. Use the library's
2489    * formatting functions to prefix the national prefix when required.
2490    *
2491    * @param regionCode  the region that we want to get the dialling prefix for
2492    * @param stripNonDigits  true to strip non-digits from the national dialling prefix
2493    * @return  the dialling prefix for the region denoted by regionCode
2494    */
2495   public String getNddPrefixForRegion(String regionCode, boolean stripNonDigits) {
2496     PhoneMetadata metadata = getMetadataForRegion(regionCode);
2497     if (metadata == null) {
2498       logger.log(Level.WARNING,
2499                  "Invalid or missing region code ("
2500                   + ((regionCode == null) ? "null" : regionCode)
2501                   + ") provided.");
2502       return null;
2503     }
2504     String nationalPrefix = metadata.getNationalPrefix();
2505     // If no national prefix was found, we return null.
2506     if (nationalPrefix.length() == 0) {
2507       return null;
2508     }
2509     if (stripNonDigits) {
2510       // Note: if any other non-numeric symbols are ever used in national prefixes, these would have
2511       // to be removed here as well.
2512       nationalPrefix = nationalPrefix.replace("~", "");
2513     }
2514     return nationalPrefix;
2515   }
2516 
2517   /**
2518    * Checks if this is a region under the North American Numbering Plan Administration (NANPA).
2519    *
2520    * @return  true if regionCode is one of the regions under NANPA
2521    */
2522   public boolean isNANPACountry(String regionCode) {
2523     return nanpaRegions.contains(regionCode);
2524   }
2525 
2526   /**
2527    * Checks if the number is a valid vanity (alpha) number such as 800 MICROSOFT. A valid vanity
2528    * number will start with at least 3 digits and will have three or more alpha characters. This
2529    * does not do region-specific checks - to work out if this number is actually valid for a region,
2530    * it should be parsed and methods such as {@link #isPossibleNumberWithReason} and
2531    * {@link #isValidNumber} should be used.
2532    *
2533    * @param number  the number that needs to be checked
2534    * @return  true if the number is a valid vanity number
2535    */
2536   public boolean isAlphaNumber(CharSequence number) {
2537     if (!isViablePhoneNumber(number)) {
2538       // Number is too short, or doesn't match the basic phone number pattern.
2539       return false;
2540     }
2541     StringBuilder strippedNumber = new StringBuilder(number);
2542     maybeStripExtension(strippedNumber);
2543     return VALID_ALPHA_PHONE_PATTERN.matcher(strippedNumber).matches();
2544   }
2545 
2546   /**
2547    * Convenience wrapper around {@link #isPossibleNumberWithReason}. Instead of returning the reason
2548    * for failure, this method returns true if the number is either a possible fully-qualified number
2549    * (containing the area code and country code), or if the number could be a possible local number
2550    * (with a country code, but missing an area code). Local numbers are considered possible if they
2551    * could be possibly dialled in this format: if the area code is needed for a call to connect, the
2552    * number is not considered possible without it.
2553    *
2554    * @param number  the number that needs to be checked
2555    * @return  true if the number is possible
2556    */
2557   public boolean isPossibleNumber(PhoneNumber number) {
2558     ValidationResult result = isPossibleNumberWithReason(number);
2559     return result == ValidationResult.IS_POSSIBLE
2560         || result == ValidationResult.IS_POSSIBLE_LOCAL_ONLY;
2561   }
2562 
2563   /**
2564    * Convenience wrapper around {@link #isPossibleNumberForTypeWithReason}. Instead of returning the
2565    * reason for failure, this method returns true if the number is either a possible fully-qualified
2566    * number (containing the area code and country code), or if the number could be a possible local
2567    * number (with a country code, but missing an area code). Local numbers are considered possible
2568    * if they could be possibly dialled in this format: if the area code is needed for a call to
2569    * connect, the number is not considered possible without it.
2570    *
2571    * @param number  the number that needs to be checked
2572    * @param type  the type we are interested in
2573    * @return  true if the number is possible for this particular type
2574    */
2575   public boolean isPossibleNumberForType(PhoneNumber number, PhoneNumberType type) {
2576     ValidationResult result = isPossibleNumberForTypeWithReason(number, type);
2577     return result == ValidationResult.IS_POSSIBLE
2578         || result == ValidationResult.IS_POSSIBLE_LOCAL_ONLY;
2579   }
2580 
2581   /**
2582    * Helper method to check a number against possible lengths for this region, based on the metadata
2583    * being passed in, and determine whether it matches, or is too short or too long.
2584    */
2585   private ValidationResult testNumberLength(CharSequence number, PhoneMetadata metadata) {
2586     return testNumberLength(number, metadata, PhoneNumberType.UNKNOWN);
2587   }
2588 
2589   /**
2590    * Helper method to check a number against possible lengths for this number type, and determine
2591    * whether it matches, or is too short or too long.
2592    */
2593   private ValidationResult testNumberLength(
2594       CharSequence number, PhoneMetadata metadata, PhoneNumberType type) {
2595     PhoneNumberDesc descForType = getNumberDescByType(metadata, type);
2596     // There should always be "possibleLengths" set for every element. This is declared in the XML
2597     // schema which is verified by PhoneNumberMetadataSchemaTest.
2598     // For size efficiency, where a sub-description (e.g. fixed-line) has the same possibleLengths
2599     // as the parent, this is missing, so we fall back to the general desc (where no numbers of the
2600     // type exist at all, there is one possible length (-1) which is guaranteed not to match the
2601     // length of any real phone number).
2602     List<Integer> possibleLengths = descForType.getPossibleLengthList().isEmpty()
2603         ? metadata.getGeneralDesc().getPossibleLengthList() : descForType.getPossibleLengthList();
2604 
2605     List<Integer> localLengths = descForType.getPossibleLengthLocalOnlyList();
2606 
2607     if (type == PhoneNumberType.FIXED_LINE_OR_MOBILE) {
2608       if (!descHasPossibleNumberData(getNumberDescByType(metadata, PhoneNumberType.FIXED_LINE))) {
2609         // The rare case has been encountered where no fixedLine data is available (true for some
2610         // non-geographical entities), so we just check mobile.
2611         return testNumberLength(number, metadata, PhoneNumberType.MOBILE);
2612       } else {
2613         PhoneNumberDesc mobileDesc = getNumberDescByType(metadata, PhoneNumberType.MOBILE);
2614         if (descHasPossibleNumberData(mobileDesc)) {
2615           // Merge the mobile data in if there was any. We have to make a copy to do this.
2616           possibleLengths = new ArrayList<>(possibleLengths);
2617           // Note that when adding the possible lengths from mobile, we have to again check they
2618           // aren't empty since if they are this indicates they are the same as the general desc and
2619           // should be obtained from there.
2620           possibleLengths.addAll(mobileDesc.getPossibleLengthCount() == 0
2621               ? metadata.getGeneralDesc().getPossibleLengthList()
2622               : mobileDesc.getPossibleLengthList());
2623           // The current list is sorted; we need to merge in the new list and re-sort (duplicates
2624           // are okay). Sorting isn't so expensive because the lists are very small.
2625           Collections.sort(possibleLengths);
2626 
2627           if (localLengths.isEmpty()) {
2628             localLengths = mobileDesc.getPossibleLengthLocalOnlyList();
2629           } else {
2630             localLengths = new ArrayList<>(localLengths);
2631             localLengths.addAll(mobileDesc.getPossibleLengthLocalOnlyList());
2632             Collections.sort(localLengths);
2633           }
2634         }
2635       }
2636     }
2637 
2638     // If the type is not supported at all (indicated by the possible lengths containing -1 at this
2639     // point) we return invalid length.
2640     if (possibleLengths.get(0) == -1) {
2641       return ValidationResult.INVALID_LENGTH;
2642     }
2643 
2644     int actualLength = number.length();
2645     // This is safe because there is never an overlap beween the possible lengths and the local-only
2646     // lengths; this is checked at build time.
2647     if (localLengths.contains(actualLength)) {
2648       return ValidationResult.IS_POSSIBLE_LOCAL_ONLY;
2649     }
2650 
2651     int minimumLength = possibleLengths.get(0);
2652     if (minimumLength == actualLength) {
2653       return ValidationResult.IS_POSSIBLE;
2654     } else if (minimumLength > actualLength) {
2655       return ValidationResult.TOO_SHORT;
2656     } else if (possibleLengths.get(possibleLengths.size() - 1) < actualLength) {
2657       return ValidationResult.TOO_LONG;
2658     }
2659     // We skip the first element; we've already checked it.
2660     return possibleLengths.subList(1, possibleLengths.size()).contains(actualLength)
2661         ? ValidationResult.IS_POSSIBLE : ValidationResult.INVALID_LENGTH;
2662   }
2663 
2664   /**
2665    * Check whether a phone number is a possible number. It provides a more lenient check than
2666    * {@link #isValidNumber} in the following sense:
2667    * <ol>
2668    *   <li> It only checks the length of phone numbers. In particular, it doesn't check starting
2669    *        digits of the number.
2670    *   <li> It doesn't attempt to figure out the type of the number, but uses general rules which
2671    *        applies to all types of phone numbers in a region. Therefore, it is much faster than
2672    *        isValidNumber.
2673    *   <li> For some numbers (particularly fixed-line), many regions have the concept of area code,
2674    *        which together with subscriber number constitute the national significant number. It is
2675    *        sometimes okay to dial only the subscriber number when dialing in the same area. This
2676    *        function will return IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is
2677    *        passed in. On the other hand, because isValidNumber validates using information on both
2678    *        starting digits (for fixed line numbers, that would most likely be area codes) and
2679    *        length (obviously includes the length of area codes for fixed line numbers), it will
2680    *        return false for the subscriber-number-only version.
2681    * </ol>
2682    * @param number  the number that needs to be checked
2683    * @return  a ValidationResult object which indicates whether the number is possible
2684    */
2685   public ValidationResult isPossibleNumberWithReason(PhoneNumber number) {
2686     return isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN);
2687   }
2688 
2689   /**
2690    * Check whether a phone number is a possible number of a particular type. For types that don't
2691    * exist in a particular region, this will return a result that isn't so useful; it is recommended
2692    * that you use {@link #getSupportedTypesForRegion} or {@link #getSupportedTypesForNonGeoEntity}
2693    * respectively before calling this method to determine whether you should call it for this number
2694    * at all.
2695    *
2696    * This provides a more lenient check than {@link #isValidNumber} in the following sense:
2697    *
2698    * <ol>
2699    *   <li> It only checks the length of phone numbers. In particular, it doesn't check starting
2700    *        digits of the number.
2701    *   <li> For some numbers (particularly fixed-line), many regions have the concept of area code,
2702    *        which together with subscriber number constitute the national significant number. It is
2703    *        sometimes okay to dial only the subscriber number when dialing in the same area. This
2704    *        function will return IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is
2705    *        passed in. On the other hand, because isValidNumber validates using information on both
2706    *        starting digits (for fixed line numbers, that would most likely be area codes) and
2707    *        length (obviously includes the length of area codes for fixed line numbers), it will
2708    *        return false for the subscriber-number-only version.
2709    * </ol>
2710    *
2711    * @param number  the number that needs to be checked
2712    * @param type  the type we are interested in
2713    * @return  a ValidationResult object which indicates whether the number is possible
2714    */
2715   public ValidationResult isPossibleNumberForTypeWithReason(
2716       PhoneNumber number, PhoneNumberType type) {
2717     String nationalNumber = getNationalSignificantNumber(number);
2718     int countryCode = number.getCountryCode();
2719     // Note: For regions that share a country calling code, like NANPA numbers, we just use the
2720     // rules from the default region (US in this case) since the getRegionCodeForNumber will not
2721     // work if the number is possible but not valid. There is in fact one country calling code (290)
2722     // where the possible number pattern differs between various regions (Saint Helena and Tristan
2723     // da Cuñha), but this is handled by putting all possible lengths for any country with this
2724     // country calling code in the metadata for the default region in this case.
2725     if (!hasValidCountryCallingCode(countryCode)) {
2726       return ValidationResult.INVALID_COUNTRY_CODE;
2727     }
2728     String regionCode = getRegionCodeForCountryCode(countryCode);
2729     // Metadata cannot be null because the country calling code is valid.
2730     PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode);
2731     return testNumberLength(nationalNumber, metadata, type);
2732   }
2733 
2734   /**
2735    * Check whether a phone number is a possible number given a number in the form of a string, and
2736    * the region where the number could be dialed from. It provides a more lenient check than
2737    * {@link #isValidNumber}. See {@link #isPossibleNumber(PhoneNumber)} for details.
2738    *
2739    * <p>This method first parses the number, then invokes {@link #isPossibleNumber(PhoneNumber)}
2740    * with the resultant PhoneNumber object.
2741    *
2742    * @param number  the number that needs to be checked
2743    * @param regionDialingFrom  the region that we are expecting the number to be dialed from.
2744    *     Note this is different from the region where the number belongs.  For example, the number
2745    *     +1 650 253 0000 is a number that belongs to US. When written in this form, it can be
2746    *     dialed from any region. When it is written as 00 1 650 253 0000, it can be dialed from any
2747    *     region which uses an international dialling prefix of 00. When it is written as
2748    *     650 253 0000, it can only be dialed from within the US, and when written as 253 0000, it
2749    *     can only be dialed from within a smaller area in the US (Mountain View, CA, to be more
2750    *     specific).
2751    * @return  true if the number is possible
2752    */
2753   public boolean isPossibleNumber(CharSequence number, String regionDialingFrom) {
2754     try {
2755       return isPossibleNumber(parse(number, regionDialingFrom));
2756     } catch (NumberParseException e) {
2757       return false;
2758     }
2759   }
2760 
2761   /**
2762    * Attempts to extract a valid number from a phone number that is too long to be valid, and resets
2763    * the PhoneNumber object passed in to that valid version. If no valid number could be extracted,
2764    * the PhoneNumber object passed in will not be modified.
2765    * @param number  a PhoneNumber object which contains a number that is too long to be valid
2766    * @return  true if a valid phone number can be successfully extracted
2767    */
2768   public boolean truncateTooLongNumber(PhoneNumber number) {
2769     if (isValidNumber(number)) {
2770       return true;
2771     }
2772     PhoneNumber numberCopy = new PhoneNumber();
2773     numberCopy.mergeFrom(number);
2774     long nationalNumber = number.getNationalNumber();
2775     do {
2776       nationalNumber /= 10;
2777       numberCopy.setNationalNumber(nationalNumber);
2778       if (isPossibleNumberWithReason(numberCopy) == ValidationResult.TOO_SHORT
2779           || nationalNumber == 0) {
2780         return false;
2781       }
2782     } while (!isValidNumber(numberCopy));
2783     number.setNationalNumber(nationalNumber);
2784     return true;
2785   }
2786 
2787   /**
2788    * Gets an {@link com.google.i18n.phonenumbers.AsYouTypeFormatter} for the specific region.
2789    *
2790    * @param regionCode  the region where the phone number is being entered
2791    * @return  an {@link com.google.i18n.phonenumbers.AsYouTypeFormatter} object, which can be used
2792    *     to format phone numbers in the specific region "as you type"
2793    */
2794   public AsYouTypeFormatter getAsYouTypeFormatter(String regionCode) {
2795     return new AsYouTypeFormatter(regionCode);
2796   }
2797 
2798   // Extracts country calling code from fullNumber, returns it and places the remaining number in
2799   // nationalNumber. It assumes that the leading plus sign or IDD has already been removed. Returns
2800   // 0 if fullNumber doesn't start with a valid country calling code, and leaves nationalNumber
2801   // unmodified.
2802   int extractCountryCode(StringBuilder fullNumber, StringBuilder nationalNumber) {
2803     if ((fullNumber.length() == 0) || (fullNumber.charAt(0) == '0')) {
2804       // Country codes do not begin with a '0'.
2805       return 0;
2806     }
2807     int potentialCountryCode;
2808     int numberLength = fullNumber.length();
2809     for (int i = 1; i <= MAX_LENGTH_COUNTRY_CODE && i <= numberLength; i++) {
2810       potentialCountryCode = Integer.parseInt(fullNumber.substring(0, i));
2811       if (countryCallingCodeToRegionCodeMap.containsKey(potentialCountryCode)) {
2812         nationalNumber.append(fullNumber.substring(i));
2813         return potentialCountryCode;
2814       }
2815     }
2816     return 0;
2817   }
2818 
2819   /**
2820    * Tries to extract a country calling code from a number. This method will return zero if no
2821    * country calling code is considered to be present. Country calling codes are extracted in the
2822    * following ways:
2823    * <ul>
2824    *  <li> by stripping the international dialing prefix of the region the person is dialing from,
2825    *       if this is present in the number, and looking at the next digits
2826    *  <li> by stripping the '+' sign if present and then looking at the next digits
2827    *  <li> by comparing the start of the number and the country calling code of the default region.
2828    *       If the number is not considered possible for the numbering plan of the default region
2829    *       initially, but starts with the country calling code of this region, validation will be
2830    *       reattempted after stripping this country calling code. If this number is considered a
2831    *       possible number, then the first digits will be considered the country calling code and
2832    *       removed as such.
2833    * </ul>
2834    * It will throw a NumberParseException if the number starts with a '+' but the country calling
2835    * code supplied after this does not match that of any known region.
2836    *
2837    * @param number  non-normalized telephone number that we wish to extract a country calling
2838    *     code from - may begin with '+'
2839    * @param defaultRegionMetadata  metadata about the region this number may be from
2840    * @param nationalNumber  a string buffer to store the national significant number in, in the case
2841    *     that a country calling code was extracted. The number is appended to any existing contents.
2842    *     If no country calling code was extracted, this will be left unchanged.
2843    * @param keepRawInput  true if the country_code_source and preferred_carrier_code fields of
2844    *     phoneNumber should be populated.
2845    * @param phoneNumber  the PhoneNumber object where the country_code and country_code_source need
2846    *     to be populated. Note the country_code is always populated, whereas country_code_source is
2847    *     only populated when keepCountryCodeSource is true.
2848    * @return  the country calling code extracted or 0 if none could be extracted
2849    */
2850   // @VisibleForTesting
2851   int maybeExtractCountryCode(CharSequence number, PhoneMetadata defaultRegionMetadata,
2852                               StringBuilder nationalNumber, boolean keepRawInput,
2853                               PhoneNumber phoneNumber)
2854       throws NumberParseException {
2855     if (number.length() == 0) {
2856       return 0;
2857     }
2858     StringBuilder fullNumber = new StringBuilder(number);
2859     // Set the default prefix to be something that will never match.
2860     String possibleCountryIddPrefix = "NonMatch";
2861     if (defaultRegionMetadata != null) {
2862       possibleCountryIddPrefix = defaultRegionMetadata.getInternationalPrefix();
2863     }
2864 
2865     CountryCodeSource countryCodeSource =
2866         maybeStripInternationalPrefixAndNormalize(fullNumber, possibleCountryIddPrefix);
2867     if (keepRawInput) {
2868       phoneNumber.setCountryCodeSource(countryCodeSource);
2869     }
2870     if (countryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY) {
2871       if (fullNumber.length() <= MIN_LENGTH_FOR_NSN) {
2872         throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
2873                                        "Phone number had an IDD, but after this was not "
2874                                        + "long enough to be a viable phone number.");
2875       }
2876       int potentialCountryCode = extractCountryCode(fullNumber, nationalNumber);
2877       if (potentialCountryCode != 0) {
2878         phoneNumber.setCountryCode(potentialCountryCode);
2879         return potentialCountryCode;
2880       }
2881 
2882       // If this fails, they must be using a strange country calling code that we don't recognize,
2883       // or that doesn't exist.
2884       throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2885                                      "Country calling code supplied was not recognised.");
2886     } else if (defaultRegionMetadata != null) {
2887       // Check to see if the number starts with the country calling code for the default region. If
2888       // so, we remove the country calling code, and do some checks on the validity of the number
2889       // before and after.
2890       int defaultCountryCode = defaultRegionMetadata.getCountryCode();
2891       String defaultCountryCodeString = String.valueOf(defaultCountryCode);
2892       String normalizedNumber = fullNumber.toString();
2893       if (normalizedNumber.startsWith(defaultCountryCodeString)) {
2894         StringBuilder potentialNationalNumber =
2895             new StringBuilder(normalizedNumber.substring(defaultCountryCodeString.length()));
2896         PhoneNumberDesc generalDesc = defaultRegionMetadata.getGeneralDesc();
2897         maybeStripNationalPrefixAndCarrierCode(
2898             potentialNationalNumber, defaultRegionMetadata, null /* Don't need the carrier code */);
2899         // If the number was not valid before but is valid now, or if it was too long before, we
2900         // consider the number with the country calling code stripped to be a better result and
2901         // keep that instead.
2902         if ((!matcherApi.matchNationalNumber(fullNumber, generalDesc, false)
2903                 && matcherApi.matchNationalNumber(potentialNationalNumber, generalDesc, false))
2904             || testNumberLength(fullNumber, defaultRegionMetadata) == ValidationResult.TOO_LONG) {
2905           nationalNumber.append(potentialNationalNumber);
2906           if (keepRawInput) {
2907             phoneNumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
2908           }
2909           phoneNumber.setCountryCode(defaultCountryCode);
2910           return defaultCountryCode;
2911         }
2912       }
2913     }
2914     // No country calling code present.
2915     phoneNumber.setCountryCode(0);
2916     return 0;
2917   }
2918 
2919   /**
2920    * Strips the IDD from the start of the number if present. Helper function used by
2921    * maybeStripInternationalPrefixAndNormalize.
2922    */
2923   private boolean parsePrefixAsIdd(Pattern iddPattern, StringBuilder number) {
2924     Matcher m = iddPattern.matcher(number);
2925     if (m.lookingAt()) {
2926       int matchEnd = m.end();
2927       // Only strip this if the first digit after the match is not a 0, since country calling codes
2928       // cannot begin with 0.
2929       Matcher digitMatcher = CAPTURING_DIGIT_PATTERN.matcher(number.substring(matchEnd));
2930       if (digitMatcher.find()) {
2931         String normalizedGroup = normalizeDigitsOnly(digitMatcher.group(1));
2932         if (normalizedGroup.equals("0")) {
2933           return false;
2934         }
2935       }
2936       number.delete(0, matchEnd);
2937       return true;
2938     }
2939     return false;
2940   }
2941 
2942   /**
2943    * Strips any international prefix (such as +, 00, 011) present in the number provided, normalizes
2944    * the resulting number, and indicates if an international prefix was present.
2945    *
2946    * @param number  the non-normalized telephone number that we wish to strip any international
2947    *     dialing prefix from
2948    * @param possibleIddPrefix  the international direct dialing prefix from the region we
2949    *     think this number may be dialed in
2950    * @return  the corresponding CountryCodeSource if an international dialing prefix could be
2951    *     removed from the number, otherwise CountryCodeSource.FROM_DEFAULT_COUNTRY if the number did
2952    *     not seem to be in international format
2953    */
2954   // @VisibleForTesting
2955   CountryCodeSource maybeStripInternationalPrefixAndNormalize(
2956       StringBuilder number,
2957       String possibleIddPrefix) {
2958     if (number.length() == 0) {
2959       return CountryCodeSource.FROM_DEFAULT_COUNTRY;
2960     }
2961     // Check to see if the number begins with one or more plus signs.
2962     Matcher m = PLUS_CHARS_PATTERN.matcher(number);
2963     if (m.lookingAt()) {
2964       number.delete(0, m.end());
2965       // Can now normalize the rest of the number since we've consumed the "+" sign at the start.
2966       normalize(number);
2967       return CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN;
2968     }
2969     // Attempt to parse the first digits as an international prefix.
2970     Pattern iddPattern = regexCache.getPatternForRegex(possibleIddPrefix);
2971     normalize(number);
2972     return parsePrefixAsIdd(iddPattern, number)
2973            ? CountryCodeSource.FROM_NUMBER_WITH_IDD
2974            : CountryCodeSource.FROM_DEFAULT_COUNTRY;
2975   }
2976 
2977   /**
2978    * Strips any national prefix (such as 0, 1) present in the number provided.
2979    *
2980    * @param number  the normalized telephone number that we wish to strip any national
2981    *     dialing prefix from
2982    * @param metadata  the metadata for the region that we think this number is from
2983    * @param carrierCode  a place to insert the carrier code if one is extracted
2984    * @return true if a national prefix or carrier code (or both) could be extracted
2985    */
2986   // @VisibleForTesting
2987   boolean maybeStripNationalPrefixAndCarrierCode(
2988       StringBuilder number, PhoneMetadata metadata, StringBuilder carrierCode) {
2989     int numberLength = number.length();
2990     String possibleNationalPrefix = metadata.getNationalPrefixForParsing();
2991     if (numberLength == 0 || possibleNationalPrefix.length() == 0) {
2992       // Early return for numbers of zero length.
2993       return false;
2994     }
2995     // Attempt to parse the first digits as a national prefix.
2996     Matcher prefixMatcher = regexCache.getPatternForRegex(possibleNationalPrefix).matcher(number);
2997     if (prefixMatcher.lookingAt()) {
2998       PhoneNumberDesc generalDesc = metadata.getGeneralDesc();
2999       // Check if the original number is viable.
3000       boolean isViableOriginalNumber = matcherApi.matchNationalNumber(number, generalDesc, false);
3001       // prefixMatcher.group(numOfGroups) == null implies nothing was captured by the capturing
3002       // groups in possibleNationalPrefix; therefore, no transformation is necessary, and we just
3003       // remove the national prefix.
3004       int numOfGroups = prefixMatcher.groupCount();
3005       String transformRule = metadata.getNationalPrefixTransformRule();
3006       if (transformRule == null || transformRule.length() == 0
3007           || prefixMatcher.group(numOfGroups) == null) {
3008         // If the original number was viable, and the resultant number is not, we return.
3009         if (isViableOriginalNumber
3010             && !matcherApi.matchNationalNumber(
3011                 number.substring(prefixMatcher.end()), generalDesc, false)) {
3012           return false;
3013         }
3014         if (carrierCode != null && numOfGroups > 0 && prefixMatcher.group(numOfGroups) != null) {
3015           carrierCode.append(prefixMatcher.group(1));
3016         }
3017         number.delete(0, prefixMatcher.end());
3018         return true;
3019       } else {
3020         // Check that the resultant number is still viable. If not, return. Check this by copying
3021         // the string buffer and making the transformation on the copy first.
3022         StringBuilder transformedNumber = new StringBuilder(number);
3023         transformedNumber.replace(0, numberLength, prefixMatcher.replaceFirst(transformRule));
3024         if (isViableOriginalNumber
3025             && !matcherApi.matchNationalNumber(transformedNumber.toString(), generalDesc, false)) {
3026           return false;
3027         }
3028         if (carrierCode != null && numOfGroups > 1) {
3029           carrierCode.append(prefixMatcher.group(1));
3030         }
3031         number.replace(0, number.length(), transformedNumber.toString());
3032         return true;
3033       }
3034     }
3035     return false;
3036   }
3037 
3038   /**
3039    * Strips any extension (as in, the part of the number dialled after the call is connected,
3040    * usually indicated with extn, ext, x or similar) from the end of the number, and returns it.
3041    *
3042    * @param number  the non-normalized telephone number that we wish to strip the extension from
3043    * @return  the phone extension
3044    */
3045   // @VisibleForTesting
3046   String maybeStripExtension(StringBuilder number) {
3047     Matcher m = EXTN_PATTERN.matcher(number);
3048     // If we find a potential extension, and the number preceding this is a viable number, we assume
3049     // it is an extension.
3050     if (m.find() && isViablePhoneNumber(number.substring(0, m.start()))) {
3051       // The numbers are captured into groups in the regular expression.
3052       for (int i = 1, length = m.groupCount(); i <= length; i++) {
3053         if (m.group(i) != null) {
3054           // We go through the capturing groups until we find one that captured some digits. If none
3055           // did, then we will return the empty string.
3056           String extension = m.group(i);
3057           number.delete(m.start(), number.length());
3058           return extension;
3059         }
3060       }
3061     }
3062     return "";
3063   }
3064 
3065   /**
3066    * Checks to see that the region code used is valid, or if it is not valid, that the number to
3067    * parse starts with a + symbol so that we can attempt to infer the region from the number.
3068    * Returns false if it cannot use the region provided and the region cannot be inferred.
3069    */
3070   private boolean checkRegionForParsing(CharSequence numberToParse, String defaultRegion) {
3071     if (!isValidRegionCode(defaultRegion)) {
3072       // If the number is null or empty, we can't infer the region.
3073       if ((numberToParse == null) || (numberToParse.length() == 0)
3074           || !PLUS_CHARS_PATTERN.matcher(numberToParse).lookingAt()) {
3075         return false;
3076       }
3077     }
3078     return true;
3079   }
3080 
3081   /**
3082    * Parses a string and returns it as a phone number in proto buffer format. The method is quite
3083    * lenient and looks for a number in the input text (raw input) and does not check whether the
3084    * string is definitely only a phone number. To do this, it ignores punctuation and white-space,
3085    * as well as any text before the number (e.g. a leading "Tel: ") and trims the non-number bits.
3086    * It will accept a number in any format (E164, national, international etc), assuming it can be
3087    * interpreted with the defaultRegion supplied. It also attempts to convert any alpha characters
3088    * into digits if it thinks this is a vanity number of the type "1800 MICROSOFT".
3089    *
3090    * <p> This method will throw a {@link com.google.i18n.phonenumbers.NumberParseException} if the
3091    * number is not considered to be a possible number. Note that validation of whether the number
3092    * is actually a valid number for a particular region is not performed. This can be done
3093    * separately with {@link #isValidNumber}.
3094    *
3095    * <p> Note this method canonicalizes the phone number such that different representations can be
3096    * easily compared, no matter what form it was originally entered in (e.g. national,
3097    * international). If you want to record context about the number being parsed, such as the raw
3098    * input that was entered, how the country code was derived etc. then call {@link
3099    * #parseAndKeepRawInput} instead.
3100    *
3101    * @param numberToParse  number that we are attempting to parse. This can contain formatting such
3102    *     as +, ( and -, as well as a phone number extension. It can also be provided in RFC3966
3103    *     format.
3104    * @param defaultRegion  region that we are expecting the number to be from. This is only used if
3105    *     the number being parsed is not written in international format. The country_code for the
3106    *     number in this case would be stored as that of the default region supplied. If the number
3107    *     is guaranteed to start with a '+' followed by the country calling code, then RegionCode.ZZ
3108    *     or null can be supplied.
3109    * @return  a phone number proto buffer filled with the parsed number
3110    * @throws NumberParseException  if the string is not considered to be a viable phone number (e.g.
3111    *     too few or too many digits) or if no default region was supplied and the number is not in
3112    *     international format (does not start with +)
3113    */
3114   public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)
3115       throws NumberParseException {
3116     PhoneNumber phoneNumber = new PhoneNumber();
3117     parse(numberToParse, defaultRegion, phoneNumber);
3118     return phoneNumber;
3119   }
3120 
3121   /**
3122    * Same as {@link #parse(CharSequence, String)}, but accepts mutable PhoneNumber as a
3123    * parameter to decrease object creation when invoked many times.
3124    */
3125   public void parse(CharSequence numberToParse, String defaultRegion, PhoneNumber phoneNumber)
3126       throws NumberParseException {
3127     parseHelper(numberToParse, defaultRegion, false, true, phoneNumber);
3128   }
3129 
3130   /**
3131    * Parses a string and returns it in proto buffer format. This method differs from {@link #parse}
3132    * in that it always populates the raw_input field of the protocol buffer with numberToParse as
3133    * well as the country_code_source field.
3134    *
3135    * @param numberToParse  number that we are attempting to parse. This can contain formatting such
3136    *     as +, ( and -, as well as a phone number extension.
3137    * @param defaultRegion  region that we are expecting the number to be from. This is only used if
3138    *     the number being parsed is not written in international format. The country calling code
3139    *     for the number in this case would be stored as that of the default region supplied.
3140    * @return  a phone number proto buffer filled with the parsed number
3141    * @throws NumberParseException  if the string is not considered to be a viable phone number or if
3142    *     no default region was supplied
3143    */
3144   public PhoneNumber parseAndKeepRawInput(CharSequence numberToParse, String defaultRegion)
3145       throws NumberParseException {
3146     PhoneNumber phoneNumber = new PhoneNumber();
3147     parseAndKeepRawInput(numberToParse, defaultRegion, phoneNumber);
3148     return phoneNumber;
3149   }
3150 
3151   /**
3152    * Same as{@link #parseAndKeepRawInput(CharSequence, String)}, but accepts a mutable
3153    * PhoneNumber as a parameter to decrease object creation when invoked many times.
3154    */
3155   public void parseAndKeepRawInput(CharSequence numberToParse, String defaultRegion,
3156                                    PhoneNumber phoneNumber)
3157       throws NumberParseException {
3158     parseHelper(numberToParse, defaultRegion, true, true, phoneNumber);
3159   }
3160 
3161   /**
3162    * Returns an iterable over all {@link PhoneNumberMatch PhoneNumberMatches} in {@code text}. This
3163    * is a shortcut for {@link #findNumbers(CharSequence, String, Leniency, long)
3164    * getMatcher(text, defaultRegion, Leniency.VALID, Long.MAX_VALUE)}.
3165    *
3166    * @param text  the text to search for phone numbers, null for no text
3167    * @param defaultRegion  region that we are expecting the number to be from. This is only used if
3168    *     the number being parsed is not written in international format. The country_code for the
3169    *     number in this case would be stored as that of the default region supplied. May be null if
3170    *     only international numbers are expected.
3171    */
3172   public Iterable<PhoneNumberMatch> findNumbers(CharSequence text, String defaultRegion) {
3173     return findNumbers(text, defaultRegion, Leniency.VALID, Long.MAX_VALUE);
3174   }
3175 
3176   /**
3177    * Returns an iterable over all {@link PhoneNumberMatch PhoneNumberMatches} in {@code text}.
3178    *
3179    * @param text  the text to search for phone numbers, null for no text
3180    * @param defaultRegion  region that we are expecting the number to be from. This is only used if
3181    *     the number being parsed is not written in international format. The country_code for the
3182    *     number in this case would be stored as that of the default region supplied. May be null if
3183    *     only international numbers are expected.
3184    * @param leniency  the leniency to use when evaluating candidate phone numbers
3185    * @param maxTries  the maximum number of invalid numbers to try before giving up on the text.
3186    *     This is to cover degenerate cases where the text has a lot of false positives in it. Must
3187    *     be {@code >= 0}.
3188    */
3189   public Iterable<PhoneNumberMatch> findNumbers(
3190       final CharSequence text, final String defaultRegion, final Leniency leniency,
3191       final long maxTries) {
3192 
3193     return new Iterable<PhoneNumberMatch>() {
3194       @Override
3195       public Iterator<PhoneNumberMatch> iterator() {
3196         return new PhoneNumberMatcher(
3197             PhoneNumberUtil.this, text, defaultRegion, leniency, maxTries);
3198       }
3199     };
3200   }
3201 
3202   /**
3203    * A helper function to set the values related to leading zeros in a PhoneNumber.
3204    */
3205   static void setItalianLeadingZerosForPhoneNumber(CharSequence nationalNumber,
3206       PhoneNumber phoneNumber) {
3207     if (nationalNumber.length() > 1 && nationalNumber.charAt(0) == '0') {
3208       phoneNumber.setItalianLeadingZero(true);
3209       int numberOfLeadingZeros = 1;
3210       // Note that if the national number is all "0"s, the last "0" is not counted as a leading
3211       // zero.
3212       while (numberOfLeadingZeros < nationalNumber.length() - 1
3213           && nationalNumber.charAt(numberOfLeadingZeros) == '0') {
3214         numberOfLeadingZeros++;
3215       }
3216       if (numberOfLeadingZeros != 1) {
3217         phoneNumber.setNumberOfLeadingZeros(numberOfLeadingZeros);
3218       }
3219     }
3220   }
3221 
3222   /**
3223    * Parses a string and fills up the phoneNumber. This method is the same as the public
3224    * parse() method, with the exception that it allows the default region to be null, for use by
3225    * isNumberMatch(). checkRegion should be set to false if it is permitted for the default region
3226    * to be null or unknown ("ZZ").
3227    *
3228    * Note if any new field is added to this method that should always be filled in, even when
3229    * keepRawInput is false, it should also be handled in the copyCoreFieldsOnly() method.
3230    */
3231   private void parseHelper(CharSequence numberToParse, String defaultRegion,
3232       boolean keepRawInput, boolean checkRegion, PhoneNumber phoneNumber)
3233       throws NumberParseException {
3234     if (numberToParse == null) {
3235       throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER,
3236                                      "The phone number supplied was null.");
3237     } else if (numberToParse.length() > MAX_INPUT_STRING_LENGTH) {
3238       throw new NumberParseException(NumberParseException.ErrorType.TOO_LONG,
3239                                      "The string supplied was too long to parse.");
3240     }
3241 
3242     StringBuilder nationalNumber = new StringBuilder();
3243     String numberBeingParsed = numberToParse.toString();
3244     buildNationalNumberForParsing(numberBeingParsed, nationalNumber);
3245 
3246     if (!isViablePhoneNumber(nationalNumber)) {
3247       throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER,
3248                                      "The string supplied did not seem to be a phone number.");
3249     }
3250 
3251     // Check the region supplied is valid, or that the extracted number starts with some sort of +
3252     // sign so the number's region can be determined.
3253     if (checkRegion && !checkRegionForParsing(nationalNumber, defaultRegion)) {
3254       throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
3255                                      "Missing or invalid default region.");
3256     }
3257 
3258     if (keepRawInput) {
3259       phoneNumber.setRawInput(numberBeingParsed);
3260     }
3261     // Attempt to parse extension first, since it doesn't require region-specific data and we want
3262     // to have the non-normalised number here.
3263     String extension = maybeStripExtension(nationalNumber);
3264     if (extension.length() > 0) {
3265       phoneNumber.setExtension(extension);
3266     }
3267 
3268     PhoneMetadata regionMetadata = getMetadataForRegion(defaultRegion);
3269     // Check to see if the number is given in international format so we know whether this number is
3270     // from the default region or not.
3271     StringBuilder normalizedNationalNumber = new StringBuilder();
3272     int countryCode = 0;
3273     try {
3274       // TODO: This method should really just take in the string buffer that has already
3275       // been created, and just remove the prefix, rather than taking in a string and then
3276       // outputting a string buffer.
3277       countryCode = maybeExtractCountryCode(nationalNumber, regionMetadata,
3278                                             normalizedNationalNumber, keepRawInput, phoneNumber);
3279     } catch (NumberParseException e) {
3280       Matcher matcher = PLUS_CHARS_PATTERN.matcher(nationalNumber);
3281       if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE
3282           && matcher.lookingAt()) {
3283         // Strip the plus-char, and try again.
3284         countryCode = maybeExtractCountryCode(nationalNumber.substring(matcher.end()),
3285                                               regionMetadata, normalizedNationalNumber,
3286                                               keepRawInput, phoneNumber);
3287         if (countryCode == 0) {
3288           throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
3289                                          "Could not interpret numbers after plus-sign.");
3290         }
3291       } else {
3292         throw new NumberParseException(e.getErrorType(), e.getMessage());
3293       }
3294     }
3295     if (countryCode != 0) {
3296       String phoneNumberRegion = getRegionCodeForCountryCode(countryCode);
3297       if (!phoneNumberRegion.equals(defaultRegion)) {
3298         // Metadata cannot be null because the country calling code is valid.
3299         regionMetadata = getMetadataForRegionOrCallingCode(countryCode, phoneNumberRegion);
3300       }
3301     } else {
3302       // If no extracted country calling code, use the region supplied instead. The national number
3303       // is just the normalized version of the number we were given to parse.
3304       normalizedNationalNumber.append(normalize(nationalNumber));
3305       if (defaultRegion != null) {
3306         countryCode = regionMetadata.getCountryCode();
3307         phoneNumber.setCountryCode(countryCode);
3308       } else if (keepRawInput) {
3309         phoneNumber.clearCountryCodeSource();
3310       }
3311     }
3312     if (normalizedNationalNumber.length() < MIN_LENGTH_FOR_NSN) {
3313       throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_NSN,
3314                                      "The string supplied is too short to be a phone number.");
3315     }
3316     if (regionMetadata != null) {
3317       StringBuilder carrierCode = new StringBuilder();
3318       StringBuilder potentialNationalNumber = new StringBuilder(normalizedNationalNumber);
3319       maybeStripNationalPrefixAndCarrierCode(potentialNationalNumber, regionMetadata, carrierCode);
3320       // We require that the NSN remaining after stripping the national prefix and carrier code be
3321       // long enough to be a possible length for the region. Otherwise, we don't do the stripping,
3322       // since the original number could be a valid short number.
3323       ValidationResult validationResult = testNumberLength(potentialNationalNumber, regionMetadata);
3324       if (validationResult != ValidationResult.TOO_SHORT
3325           && validationResult != ValidationResult.IS_POSSIBLE_LOCAL_ONLY
3326           && validationResult != ValidationResult.INVALID_LENGTH) {
3327         normalizedNationalNumber = potentialNationalNumber;
3328         if (keepRawInput && carrierCode.length() > 0) {
3329           phoneNumber.setPreferredDomesticCarrierCode(carrierCode.toString());
3330         }
3331       }
3332     }
3333     int lengthOfNationalNumber = normalizedNationalNumber.length();
3334     if (lengthOfNationalNumber < MIN_LENGTH_FOR_NSN) {
3335       throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_NSN,
3336                                      "The string supplied is too short to be a phone number.");
3337     }
3338     if (lengthOfNationalNumber > MAX_LENGTH_FOR_NSN) {
3339       throw new NumberParseException(NumberParseException.ErrorType.TOO_LONG,
3340                                      "The string supplied is too long to be a phone number.");
3341     }
3342     setItalianLeadingZerosForPhoneNumber(normalizedNationalNumber, phoneNumber);
3343     phoneNumber.setNationalNumber(Long.parseLong(normalizedNationalNumber.toString()));
3344   }
3345 
3346   /**
3347    * Converts numberToParse to a form that we can parse and write it to nationalNumber if it is
3348    * written in RFC3966; otherwise extract a possible number out of it and write to nationalNumber.
3349    */
3350   private void buildNationalNumberForParsing(String numberToParse, StringBuilder nationalNumber) {
3351     int indexOfPhoneContext = numberToParse.indexOf(RFC3966_PHONE_CONTEXT);
3352     if (indexOfPhoneContext >= 0) {
3353       int phoneContextStart = indexOfPhoneContext + RFC3966_PHONE_CONTEXT.length();
3354       // If the phone context contains a phone number prefix, we need to capture it, whereas domains
3355       // will be ignored.
3356       if (phoneContextStart < (numberToParse.length() - 1)
3357           && numberToParse.charAt(phoneContextStart) == PLUS_SIGN) {
3358         // Additional parameters might follow the phone context. If so, we will remove them here
3359         // because the parameters after phone context are not important for parsing the
3360         // phone number.
3361         int phoneContextEnd = numberToParse.indexOf(';', phoneContextStart);
3362         if (phoneContextEnd > 0) {
3363           nationalNumber.append(numberToParse.substring(phoneContextStart, phoneContextEnd));
3364         } else {
3365           nationalNumber.append(numberToParse.substring(phoneContextStart));
3366         }
3367       }
3368 
3369       // Now append everything between the "tel:" prefix and the phone-context. This should include
3370       // the national number, an optional extension or isdn-subaddress component. Note we also
3371       // handle the case when "tel:" is missing, as we have seen in some of the phone number inputs.
3372       // In that case, we append everything from the beginning.
3373       int indexOfRfc3966Prefix = numberToParse.indexOf(RFC3966_PREFIX);
3374       int indexOfNationalNumber = (indexOfRfc3966Prefix >= 0)
3375           ? indexOfRfc3966Prefix + RFC3966_PREFIX.length() : 0;
3376       nationalNumber.append(numberToParse.substring(indexOfNationalNumber, indexOfPhoneContext));
3377     } else {
3378       // Extract a possible number from the string passed in (this strips leading characters that
3379       // could not be the start of a phone number.)
3380       nationalNumber.append(extractPossibleNumber(numberToParse));
3381     }
3382 
3383     // Delete the isdn-subaddress and everything after it if it is present. Note extension won't
3384     // appear at the same time with isdn-subaddress according to paragraph 5.3 of the RFC3966 spec,
3385     int indexOfIsdn = nationalNumber.indexOf(RFC3966_ISDN_SUBADDRESS);
3386     if (indexOfIsdn > 0) {
3387       nationalNumber.delete(indexOfIsdn, nationalNumber.length());
3388     }
3389     // If both phone context and isdn-subaddress are absent but other parameters are present, the
3390     // parameters are left in nationalNumber. This is because we are concerned about deleting
3391     // content from a potential number string when there is no strong evidence that the number is
3392     // actually written in RFC3966.
3393   }
3394 
3395   /**
3396    * Returns a new phone number containing only the fields needed to uniquely identify a phone
3397    * number, rather than any fields that capture the context in which the phone number was created.
3398    * These fields correspond to those set in parse() rather than parseAndKeepRawInput().
3399    */
3400   private static PhoneNumber copyCoreFieldsOnly(PhoneNumber phoneNumberIn) {
3401     PhoneNumber phoneNumber = new PhoneNumber();
3402     phoneNumber.setCountryCode(phoneNumberIn.getCountryCode());
3403     phoneNumber.setNationalNumber(phoneNumberIn.getNationalNumber());
3404     if (phoneNumberIn.getExtension().length() > 0) {
3405       phoneNumber.setExtension(phoneNumberIn.getExtension());
3406     }
3407     if (phoneNumberIn.isItalianLeadingZero()) {
3408       phoneNumber.setItalianLeadingZero(true);
3409       // This field is only relevant if there are leading zeros at all.
3410       phoneNumber.setNumberOfLeadingZeros(phoneNumberIn.getNumberOfLeadingZeros());
3411     }
3412     return phoneNumber;
3413   }
3414 
3415   /**
3416    * Takes two phone numbers and compares them for equality.
3417    *
3418    * <p>Returns EXACT_MATCH if the country_code, NSN, presence of a leading zero for Italian numbers
3419    * and any extension present are the same.
3420    * Returns NSN_MATCH if either or both has no region specified, and the NSNs and extensions are
3421    * the same.
3422    * Returns SHORT_NSN_MATCH if either or both has no region specified, or the region specified is
3423    * the same, and one NSN could be a shorter version of the other number. This includes the case
3424    * where one has an extension specified, and the other does not.
3425    * Returns NO_MATCH otherwise.
3426    * For example, the numbers +1 345 657 1234 and 657 1234 are a SHORT_NSN_MATCH.
3427    * The numbers +1 345 657 1234 and 345 657 are a NO_MATCH.
3428    *
3429    * @param firstNumberIn  first number to compare
3430    * @param secondNumberIn  second number to compare
3431    *
3432    * @return  NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH or EXACT_MATCH depending on the level of equality
3433    *     of the two numbers, described in the method definition.
3434    */
3435   public MatchType isNumberMatch(PhoneNumber firstNumberIn, PhoneNumber secondNumberIn) {
3436     // We only care about the fields that uniquely define a number, so we copy these across
3437     // explicitly.
3438     PhoneNumber firstNumber = copyCoreFieldsOnly(firstNumberIn);
3439     PhoneNumber secondNumber = copyCoreFieldsOnly(secondNumberIn);
3440     // Early exit if both had extensions and these are different.
3441     if (firstNumber.hasExtension() && secondNumber.hasExtension()
3442         && !firstNumber.getExtension().equals(secondNumber.getExtension())) {
3443       return MatchType.NO_MATCH;
3444     }
3445     int firstNumberCountryCode = firstNumber.getCountryCode();
3446     int secondNumberCountryCode = secondNumber.getCountryCode();
3447     // Both had country_code specified.
3448     if (firstNumberCountryCode != 0 && secondNumberCountryCode != 0) {
3449       if (firstNumber.exactlySameAs(secondNumber)) {
3450         return MatchType.EXACT_MATCH;
3451       } else if (firstNumberCountryCode == secondNumberCountryCode
3452           && isNationalNumberSuffixOfTheOther(firstNumber, secondNumber)) {
3453         // A SHORT_NSN_MATCH occurs if there is a difference because of the presence or absence of
3454         // an 'Italian leading zero', the presence or absence of an extension, or one NSN being a
3455         // shorter variant of the other.
3456         return MatchType.SHORT_NSN_MATCH;
3457       }
3458       // This is not a match.
3459       return MatchType.NO_MATCH;
3460     }
3461     // Checks cases where one or both country_code fields were not specified. To make equality
3462     // checks easier, we first set the country_code fields to be equal.
3463     firstNumber.setCountryCode(secondNumberCountryCode);
3464     // If all else was the same, then this is an NSN_MATCH.
3465     if (firstNumber.exactlySameAs(secondNumber)) {
3466       return MatchType.NSN_MATCH;
3467     }
3468     if (isNationalNumberSuffixOfTheOther(firstNumber, secondNumber)) {
3469       return MatchType.SHORT_NSN_MATCH;
3470     }
3471     return MatchType.NO_MATCH;
3472   }
3473 
3474   // Returns true when one national number is the suffix of the other or both are the same.
3475   private boolean isNationalNumberSuffixOfTheOther(PhoneNumber firstNumber,
3476                                                    PhoneNumber secondNumber) {
3477     String firstNumberNationalNumber = String.valueOf(firstNumber.getNationalNumber());
3478     String secondNumberNationalNumber = String.valueOf(secondNumber.getNationalNumber());
3479     // Note that endsWith returns true if the numbers are equal.
3480     return firstNumberNationalNumber.endsWith(secondNumberNationalNumber)
3481         || secondNumberNationalNumber.endsWith(firstNumberNationalNumber);
3482   }
3483 
3484   /**
3485    * Takes two phone numbers as strings and compares them for equality. This is a convenience
3486    * wrapper for {@link #isNumberMatch(PhoneNumber, PhoneNumber)}. No default region is known.
3487    *
3488    * @param firstNumber  first number to compare. Can contain formatting, and can have country
3489    *     calling code specified with + at the start.
3490    * @param secondNumber  second number to compare. Can contain formatting, and can have country
3491    *     calling code specified with + at the start.
3492    * @return  NOT_A_NUMBER, NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH, EXACT_MATCH. See
3493    *     {@link #isNumberMatch(PhoneNumber, PhoneNumber)} for more details.
3494    */
3495   public MatchType isNumberMatch(CharSequence firstNumber, CharSequence secondNumber) {
3496     try {
3497       PhoneNumber firstNumberAsProto = parse(firstNumber, UNKNOWN_REGION);
3498       return isNumberMatch(firstNumberAsProto, secondNumber);
3499     } catch (NumberParseException e) {
3500       if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE) {
3501         try {
3502           PhoneNumber secondNumberAsProto = parse(secondNumber, UNKNOWN_REGION);
3503           return isNumberMatch(secondNumberAsProto, firstNumber);
3504         } catch (NumberParseException e2) {
3505           if (e2.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE) {
3506             try {
3507               PhoneNumber firstNumberProto = new PhoneNumber();
3508               PhoneNumber secondNumberProto = new PhoneNumber();
3509               parseHelper(firstNumber, null, false, false, firstNumberProto);
3510               parseHelper(secondNumber, null, false, false, secondNumberProto);
3511               return isNumberMatch(firstNumberProto, secondNumberProto);
3512             } catch (NumberParseException e3) {
3513               // Fall through and return MatchType.NOT_A_NUMBER.
3514             }
3515           }
3516         }
3517       }
3518     }
3519     // One or more of the phone numbers we are trying to match is not a viable phone number.
3520     return MatchType.NOT_A_NUMBER;
3521   }
3522 
3523   /**
3524    * Takes two phone numbers and compares them for equality. This is a convenience wrapper for
3525    * {@link #isNumberMatch(PhoneNumber, PhoneNumber)}. No default region is known.
3526    *
3527    * @param firstNumber  first number to compare in proto buffer format
3528    * @param secondNumber  second number to compare. Can contain formatting, and can have country
3529    *     calling code specified with + at the start.
3530    * @return  NOT_A_NUMBER, NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH, EXACT_MATCH. See
3531    *     {@link #isNumberMatch(PhoneNumber, PhoneNumber)} for more details.
3532    */
3533   public MatchType isNumberMatch(PhoneNumber firstNumber, CharSequence secondNumber) {
3534     // First see if the second number has an implicit country calling code, by attempting to parse
3535     // it.
3536     try {
3537       PhoneNumber secondNumberAsProto = parse(secondNumber, UNKNOWN_REGION);
3538       return isNumberMatch(firstNumber, secondNumberAsProto);
3539     } catch (NumberParseException e) {
3540       if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE) {
3541         // The second number has no country calling code. EXACT_MATCH is no longer possible.
3542         // We parse it as if the region was the same as that for the first number, and if
3543         // EXACT_MATCH is returned, we replace this with NSN_MATCH.
3544         String firstNumberRegion = getRegionCodeForCountryCode(firstNumber.getCountryCode());
3545         try {
3546           if (!firstNumberRegion.equals(UNKNOWN_REGION)) {
3547             PhoneNumber secondNumberWithFirstNumberRegion = parse(secondNumber, firstNumberRegion);
3548             MatchType match = isNumberMatch(firstNumber, secondNumberWithFirstNumberRegion);
3549             if (match == MatchType.EXACT_MATCH) {
3550               return MatchType.NSN_MATCH;
3551             }
3552             return match;
3553           } else {
3554             // If the first number didn't have a valid country calling code, then we parse the
3555             // second number without one as well.
3556             PhoneNumber secondNumberProto = new PhoneNumber();
3557             parseHelper(secondNumber, null, false, false, secondNumberProto);
3558             return isNumberMatch(firstNumber, secondNumberProto);
3559           }
3560         } catch (NumberParseException e2) {
3561           // Fall-through to return NOT_A_NUMBER.
3562         }
3563       }
3564     }
3565     // One or more of the phone numbers we are trying to match is not a viable phone number.
3566     return MatchType.NOT_A_NUMBER;
3567   }
3568 
3569   /**
3570    * Returns true if the number can be dialled from outside the region, or unknown. If the number
3571    * can only be dialled from within the region, returns false. Does not check the number is a valid
3572    * number. Note that, at the moment, this method does not handle short numbers (which are
3573    * currently all presumed to not be diallable from outside their country).
3574    *
3575    * @param number  the phone-number for which we want to know whether it is diallable from
3576    *     outside the region
3577    */
3578   public boolean canBeInternationallyDialled(PhoneNumber number) {
3579     PhoneMetadata metadata = getMetadataForRegion(getRegionCodeForNumber(number));
3580     if (metadata == null) {
3581       // Note numbers belonging to non-geographical entities (e.g. +800 numbers) are always
3582       // internationally diallable, and will be caught here.
3583       return true;
3584     }
3585     String nationalSignificantNumber = getNationalSignificantNumber(number);
3586     return !isNumberMatchingDesc(nationalSignificantNumber, metadata.getNoInternationalDialling());
3587   }
3588 
3589   /**
3590    * Returns true if the supplied region supports mobile number portability. Returns false for
3591    * invalid, unknown or regions that don't support mobile number portability.
3592    *
3593    * @param regionCode  the region for which we want to know whether it supports mobile number
3594    *     portability or not
3595    */
3596   public boolean isMobileNumberPortableRegion(String regionCode) {
3597     PhoneMetadata metadata = getMetadataForRegion(regionCode);
3598     if (metadata == null) {
3599       logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode);
3600       return false;
3601     }
3602     return metadata.getMobileNumberPortableRegion();
3603   }
3604 }
3605