diff options
author | Narayan Kamath <narayan@google.com> | 2014-12-18 11:56:40 +0000 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2014-12-23 12:32:44 +0000 |
commit | a77faddfc3b3e4cca8f585c82d669054aec221f4 (patch) | |
tree | b3ca5eaf70be2df2a1a9cfc684532d1563d759a7 /libphonenumber/src/com | |
parent | eec8af34d3129d0f37c45ff8a82b4212724a6d79 (diff) | |
download | libphonenumber-a77faddfc3b3e4cca8f585c82d669054aec221f4.tar.gz |
Update libphonenumber to an unmodified copy of v7.0.1
Copied from upstream commit eb7f783d2fd7d222a10283a72d9e7 with no
local modifications and a cherry-pick of commit 5b00cb5b2dc0582c29
(JAVA/JS: Documentation fix and added missing licences.) from upstream
master.
Added Android.mk to build the code for platform and unbundled use.
Note that while we rename packages, we don't rename resources to make
sure they're found.
Change-Id: Idb886f1b5d7bca491b9f7f8d18574a88f08593ba
Diffstat (limited to 'libphonenumber/src/com')
546 files changed, 8431 insertions, 0 deletions
diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/AlternateFormatsCountryCodeSet.java b/libphonenumber/src/com/google/i18n/phonenumbers/AlternateFormatsCountryCodeSet.java new file mode 100644 index 00000000..c07a1739 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/AlternateFormatsCountryCodeSet.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file is automatically generated by {@link BuildMetadataProtoFromXml}. + * Please don't modify it directly. + */ + +package com.google.i18n.phonenumbers; + +import java.util.HashSet; +import java.util.Set; + +public class AlternateFormatsCountryCodeSet { + // A set of all country codes for which data is available. + static Set<Integer> getCountryCodeSet() { + // The capacity is set to 57 as there are 43 different entries, + // and this offers a load factor of roughly 0.75. + Set<Integer> countryCodeSet = new HashSet<Integer>(57); + + countryCodeSet.add(7); + countryCodeSet.add(27); + countryCodeSet.add(30); + countryCodeSet.add(31); + countryCodeSet.add(34); + countryCodeSet.add(36); + countryCodeSet.add(43); + countryCodeSet.add(44); + countryCodeSet.add(49); + countryCodeSet.add(54); + countryCodeSet.add(55); + countryCodeSet.add(58); + countryCodeSet.add(61); + countryCodeSet.add(62); + countryCodeSet.add(63); + countryCodeSet.add(66); + countryCodeSet.add(81); + countryCodeSet.add(84); + countryCodeSet.add(90); + countryCodeSet.add(91); + countryCodeSet.add(94); + countryCodeSet.add(95); + countryCodeSet.add(255); + countryCodeSet.add(350); + countryCodeSet.add(351); + countryCodeSet.add(352); + countryCodeSet.add(358); + countryCodeSet.add(359); + countryCodeSet.add(372); + countryCodeSet.add(373); + countryCodeSet.add(380); + countryCodeSet.add(381); + countryCodeSet.add(385); + countryCodeSet.add(505); + countryCodeSet.add(506); + countryCodeSet.add(595); + countryCodeSet.add(675); + countryCodeSet.add(676); + countryCodeSet.add(679); + countryCodeSet.add(855); + countryCodeSet.add(971); + countryCodeSet.add(972); + countryCodeSet.add(995); + + return countryCodeSet; + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java b/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java new file mode 100644 index 00000000..ad63a40a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java @@ -0,0 +1,656 @@ +/* + * Copyright (C) 2009 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A formatter which formats phone numbers as they are entered. + * + * <p>An AsYouTypeFormatter can be created by invoking + * {@link PhoneNumberUtil#getAsYouTypeFormatter}. After that, digits can be added by invoking + * {@link #inputDigit} on the formatter instance, and the partially formatted phone number will be + * returned each time a digit is added. {@link #clear} can be invoked before formatting a new + * number. + * + * <p>See the unittests for more details on how the formatter is to be used. + * + * @author Shaopeng Jia + */ +public class AsYouTypeFormatter { + private String currentOutput = ""; + private StringBuilder formattingTemplate = new StringBuilder(); + // The pattern from numberFormat that is currently used to create formattingTemplate. + private String currentFormattingPattern = ""; + private StringBuilder accruedInput = new StringBuilder(); + private StringBuilder accruedInputWithoutFormatting = new StringBuilder(); + // This indicates whether AsYouTypeFormatter is currently doing the formatting. + private boolean ableToFormat = true; + // Set to true when users enter their own formatting. AsYouTypeFormatter will do no formatting at + // all when this is set to true. + private boolean inputHasFormatting = false; + // This is set to true when we know the user is entering a full national significant number, since + // we have either detected a national prefix or an international dialing prefix. When this is + // true, we will no longer use local number formatting patterns. + private boolean isCompleteNumber = false; + private boolean isExpectingCountryCallingCode = false; + private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); + private String defaultCountry; + + // Character used when appropriate to separate a prefix, such as a long NDD or a country calling + // code, from the national number. + private static final char SEPARATOR_BEFORE_NATIONAL_NUMBER = ' '; + private static final PhoneMetadata EMPTY_METADATA = + new PhoneMetadata().setInternationalPrefix("NA"); + private PhoneMetadata defaultMetadata; + private PhoneMetadata currentMetadata; + + // A pattern that is used to match character classes in regular expressions. An example of a + // character class is [1-4]. + private static final Pattern CHARACTER_CLASS_PATTERN = Pattern.compile("\\[([^\\[\\]])*\\]"); + // Any digit in a regular expression that actually denotes a digit. For example, in the regular + // expression 80[0-2]\d{6,10}, the first 2 digits (8 and 0) are standalone digits, but the rest + // are not. + // Two look-aheads are needed because the number following \\d could be a two-digit number, since + // the phone number can be as long as 15 digits. + private static final Pattern STANDALONE_DIGIT_PATTERN = Pattern.compile("\\d(?=[^,}][^,}])"); + + // A pattern that is used to determine if a numberFormat under availableFormats is eligible to be + // used by the AYTF. It is eligible when the format element under numberFormat contains groups of + // the dollar sign followed by a single digit, separated by valid phone number punctuation. This + // prevents invalid punctuation (such as the star sign in Israeli star numbers) getting into the + // output of the AYTF. + private static final Pattern ELIGIBLE_FORMAT_PATTERN = + Pattern.compile("[" + PhoneNumberUtil.VALID_PUNCTUATION + "]*" + + "(\\$\\d" + "[" + PhoneNumberUtil.VALID_PUNCTUATION + "]*)+"); + // A set of characters that, if found in a national prefix formatting rules, are an indicator to + // us that we should separate the national prefix from the number when formatting. + private static final Pattern NATIONAL_PREFIX_SEPARATORS_PATTERN = Pattern.compile("[- ]"); + + // This is the minimum length of national number accrued that is required to trigger the + // formatter. The first element of the leadingDigitsPattern of each numberFormat contains a + // regular expression that matches up to this number of digits. + private static final int MIN_LEADING_DIGITS_LENGTH = 3; + + // The digits that have not been entered yet will be represented by a \u2008, the punctuation + // space. + private static final String DIGIT_PLACEHOLDER = "\u2008"; + private static final Pattern DIGIT_PATTERN = Pattern.compile(DIGIT_PLACEHOLDER); + private int lastMatchPosition = 0; + // The position of a digit upon which inputDigitAndRememberPosition is most recently invoked, as + // found in the original sequence of characters the user entered. + private int originalPosition = 0; + // The position of a digit upon which inputDigitAndRememberPosition is most recently invoked, as + // found in accruedInputWithoutFormatting. + private int positionToRemember = 0; + // This contains anything that has been entered so far preceding the national significant number, + // and it is formatted (e.g. with space inserted). For example, this can contain IDD, country + // code, and/or NDD, etc. + private StringBuilder prefixBeforeNationalNumber = new StringBuilder(); + private boolean shouldAddSpaceAfterNationalPrefix = false; + // This contains the national prefix that has been extracted. It contains only digits without + // formatting. + private String extractedNationalPrefix = ""; + private StringBuilder nationalNumber = new StringBuilder(); + private List<NumberFormat> possibleFormats = new ArrayList<NumberFormat>(); + + // A cache for frequently used country-specific regular expressions. + private RegexCache regexCache = new RegexCache(64); + + /** + * Constructs an as-you-type formatter. Should be obtained from {@link + * PhoneNumberUtil#getAsYouTypeFormatter}. + * + * @param regionCode the country/region where the phone number is being entered + */ + AsYouTypeFormatter(String regionCode) { + defaultCountry = regionCode; + currentMetadata = getMetadataForRegion(defaultCountry); + defaultMetadata = currentMetadata; + } + + // The metadata needed by this class is the same for all regions sharing the same country calling + // code. Therefore, we return the metadata for "main" region for this country calling code. + private PhoneMetadata getMetadataForRegion(String regionCode) { + int countryCallingCode = phoneUtil.getCountryCodeForRegion(regionCode); + String mainCountry = phoneUtil.getRegionCodeForCountryCode(countryCallingCode); + PhoneMetadata metadata = phoneUtil.getMetadataForRegion(mainCountry); + if (metadata != null) { + return metadata; + } + // Set to a default instance of the metadata. This allows us to function with an incorrect + // region code, even if formatting only works for numbers specified with "+". + return EMPTY_METADATA; + } + + // Returns true if a new template is created as opposed to reusing the existing template. + private boolean maybeCreateNewTemplate() { + // When there are multiple available formats, the formatter uses the first format where a + // formatting template could be created. + Iterator<NumberFormat> it = possibleFormats.iterator(); + while (it.hasNext()) { + NumberFormat numberFormat = it.next(); + String pattern = numberFormat.getPattern(); + if (currentFormattingPattern.equals(pattern)) { + return false; + } + if (createFormattingTemplate(numberFormat)) { + currentFormattingPattern = pattern; + shouldAddSpaceAfterNationalPrefix = + NATIONAL_PREFIX_SEPARATORS_PATTERN.matcher( + numberFormat.getNationalPrefixFormattingRule()).find(); + // With a new formatting template, the matched position using the old template needs to be + // reset. + lastMatchPosition = 0; + return true; + } else { // Remove the current number format from possibleFormats. + it.remove(); + } + } + ableToFormat = false; + return false; + } + + private void getAvailableFormats(String leadingDigits) { + List<NumberFormat> formatList = + (isCompleteNumber && currentMetadata.intlNumberFormatSize() > 0) + ? currentMetadata.intlNumberFormats() + : currentMetadata.numberFormats(); + boolean nationalPrefixIsUsedByCountry = currentMetadata.hasNationalPrefix(); + for (NumberFormat format : formatList) { + if (!nationalPrefixIsUsedByCountry || isCompleteNumber || + format.isNationalPrefixOptionalWhenFormatting() || + PhoneNumberUtil.formattingRuleHasFirstGroupOnly( + format.getNationalPrefixFormattingRule())) { + if (isFormatEligible(format.getFormat())) { + possibleFormats.add(format); + } + } + } + narrowDownPossibleFormats(leadingDigits); + } + + private boolean isFormatEligible(String format) { + return ELIGIBLE_FORMAT_PATTERN.matcher(format).matches(); + } + + private void narrowDownPossibleFormats(String leadingDigits) { + int indexOfLeadingDigitsPattern = leadingDigits.length() - MIN_LEADING_DIGITS_LENGTH; + Iterator<NumberFormat> it = possibleFormats.iterator(); + while (it.hasNext()) { + NumberFormat format = it.next(); + if (format.leadingDigitsPatternSize() == 0) { + // Keep everything that isn't restricted by leading digits. + continue; + } + int lastLeadingDigitsPattern = + Math.min(indexOfLeadingDigitsPattern, format.leadingDigitsPatternSize() - 1); + Pattern leadingDigitsPattern = regexCache.getPatternForRegex( + format.getLeadingDigitsPattern(lastLeadingDigitsPattern)); + Matcher m = leadingDigitsPattern.matcher(leadingDigits); + if (!m.lookingAt()) { + it.remove(); + } + } + } + + private boolean createFormattingTemplate(NumberFormat format) { + String numberPattern = format.getPattern(); + + // The formatter doesn't format numbers when numberPattern contains "|", e.g. + // (20|3)\d{4}. In those cases we quickly return. + if (numberPattern.indexOf('|') != -1) { + return false; + } + + // Replace anything in the form of [..] with \d + numberPattern = CHARACTER_CLASS_PATTERN.matcher(numberPattern).replaceAll("\\\\d"); + + // Replace any standalone digit (not the one in d{}) with \d + numberPattern = STANDALONE_DIGIT_PATTERN.matcher(numberPattern).replaceAll("\\\\d"); + formattingTemplate.setLength(0); + String tempTemplate = getFormattingTemplate(numberPattern, format.getFormat()); + if (tempTemplate.length() > 0) { + formattingTemplate.append(tempTemplate); + return true; + } + return false; + } + + // Gets a formatting template which can be used to efficiently format a partial number where + // digits are added one by one. + private String getFormattingTemplate(String numberPattern, String numberFormat) { + // Creates a phone number consisting only of the digit 9 that matches the + // numberPattern by applying the pattern to the longestPhoneNumber string. + String longestPhoneNumber = "999999999999999"; + Matcher m = regexCache.getPatternForRegex(numberPattern).matcher(longestPhoneNumber); + m.find(); // this will always succeed + String aPhoneNumber = m.group(); + // No formatting template can be created if the number of digits entered so far is longer than + // the maximum the current formatting rule can accommodate. + if (aPhoneNumber.length() < nationalNumber.length()) { + return ""; + } + // Formats the number according to numberFormat + String template = aPhoneNumber.replaceAll(numberPattern, numberFormat); + // Replaces each digit with character DIGIT_PLACEHOLDER + template = template.replaceAll("9", DIGIT_PLACEHOLDER); + return template; + } + + /** + * Clears the internal state of the formatter, so it can be reused. + */ + public void clear() { + currentOutput = ""; + accruedInput.setLength(0); + accruedInputWithoutFormatting.setLength(0); + formattingTemplate.setLength(0); + lastMatchPosition = 0; + currentFormattingPattern = ""; + prefixBeforeNationalNumber.setLength(0); + extractedNationalPrefix = ""; + nationalNumber.setLength(0); + ableToFormat = true; + inputHasFormatting = false; + positionToRemember = 0; + originalPosition = 0; + isCompleteNumber = false; + isExpectingCountryCallingCode = false; + possibleFormats.clear(); + shouldAddSpaceAfterNationalPrefix = false; + if (!currentMetadata.equals(defaultMetadata)) { + currentMetadata = getMetadataForRegion(defaultCountry); + } + } + + /** + * Formats a phone number on-the-fly as each digit is entered. + * + * @param nextChar the most recently entered digit of a phone number. Formatting characters are + * allowed, but as soon as they are encountered this method formats the number as entered and + * not "as you type" anymore. Full width digits and Arabic-indic digits are allowed, and will + * be shown as they are. + * @return the partially formatted phone number. + */ + public String inputDigit(char nextChar) { + currentOutput = inputDigitWithOptionToRememberPosition(nextChar, false); + return currentOutput; + } + + /** + * Same as {@link #inputDigit}, but remembers the position where {@code nextChar} is inserted, so + * that it can be retrieved later by using {@link #getRememberedPosition}. The remembered + * position will be automatically adjusted if additional formatting characters are later + * inserted/removed in front of {@code nextChar}. + */ + public String inputDigitAndRememberPosition(char nextChar) { + currentOutput = inputDigitWithOptionToRememberPosition(nextChar, true); + return currentOutput; + } + + @SuppressWarnings("fallthrough") + private String inputDigitWithOptionToRememberPosition(char nextChar, boolean rememberPosition) { + accruedInput.append(nextChar); + if (rememberPosition) { + originalPosition = accruedInput.length(); + } + // We do formatting on-the-fly only when each character entered is either a digit, or a plus + // sign (accepted at the start of the number only). + if (!isDigitOrLeadingPlusSign(nextChar)) { + ableToFormat = false; + inputHasFormatting = true; + } else { + nextChar = normalizeAndAccrueDigitsAndPlusSign(nextChar, rememberPosition); + } + if (!ableToFormat) { + // When we are unable to format because of reasons other than that formatting chars have been + // entered, it can be due to really long IDDs or NDDs. If that is the case, we might be able + // to do formatting again after extracting them. + if (inputHasFormatting) { + return accruedInput.toString(); + } else if (attemptToExtractIdd()) { + if (attemptToExtractCountryCallingCode()) { + return attemptToChoosePatternWithPrefixExtracted(); + } + } else if (ableToExtractLongerNdd()) { + // Add an additional space to separate long NDD and national significant number for + // readability. We don't set shouldAddSpaceAfterNationalPrefix to true, since we don't want + // this to change later when we choose formatting templates. + prefixBeforeNationalNumber.append(SEPARATOR_BEFORE_NATIONAL_NUMBER); + return attemptToChoosePatternWithPrefixExtracted(); + } + return accruedInput.toString(); + } + + // We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH digits (the plus + // sign is counted as a digit as well for this purpose) have been entered. + switch (accruedInputWithoutFormatting.length()) { + case 0: + case 1: + case 2: + return accruedInput.toString(); + case 3: + if (attemptToExtractIdd()) { + isExpectingCountryCallingCode = true; + } else { // No IDD or plus sign is found, might be entering in national format. + extractedNationalPrefix = removeNationalPrefixFromNationalNumber(); + return attemptToChooseFormattingPattern(); + } + default: + if (isExpectingCountryCallingCode) { + if (attemptToExtractCountryCallingCode()) { + isExpectingCountryCallingCode = false; + } + return prefixBeforeNationalNumber + nationalNumber.toString(); + } + if (possibleFormats.size() > 0) { // The formatting patterns are already chosen. + String tempNationalNumber = inputDigitHelper(nextChar); + // See if the accrued digits can be formatted properly already. If not, use the results + // from inputDigitHelper, which does formatting based on the formatting pattern chosen. + String formattedNumber = attemptToFormatAccruedDigits(); + if (formattedNumber.length() > 0) { + return formattedNumber; + } + narrowDownPossibleFormats(nationalNumber.toString()); + if (maybeCreateNewTemplate()) { + return inputAccruedNationalNumber(); + } + return ableToFormat + ? appendNationalNumber(tempNationalNumber) + : accruedInput.toString(); + } else { + return attemptToChooseFormattingPattern(); + } + } + } + + private String attemptToChoosePatternWithPrefixExtracted() { + ableToFormat = true; + isExpectingCountryCallingCode = false; + possibleFormats.clear(); + return attemptToChooseFormattingPattern(); + } + + // @VisibleForTesting + String getExtractedNationalPrefix() { + return extractedNationalPrefix; + } + + // Some national prefixes are a substring of others. If extracting the shorter NDD doesn't result + // in a number we can format, we try to see if we can extract a longer version here. + private boolean ableToExtractLongerNdd() { + if (extractedNationalPrefix.length() > 0) { + // Put the extracted NDD back to the national number before attempting to extract a new NDD. + nationalNumber.insert(0, extractedNationalPrefix); + // Remove the previously extracted NDD from prefixBeforeNationalNumber. We cannot simply set + // it to empty string because people sometimes incorrectly enter national prefix after the + // country code, e.g. +44 (0)20-1234-5678. + int indexOfPreviousNdd = prefixBeforeNationalNumber.lastIndexOf(extractedNationalPrefix); + prefixBeforeNationalNumber.setLength(indexOfPreviousNdd); + } + return !extractedNationalPrefix.equals(removeNationalPrefixFromNationalNumber()); + } + + private boolean isDigitOrLeadingPlusSign(char nextChar) { + return Character.isDigit(nextChar) || + (accruedInput.length() == 1 && + PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(Character.toString(nextChar)).matches()); + } + + /** + * Check to see if there is an exact pattern match for these digits. If so, we should use this + * instead of any other formatting template whose leadingDigitsPattern also matches the input. + */ + String attemptToFormatAccruedDigits() { + for (NumberFormat numberFormat : possibleFormats) { + Matcher m = regexCache.getPatternForRegex(numberFormat.getPattern()).matcher(nationalNumber); + if (m.matches()) { + shouldAddSpaceAfterNationalPrefix = + NATIONAL_PREFIX_SEPARATORS_PATTERN.matcher( + numberFormat.getNationalPrefixFormattingRule()).find(); + String formattedNumber = m.replaceAll(numberFormat.getFormat()); + return appendNationalNumber(formattedNumber); + } + } + return ""; + } + + /** + * Returns the current position in the partially formatted phone number of the character which was + * previously passed in as the parameter of {@link #inputDigitAndRememberPosition}. + */ + public int getRememberedPosition() { + if (!ableToFormat) { + return originalPosition; + } + int accruedInputIndex = 0, currentOutputIndex = 0; + while (accruedInputIndex < positionToRemember && currentOutputIndex < currentOutput.length()) { + if (accruedInputWithoutFormatting.charAt(accruedInputIndex) == + currentOutput.charAt(currentOutputIndex)) { + accruedInputIndex++; + } + currentOutputIndex++; + } + return currentOutputIndex; + } + + /** + * Combines the national number with any prefix (IDD/+ and country code or national prefix) that + * was collected. A space will be inserted between them if the current formatting template + * indicates this to be suitable. + */ + private String appendNationalNumber(String nationalNumber) { + int prefixBeforeNationalNumberLength = prefixBeforeNationalNumber.length(); + if (shouldAddSpaceAfterNationalPrefix && prefixBeforeNationalNumberLength > 0 && + prefixBeforeNationalNumber.charAt(prefixBeforeNationalNumberLength - 1) + != SEPARATOR_BEFORE_NATIONAL_NUMBER) { + // We want to add a space after the national prefix if the national prefix formatting rule + // indicates that this would normally be done, with the exception of the case where we already + // appended a space because the NDD was surprisingly long. + return new String(prefixBeforeNationalNumber) + SEPARATOR_BEFORE_NATIONAL_NUMBER + + nationalNumber; + } else { + return prefixBeforeNationalNumber + nationalNumber; + } + } + + /** + * Attempts to set the formatting template and returns a string which contains the formatted + * version of the digits entered so far. + */ + private String attemptToChooseFormattingPattern() { + // We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH digits of national + // number (excluding national prefix) have been entered. + if (nationalNumber.length() >= MIN_LEADING_DIGITS_LENGTH) { + + getAvailableFormats(nationalNumber.toString()); + // See if the accrued digits can be formatted properly already. + String formattedNumber = attemptToFormatAccruedDigits(); + if (formattedNumber.length() > 0) { + return formattedNumber; + } + return maybeCreateNewTemplate() ? inputAccruedNationalNumber() : accruedInput.toString(); + } else { + return appendNationalNumber(nationalNumber.toString()); + } + } + + /** + * Invokes inputDigitHelper on each digit of the national number accrued, and returns a formatted + * string in the end. + */ + private String inputAccruedNationalNumber() { + int lengthOfNationalNumber = nationalNumber.length(); + if (lengthOfNationalNumber > 0) { + String tempNationalNumber = ""; + for (int i = 0; i < lengthOfNationalNumber; i++) { + tempNationalNumber = inputDigitHelper(nationalNumber.charAt(i)); + } + return ableToFormat ? appendNationalNumber(tempNationalNumber) : accruedInput.toString(); + } else { + return prefixBeforeNationalNumber.toString(); + } + } + + /** + * Returns true if the current country is a NANPA country and the national number begins with + * the national prefix. + */ + private boolean isNanpaNumberWithNationalPrefix() { + // For NANPA numbers beginning with 1[2-9], treat the 1 as the national prefix. The reason is + // that national significant numbers in NANPA always start with [2-9] after the national prefix. + // Numbers beginning with 1[01] can only be short/emergency numbers, which don't need the + // national prefix. + return (currentMetadata.getCountryCode() == 1) && (nationalNumber.charAt(0) == '1') && + (nationalNumber.charAt(1) != '0') && (nationalNumber.charAt(1) != '1'); + } + + // Returns the national prefix extracted, or an empty string if it is not present. + private String removeNationalPrefixFromNationalNumber() { + int startOfNationalNumber = 0; + if (isNanpaNumberWithNationalPrefix()) { + startOfNationalNumber = 1; + prefixBeforeNationalNumber.append('1').append(SEPARATOR_BEFORE_NATIONAL_NUMBER); + isCompleteNumber = true; + } else if (currentMetadata.hasNationalPrefixForParsing()) { + Pattern nationalPrefixForParsing = + regexCache.getPatternForRegex(currentMetadata.getNationalPrefixForParsing()); + Matcher m = nationalPrefixForParsing.matcher(nationalNumber); + // Since some national prefix patterns are entirely optional, check that a national prefix + // could actually be extracted. + if (m.lookingAt() && m.end() > 0) { + // When the national prefix is detected, we use international formatting rules instead of + // national ones, because national formatting rules could contain local formatting rules + // for numbers entered without area code. + isCompleteNumber = true; + startOfNationalNumber = m.end(); + prefixBeforeNationalNumber.append(nationalNumber.substring(0, startOfNationalNumber)); + } + } + String nationalPrefix = nationalNumber.substring(0, startOfNationalNumber); + nationalNumber.delete(0, startOfNationalNumber); + return nationalPrefix; + } + + /** + * Extracts IDD and plus sign to prefixBeforeNationalNumber when they are available, and places + * the remaining input into nationalNumber. + * + * @return true when accruedInputWithoutFormatting begins with the plus sign or valid IDD for + * defaultCountry. + */ + private boolean attemptToExtractIdd() { + Pattern internationalPrefix = + regexCache.getPatternForRegex("\\" + PhoneNumberUtil.PLUS_SIGN + "|" + + currentMetadata.getInternationalPrefix()); + Matcher iddMatcher = internationalPrefix.matcher(accruedInputWithoutFormatting); + if (iddMatcher.lookingAt()) { + isCompleteNumber = true; + int startOfCountryCallingCode = iddMatcher.end(); + nationalNumber.setLength(0); + nationalNumber.append(accruedInputWithoutFormatting.substring(startOfCountryCallingCode)); + prefixBeforeNationalNumber.setLength(0); + prefixBeforeNationalNumber.append( + accruedInputWithoutFormatting.substring(0, startOfCountryCallingCode)); + if (accruedInputWithoutFormatting.charAt(0) != PhoneNumberUtil.PLUS_SIGN) { + prefixBeforeNationalNumber.append(SEPARATOR_BEFORE_NATIONAL_NUMBER); + } + return true; + } + return false; + } + + /** + * Extracts the country calling code from the beginning of nationalNumber to + * prefixBeforeNationalNumber when they are available, and places the remaining input into + * nationalNumber. + * + * @return true when a valid country calling code can be found. + */ + private boolean attemptToExtractCountryCallingCode() { + if (nationalNumber.length() == 0) { + return false; + } + StringBuilder numberWithoutCountryCallingCode = new StringBuilder(); + int countryCode = phoneUtil.extractCountryCode(nationalNumber, numberWithoutCountryCallingCode); + if (countryCode == 0) { + return false; + } + nationalNumber.setLength(0); + nationalNumber.append(numberWithoutCountryCallingCode); + String newRegionCode = phoneUtil.getRegionCodeForCountryCode(countryCode); + if (PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY.equals(newRegionCode)) { + currentMetadata = phoneUtil.getMetadataForNonGeographicalRegion(countryCode); + } else if (!newRegionCode.equals(defaultCountry)) { + currentMetadata = getMetadataForRegion(newRegionCode); + } + String countryCodeString = Integer.toString(countryCode); + prefixBeforeNationalNumber.append(countryCodeString).append(SEPARATOR_BEFORE_NATIONAL_NUMBER); + // When we have successfully extracted the IDD, the previously extracted NDD should be cleared + // because it is no longer valid. + extractedNationalPrefix = ""; + return true; + } + + // Accrues digits and the plus sign to accruedInputWithoutFormatting for later use. If nextChar + // contains a digit in non-ASCII format (e.g. the full-width version of digits), it is first + // normalized to the ASCII version. The return value is nextChar itself, or its normalized + // version, if nextChar is a digit in non-ASCII format. This method assumes its input is either a + // digit or the plus sign. + private char normalizeAndAccrueDigitsAndPlusSign(char nextChar, boolean rememberPosition) { + char normalizedChar; + if (nextChar == PhoneNumberUtil.PLUS_SIGN) { + normalizedChar = nextChar; + accruedInputWithoutFormatting.append(nextChar); + } else { + int radix = 10; + normalizedChar = Character.forDigit(Character.digit(nextChar, radix), radix); + accruedInputWithoutFormatting.append(normalizedChar); + nationalNumber.append(normalizedChar); + } + if (rememberPosition) { + positionToRemember = accruedInputWithoutFormatting.length(); + } + return normalizedChar; + } + + private String inputDigitHelper(char nextChar) { + Matcher digitMatcher = DIGIT_PATTERN.matcher(formattingTemplate); + if (digitMatcher.find(lastMatchPosition)) { + String tempTemplate = digitMatcher.replaceFirst(Character.toString(nextChar)); + formattingTemplate.replace(0, tempTemplate.length(), tempTemplate); + lastMatchPosition = digitMatcher.start(); + return formattingTemplate.substring(0, lastMatchPosition + 1); + } else { + if (possibleFormats.size() == 1) { + // More digits are entered than we could handle, and there are no other valid patterns to + // try. + ableToFormat = false; + } // else, we just reset the formatting pattern. + currentFormattingPattern = ""; + return accruedInput.toString(); + } + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java b/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java new file mode 100644 index 00000000..5f3e269e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java @@ -0,0 +1,941 @@ +/* + * Copyright (C) 2010 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file is automatically generated by {@link BuildMetadataProtoFromXml}. + * Please don't modify it directly. + */ + +package com.google.i18n.phonenumbers; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CountryCodeToRegionCodeMap { + // A mapping from a country code to the region codes which denote the + // country/region represented by that country code. In the case of multiple + // countries sharing a calling code, such as the NANPA countries, the one + // indicated with "isMainCountryForCode" in the metadata should be first. + static Map<Integer, List<String>> getCountryCodeToRegionCodeMap() { + // The capacity is set to 286 as there are 215 different entries, + // and this offers a load factor of roughly 0.75. + Map<Integer, List<String>> countryCodeToRegionCodeMap = + new HashMap<Integer, List<String>>(286); + + ArrayList<String> listWithRegionCode; + + listWithRegionCode = new ArrayList<String>(25); + listWithRegionCode.add("US"); + listWithRegionCode.add("AG"); + listWithRegionCode.add("AI"); + listWithRegionCode.add("AS"); + listWithRegionCode.add("BB"); + listWithRegionCode.add("BM"); + listWithRegionCode.add("BS"); + listWithRegionCode.add("CA"); + listWithRegionCode.add("DM"); + listWithRegionCode.add("DO"); + listWithRegionCode.add("GD"); + listWithRegionCode.add("GU"); + listWithRegionCode.add("JM"); + listWithRegionCode.add("KN"); + listWithRegionCode.add("KY"); + listWithRegionCode.add("LC"); + listWithRegionCode.add("MP"); + listWithRegionCode.add("MS"); + listWithRegionCode.add("PR"); + listWithRegionCode.add("SX"); + listWithRegionCode.add("TC"); + listWithRegionCode.add("TT"); + listWithRegionCode.add("VC"); + listWithRegionCode.add("VG"); + listWithRegionCode.add("VI"); + countryCodeToRegionCodeMap.put(1, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("RU"); + listWithRegionCode.add("KZ"); + countryCodeToRegionCodeMap.put(7, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("EG"); + countryCodeToRegionCodeMap.put(20, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ZA"); + countryCodeToRegionCodeMap.put(27, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GR"); + countryCodeToRegionCodeMap.put(30, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NL"); + countryCodeToRegionCodeMap.put(31, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BE"); + countryCodeToRegionCodeMap.put(32, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("FR"); + countryCodeToRegionCodeMap.put(33, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ES"); + countryCodeToRegionCodeMap.put(34, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("HU"); + countryCodeToRegionCodeMap.put(36, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IT"); + countryCodeToRegionCodeMap.put(39, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("RO"); + countryCodeToRegionCodeMap.put(40, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CH"); + countryCodeToRegionCodeMap.put(41, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AT"); + countryCodeToRegionCodeMap.put(43, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(4); + listWithRegionCode.add("GB"); + listWithRegionCode.add("GG"); + listWithRegionCode.add("IM"); + listWithRegionCode.add("JE"); + countryCodeToRegionCodeMap.put(44, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("DK"); + countryCodeToRegionCodeMap.put(45, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SE"); + countryCodeToRegionCodeMap.put(46, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("NO"); + listWithRegionCode.add("SJ"); + countryCodeToRegionCodeMap.put(47, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PL"); + countryCodeToRegionCodeMap.put(48, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("DE"); + countryCodeToRegionCodeMap.put(49, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PE"); + countryCodeToRegionCodeMap.put(51, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MX"); + countryCodeToRegionCodeMap.put(52, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CU"); + countryCodeToRegionCodeMap.put(53, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AR"); + countryCodeToRegionCodeMap.put(54, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BR"); + countryCodeToRegionCodeMap.put(55, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CL"); + countryCodeToRegionCodeMap.put(56, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CO"); + countryCodeToRegionCodeMap.put(57, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("VE"); + countryCodeToRegionCodeMap.put(58, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MY"); + countryCodeToRegionCodeMap.put(60, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(3); + listWithRegionCode.add("AU"); + listWithRegionCode.add("CC"); + listWithRegionCode.add("CX"); + countryCodeToRegionCodeMap.put(61, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ID"); + countryCodeToRegionCodeMap.put(62, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PH"); + countryCodeToRegionCodeMap.put(63, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NZ"); + countryCodeToRegionCodeMap.put(64, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SG"); + countryCodeToRegionCodeMap.put(65, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TH"); + countryCodeToRegionCodeMap.put(66, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("JP"); + countryCodeToRegionCodeMap.put(81, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KR"); + countryCodeToRegionCodeMap.put(82, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("VN"); + countryCodeToRegionCodeMap.put(84, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CN"); + countryCodeToRegionCodeMap.put(86, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TR"); + countryCodeToRegionCodeMap.put(90, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IN"); + countryCodeToRegionCodeMap.put(91, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PK"); + countryCodeToRegionCodeMap.put(92, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AF"); + countryCodeToRegionCodeMap.put(93, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LK"); + countryCodeToRegionCodeMap.put(94, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MM"); + countryCodeToRegionCodeMap.put(95, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IR"); + countryCodeToRegionCodeMap.put(98, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SS"); + countryCodeToRegionCodeMap.put(211, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("MA"); + listWithRegionCode.add("EH"); + countryCodeToRegionCodeMap.put(212, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("DZ"); + countryCodeToRegionCodeMap.put(213, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TN"); + countryCodeToRegionCodeMap.put(216, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LY"); + countryCodeToRegionCodeMap.put(218, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GM"); + countryCodeToRegionCodeMap.put(220, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SN"); + countryCodeToRegionCodeMap.put(221, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MR"); + countryCodeToRegionCodeMap.put(222, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ML"); + countryCodeToRegionCodeMap.put(223, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GN"); + countryCodeToRegionCodeMap.put(224, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CI"); + countryCodeToRegionCodeMap.put(225, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BF"); + countryCodeToRegionCodeMap.put(226, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NE"); + countryCodeToRegionCodeMap.put(227, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TG"); + countryCodeToRegionCodeMap.put(228, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BJ"); + countryCodeToRegionCodeMap.put(229, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MU"); + countryCodeToRegionCodeMap.put(230, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LR"); + countryCodeToRegionCodeMap.put(231, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SL"); + countryCodeToRegionCodeMap.put(232, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GH"); + countryCodeToRegionCodeMap.put(233, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NG"); + countryCodeToRegionCodeMap.put(234, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TD"); + countryCodeToRegionCodeMap.put(235, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CF"); + countryCodeToRegionCodeMap.put(236, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CM"); + countryCodeToRegionCodeMap.put(237, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CV"); + countryCodeToRegionCodeMap.put(238, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ST"); + countryCodeToRegionCodeMap.put(239, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GQ"); + countryCodeToRegionCodeMap.put(240, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GA"); + countryCodeToRegionCodeMap.put(241, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CG"); + countryCodeToRegionCodeMap.put(242, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CD"); + countryCodeToRegionCodeMap.put(243, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AO"); + countryCodeToRegionCodeMap.put(244, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GW"); + countryCodeToRegionCodeMap.put(245, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IO"); + countryCodeToRegionCodeMap.put(246, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AC"); + countryCodeToRegionCodeMap.put(247, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SC"); + countryCodeToRegionCodeMap.put(248, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SD"); + countryCodeToRegionCodeMap.put(249, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("RW"); + countryCodeToRegionCodeMap.put(250, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ET"); + countryCodeToRegionCodeMap.put(251, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SO"); + countryCodeToRegionCodeMap.put(252, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("DJ"); + countryCodeToRegionCodeMap.put(253, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KE"); + countryCodeToRegionCodeMap.put(254, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TZ"); + countryCodeToRegionCodeMap.put(255, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("UG"); + countryCodeToRegionCodeMap.put(256, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BI"); + countryCodeToRegionCodeMap.put(257, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MZ"); + countryCodeToRegionCodeMap.put(258, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ZM"); + countryCodeToRegionCodeMap.put(260, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MG"); + countryCodeToRegionCodeMap.put(261, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("RE"); + listWithRegionCode.add("YT"); + countryCodeToRegionCodeMap.put(262, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ZW"); + countryCodeToRegionCodeMap.put(263, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NA"); + countryCodeToRegionCodeMap.put(264, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MW"); + countryCodeToRegionCodeMap.put(265, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LS"); + countryCodeToRegionCodeMap.put(266, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BW"); + countryCodeToRegionCodeMap.put(267, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SZ"); + countryCodeToRegionCodeMap.put(268, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KM"); + countryCodeToRegionCodeMap.put(269, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("SH"); + listWithRegionCode.add("TA"); + countryCodeToRegionCodeMap.put(290, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ER"); + countryCodeToRegionCodeMap.put(291, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AW"); + countryCodeToRegionCodeMap.put(297, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("FO"); + countryCodeToRegionCodeMap.put(298, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GL"); + countryCodeToRegionCodeMap.put(299, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GI"); + countryCodeToRegionCodeMap.put(350, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PT"); + countryCodeToRegionCodeMap.put(351, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LU"); + countryCodeToRegionCodeMap.put(352, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IE"); + countryCodeToRegionCodeMap.put(353, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IS"); + countryCodeToRegionCodeMap.put(354, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AL"); + countryCodeToRegionCodeMap.put(355, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MT"); + countryCodeToRegionCodeMap.put(356, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CY"); + countryCodeToRegionCodeMap.put(357, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("FI"); + listWithRegionCode.add("AX"); + countryCodeToRegionCodeMap.put(358, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BG"); + countryCodeToRegionCodeMap.put(359, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LT"); + countryCodeToRegionCodeMap.put(370, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LV"); + countryCodeToRegionCodeMap.put(371, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("EE"); + countryCodeToRegionCodeMap.put(372, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MD"); + countryCodeToRegionCodeMap.put(373, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AM"); + countryCodeToRegionCodeMap.put(374, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BY"); + countryCodeToRegionCodeMap.put(375, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AD"); + countryCodeToRegionCodeMap.put(376, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MC"); + countryCodeToRegionCodeMap.put(377, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SM"); + countryCodeToRegionCodeMap.put(378, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("VA"); + countryCodeToRegionCodeMap.put(379, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("UA"); + countryCodeToRegionCodeMap.put(380, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("RS"); + countryCodeToRegionCodeMap.put(381, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("ME"); + countryCodeToRegionCodeMap.put(382, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("HR"); + countryCodeToRegionCodeMap.put(385, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SI"); + countryCodeToRegionCodeMap.put(386, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BA"); + countryCodeToRegionCodeMap.put(387, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MK"); + countryCodeToRegionCodeMap.put(389, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CZ"); + countryCodeToRegionCodeMap.put(420, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SK"); + countryCodeToRegionCodeMap.put(421, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LI"); + countryCodeToRegionCodeMap.put(423, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("FK"); + countryCodeToRegionCodeMap.put(500, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BZ"); + countryCodeToRegionCodeMap.put(501, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GT"); + countryCodeToRegionCodeMap.put(502, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SV"); + countryCodeToRegionCodeMap.put(503, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("HN"); + countryCodeToRegionCodeMap.put(504, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NI"); + countryCodeToRegionCodeMap.put(505, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CR"); + countryCodeToRegionCodeMap.put(506, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PA"); + countryCodeToRegionCodeMap.put(507, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PM"); + countryCodeToRegionCodeMap.put(508, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("HT"); + countryCodeToRegionCodeMap.put(509, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(3); + listWithRegionCode.add("GP"); + listWithRegionCode.add("BL"); + listWithRegionCode.add("MF"); + countryCodeToRegionCodeMap.put(590, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BO"); + countryCodeToRegionCodeMap.put(591, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GY"); + countryCodeToRegionCodeMap.put(592, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("EC"); + countryCodeToRegionCodeMap.put(593, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GF"); + countryCodeToRegionCodeMap.put(594, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PY"); + countryCodeToRegionCodeMap.put(595, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MQ"); + countryCodeToRegionCodeMap.put(596, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SR"); + countryCodeToRegionCodeMap.put(597, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("UY"); + countryCodeToRegionCodeMap.put(598, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(2); + listWithRegionCode.add("CW"); + listWithRegionCode.add("BQ"); + countryCodeToRegionCodeMap.put(599, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TL"); + countryCodeToRegionCodeMap.put(670, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NF"); + countryCodeToRegionCodeMap.put(672, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BN"); + countryCodeToRegionCodeMap.put(673, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NR"); + countryCodeToRegionCodeMap.put(674, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PG"); + countryCodeToRegionCodeMap.put(675, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TO"); + countryCodeToRegionCodeMap.put(676, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SB"); + countryCodeToRegionCodeMap.put(677, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("VU"); + countryCodeToRegionCodeMap.put(678, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("FJ"); + countryCodeToRegionCodeMap.put(679, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PW"); + countryCodeToRegionCodeMap.put(680, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("WF"); + countryCodeToRegionCodeMap.put(681, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("CK"); + countryCodeToRegionCodeMap.put(682, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NU"); + countryCodeToRegionCodeMap.put(683, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("WS"); + countryCodeToRegionCodeMap.put(685, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KI"); + countryCodeToRegionCodeMap.put(686, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NC"); + countryCodeToRegionCodeMap.put(687, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TV"); + countryCodeToRegionCodeMap.put(688, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PF"); + countryCodeToRegionCodeMap.put(689, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TK"); + countryCodeToRegionCodeMap.put(690, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("FM"); + countryCodeToRegionCodeMap.put(691, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MH"); + countryCodeToRegionCodeMap.put(692, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(800, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(808, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KP"); + countryCodeToRegionCodeMap.put(850, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("HK"); + countryCodeToRegionCodeMap.put(852, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MO"); + countryCodeToRegionCodeMap.put(853, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KH"); + countryCodeToRegionCodeMap.put(855, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LA"); + countryCodeToRegionCodeMap.put(856, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(870, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(878, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BD"); + countryCodeToRegionCodeMap.put(880, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(881, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(882, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(883, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TW"); + countryCodeToRegionCodeMap.put(886, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(888, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MV"); + countryCodeToRegionCodeMap.put(960, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("LB"); + countryCodeToRegionCodeMap.put(961, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("JO"); + countryCodeToRegionCodeMap.put(962, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SY"); + countryCodeToRegionCodeMap.put(963, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IQ"); + countryCodeToRegionCodeMap.put(964, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KW"); + countryCodeToRegionCodeMap.put(965, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("SA"); + countryCodeToRegionCodeMap.put(966, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("YE"); + countryCodeToRegionCodeMap.put(967, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("OM"); + countryCodeToRegionCodeMap.put(968, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("PS"); + countryCodeToRegionCodeMap.put(970, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AE"); + countryCodeToRegionCodeMap.put(971, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("IL"); + countryCodeToRegionCodeMap.put(972, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BH"); + countryCodeToRegionCodeMap.put(973, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("QA"); + countryCodeToRegionCodeMap.put(974, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("BT"); + countryCodeToRegionCodeMap.put(975, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("MN"); + countryCodeToRegionCodeMap.put(976, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("NP"); + countryCodeToRegionCodeMap.put(977, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("001"); + countryCodeToRegionCodeMap.put(979, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TJ"); + countryCodeToRegionCodeMap.put(992, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("TM"); + countryCodeToRegionCodeMap.put(993, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("AZ"); + countryCodeToRegionCodeMap.put(994, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("GE"); + countryCodeToRegionCodeMap.put(995, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("KG"); + countryCodeToRegionCodeMap.put(996, listWithRegionCode); + + listWithRegionCode = new ArrayList<String>(1); + listWithRegionCode.add("UZ"); + countryCodeToRegionCodeMap.put(998, listWithRegionCode); + + return countryCodeToRegionCodeMap; + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/MetadataLoader.java b/libphonenumber/src/com/google/i18n/phonenumbers/MetadataLoader.java new file mode 100644 index 00000000..1ab3e931 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/MetadataLoader.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import java.io.InputStream; + +/** + * Interface for caller to specify a customized phone metadata loader. + */ +public interface MetadataLoader { + /** + * Returns an input stream corresponding to the metadata to load. + * + * @param metadataFileName File name (including path) of metadata to load. File path is an + * absolute class path like /com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto. + * @return The input stream for the metadata file. The library will close this stream + * after it is done. Return null in case the metadata file could not be found. + */ + public InputStream loadMetadata(String metadataFileName); +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java b/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java new file mode 100644 index 00000000..e6f44dee --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Class encapsulating loading of PhoneNumber Metadata information. Currently this is used only for + * additional data files such as PhoneNumberAlternateFormats, but in the future it is envisaged it + * would handle the main metadata file (PhoneNumberMetadata.xml) as well. + */ +class MetadataManager { + private static final String ALTERNATE_FORMATS_FILE_PREFIX = + "/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto"; + private static final String SHORT_NUMBER_METADATA_FILE_PREFIX = + "/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto"; + + private static final Logger LOGGER = Logger.getLogger(MetadataManager.class.getName()); + + private static final Map<Integer, PhoneMetadata> callingCodeToAlternateFormatsMap = + Collections.synchronizedMap(new HashMap<Integer, PhoneMetadata>()); + private static final Map<String, PhoneMetadata> regionCodeToShortNumberMetadataMap = + Collections.synchronizedMap(new HashMap<String, PhoneMetadata>()); + + // A set of which country calling codes there are alternate format data for. If the set has an + // entry for a code, then there should be data for that code linked into the resources. + private static final Set<Integer> countryCodeSet = + AlternateFormatsCountryCodeSet.getCountryCodeSet(); + + // A set of which region codes there are short number data for. If the set has an entry for a + // code, then there should be data for that code linked into the resources. + private static final Set<String> regionCodeSet = ShortNumbersRegionCodeSet.getRegionCodeSet(); + + private MetadataManager() { + } + + private static void close(InputStream in) { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + LOGGER.log(Level.WARNING, e.toString()); + } + } + } + + private static void loadAlternateFormatsMetadataFromFile(int countryCallingCode) { + InputStream source = PhoneNumberMatcher.class.getResourceAsStream( + ALTERNATE_FORMATS_FILE_PREFIX + "_" + countryCallingCode); + ObjectInputStream in = null; + try { + in = new ObjectInputStream(source); + PhoneMetadataCollection alternateFormats = new PhoneMetadataCollection(); + alternateFormats.readExternal(in); + for (PhoneMetadata metadata : alternateFormats.getMetadataList()) { + callingCodeToAlternateFormatsMap.put(metadata.getCountryCode(), metadata); + } + } catch (IOException e) { + LOGGER.log(Level.WARNING, e.toString()); + } finally { + close(in); + } + } + + static PhoneMetadata getAlternateFormatsForCountry(int countryCallingCode) { + if (!countryCodeSet.contains(countryCallingCode)) { + return null; + } + synchronized (callingCodeToAlternateFormatsMap) { + if (!callingCodeToAlternateFormatsMap.containsKey(countryCallingCode)) { + loadAlternateFormatsMetadataFromFile(countryCallingCode); + } + } + return callingCodeToAlternateFormatsMap.get(countryCallingCode); + } + + private static void loadShortNumberMetadataFromFile(String regionCode) { + InputStream source = PhoneNumberMatcher.class.getResourceAsStream( + SHORT_NUMBER_METADATA_FILE_PREFIX + "_" + regionCode); + ObjectInputStream in = null; + try { + in = new ObjectInputStream(source); + PhoneMetadataCollection shortNumberMetadata = new PhoneMetadataCollection(); + shortNumberMetadata.readExternal(in); + for (PhoneMetadata metadata : shortNumberMetadata.getMetadataList()) { + regionCodeToShortNumberMetadataMap.put(regionCode, metadata); + } + } catch (IOException e) { + LOGGER.log(Level.WARNING, e.toString()); + } finally { + close(in); + } + } + + // @VisibleForTesting + static Set<String> getShortNumberMetadataSupportedRegions() { + return regionCodeSet; + } + + static PhoneMetadata getShortNumberMetadataForRegion(String regionCode) { + if (!regionCodeSet.contains(regionCode)) { + return null; + } + synchronized (regionCodeToShortNumberMetadataMap) { + if (!regionCodeToShortNumberMetadataMap.containsKey(regionCode)) { + loadShortNumberMetadataFromFile(regionCode); + } + } + return regionCodeToShortNumberMetadataMap.get(regionCode); + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java b/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java new file mode 100644 index 00000000..082fcc81 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +/** + * Generic exception class for errors encountered when parsing phone numbers. + */ +@SuppressWarnings("serial") +public class NumberParseException extends Exception { + + public enum ErrorType { + INVALID_COUNTRY_CODE, + // This generally indicates the string passed in had less than 3 digits in it. More + // specifically, the number failed to match the regular expression VALID_PHONE_NUMBER in + // PhoneNumberUtil.java. + NOT_A_NUMBER, + // This indicates the string started with an international dialing prefix, but after this was + // stripped from the number, had less digits than any valid phone number (including country + // code) could have. + TOO_SHORT_AFTER_IDD, + // This indicates the string, after any country code has been stripped, had less digits than any + // valid phone number could have. + TOO_SHORT_NSN, + // This indicates the string had more digits than any valid phone number could have. + TOO_LONG, + } + + private ErrorType errorType; + private String message; + + public NumberParseException(ErrorType errorType, String message) { + super(message); + this.message = message; + this.errorType = errorType; + } + + /** + * Returns the error type of the exception that has been thrown. + */ + public ErrorType getErrorType() { + return errorType; + } + + @Override + public String toString() { + return "Error type: " + errorType + ". " + message; + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java b/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java new file mode 100644 index 00000000..4ce3cabd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; + +import java.util.Arrays; + +/** + * The immutable match of a phone number within a piece of text. Matches may be found using + * {@link PhoneNumberUtil#findNumbers}. + * + * <p>A match consists of the {@linkplain #number() phone number} as well as the + * {@linkplain #start() start} and {@linkplain #end() end} offsets of the corresponding subsequence + * of the searched text. Use {@link #rawString()} to obtain a copy of the matched subsequence. + * + * <p>The following annotated example clarifies the relationship between the searched text, the + * match offsets, and the parsed number: + + * <pre> + * CharSequence text = "Call me at +1 425 882-8080 for details."; + * RegionCode country = RegionCode.US; + * PhoneNumberUtil util = PhoneNumberUtil.getInstance(); + * + * // Find the first phone number match: + * PhoneNumberMatch m = util.findNumbers(text, country).iterator().next(); + * + * // rawString() contains the phone number as it appears in the text. + * "+1 425 882-8080".equals(m.rawString()); + * + * // start() and end() define the range of the matched subsequence. + * CharSequence subsequence = text.subSequence(m.start(), m.end()); + * "+1 425 882-8080".contentEquals(subsequence); + * + * // number() returns the the same result as PhoneNumberUtil.{@link PhoneNumberUtil#parse parse()} + * // invoked on rawString(). + * util.parse(m.rawString(), country).equals(m.number()); + * </pre> + */ +public final class PhoneNumberMatch { + /** The start index into the text. */ + private final int start; + /** The raw substring matched. */ + private final String rawString; + /** The matched phone number. */ + private final PhoneNumber number; + + /** + * Creates a new match. + * + * @param start the start index into the target text + * @param rawString the matched substring of the target text + * @param number the matched phone number + */ + PhoneNumberMatch(int start, String rawString, PhoneNumber number) { + if (start < 0) { + throw new IllegalArgumentException("Start index must be >= 0."); + } + if (rawString == null || number == null) { + throw new NullPointerException(); + } + this.start = start; + this.rawString = rawString; + this.number = number; + } + + /** Returns the phone number matched by the receiver. */ + public PhoneNumber number() { + return number; + } + + /** Returns the start index of the matched phone number within the searched text. */ + public int start() { + return start; + } + + /** Returns the exclusive end index of the matched phone number within the searched text. */ + public int end() { + return start + rawString.length(); + } + + /** Returns the raw string matched as a phone number in the searched text. */ + public String rawString() { + return rawString; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[]{start, rawString, number}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PhoneNumberMatch)) { + return false; + } + PhoneNumberMatch other = (PhoneNumberMatch) obj; + return rawString.equals(other.rawString) && (start == other.start) && + number.equals(other.number); + } + + @Override + public String toString() { + return "PhoneNumberMatch [" + start() + "," + end() + ") " + rawString; + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java b/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java new file mode 100644 index 00000000..34e8d163 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java @@ -0,0 +1,725 @@ +/* + * Copyright (C) 2011 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import com.google.i18n.phonenumbers.PhoneNumberUtil.Leniency; +import com.google.i18n.phonenumbers.PhoneNumberUtil.MatchType; +import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat; +import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; + +import java.lang.Character.UnicodeBlock; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A stateful class that finds and extracts telephone numbers from {@linkplain CharSequence text}. + * Instances can be created using the {@linkplain PhoneNumberUtil#findNumbers factory methods} in + * {@link PhoneNumberUtil}. + * + * <p>Vanity numbers (phone numbers using alphabetic digits such as <tt>1-800-SIX-FLAGS</tt> are + * not found. + * + * <p>This class is not thread-safe. + */ +final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> { + /** + * The phone number pattern used by {@link #find}, similar to + * {@code PhoneNumberUtil.VALID_PHONE_NUMBER}, but with the following differences: + * <ul> + * <li>All captures are limited in order to place an upper bound to the text matched by the + * pattern. + * <ul> + * <li>Leading punctuation / plus signs are limited. + * <li>Consecutive occurrences of punctuation are limited. + * <li>Number of digits is limited. + * </ul> + * <li>No whitespace is allowed at the start or end. + * <li>No alpha digits (vanity numbers such as 1-800-SIX-FLAGS) are currently supported. + * </ul> + */ + private static final Pattern PATTERN; + /** + * Matches strings that look like publication pages. Example: + * <pre>Computing Complete Answers to Queries in the Presence of Limited Access Patterns. + * Chen Li. VLDB J. 12(3): 211-227 (2003).</pre> + * + * The string "211-227 (2003)" is not a telephone number. + */ + private static final Pattern PUB_PAGES = Pattern.compile("\\d{1,5}-+\\d{1,5}\\s{0,4}\\(\\d{1,4}"); + + /** + * Matches strings that look like dates using "/" as a separator. Examples: 3/10/2011, 31/10/96 or + * 08/31/95. + */ + private static final Pattern SLASH_SEPARATED_DATES = + Pattern.compile("(?:(?:[0-3]?\\d/[01]?\\d)|(?:[01]?\\d/[0-3]?\\d))/(?:[12]\\d)?\\d{2}"); + + /** + * Matches timestamps. Examples: "2012-01-02 08:00". Note that the reg-ex does not include the + * trailing ":\d\d" -- that is covered by TIME_STAMPS_SUFFIX. + */ + private static final Pattern TIME_STAMPS = + Pattern.compile("[12]\\d{3}[-/]?[01]\\d[-/]?[0-3]\\d +[0-2]\\d$"); + private static final Pattern TIME_STAMPS_SUFFIX = Pattern.compile(":[0-5]\\d"); + + /** + * Pattern to check that brackets match. Opening brackets should be closed within a phone number. + * This also checks that there is something inside the brackets. Having no brackets at all is also + * fine. + */ + private static final Pattern MATCHING_BRACKETS; + + /** + * Patterns used to extract phone numbers from a larger phone-number-like pattern. These are + * ordered according to specificity. For example, white-space is last since that is frequently + * used in numbers, not just to separate two numbers. We have separate patterns since we don't + * want to break up the phone-number-like text on more than one different kind of symbol at one + * time, although symbols of the same type (e.g. space) can be safely grouped together. + * + * Note that if there is a match, we will always check any text found up to the first match as + * well. + */ + private static final Pattern[] INNER_MATCHES = { + // Breaks on the slash - e.g. "651-234-2345/332-445-1234" + Pattern.compile("/+(.*)"), + // Note that the bracket here is inside the capturing group, since we consider it part of the + // phone number. Will match a pattern like "(650) 223 3345 (754) 223 3321". + Pattern.compile("(\\([^(]*)"), + // Breaks on a hyphen - e.g. "12345 - 332-445-1234 is my number." + // We require a space on either side of the hyphen for it to be considered a separator. + Pattern.compile("(?:\\p{Z}-|-\\p{Z})\\p{Z}*(.+)"), + // Various types of wide hyphens. Note we have decided not to enforce a space here, since it's + // possible that it's supposed to be used to break two numbers without spaces, and we haven't + // seen many instances of it used within a number. + Pattern.compile("[\u2012-\u2015\uFF0D]\\p{Z}*(.+)"), + // Breaks on a full stop - e.g. "12345. 332-445-1234 is my number." + Pattern.compile("\\.+\\p{Z}*([^.]+)"), + // Breaks on space - e.g. "3324451234 8002341234" + Pattern.compile("\\p{Z}+(\\P{Z}+)") + }; + + /** + * Punctuation that may be at the start of a phone number - brackets and plus signs. + */ + private static final Pattern LEAD_CLASS; + + static { + /* Builds the MATCHING_BRACKETS and PATTERN regular expressions. The building blocks below exist + * to make the pattern more easily understood. */ + + String openingParens = "(\\[\uFF08\uFF3B"; + String closingParens = ")\\]\uFF09\uFF3D"; + String nonParens = "[^" + openingParens + closingParens + "]"; + + /* Limit on the number of pairs of brackets in a phone number. */ + String bracketPairLimit = limit(0, 3); + /* + * An opening bracket at the beginning may not be closed, but subsequent ones should be. It's + * also possible that the leading bracket was dropped, so we shouldn't be surprised if we see a + * closing bracket first. We limit the sets of brackets in a phone number to four. + */ + MATCHING_BRACKETS = Pattern.compile( + "(?:[" + openingParens + "])?" + "(?:" + nonParens + "+" + "[" + closingParens + "])?" + + nonParens + "+" + + "(?:[" + openingParens + "]" + nonParens + "+[" + closingParens + "])" + bracketPairLimit + + nonParens + "*"); + + /* Limit on the number of leading (plus) characters. */ + String leadLimit = limit(0, 2); + /* Limit on the number of consecutive punctuation characters. */ + String punctuationLimit = limit(0, 4); + /* The maximum number of digits allowed in a digit-separated block. As we allow all digits in a + * single block, set high enough to accommodate the entire national number and the international + * country code. */ + int digitBlockLimit = + PhoneNumberUtil.MAX_LENGTH_FOR_NSN + PhoneNumberUtil.MAX_LENGTH_COUNTRY_CODE; + /* Limit on the number of blocks separated by punctuation. Uses digitBlockLimit since some + * formats use spaces to separate each digit. */ + String blockLimit = limit(0, digitBlockLimit); + + /* A punctuation sequence allowing white space. */ + String punctuation = "[" + PhoneNumberUtil.VALID_PUNCTUATION + "]" + punctuationLimit; + /* A digits block without punctuation. */ + String digitSequence = "\\p{Nd}" + limit(1, digitBlockLimit); + + String leadClassChars = openingParens + PhoneNumberUtil.PLUS_CHARS; + String leadClass = "[" + leadClassChars + "]"; + LEAD_CLASS = Pattern.compile(leadClass); + + /* Phone number pattern allowing optional punctuation. */ + PATTERN = Pattern.compile( + "(?:" + leadClass + punctuation + ")" + leadLimit + + digitSequence + "(?:" + punctuation + digitSequence + ")" + blockLimit + + "(?:" + PhoneNumberUtil.EXTN_PATTERNS_FOR_MATCHING + ")?", + PhoneNumberUtil.REGEX_FLAGS); + } + + /** Returns a regular expression quantifier with an upper and lower limit. */ + private static String limit(int lower, int upper) { + if ((lower < 0) || (upper <= 0) || (upper < lower)) { + throw new IllegalArgumentException(); + } + return "{" + lower + "," + upper + "}"; + } + + /** The potential states of a PhoneNumberMatcher. */ + private enum State { + NOT_READY, READY, DONE + } + + /** The phone number utility. */ + private final PhoneNumberUtil phoneUtil; + /** The text searched for phone numbers. */ + private final CharSequence text; + /** + * The region (country) to assume for phone numbers without an international prefix, possibly + * null. + */ + private final String preferredRegion; + /** The degree of validation requested. */ + private final Leniency leniency; + /** The maximum number of retries after matching an invalid number. */ + private long maxTries; + + /** The iteration tristate. */ + private State state = State.NOT_READY; + /** The last successful match, null unless in {@link State#READY}. */ + private PhoneNumberMatch lastMatch = null; + /** The next index to start searching at. Undefined in {@link State#DONE}. */ + private int searchIndex = 0; + + /** + * Creates a new instance. See the factory methods in {@link PhoneNumberUtil} on how to obtain a + * new instance. + * + * @param util the phone number util to use + * @param text the character sequence that we will search, null for no text + * @param country the country to assume for phone numbers not written in international format + * (with a leading plus, or with the international dialing prefix of the + * specified region). May be null or "ZZ" if only numbers with a + * leading plus should be considered. + * @param leniency the leniency to use when evaluating candidate phone numbers + * @param maxTries the maximum number of invalid numbers to try before giving up on the text. + * This is to cover degenerate cases where the text has a lot of false positives + * in it. Must be {@code >= 0}. + */ + PhoneNumberMatcher(PhoneNumberUtil util, CharSequence text, String country, Leniency leniency, + long maxTries) { + + if ((util == null) || (leniency == null)) { + throw new NullPointerException(); + } + if (maxTries < 0) { + throw new IllegalArgumentException(); + } + this.phoneUtil = util; + this.text = (text != null) ? text : ""; + this.preferredRegion = country; + this.leniency = leniency; + this.maxTries = maxTries; + } + + /** + * Attempts to find the next subsequence in the searched sequence on or after {@code searchIndex} + * that represents a phone number. Returns the next match, null if none was found. + * + * @param index the search index to start searching at + * @return the phone number match found, null if none can be found + */ + private PhoneNumberMatch find(int index) { + Matcher matcher = PATTERN.matcher(text); + while ((maxTries > 0) && matcher.find(index)) { + int start = matcher.start(); + CharSequence candidate = text.subSequence(start, matcher.end()); + + // Check for extra numbers at the end. + // TODO: This is the place to start when trying to support extraction of multiple phone number + // from split notations (+41 79 123 45 67 / 68). + candidate = trimAfterFirstMatch(PhoneNumberUtil.SECOND_NUMBER_START_PATTERN, candidate); + + PhoneNumberMatch match = extractMatch(candidate, start); + if (match != null) { + return match; + } + + index = start + candidate.length(); + maxTries--; + } + + return null; + } + + /** + * Trims away any characters after the first match of {@code pattern} in {@code candidate}, + * returning the trimmed version. + */ + private static CharSequence trimAfterFirstMatch(Pattern pattern, CharSequence candidate) { + Matcher trailingCharsMatcher = pattern.matcher(candidate); + if (trailingCharsMatcher.find()) { + candidate = candidate.subSequence(0, trailingCharsMatcher.start()); + } + return candidate; + } + + /** + * Helper method to determine if a character is a Latin-script letter or not. For our purposes, + * combining marks should also return true since we assume they have been added to a preceding + * Latin character. + */ + // @VisibleForTesting + static boolean isLatinLetter(char letter) { + // Combining marks are a subset of non-spacing-mark. + if (!Character.isLetter(letter) && Character.getType(letter) != Character.NON_SPACING_MARK) { + return false; + } + UnicodeBlock block = UnicodeBlock.of(letter); + return block.equals(UnicodeBlock.BASIC_LATIN) || + block.equals(UnicodeBlock.LATIN_1_SUPPLEMENT) || + block.equals(UnicodeBlock.LATIN_EXTENDED_A) || + block.equals(UnicodeBlock.LATIN_EXTENDED_ADDITIONAL) || + block.equals(UnicodeBlock.LATIN_EXTENDED_B) || + block.equals(UnicodeBlock.COMBINING_DIACRITICAL_MARKS); + } + + private static boolean isInvalidPunctuationSymbol(char character) { + return character == '%' || Character.getType(character) == Character.CURRENCY_SYMBOL; + } + + /** + * Attempts to extract a match from a {@code candidate} character sequence. + * + * @param candidate the candidate text that might contain a phone number + * @param offset the offset of {@code candidate} within {@link #text} + * @return the match found, null if none can be found + */ + private PhoneNumberMatch extractMatch(CharSequence candidate, int offset) { + // Skip a match that is more likely to be a date. + if (SLASH_SEPARATED_DATES.matcher(candidate).find()) { + return null; + } + + // Skip potential time-stamps. + if (TIME_STAMPS.matcher(candidate).find()) { + String followingText = text.toString().substring(offset + candidate.length()); + if (TIME_STAMPS_SUFFIX.matcher(followingText).lookingAt()) { + return null; + } + } + + // Try to come up with a valid match given the entire candidate. + String rawString = candidate.toString(); + PhoneNumberMatch match = parseAndVerify(rawString, offset); + if (match != null) { + return match; + } + + // If that failed, try to find an "inner match" - there might be a phone number within this + // candidate. + return extractInnerMatch(rawString, offset); + } + + /** + * Attempts to extract a match from {@code candidate} if the whole candidate does not qualify as a + * match. + * + * @param candidate the candidate text that might contain a phone number + * @param offset the current offset of {@code candidate} within {@link #text} + * @return the match found, null if none can be found + */ + private PhoneNumberMatch extractInnerMatch(String candidate, int offset) { + for (Pattern possibleInnerMatch : INNER_MATCHES) { + int rangeStart = 0; + Matcher groupMatcher = possibleInnerMatch.matcher(candidate); + boolean isFirstMatch = true; + while (groupMatcher.find() && maxTries > 0) { + if (isFirstMatch) { + // We should handle any group before this one too. + CharSequence group = trimAfterFirstMatch( + PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN, + candidate.substring(0, groupMatcher.start())); + PhoneNumberMatch match = parseAndVerify(group.toString(), offset); + if (match != null) { + return match; + } + maxTries--; + isFirstMatch = false; + } + CharSequence group = trimAfterFirstMatch( + PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN, groupMatcher.group(1)); + PhoneNumberMatch match = parseAndVerify(group.toString(), offset + groupMatcher.start(1)); + if (match != null) { + return match; + } + maxTries--; + } + } + return null; + } + + /** + * Parses a phone number from the {@code candidate} using {@link PhoneNumberUtil#parse} and + * verifies it matches the requested {@link #leniency}. If parsing and verification succeed, a + * corresponding {@link PhoneNumberMatch} is returned, otherwise this method returns null. + * + * @param candidate the candidate match + * @param offset the offset of {@code candidate} within {@link #text} + * @return the parsed and validated phone number match, or null + */ + private PhoneNumberMatch parseAndVerify(String candidate, int offset) { + try { + // Check the candidate doesn't contain any formatting which would indicate that it really + // isn't a phone number. + if (!MATCHING_BRACKETS.matcher(candidate).matches() || PUB_PAGES.matcher(candidate).find()) { + return null; + } + + // If leniency is set to VALID or stricter, we also want to skip numbers that are surrounded + // by Latin alphabetic characters, to skip cases like abc8005001234 or 8005001234def. + if (leniency.compareTo(Leniency.VALID) >= 0) { + // If the candidate is not at the start of the text, and does not start with phone-number + // punctuation, check the previous character. + if (offset > 0 && !LEAD_CLASS.matcher(candidate).lookingAt()) { + char previousChar = text.charAt(offset - 1); + // We return null if it is a latin letter or an invalid punctuation symbol. + if (isInvalidPunctuationSymbol(previousChar) || isLatinLetter(previousChar)) { + return null; + } + } + int lastCharIndex = offset + candidate.length(); + if (lastCharIndex < text.length()) { + char nextChar = text.charAt(lastCharIndex); + if (isInvalidPunctuationSymbol(nextChar) || isLatinLetter(nextChar)) { + return null; + } + } + } + + PhoneNumber number = phoneUtil.parseAndKeepRawInput(candidate, preferredRegion); + + // Check Israel * numbers: these are a special case in that they are four-digit numbers that + // our library supports, but they can only be dialled with a leading *. Since we don't + // actually store or detect the * in our phone number library, this means in practice we + // detect most four digit numbers as being valid for Israel. We are considering moving these + // numbers to ShortNumberInfo instead, in which case this problem would go away, but in the + // meantime we want to restrict the false matches so we only allow these numbers if they are + // preceded by a star. We enforce this for all leniency levels even though these numbers are + // technically accepted by isPossibleNumber and isValidNumber since we consider it to be a + // deficiency in those methods that they accept these numbers without the *. + // TODO: Remove this or make it significantly less hacky once we've decided how to + // handle these short codes going forward in ShortNumberInfo. We could use the formatting + // rules for instance, but that would be slower. + if (phoneUtil.getRegionCodeForCountryCode(number.getCountryCode()).equals("IL") && + phoneUtil.getNationalSignificantNumber(number).length() == 4 && + (offset == 0 || (offset > 0 && text.charAt(offset - 1) != '*'))) { + // No match. + return null; + } + + if (leniency.verify(number, candidate, phoneUtil)) { + // We used parseAndKeepRawInput to create this number, but for now we don't return the extra + // values parsed. TODO: stop clearing all values here and switch all users over + // to using rawInput() rather than the rawString() of PhoneNumberMatch. + number.clearCountryCodeSource(); + number.clearRawInput(); + number.clearPreferredDomesticCarrierCode(); + return new PhoneNumberMatch(offset, candidate, number); + } + } catch (NumberParseException e) { + // ignore and continue + } + return null; + } + + /** + * Small helper interface such that the number groups can be checked according to different + * criteria, both for our default way of performing formatting and for any alternate formats we + * may want to check. + */ + interface NumberGroupingChecker { + /** + * Returns true if the groups of digits found in our candidate phone number match our + * expectations. + * + * @param number the original number we found when parsing + * @param normalizedCandidate the candidate number, normalized to only contain ASCII digits, + * but with non-digits (spaces etc) retained + * @param expectedNumberGroups the groups of digits that we would expect to see if we + * formatted this number + */ + boolean checkGroups(PhoneNumberUtil util, PhoneNumber number, + StringBuilder normalizedCandidate, String[] expectedNumberGroups); + } + + static boolean allNumberGroupsRemainGrouped(PhoneNumberUtil util, + PhoneNumber number, + StringBuilder normalizedCandidate, + String[] formattedNumberGroups) { + int fromIndex = 0; + if (number.getCountryCodeSource() != CountryCodeSource.FROM_DEFAULT_COUNTRY) { + // First skip the country code if the normalized candidate contained it. + String countryCode = Integer.toString(number.getCountryCode()); + fromIndex = normalizedCandidate.indexOf(countryCode) + countryCode.length(); + } + // Check each group of consecutive digits are not broken into separate groupings in the + // {@code normalizedCandidate} string. + for (int i = 0; i < formattedNumberGroups.length; i++) { + // Fails if the substring of {@code normalizedCandidate} starting from {@code fromIndex} + // doesn't contain the consecutive digits in formattedNumberGroups[i]. + fromIndex = normalizedCandidate.indexOf(formattedNumberGroups[i], fromIndex); + if (fromIndex < 0) { + return false; + } + // Moves {@code fromIndex} forward. + fromIndex += formattedNumberGroups[i].length(); + if (i == 0 && fromIndex < normalizedCandidate.length()) { + // We are at the position right after the NDC. We get the region used for formatting + // information based on the country code in the phone number, rather than the number itself, + // as we do not need to distinguish between different countries with the same country + // calling code and this is faster. + String region = util.getRegionCodeForCountryCode(number.getCountryCode()); + if (util.getNddPrefixForRegion(region, true) != null && + Character.isDigit(normalizedCandidate.charAt(fromIndex))) { + // This means there is no formatting symbol after the NDC. In this case, we only + // accept the number if there is no formatting symbol at all in the number, except + // for extensions. This is only important for countries with national prefixes. + String nationalSignificantNumber = util.getNationalSignificantNumber(number); + return normalizedCandidate.substring(fromIndex - formattedNumberGroups[i].length()) + .startsWith(nationalSignificantNumber); + } + } + } + // The check here makes sure that we haven't mistakenly already used the extension to + // match the last group of the subscriber number. Note the extension cannot have + // formatting in-between digits. + return normalizedCandidate.substring(fromIndex).contains(number.getExtension()); + } + + static boolean allNumberGroupsAreExactlyPresent(PhoneNumberUtil util, + PhoneNumber number, + StringBuilder normalizedCandidate, + String[] formattedNumberGroups) { + String[] candidateGroups = + PhoneNumberUtil.NON_DIGITS_PATTERN.split(normalizedCandidate.toString()); + // Set this to the last group, skipping it if the number has an extension. + int candidateNumberGroupIndex = + number.hasExtension() ? candidateGroups.length - 2 : candidateGroups.length - 1; + // First we check if the national significant number is formatted as a block. + // We use contains and not equals, since the national significant number may be present with + // a prefix such as a national number prefix, or the country code itself. + if (candidateGroups.length == 1 || + candidateGroups[candidateNumberGroupIndex].contains( + util.getNationalSignificantNumber(number))) { + return true; + } + // Starting from the end, go through in reverse, excluding the first group, and check the + // candidate and number groups are the same. + for (int formattedNumberGroupIndex = (formattedNumberGroups.length - 1); + formattedNumberGroupIndex > 0 && candidateNumberGroupIndex >= 0; + formattedNumberGroupIndex--, candidateNumberGroupIndex--) { + if (!candidateGroups[candidateNumberGroupIndex].equals( + formattedNumberGroups[formattedNumberGroupIndex])) { + return false; + } + } + // Now check the first group. There may be a national prefix at the start, so we only check + // that the candidate group ends with the formatted number group. + return (candidateNumberGroupIndex >= 0 && + candidateGroups[candidateNumberGroupIndex].endsWith(formattedNumberGroups[0])); + } + + /** + * Helper method to get the national-number part of a number, formatted without any national + * prefix, and return it as a set of digit blocks that would be formatted together. + */ + private static String[] getNationalNumberGroups(PhoneNumberUtil util, PhoneNumber number, + NumberFormat formattingPattern) { + if (formattingPattern == null) { + // This will be in the format +CC-DG;ext=EXT where DG represents groups of digits. + String rfc3966Format = util.format(number, PhoneNumberFormat.RFC3966); + // We remove the extension part from the formatted string before splitting it into different + // groups. + int endIndex = rfc3966Format.indexOf(';'); + if (endIndex < 0) { + endIndex = rfc3966Format.length(); + } + // The country-code will have a '-' following it. + int startIndex = rfc3966Format.indexOf('-') + 1; + return rfc3966Format.substring(startIndex, endIndex).split("-"); + } else { + // We format the NSN only, and split that according to the separator. + String nationalSignificantNumber = util.getNationalSignificantNumber(number); + return util.formatNsnUsingPattern(nationalSignificantNumber, + formattingPattern, PhoneNumberFormat.RFC3966).split("-"); + } + } + + static boolean checkNumberGroupingIsValid( + PhoneNumber number, String candidate, PhoneNumberUtil util, NumberGroupingChecker checker) { + // TODO: Evaluate how this works for other locales (testing has been limited to NANPA regions) + // and optimise if necessary. + StringBuilder normalizedCandidate = + PhoneNumberUtil.normalizeDigits(candidate, true /* keep non-digits */); + String[] formattedNumberGroups = getNationalNumberGroups(util, number, null); + if (checker.checkGroups(util, number, normalizedCandidate, formattedNumberGroups)) { + return true; + } + // If this didn't pass, see if there are any alternate formats, and try them instead. + PhoneMetadata alternateFormats = + MetadataManager.getAlternateFormatsForCountry(number.getCountryCode()); + if (alternateFormats != null) { + for (NumberFormat alternateFormat : alternateFormats.numberFormats()) { + formattedNumberGroups = getNationalNumberGroups(util, number, alternateFormat); + if (checker.checkGroups(util, number, normalizedCandidate, formattedNumberGroups)) { + return true; + } + } + } + return false; + } + + static boolean containsMoreThanOneSlashInNationalNumber(PhoneNumber number, String candidate) { + int firstSlashInBodyIndex = candidate.indexOf('/'); + if (firstSlashInBodyIndex < 0) { + // No slashes, this is okay. + return false; + } + // Now look for a second one. + int secondSlashInBodyIndex = candidate.indexOf('/', firstSlashInBodyIndex + 1); + if (secondSlashInBodyIndex < 0) { + // Only one slash, this is okay. + return false; + } + + // If the first slash is after the country calling code, this is permitted. + boolean candidateHasCountryCode = + (number.getCountryCodeSource() == CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN || + number.getCountryCodeSource() == CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN); + if (candidateHasCountryCode && + PhoneNumberUtil.normalizeDigitsOnly(candidate.substring(0, firstSlashInBodyIndex)) + .equals(Integer.toString(number.getCountryCode()))) { + // Any more slashes and this is illegal. + return candidate.substring(secondSlashInBodyIndex + 1).contains("/"); + } + return true; + } + + static boolean containsOnlyValidXChars( + PhoneNumber number, String candidate, PhoneNumberUtil util) { + // The characters 'x' and 'X' can be (1) a carrier code, in which case they always precede the + // national significant number or (2) an extension sign, in which case they always precede the + // extension number. We assume a carrier code is more than 1 digit, so the first case has to + // have more than 1 consecutive 'x' or 'X', whereas the second case can only have exactly 1 'x' + // or 'X'. We ignore the character if it appears as the last character of the string. + for (int index = 0; index < candidate.length() - 1; index++) { + char charAtIndex = candidate.charAt(index); + if (charAtIndex == 'x' || charAtIndex == 'X') { + char charAtNextIndex = candidate.charAt(index + 1); + if (charAtNextIndex == 'x' || charAtNextIndex == 'X') { + // This is the carrier code case, in which the 'X's always precede the national + // significant number. + index++; + if (util.isNumberMatch(number, candidate.substring(index)) != MatchType.NSN_MATCH) { + return false; + } + // This is the extension sign case, in which the 'x' or 'X' should always precede the + // extension number. + } else if (!PhoneNumberUtil.normalizeDigitsOnly(candidate.substring(index)).equals( + number.getExtension())) { + return false; + } + } + } + return true; + } + + static boolean isNationalPrefixPresentIfRequired(PhoneNumber number, PhoneNumberUtil util) { + // First, check how we deduced the country code. If it was written in international format, then + // the national prefix is not required. + if (number.getCountryCodeSource() != CountryCodeSource.FROM_DEFAULT_COUNTRY) { + return true; + } + String phoneNumberRegion = + util.getRegionCodeForCountryCode(number.getCountryCode()); + PhoneMetadata metadata = util.getMetadataForRegion(phoneNumberRegion); + if (metadata == null) { + return true; + } + // Check if a national prefix should be present when formatting this number. + String nationalNumber = util.getNationalSignificantNumber(number); + NumberFormat formatRule = + util.chooseFormattingPatternForNumber(metadata.numberFormats(), nationalNumber); + // To do this, we check that a national prefix formatting rule was present and that it wasn't + // just the first-group symbol ($1) with punctuation. + if ((formatRule != null) && formatRule.getNationalPrefixFormattingRule().length() > 0) { + if (formatRule.isNationalPrefixOptionalWhenFormatting()) { + // The national-prefix is optional in these cases, so we don't need to check if it was + // present. + return true; + } + if (PhoneNumberUtil.formattingRuleHasFirstGroupOnly( + formatRule.getNationalPrefixFormattingRule())) { + // National Prefix not needed for this number. + return true; + } + // Normalize the remainder. + String rawInputCopy = PhoneNumberUtil.normalizeDigitsOnly(number.getRawInput()); + StringBuilder rawInput = new StringBuilder(rawInputCopy); + // Check if we found a national prefix and/or carrier code at the start of the raw input, and + // return the result. + return util.maybeStripNationalPrefixAndCarrierCode(rawInput, metadata, null); + } + return true; + } + + public boolean hasNext() { + if (state == State.NOT_READY) { + lastMatch = find(searchIndex); + if (lastMatch == null) { + state = State.DONE; + } else { + searchIndex = lastMatch.end(); + state = State.READY; + } + } + return state == State.READY; + } + + public PhoneNumberMatch next() { + // Check the state and find the next match as a side-effect if necessary. + if (!hasNext()) { + throw new NoSuchElementException(); + } + + // Don't retain that memory any longer than necessary. + PhoneNumberMatch result = lastMatch; + lastMatch = null; + state = State.NOT_READY; + return result; + } + + /** + * Always throws {@link UnsupportedOperationException} as removal is not supported. + */ + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java new file mode 100644 index 00000000..418164a8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java @@ -0,0 +1,3232 @@ +/* + * Copyright (C) 2009 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Utility for international phone numbers. Functionality includes formatting, parsing and + * validation. + * + * <p>If you use this library, and want to be notified about important changes, please sign up to + * our <a href="http://groups.google.com/group/libphonenumber-discuss/about">mailing list</a>. + * + * NOTE: A lot of methods in this class require Region Code strings. These must be provided using + * ISO 3166-1 two-letter country-code format. These should be in upper-case. The list of the codes + * can be found here: + * http://www.iso.org/iso/country_codes/iso_3166_code_lists/country_names_and_code_elements.htm + * + * @author Shaopeng Jia + */ +public class PhoneNumberUtil { + // @VisibleForTesting + static final MetadataLoader DEFAULT_METADATA_LOADER = new MetadataLoader() { + public InputStream loadMetadata(String metadataFileName) { + return PhoneNumberUtil.class.getResourceAsStream(metadataFileName); + } + }; + + private static final Logger logger = Logger.getLogger(PhoneNumberUtil.class.getName()); + + /** Flags to use when compiling regular expressions for phone numbers. */ + static final int REGEX_FLAGS = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE; + // The minimum and maximum length of the national significant number. + private static final int MIN_LENGTH_FOR_NSN = 2; + // The ITU says the maximum length should be 15, but we have found longer numbers in Germany. + static final int MAX_LENGTH_FOR_NSN = 17; + // The maximum length of the country calling code. + static final int MAX_LENGTH_COUNTRY_CODE = 3; + // We don't allow input strings for parsing to be longer than 250 chars. This prevents malicious + // input from overflowing the regular-expression engine. + private static final int MAX_INPUT_STRING_LENGTH = 250; + + private static final String META_DATA_FILE_PREFIX = + "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto"; + + // Region-code for the unknown region. + private static final String UNKNOWN_REGION = "ZZ"; + + private static final int NANPA_COUNTRY_CODE = 1; + + // The prefix that needs to be inserted in front of a Colombian landline number when dialed from + // a mobile phone in Colombia. + private static final String COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX = "3"; + + // Map of country calling codes that use a mobile token before the area code. One example of when + // this is relevant is when determining the length of the national destination code, which should + // be the length of the area code plus the length of the mobile token. + private static final Map<Integer, String> MOBILE_TOKEN_MAPPINGS; + + // The PLUS_SIGN signifies the international prefix. + static final char PLUS_SIGN = '+'; + + private static final char STAR_SIGN = '*'; + + private static final String RFC3966_EXTN_PREFIX = ";ext="; + private static final String RFC3966_PREFIX = "tel:"; + private static final String RFC3966_PHONE_CONTEXT = ";phone-context="; + private static final String RFC3966_ISDN_SUBADDRESS = ";isub="; + + // A map that contains characters that are essential when dialling. That means any of the + // characters in this map must not be removed from a number when dialling, otherwise the call + // will not reach the intended destination. + private static final Map<Character, Character> DIALLABLE_CHAR_MAPPINGS; + + // Only upper-case variants of alpha characters are stored. + private static final Map<Character, Character> ALPHA_MAPPINGS; + + // For performance reasons, amalgamate both into one map. + private static final Map<Character, Character> ALPHA_PHONE_MAPPINGS; + + // Separate map of all symbols that we wish to retain when formatting alpha numbers. This + // includes digits, ASCII letters and number grouping symbols such as "-" and " ". + private static final Map<Character, Character> ALL_PLUS_NUMBER_GROUPING_SYMBOLS; + + static { + HashMap<Integer, String> mobileTokenMap = new HashMap<Integer, String>(); + mobileTokenMap.put(52, "1"); + mobileTokenMap.put(54, "9"); + MOBILE_TOKEN_MAPPINGS = Collections.unmodifiableMap(mobileTokenMap); + + // Simple ASCII digits map used to populate ALPHA_PHONE_MAPPINGS and + // ALL_PLUS_NUMBER_GROUPING_SYMBOLS. + HashMap<Character, Character> asciiDigitMappings = new HashMap<Character, Character>(); + asciiDigitMappings.put('0', '0'); + asciiDigitMappings.put('1', '1'); + asciiDigitMappings.put('2', '2'); + asciiDigitMappings.put('3', '3'); + asciiDigitMappings.put('4', '4'); + asciiDigitMappings.put('5', '5'); + asciiDigitMappings.put('6', '6'); + asciiDigitMappings.put('7', '7'); + asciiDigitMappings.put('8', '8'); + asciiDigitMappings.put('9', '9'); + + HashMap<Character, Character> alphaMap = new HashMap<Character, Character>(40); + alphaMap.put('A', '2'); + alphaMap.put('B', '2'); + alphaMap.put('C', '2'); + alphaMap.put('D', '3'); + alphaMap.put('E', '3'); + alphaMap.put('F', '3'); + alphaMap.put('G', '4'); + alphaMap.put('H', '4'); + alphaMap.put('I', '4'); + alphaMap.put('J', '5'); + alphaMap.put('K', '5'); + alphaMap.put('L', '5'); + alphaMap.put('M', '6'); + alphaMap.put('N', '6'); + alphaMap.put('O', '6'); + alphaMap.put('P', '7'); + alphaMap.put('Q', '7'); + alphaMap.put('R', '7'); + alphaMap.put('S', '7'); + alphaMap.put('T', '8'); + alphaMap.put('U', '8'); + alphaMap.put('V', '8'); + alphaMap.put('W', '9'); + alphaMap.put('X', '9'); + alphaMap.put('Y', '9'); + alphaMap.put('Z', '9'); + ALPHA_MAPPINGS = Collections.unmodifiableMap(alphaMap); + + HashMap<Character, Character> combinedMap = new HashMap<Character, Character>(100); + combinedMap.putAll(ALPHA_MAPPINGS); + combinedMap.putAll(asciiDigitMappings); + ALPHA_PHONE_MAPPINGS = Collections.unmodifiableMap(combinedMap); + + HashMap<Character, Character> diallableCharMap = new HashMap<Character, Character>(); + diallableCharMap.putAll(asciiDigitMappings); + diallableCharMap.put(PLUS_SIGN, PLUS_SIGN); + diallableCharMap.put('*', '*'); + DIALLABLE_CHAR_MAPPINGS = Collections.unmodifiableMap(diallableCharMap); + + HashMap<Character, Character> allPlusNumberGroupings = new HashMap<Character, Character>(); + // Put (lower letter -> upper letter) and (upper letter -> upper letter) mappings. + for (char c : ALPHA_MAPPINGS.keySet()) { + allPlusNumberGroupings.put(Character.toLowerCase(c), c); + allPlusNumberGroupings.put(c, c); + } + allPlusNumberGroupings.putAll(asciiDigitMappings); + // Put grouping symbols. + allPlusNumberGroupings.put('-', '-'); + allPlusNumberGroupings.put('\uFF0D', '-'); + allPlusNumberGroupings.put('\u2010', '-'); + allPlusNumberGroupings.put('\u2011', '-'); + allPlusNumberGroupings.put('\u2012', '-'); + allPlusNumberGroupings.put('\u2013', '-'); + allPlusNumberGroupings.put('\u2014', '-'); + allPlusNumberGroupings.put('\u2015', '-'); + allPlusNumberGroupings.put('\u2212', '-'); + allPlusNumberGroupings.put('/', '/'); + allPlusNumberGroupings.put('\uFF0F', '/'); + allPlusNumberGroupings.put(' ', ' '); + allPlusNumberGroupings.put('\u3000', ' '); + allPlusNumberGroupings.put('\u2060', ' '); + allPlusNumberGroupings.put('.', '.'); + allPlusNumberGroupings.put('\uFF0E', '.'); + ALL_PLUS_NUMBER_GROUPING_SYMBOLS = Collections.unmodifiableMap(allPlusNumberGroupings); + } + + // Pattern that makes it easy to distinguish whether a region has a unique international dialing + // prefix or not. If a region has a unique international prefix (e.g. 011 in USA), it will be + // represented as a string that contains a sequence of ASCII digits. If there are multiple + // available international prefixes in a region, they will be represented as a regex string that + // always contains character(s) other than ASCII digits. + // Note this regex also includes tilde, which signals waiting for the tone. + private static final Pattern UNIQUE_INTERNATIONAL_PREFIX = + Pattern.compile("[\\d]+(?:[~\u2053\u223C\uFF5E][\\d]+)?"); + + // Regular expression of acceptable punctuation found in phone numbers. This excludes punctuation + // found as a leading character only. + // This consists of dash characters, white space characters, full stops, slashes, + // square brackets, parentheses and tildes. It also includes the letter 'x' as that is found as a + // placeholder for carrier information in some phone numbers. Full-width variants are also + // present. + static final String VALID_PUNCTUATION = "-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F " + + "\u00A0\u00AD\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E"; + + private static final String DIGITS = "\\p{Nd}"; + // We accept alpha characters in phone numbers, ASCII only, upper and lower case. + private static final String VALID_ALPHA = + Arrays.toString(ALPHA_MAPPINGS.keySet().toArray()).replaceAll("[, \\[\\]]", "") + + Arrays.toString(ALPHA_MAPPINGS.keySet().toArray()).toLowerCase().replaceAll("[, \\[\\]]", ""); + static final String PLUS_CHARS = "+\uFF0B"; + static final Pattern PLUS_CHARS_PATTERN = Pattern.compile("[" + PLUS_CHARS + "]+"); + private static final Pattern SEPARATOR_PATTERN = Pattern.compile("[" + VALID_PUNCTUATION + "]+"); + private static final Pattern CAPTURING_DIGIT_PATTERN = Pattern.compile("(" + DIGITS + ")"); + + // Regular expression of acceptable characters that may start a phone number for the purposes of + // parsing. This allows us to strip away meaningless prefixes to phone numbers that may be + // mistakenly given to us. This consists of digits, the plus symbol and arabic-indic digits. This + // does not contain alpha characters, although they may be used later in the number. It also does + // not include other punctuation, as this will be stripped later during parsing and is of no + // information value when parsing a number. + private static final String VALID_START_CHAR = "[" + PLUS_CHARS + DIGITS + "]"; + private static final Pattern VALID_START_CHAR_PATTERN = Pattern.compile(VALID_START_CHAR); + + // Regular expression of characters typically used to start a second phone number for the purposes + // of parsing. This allows us to strip off parts of the number that are actually the start of + // another number, such as for: (530) 583-6985 x302/x2303 -> the second extension here makes this + // actually two phone numbers, (530) 583-6985 x302 and (530) 583-6985 x2303. We remove the second + // extension so that the first number is parsed correctly. + private static final String SECOND_NUMBER_START = "[\\\\/] *x"; + static final Pattern SECOND_NUMBER_START_PATTERN = Pattern.compile(SECOND_NUMBER_START); + + // Regular expression of trailing characters that we want to remove. We remove all characters that + // are not alpha or numerical characters. The hash character is retained here, as it may signify + // the previous block was an extension. + private static final String UNWANTED_END_CHARS = "[[\\P{N}&&\\P{L}]&&[^#]]+$"; + static final Pattern UNWANTED_END_CHAR_PATTERN = Pattern.compile(UNWANTED_END_CHARS); + + // We use this pattern to check if the phone number has at least three letters in it - if so, then + // we treat it as a number where some phone-number digits are represented by letters. + private static final Pattern VALID_ALPHA_PHONE_PATTERN = Pattern.compile("(?:.*?[A-Za-z]){3}.*"); + + // Regular expression of viable phone numbers. This is location independent. Checks we have at + // least three leading digits, and only valid punctuation, alpha characters and + // digits in the phone number. Does not include extension data. + // The symbol 'x' is allowed here as valid punctuation since it is often used as a placeholder for + // carrier codes, for example in Brazilian phone numbers. We also allow multiple "+" characters at + // the start. + // Corresponds to the following: + // [digits]{minLengthNsn}| + // plus_sign*(([punctuation]|[star])*[digits]){3,}([punctuation]|[star]|[digits]|[alpha])* + // + // The first reg-ex is to allow short numbers (two digits long) to be parsed if they are entered + // as "15" etc, but only if there is no punctuation in them. The second expression restricts the + // number of digits to three or more, but then allows them to be in international form, and to + // have alpha-characters and punctuation. + // + // Note VALID_PUNCTUATION starts with a -, so must be the first in the range. + private static final String VALID_PHONE_NUMBER = + DIGITS + "{" + MIN_LENGTH_FOR_NSN + "}" + "|" + + "[" + PLUS_CHARS + "]*+(?:[" + VALID_PUNCTUATION + STAR_SIGN + "]*" + DIGITS + "){3,}[" + + VALID_PUNCTUATION + STAR_SIGN + VALID_ALPHA + DIGITS + "]*"; + + // Default extension prefix to use when formatting. This will be put in front of any extension + // component of the number, after the main national number is formatted. For example, if you wish + // the default extension formatting to be " extn: 3456", then you should specify " extn: " here + // as the default extension prefix. This can be overridden by region-specific preferences. + private static final String DEFAULT_EXTN_PREFIX = " ext. "; + + // Pattern to capture digits used in an extension. Places a maximum length of "7" for an + // extension. + private static final String CAPTURING_EXTN_DIGITS = "(" + DIGITS + "{1,7})"; + // Regexp of all possible ways to write extensions, for use when parsing. This will be run as a + // case-insensitive regexp match. Wide character versions are also provided after each ASCII + // version. + private static final String EXTN_PATTERNS_FOR_PARSING; + static final String EXTN_PATTERNS_FOR_MATCHING; + static { + // One-character symbols that can be used to indicate an extension. + String singleExtnSymbolsForMatching = "x\uFF58#\uFF03~\uFF5E"; + // For parsing, we are slightly more lenient in our interpretation than for matching. Here we + // allow a "comma" as a possible extension indicator. When matching, this is hardly ever used to + // indicate this. + String singleExtnSymbolsForParsing = "," + singleExtnSymbolsForMatching; + + EXTN_PATTERNS_FOR_PARSING = createExtnPattern(singleExtnSymbolsForParsing); + EXTN_PATTERNS_FOR_MATCHING = createExtnPattern(singleExtnSymbolsForMatching); + } + + /** + * Helper initialiser method to create the regular-expression pattern to match extensions, + * allowing the one-char extension symbols provided by {@code singleExtnSymbols}. + */ + private static String createExtnPattern(String singleExtnSymbols) { + // There are three regular expressions here. The first covers RFC 3966 format, where the + // extension is added using ";ext=". The second more generic one starts with optional white + // space and ends with an optional full stop (.), followed by zero or more spaces/tabs and then + // the numbers themselves. The other one covers the special case of American numbers where the + // extension is written with a hash at the end, such as "- 503#". + // Note that the only capturing groups should be around the digits that you want to capture as + // part of the extension, or else parsing will fail! + // Canonical-equivalence doesn't seem to be an option with Android java, so we allow two options + // for representing the accented o - the character itself, and one in the unicode decomposed + // form with the combining acute accent. + return (RFC3966_EXTN_PREFIX + CAPTURING_EXTN_DIGITS + "|" + "[ \u00A0\\t,]*" + + "(?:e?xt(?:ensi(?:o\u0301?|\u00F3))?n?|\uFF45?\uFF58\uFF54\uFF4E?|" + + "[" + singleExtnSymbols + "]|int|anexo|\uFF49\uFF4E\uFF54)" + + "[:\\.\uFF0E]?[ \u00A0\\t,-]*" + CAPTURING_EXTN_DIGITS + "#?|" + + "[- ]+(" + DIGITS + "{1,5})#"); + } + + // Regexp of all known extension prefixes used by different regions followed by 1 or more valid + // digits, for use when parsing. + private static final Pattern EXTN_PATTERN = + Pattern.compile("(?:" + EXTN_PATTERNS_FOR_PARSING + ")$", REGEX_FLAGS); + + // We append optionally the extension pattern to the end here, as a valid phone number may + // have an extension prefix appended, followed by 1 or more digits. + private static final Pattern VALID_PHONE_NUMBER_PATTERN = + Pattern.compile(VALID_PHONE_NUMBER + "(?:" + EXTN_PATTERNS_FOR_PARSING + ")?", REGEX_FLAGS); + + static final Pattern NON_DIGITS_PATTERN = Pattern.compile("(\\D+)"); + + // The FIRST_GROUP_PATTERN was originally set to $1 but there are some countries for which the + // first group is not used in the national pattern (e.g. Argentina) so the $1 group does not match + // correctly. Therefore, we use \d, so that the first group actually used in the pattern will be + // matched. + private static final Pattern FIRST_GROUP_PATTERN = Pattern.compile("(\\$\\d)"); + private static final Pattern NP_PATTERN = Pattern.compile("\\$NP"); + private static final Pattern FG_PATTERN = Pattern.compile("\\$FG"); + private static final Pattern CC_PATTERN = Pattern.compile("\\$CC"); + + // A pattern that is used to determine if the national prefix formatting rule has the first group + // only, i.e., does not start with the national prefix. Note that the pattern explicitly allows + // for unbalanced parentheses. + private static final Pattern FIRST_GROUP_ONLY_PREFIX_PATTERN = Pattern.compile("\\(?\\$1\\)?"); + + private static PhoneNumberUtil instance = null; + + public static final String REGION_CODE_FOR_NON_GEO_ENTITY = "001"; + + /** + * INTERNATIONAL and NATIONAL formats are consistent with the definition in ITU-T Recommendation + * E123. For example, the number of the Google Switzerland office will be written as + * "+41 44 668 1800" in INTERNATIONAL format, and as "044 668 1800" in NATIONAL format. + * E164 format is as per INTERNATIONAL format but with no formatting applied, e.g. + * "+41446681800". RFC3966 is as per INTERNATIONAL format, but with all spaces and other + * separating symbols replaced with a hyphen, and with any phone number extension appended with + * ";ext=". It also will have a prefix of "tel:" added, e.g. "tel:+41-44-668-1800". + * + * Note: If you are considering storing the number in a neutral format, you are highly advised to + * use the PhoneNumber class. + */ + public enum PhoneNumberFormat { + E164, + INTERNATIONAL, + NATIONAL, + RFC3966 + } + + /** + * Type of phone numbers. + */ + public enum PhoneNumberType { + FIXED_LINE, + MOBILE, + // In some regions (e.g. the USA), it is impossible to distinguish between fixed-line and + // mobile numbers by looking at the phone number itself. + FIXED_LINE_OR_MOBILE, + // Freephone lines + TOLL_FREE, + PREMIUM_RATE, + // The cost of this call is shared between the caller and the recipient, and is hence typically + // less than PREMIUM_RATE calls. See // http://en.wikipedia.org/wiki/Shared_Cost_Service for + // more information. + SHARED_COST, + // Voice over IP numbers. This includes TSoIP (Telephony Service over IP). + VOIP, + // A personal number is associated with a particular person, and may be routed to either a + // MOBILE or FIXED_LINE number. Some more information can be found here: + // http://en.wikipedia.org/wiki/Personal_Numbers + PERSONAL_NUMBER, + PAGER, + // Used for "Universal Access Numbers" or "Company Numbers". They may be further routed to + // specific offices, but allow one number to be used for a company. + UAN, + // Used for "Voice Mail Access Numbers". + VOICEMAIL, + // A phone number is of type UNKNOWN when it does not fit any of the known patterns for a + // specific region. + UNKNOWN + } + + /** + * Types of phone number matches. See detailed description beside the isNumberMatch() method. + */ + public enum MatchType { + NOT_A_NUMBER, + NO_MATCH, + SHORT_NSN_MATCH, + NSN_MATCH, + EXACT_MATCH, + } + + /** + * Possible outcomes when testing if a PhoneNumber is possible. + */ + public enum ValidationResult { + IS_POSSIBLE, + INVALID_COUNTRY_CODE, + TOO_SHORT, + TOO_LONG, + } + + /** + * Leniency when {@linkplain PhoneNumberUtil#findNumbers finding} potential phone numbers in text + * segments. The levels here are ordered in increasing strictness. + */ + public enum Leniency { + /** + * Phone numbers accepted are {@linkplain PhoneNumberUtil#isPossibleNumber(PhoneNumber) + * possible}, but not necessarily {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid}. + */ + POSSIBLE { + @Override + boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) { + return util.isPossibleNumber(number); + } + }, + /** + * Phone numbers accepted are {@linkplain PhoneNumberUtil#isPossibleNumber(PhoneNumber) + * possible} and {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid}. Numbers written + * in national format must have their national-prefix present if it is usually written for a + * number of this type. + */ + VALID { + @Override + boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) { + if (!util.isValidNumber(number) || + !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate, util)) { + return false; + } + return PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util); + } + }, + /** + * Phone numbers accepted are {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid} and + * are grouped in a possible way for this locale. For example, a US number written as + * "65 02 53 00 00" and "650253 0000" are not accepted at this leniency level, whereas + * "650 253 0000", "650 2530000" or "6502530000" are. + * Numbers with more than one '/' symbol in the national significant number are also dropped at + * this level. + * <p> + * Warning: This level might result in lower coverage especially for regions outside of country + * code "+1". If you are not sure about which level to use, email the discussion group + * libphonenumber-discuss@googlegroups.com. + */ + STRICT_GROUPING { + @Override + boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) { + if (!util.isValidNumber(number) || + !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate, util) || + PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate) || + !PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util)) { + return false; + } + return PhoneNumberMatcher.checkNumberGroupingIsValid( + number, candidate, util, new PhoneNumberMatcher.NumberGroupingChecker() { + public boolean checkGroups(PhoneNumberUtil util, PhoneNumber number, + StringBuilder normalizedCandidate, + String[] expectedNumberGroups) { + return PhoneNumberMatcher.allNumberGroupsRemainGrouped( + util, number, normalizedCandidate, expectedNumberGroups); + } + }); + } + }, + /** + * Phone numbers accepted are {@linkplain PhoneNumberUtil#isValidNumber(PhoneNumber) valid} and + * are grouped in the same way that we would have formatted it, or as a single block. For + * example, a US number written as "650 2530000" is not accepted at this leniency level, whereas + * "650 253 0000" or "6502530000" are. + * Numbers with more than one '/' symbol are also dropped at this level. + * <p> + * Warning: This level might result in lower coverage especially for regions outside of country + * code "+1". If you are not sure about which level to use, email the discussion group + * libphonenumber-discuss@googlegroups.com. + */ + EXACT_GROUPING { + @Override + boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) { + if (!util.isValidNumber(number) || + !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate, util) || + PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate) || + !PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util)) { + return false; + } + return PhoneNumberMatcher.checkNumberGroupingIsValid( + number, candidate, util, new PhoneNumberMatcher.NumberGroupingChecker() { + public boolean checkGroups(PhoneNumberUtil util, PhoneNumber number, + StringBuilder normalizedCandidate, + String[] expectedNumberGroups) { + return PhoneNumberMatcher.allNumberGroupsAreExactlyPresent( + util, number, normalizedCandidate, expectedNumberGroups); + } + }); + } + }; + + /** Returns true if {@code number} is a verified number according to this leniency. */ + abstract boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util); + } + + // A mapping from a country calling code to the region codes which denote the region represented + // by that country calling code. In the case of multiple regions sharing a calling code, such as + // the NANPA regions, the one indicated with "isMainCountryForCode" in the metadata should be + // first. + private final Map<Integer, List<String>> countryCallingCodeToRegionCodeMap; + + // The set of regions that share country calling code 1. + // There are roughly 26 regions. + // We set the initial capacity of the HashSet to 35 to offer a load factor of roughly 0.75. + private final Set<String> nanpaRegions = new HashSet<String>(35); + + // A mapping from a region code to the PhoneMetadata for that region. + // Note: Synchronization, though only needed for the Android version of the library, is used in + // all versions for consistency. + private final Map<String, PhoneMetadata> regionToMetadataMap = + Collections.synchronizedMap(new HashMap<String, PhoneMetadata>()); + + // A mapping from a country calling code for a non-geographical entity to the PhoneMetadata for + // that country calling code. Examples of the country calling codes include 800 (International + // Toll Free Service) and 808 (International Shared Cost Service). + // Note: Synchronization, though only needed for the Android version of the library, is used in + // all versions for consistency. + private final Map<Integer, PhoneMetadata> countryCodeToNonGeographicalMetadataMap = + Collections.synchronizedMap(new HashMap<Integer, PhoneMetadata>()); + + // A cache for frequently used region-specific regular expressions. + // The initial capacity is set to 100 as this seems to be an optimal value for Android, based on + // performance measurements. + private final RegexCache regexCache = new RegexCache(100); + + // The set of regions the library supports. + // There are roughly 240 of them and we set the initial capacity of the HashSet to 320 to offer a + // load factor of roughly 0.75. + private final Set<String> supportedRegions = new HashSet<String>(320); + + // The set of county calling codes that map to the non-geo entity region ("001"). This set + // currently contains < 12 elements so the default capacity of 16 (load factor=0.75) is fine. + private final Set<Integer> countryCodesForNonGeographicalRegion = new HashSet<Integer>(); + + // The prefix of the metadata files from which region data is loaded. + private final String currentFilePrefix; + // The metadata loader used to inject alternative metadata sources. + private final MetadataLoader metadataLoader; + + /** + * This class implements a singleton, the constructor is only visible to facilitate testing. + */ + // @VisibleForTesting + PhoneNumberUtil(String filePrefix, MetadataLoader metadataLoader, + Map<Integer, List<String>> countryCallingCodeToRegionCodeMap) { + this.currentFilePrefix = filePrefix; + this.metadataLoader = metadataLoader; + this.countryCallingCodeToRegionCodeMap = countryCallingCodeToRegionCodeMap; + for (Map.Entry<Integer, List<String>> entry : countryCallingCodeToRegionCodeMap.entrySet()) { + List<String> regionCodes = entry.getValue(); + // We can assume that if the county calling code maps to the non-geo entity region code then + // that's the only region code it maps to. + if (regionCodes.size() == 1 && REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCodes.get(0))) { + // This is the subset of all country codes that map to the non-geo entity region code. + countryCodesForNonGeographicalRegion.add(entry.getKey()); + } else { + // The supported regions set does not include the "001" non-geo entity region code. + supportedRegions.addAll(regionCodes); + } + } + // If the non-geo entity still got added to the set of supported regions it must be because + // there are entries that list the non-geo entity alongside normal regions (which is wrong). + // If we discover this, remove the non-geo entity from the set of supported regions and log. + if (supportedRegions.remove(REGION_CODE_FOR_NON_GEO_ENTITY)) { + logger.log(Level.WARNING, "invalid metadata " + + "(country calling code was mapped to the non-geo entity as well as specific region(s))"); + } + nanpaRegions.addAll(countryCallingCodeToRegionCodeMap.get(NANPA_COUNTRY_CODE)); + } + + // @VisibleForTesting + void loadMetadataFromFile(String filePrefix, String regionCode, int countryCallingCode, + MetadataLoader metadataLoader) { + boolean isNonGeoRegion = REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode); + String fileName = filePrefix + "_" + + (isNonGeoRegion ? String.valueOf(countryCallingCode) : regionCode); + InputStream source = metadataLoader.loadMetadata(fileName); + if (source == null) { + logger.log(Level.SEVERE, "missing metadata: " + fileName); + throw new IllegalStateException("missing metadata: " + fileName); + } + ObjectInputStream in = null; + try { + in = new ObjectInputStream(source); + PhoneMetadataCollection metadataCollection = loadMetadataAndCloseInput(in); + List<PhoneMetadata> metadataList = metadataCollection.getMetadataList(); + if (metadataList.isEmpty()) { + logger.log(Level.SEVERE, "empty metadata: " + fileName); + throw new IllegalStateException("empty metadata: " + fileName); + } + if (metadataList.size() > 1) { + logger.log(Level.WARNING, "invalid metadata (too many entries): " + fileName); + } + PhoneMetadata metadata = metadataList.get(0); + if (isNonGeoRegion) { + countryCodeToNonGeographicalMetadataMap.put(countryCallingCode, metadata); + } else { + regionToMetadataMap.put(regionCode, metadata); + } + } catch (IOException e) { + logger.log(Level.SEVERE, "cannot load/parse metadata: " + fileName, e); + throw new RuntimeException("cannot load/parse metadata: " + fileName, e); + } + } + + /** + * Loads the metadata protocol buffer from the given stream and closes the stream afterwards. Any + * exceptions that occur while reading the stream are propagated (though exceptions that occur + * when the stream is closed will be ignored). + * + * @param source the non-null stream from which metadata is to be read. + * @return the loaded metadata protocol buffer. + */ + private static PhoneMetadataCollection loadMetadataAndCloseInput(ObjectInputStream source) { + PhoneMetadataCollection metadataCollection = new PhoneMetadataCollection(); + try { + metadataCollection.readExternal(source); + } catch (IOException e) { + logger.log(Level.WARNING, "error reading input (ignored)", e); + } finally { + try { + source.close(); + } catch (IOException e) { + logger.log(Level.WARNING, "error closing input stream (ignored)", e); + } finally { + return metadataCollection; + } + } + } + + /** + * Attempts to extract a possible number from the string passed in. This currently strips all + * leading characters that cannot be used to start a phone number. Characters that can be used to + * start a phone number are defined in the VALID_START_CHAR_PATTERN. If none of these characters + * are found in the number passed in, an empty string is returned. This function also attempts to + * strip off any alternative extensions or endings if two or more are present, such as in the case + * of: (530) 583-6985 x302/x2303. The second extension here makes this actually two phone numbers, + * (530) 583-6985 x302 and (530) 583-6985 x2303. We remove the second extension so that the first + * number is parsed correctly. + * + * @param number the string that might contain a phone number + * @return the number, stripped of any non-phone-number prefix (such as "Tel:") or an empty + * string if no character used to start phone numbers (such as + or any digit) is + * found in the number + */ + static String extractPossibleNumber(String number) { + Matcher m = VALID_START_CHAR_PATTERN.matcher(number); + if (m.find()) { + number = number.substring(m.start()); + // Remove trailing non-alpha non-numerical characters. + Matcher trailingCharsMatcher = UNWANTED_END_CHAR_PATTERN.matcher(number); + if (trailingCharsMatcher.find()) { + number = number.substring(0, trailingCharsMatcher.start()); + logger.log(Level.FINER, "Stripped trailing characters: " + number); + } + // Check for extra numbers at the end. + Matcher secondNumber = SECOND_NUMBER_START_PATTERN.matcher(number); + if (secondNumber.find()) { + number = number.substring(0, secondNumber.start()); + } + return number; + } else { + return ""; + } + } + + /** + * Checks to see if the string of characters could possibly be a phone number at all. At the + * moment, checks to see that the string begins with at least 2 digits, ignoring any punctuation + * commonly found in phone numbers. + * This method does not require the number to be normalized in advance - but does assume that + * leading non-number symbols have been removed, such as by the method extractPossibleNumber. + * + * @param number string to be checked for viability as a phone number + * @return true if the number could be a phone number of some sort, otherwise false + */ + // @VisibleForTesting + static boolean isViablePhoneNumber(String number) { + if (number.length() < MIN_LENGTH_FOR_NSN) { + return false; + } + Matcher m = VALID_PHONE_NUMBER_PATTERN.matcher(number); + return m.matches(); + } + + /** + * Normalizes a string of characters representing a phone number. This performs the following + * conversions: + * Punctuation is stripped. + * For ALPHA/VANITY numbers: + * Letters are converted to their numeric representation on a telephone keypad. The keypad + * used here is the one defined in ITU Recommendation E.161. This is only done if there are + * 3 or more letters in the number, to lessen the risk that such letters are typos. + * For other numbers: + * Wide-ascii digits are converted to normal ASCII (European) digits. + * Arabic-Indic numerals are converted to European numerals. + * Spurious alpha characters are stripped. + * + * @param number a string of characters representing a phone number + * @return the normalized string version of the phone number + */ + static String normalize(String number) { + Matcher m = VALID_ALPHA_PHONE_PATTERN.matcher(number); + if (m.matches()) { + return normalizeHelper(number, ALPHA_PHONE_MAPPINGS, true); + } else { + return normalizeDigitsOnly(number); + } + } + + /** + * Normalizes a string of characters representing a phone number. This is a wrapper for + * normalize(String number) but does in-place normalization of the StringBuilder provided. + * + * @param number a StringBuilder of characters representing a phone number that will be + * normalized in place + */ + static void normalize(StringBuilder number) { + String normalizedNumber = normalize(number.toString()); + number.replace(0, number.length(), normalizedNumber); + } + + /** + * Normalizes a string of characters representing a phone number. This converts wide-ascii and + * arabic-indic numerals to European numerals, and strips punctuation and alpha characters. + * + * @param number a string of characters representing a phone number + * @return the normalized string version of the phone number + */ + public static String normalizeDigitsOnly(String number) { + return normalizeDigits(number, false /* strip non-digits */).toString(); + } + + static StringBuilder normalizeDigits(String number, boolean keepNonDigits) { + StringBuilder normalizedDigits = new StringBuilder(number.length()); + for (char c : number.toCharArray()) { + int digit = Character.digit(c, 10); + if (digit != -1) { + normalizedDigits.append(digit); + } else if (keepNonDigits) { + normalizedDigits.append(c); + } + } + return normalizedDigits; + } + + /** + * Normalizes a string of characters representing a phone number. This strips all characters which + * are not diallable on a mobile phone keypad (including all non-ASCII digits). + * + * @param number a string of characters representing a phone number + * @return the normalized string version of the phone number + */ + static String normalizeDiallableCharsOnly(String number) { + return normalizeHelper(number, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */); + } + + /** + * Converts all alpha characters in a number to their respective digits on a keypad, but retains + * existing formatting. + */ + public static String convertAlphaCharactersInNumber(String number) { + return normalizeHelper(number, ALPHA_PHONE_MAPPINGS, false); + } + + /** + * Gets the length of the geographical area code from the + * PhoneNumber object passed in, so that clients could use it + * to split a national significant number into geographical area code and subscriber number. It + * works in such a way that the resultant subscriber number should be diallable, at least on some + * devices. An example of how this could be used: + * + * <pre> + * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); + * PhoneNumber number = phoneUtil.parse("16502530000", "US"); + * String nationalSignificantNumber = phoneUtil.getNationalSignificantNumber(number); + * String areaCode; + * String subscriberNumber; + * + * int areaCodeLength = phoneUtil.getLengthOfGeographicalAreaCode(number); + * if (areaCodeLength > 0) { + * areaCode = nationalSignificantNumber.substring(0, areaCodeLength); + * subscriberNumber = nationalSignificantNumber.substring(areaCodeLength); + * } else { + * areaCode = ""; + * subscriberNumber = nationalSignificantNumber; + * } + * </pre> + * + * N.B.: area code is a very ambiguous concept, so the I18N team generally recommends against + * using it for most purposes, but recommends using the more general {@code national_number} + * instead. Read the following carefully before deciding to use this method: + * <ul> + * <li> geographical area codes change over time, and this method honors those changes; + * therefore, it doesn't guarantee the stability of the result it produces. + * <li> subscriber numbers may not be diallable from all devices (notably mobile devices, which + * typically requires the full national_number to be dialled in most regions). + * <li> most non-geographical numbers have no area codes, including numbers from non-geographical + * entities + * <li> some geographical numbers have no area codes. + * </ul> + * @param number the PhoneNumber object for which clients + * want to know the length of the area code. + * @return the length of area code of the PhoneNumber object + * passed in. + */ + public int getLengthOfGeographicalAreaCode(PhoneNumber number) { + PhoneMetadata metadata = getMetadataForRegion(getRegionCodeForNumber(number)); + if (metadata == null) { + return 0; + } + // If a country doesn't use a national prefix, and this number doesn't have an Italian leading + // zero, we assume it is a closed dialling plan with no area codes. + if (!metadata.hasNationalPrefix() && !number.isItalianLeadingZero()) { + return 0; + } + + if (!isNumberGeographical(number)) { + return 0; + } + + return getLengthOfNationalDestinationCode(number); + } + + /** + * Gets the length of the national destination code (NDC) from the + * PhoneNumber object passed in, so that clients could use it + * to split a national significant number into NDC and subscriber number. The NDC of a phone + * number is normally the first group of digit(s) right after the country calling code when the + * number is formatted in the international format, if there is a subscriber number part that + * follows. An example of how this could be used: + * + * <pre> + * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); + * PhoneNumber number = phoneUtil.parse("18002530000", "US"); + * String nationalSignificantNumber = phoneUtil.getNationalSignificantNumber(number); + * String nationalDestinationCode; + * String subscriberNumber; + * + * int nationalDestinationCodeLength = phoneUtil.getLengthOfNationalDestinationCode(number); + * if (nationalDestinationCodeLength > 0) { + * nationalDestinationCode = nationalSignificantNumber.substring(0, + * nationalDestinationCodeLength); + * subscriberNumber = nationalSignificantNumber.substring(nationalDestinationCodeLength); + * } else { + * nationalDestinationCode = ""; + * subscriberNumber = nationalSignificantNumber; + * } + * </pre> + * + * Refer to the unittests to see the difference between this function and + * {@link #getLengthOfGeographicalAreaCode}. + * + * @param number the PhoneNumber object for which clients + * want to know the length of the NDC. + * @return the length of NDC of the PhoneNumber object + * passed in. + */ + public int getLengthOfNationalDestinationCode(PhoneNumber number) { + PhoneNumber copiedProto; + if (number.hasExtension()) { + // We don't want to alter the proto given to us, but we don't want to include the extension + // when we format it, so we copy it and clear the extension here. + copiedProto = new PhoneNumber(); + copiedProto.mergeFrom(number); + copiedProto.clearExtension(); + } else { + copiedProto = number; + } + + String nationalSignificantNumber = format(copiedProto, + PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL); + String[] numberGroups = NON_DIGITS_PATTERN.split(nationalSignificantNumber); + // The pattern will start with "+COUNTRY_CODE " so the first group will always be the empty + // string (before the + symbol) and the second group will be the country calling code. The third + // group will be area code if it is not the last group. + if (numberGroups.length <= 3) { + return 0; + } + + if (getNumberType(number) == PhoneNumberType.MOBILE) { + // For example Argentinian mobile numbers, when formatted in the international format, are in + // the form of +54 9 NDC XXXX.... As a result, we take the length of the third group (NDC) and + // add the length of the second group (which is the mobile token), which also forms part of + // the national significant number. This assumes that the mobile token is always formatted + // separately from the rest of the phone number. + String mobileToken = getCountryMobileToken(number.getCountryCode()); + if (!mobileToken.equals("")) { + return numberGroups[2].length() + numberGroups[3].length(); + } + } + return numberGroups[2].length(); + } + + /** + * Returns the mobile token for the provided country calling code if it has one, otherwise + * returns an empty string. A mobile token is a number inserted before the area code when dialing + * a mobile number from that country from abroad. + * + * @param countryCallingCode the country calling code for which we want the mobile token + * @return the mobile token, as a string, for the given country calling code + */ + public static String getCountryMobileToken(int countryCallingCode) { + if (MOBILE_TOKEN_MAPPINGS.containsKey(countryCallingCode)) { + return MOBILE_TOKEN_MAPPINGS.get(countryCallingCode); + } + return ""; + } + + /** + * Normalizes a string of characters representing a phone number by replacing all characters found + * in the accompanying map with the values therein, and stripping all other characters if + * removeNonMatches is true. + * + * @param number a string of characters representing a phone number + * @param normalizationReplacements a mapping of characters to what they should be replaced by in + * the normalized version of the phone number + * @param removeNonMatches indicates whether characters that are not able to be replaced + * should be stripped from the number. If this is false, they + * will be left unchanged in the number. + * @return the normalized string version of the phone number + */ + private static String normalizeHelper(String number, + Map<Character, Character> normalizationReplacements, + boolean removeNonMatches) { + StringBuilder normalizedNumber = new StringBuilder(number.length()); + for (int i = 0; i < number.length(); i++) { + char character = number.charAt(i); + Character newDigit = normalizationReplacements.get(Character.toUpperCase(character)); + if (newDigit != null) { + normalizedNumber.append(newDigit); + } else if (!removeNonMatches) { + normalizedNumber.append(character); + } + // If neither of the above are true, we remove this character. + } + return normalizedNumber.toString(); + } + + /** + * Sets or resets the PhoneNumberUtil singleton instance. If set to null, the next call to + * {@code getInstance()} will load (and return) the default instance. + */ + // @VisibleForTesting + static synchronized void setInstance(PhoneNumberUtil util) { + instance = util; + } + + /** + * Convenience method to get a list of what regions the library has metadata for. + */ + public Set<String> getSupportedRegions() { + return Collections.unmodifiableSet(supportedRegions); + } + + /** + * Convenience method to get a list of what global network calling codes the library has metadata + * for. + */ + public Set<Integer> getSupportedGlobalNetworkCallingCodes() { + return Collections.unmodifiableSet(countryCodesForNonGeographicalRegion); + } + + /** + * Gets a {@link PhoneNumberUtil} instance to carry out international phone number formatting, + * parsing, or validation. The instance is loaded with phone number metadata for a number of most + * commonly used regions. + * + * <p>The {@link PhoneNumberUtil} is implemented as a singleton. Therefore, calling getInstance + * multiple times will only result in one instance being created. + * + * @return a PhoneNumberUtil instance + */ + public static synchronized PhoneNumberUtil getInstance() { + if (instance == null) { + setInstance(createInstance(DEFAULT_METADATA_LOADER)); + } + return instance; + } + + /** + * Create a new {@link PhoneNumberUtil} instance to carry out international phone number + * formatting, parsing, or validation. The instance is loaded with all metadata by + * using the metadataLoader specified. + * + * This method should only be used in the rare case in which you want to manage your own + * metadata loading. Calling this method multiple times is very expensive, as each time + * a new instance is created from scratch. When in doubt, use {@link #getInstance}. + * + * @param metadataLoader Customized metadata loader. If null, default metadata loader will + * be used. This should not be null. + * @return a PhoneNumberUtil instance + */ + public static PhoneNumberUtil createInstance(MetadataLoader metadataLoader) { + if (metadataLoader == null) { + throw new IllegalArgumentException("metadataLoader could not be null."); + } + return new PhoneNumberUtil(META_DATA_FILE_PREFIX, metadataLoader, + CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap()); + } + + /** + * Helper function to check if the national prefix formatting rule has the first group only, i.e., + * does not start with the national prefix. + */ + static boolean formattingRuleHasFirstGroupOnly(String nationalPrefixFormattingRule) { + return nationalPrefixFormattingRule.length() == 0 || + FIRST_GROUP_ONLY_PREFIX_PATTERN.matcher(nationalPrefixFormattingRule).matches(); + } + + /** + * Tests whether a phone number has a geographical association. It checks if the number is + * associated to a certain region in the country where it belongs to. Note that this doesn't + * verify if the number is actually in use. + * + * A similar method is implemented as PhoneNumberOfflineGeocoder.canBeGeocoded, which performs a + * looser check, since it only prevents cases where prefixes overlap for geocodable and + * non-geocodable numbers. Also, if new phone number types were added, we should check if this + * other method should be updated too. + */ + boolean isNumberGeographical(PhoneNumber phoneNumber) { + PhoneNumberType numberType = getNumberType(phoneNumber); + // TODO: Include mobile phone numbers from countries like Indonesia, which has some + // mobile numbers that are geographical. + return numberType == PhoneNumberType.FIXED_LINE || + numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE; + } + + /** + * Helper function to check region code is not unknown or null. + */ + private boolean isValidRegionCode(String regionCode) { + return regionCode != null && supportedRegions.contains(regionCode); + } + + /** + * Helper function to check the country calling code is valid. + */ + private boolean hasValidCountryCallingCode(int countryCallingCode) { + return countryCallingCodeToRegionCodeMap.containsKey(countryCallingCode); + } + + /** + * Formats a phone number in the specified format using default rules. Note that this does not + * promise to produce a phone number that the user can dial from where they are - although we do + * format in either 'national' or 'international' format depending on what the client asks for, we + * do not currently support a more abbreviated format, such as for users in the same "area" who + * could potentially dial the number without area code. Note that if the phone number has a + * country calling code of 0 or an otherwise invalid country calling code, we cannot work out + * which formatting rules to apply so we return the national significant number with no formatting + * applied. + * + * @param number the phone number to be formatted + * @param numberFormat the format the phone number should be formatted into + * @return the formatted phone number + */ + public String format(PhoneNumber number, PhoneNumberFormat numberFormat) { + if (number.getNationalNumber() == 0 && number.hasRawInput()) { + // Unparseable numbers that kept their raw input just use that. + // This is the only case where a number can be formatted as E164 without a + // leading '+' symbol (but the original number wasn't parseable anyway). + // TODO: Consider removing the 'if' above so that unparseable + // strings without raw input format to the empty string instead of "+00" + String rawInput = number.getRawInput(); + if (rawInput.length() > 0) { + return rawInput; + } + } + StringBuilder formattedNumber = new StringBuilder(20); + format(number, numberFormat, formattedNumber); + return formattedNumber.toString(); + } + + /** + * Same as {@link #format(PhoneNumber, PhoneNumberFormat)}, but accepts a mutable StringBuilder as + * a parameter to decrease object creation when invoked many times. + */ + public void format(PhoneNumber number, PhoneNumberFormat numberFormat, + StringBuilder formattedNumber) { + // Clear the StringBuilder first. + formattedNumber.setLength(0); + int countryCallingCode = number.getCountryCode(); + String nationalSignificantNumber = getNationalSignificantNumber(number); + + if (numberFormat == PhoneNumberFormat.E164) { + // Early exit for E164 case (even if the country calling code is invalid) since no formatting + // of the national number needs to be applied. Extensions are not formatted. + formattedNumber.append(nationalSignificantNumber); + prefixNumberWithCountryCallingCode(countryCallingCode, PhoneNumberFormat.E164, + formattedNumber); + return; + } + if (!hasValidCountryCallingCode(countryCallingCode)) { + formattedNumber.append(nationalSignificantNumber); + return; + } + // Note getRegionCodeForCountryCode() is used because formatting information for regions which + // share a country calling code is contained by only one region for performance reasons. For + // example, for NANPA regions it will be contained in the metadata for US. + String regionCode = getRegionCodeForCountryCode(countryCallingCode); + // Metadata cannot be null because the country calling code is valid (which means that the + // region code cannot be ZZ and must be one of our supported region codes). + PhoneMetadata metadata = + getMetadataForRegionOrCallingCode(countryCallingCode, regionCode); + formattedNumber.append(formatNsn(nationalSignificantNumber, metadata, numberFormat)); + maybeAppendFormattedExtension(number, metadata, numberFormat, formattedNumber); + prefixNumberWithCountryCallingCode(countryCallingCode, numberFormat, formattedNumber); + } + + /** + * Formats a phone number in the specified format using client-defined formatting rules. Note that + * if the phone number has a country calling code of zero or an otherwise invalid country calling + * code, we cannot work out things like whether there should be a national prefix applied, or how + * to format extensions, so we return the national significant number with no formatting applied. + * + * @param number the phone number to be formatted + * @param numberFormat the format the phone number should be formatted into + * @param userDefinedFormats formatting rules specified by clients + * @return the formatted phone number + */ + public String formatByPattern(PhoneNumber number, + PhoneNumberFormat numberFormat, + List<NumberFormat> userDefinedFormats) { + int countryCallingCode = number.getCountryCode(); + String nationalSignificantNumber = getNationalSignificantNumber(number); + if (!hasValidCountryCallingCode(countryCallingCode)) { + return nationalSignificantNumber; + } + // Note getRegionCodeForCountryCode() is used because formatting information for regions which + // share a country calling code is contained by only one region for performance reasons. For + // example, for NANPA regions it will be contained in the metadata for US. + String regionCode = getRegionCodeForCountryCode(countryCallingCode); + // Metadata cannot be null because the country calling code is valid + PhoneMetadata metadata = + getMetadataForRegionOrCallingCode(countryCallingCode, regionCode); + + StringBuilder formattedNumber = new StringBuilder(20); + + NumberFormat formattingPattern = + chooseFormattingPatternForNumber(userDefinedFormats, nationalSignificantNumber); + if (formattingPattern == null) { + // If no pattern above is matched, we format the number as a whole. + formattedNumber.append(nationalSignificantNumber); + } else { + NumberFormat numFormatCopy = new NumberFormat(); + // Before we do a replacement of the national prefix pattern $NP with the national prefix, we + // need to copy the rule so that subsequent replacements for different numbers have the + // appropriate national prefix. + numFormatCopy.mergeFrom(formattingPattern); + String nationalPrefixFormattingRule = formattingPattern.getNationalPrefixFormattingRule(); + if (nationalPrefixFormattingRule.length() > 0) { + String nationalPrefix = metadata.getNationalPrefix(); + if (nationalPrefix.length() > 0) { + // Replace $NP with national prefix and $FG with the first group ($1). + nationalPrefixFormattingRule = + NP_PATTERN.matcher(nationalPrefixFormattingRule).replaceFirst(nationalPrefix); + nationalPrefixFormattingRule = + FG_PATTERN.matcher(nationalPrefixFormattingRule).replaceFirst("\\$1"); + numFormatCopy.setNationalPrefixFormattingRule(nationalPrefixFormattingRule); + } else { + // We don't want to have a rule for how to format the national prefix if there isn't one. + numFormatCopy.clearNationalPrefixFormattingRule(); + } + } + formattedNumber.append( + formatNsnUsingPattern(nationalSignificantNumber, numFormatCopy, numberFormat)); + } + maybeAppendFormattedExtension(number, metadata, numberFormat, formattedNumber); + prefixNumberWithCountryCallingCode(countryCallingCode, numberFormat, formattedNumber); + return formattedNumber.toString(); + } + + /** + * Formats a phone number in national format for dialing using the carrier as specified in the + * {@code carrierCode}. The {@code carrierCode} will always be used regardless of whether the + * phone number already has a preferred domestic carrier code stored. If {@code carrierCode} + * contains an empty string, returns the number in national format without any carrier code. + * + * @param number the phone number to be formatted + * @param carrierCode the carrier selection code to be used + * @return the formatted phone number in national format for dialing using the carrier as + * specified in the {@code carrierCode} + */ + public String formatNationalNumberWithCarrierCode(PhoneNumber number, String carrierCode) { + int countryCallingCode = number.getCountryCode(); + String nationalSignificantNumber = getNationalSignificantNumber(number); + if (!hasValidCountryCallingCode(countryCallingCode)) { + return nationalSignificantNumber; + } + + // Note getRegionCodeForCountryCode() is used because formatting information for regions which + // share a country calling code is contained by only one region for performance reasons. For + // example, for NANPA regions it will be contained in the metadata for US. + String regionCode = getRegionCodeForCountryCode(countryCallingCode); + // Metadata cannot be null because the country calling code is valid. + PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCallingCode, regionCode); + + StringBuilder formattedNumber = new StringBuilder(20); + formattedNumber.append(formatNsn(nationalSignificantNumber, metadata, + PhoneNumberFormat.NATIONAL, carrierCode)); + maybeAppendFormattedExtension(number, metadata, PhoneNumberFormat.NATIONAL, formattedNumber); + prefixNumberWithCountryCallingCode(countryCallingCode, PhoneNumberFormat.NATIONAL, + formattedNumber); + return formattedNumber.toString(); + } + + private PhoneMetadata getMetadataForRegionOrCallingCode( + int countryCallingCode, String regionCode) { + return REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode) + ? getMetadataForNonGeographicalRegion(countryCallingCode) + : getMetadataForRegion(regionCode); + } + + /** + * Formats a phone number in national format for dialing using the carrier as specified in the + * preferredDomesticCarrierCode field of the PhoneNumber object passed in. If that is missing, + * use the {@code fallbackCarrierCode} passed in instead. If there is no + * {@code preferredDomesticCarrierCode}, and the {@code fallbackCarrierCode} contains an empty + * string, return the number in national format without any carrier code. + * + * <p>Use {@link #formatNationalNumberWithCarrierCode} instead if the carrier code passed in + * should take precedence over the number's {@code preferredDomesticCarrierCode} when formatting. + * + * @param number the phone number to be formatted + * @param fallbackCarrierCode the carrier selection code to be used, if none is found in the + * phone number itself + * @return the formatted phone number in national format for dialing using the number's + * {@code preferredDomesticCarrierCode}, or the {@code fallbackCarrierCode} passed in if + * none is found + */ + public String formatNationalNumberWithPreferredCarrierCode(PhoneNumber number, + String fallbackCarrierCode) { + return formatNationalNumberWithCarrierCode(number, number.hasPreferredDomesticCarrierCode() + ? number.getPreferredDomesticCarrierCode() + : fallbackCarrierCode); + } + + /** + * Returns a number formatted in such a way that it can be dialed from a mobile phone in a + * specific region. If the number cannot be reached from the region (e.g. some countries block + * toll-free numbers from being called outside of the country), the method returns an empty + * string. + * + * @param number the phone number to be formatted + * @param regionCallingFrom the region where the call is being placed + * @param withFormatting whether the number should be returned with formatting symbols, such as + * spaces and dashes. + * @return the formatted phone number + */ + public String formatNumberForMobileDialing(PhoneNumber number, String regionCallingFrom, + boolean withFormatting) { + int countryCallingCode = number.getCountryCode(); + if (!hasValidCountryCallingCode(countryCallingCode)) { + return number.hasRawInput() ? number.getRawInput() : ""; + } + + String formattedNumber = ""; + // Clear the extension, as that part cannot normally be dialed together with the main number. + PhoneNumber numberNoExt = new PhoneNumber().mergeFrom(number).clearExtension(); + String regionCode = getRegionCodeForCountryCode(countryCallingCode); + PhoneNumberType numberType = getNumberType(numberNoExt); + boolean isValidNumber = (numberType != PhoneNumberType.UNKNOWN); + if (regionCallingFrom.equals(regionCode)) { + boolean isFixedLineOrMobile = + (numberType == PhoneNumberType.FIXED_LINE) || (numberType == PhoneNumberType.MOBILE) || + (numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE); + // Carrier codes may be needed in some countries. We handle this here. + if (regionCode.equals("CO") && numberType == PhoneNumberType.FIXED_LINE) { + formattedNumber = + formatNationalNumberWithCarrierCode(numberNoExt, COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX); + } else if (regionCode.equals("BR") && isFixedLineOrMobile) { + formattedNumber = numberNoExt.hasPreferredDomesticCarrierCode() + ? formattedNumber = formatNationalNumberWithPreferredCarrierCode(numberNoExt, "") + // Brazilian fixed line and mobile numbers need to be dialed with a carrier code when + // called within Brazil. Without that, most of the carriers won't connect the call. + // Because of that, we return an empty string here. + : ""; + } else if (isValidNumber && regionCode.equals("HU")) { + // The national format for HU numbers doesn't contain the national prefix, because that is + // how numbers are normally written down. However, the national prefix is obligatory when + // dialing from a mobile phone, except for short numbers. As a result, we add it back here + // if it is a valid regular length phone number. + formattedNumber = + getNddPrefixForRegion(regionCode, true /* strip non-digits */) + + " " + format(numberNoExt, PhoneNumberFormat.NATIONAL); + } else if (countryCallingCode == NANPA_COUNTRY_CODE) { + // For NANPA countries, we output international format for numbers that can be dialed + // internationally, since that always works, except for numbers which might potentially be + // short numbers, which are always dialled in national format. + PhoneMetadata regionMetadata = getMetadataForRegion(regionCallingFrom); + if (canBeInternationallyDialled(numberNoExt) && + !isShorterThanPossibleNormalNumber(regionMetadata, + getNationalSignificantNumber(numberNoExt))) { + formattedNumber = format(numberNoExt, PhoneNumberFormat.INTERNATIONAL); + } else { + formattedNumber = format(numberNoExt, PhoneNumberFormat.NATIONAL); + } + } else { + // For non-geographical countries, and Mexican and Chilean fixed line and mobile numbers, we + // output international format for numbers that can be dialed internationally as that always + // works. + if ((regionCode.equals(REGION_CODE_FOR_NON_GEO_ENTITY) || + // MX fixed line and mobile numbers should always be formatted in international format, + // even when dialed within MX. For national format to work, a carrier code needs to be + // used, and the correct carrier code depends on if the caller and callee are from the + // same local area. It is trickier to get that to work correctly than using + // international format, which is tested to work fine on all carriers. + // CL fixed line numbers need the national prefix when dialing in the national format, + // but don't have it when used for display. The reverse is true for mobile numbers. + // As a result, we output them in the international format to make it work. + ((regionCode.equals("MX") || regionCode.equals("CL")) && + isFixedLineOrMobile)) && + canBeInternationallyDialled(numberNoExt)) { + formattedNumber = format(numberNoExt, PhoneNumberFormat.INTERNATIONAL); + } else { + formattedNumber = format(numberNoExt, PhoneNumberFormat.NATIONAL); + } + } + } else if (isValidNumber && canBeInternationallyDialled(numberNoExt)) { + // We assume that short numbers are not diallable from outside their region, so if a number + // is not a valid regular length phone number, we treat it as if it cannot be internationally + // dialled. + return withFormatting ? format(numberNoExt, PhoneNumberFormat.INTERNATIONAL) + : format(numberNoExt, PhoneNumberFormat.E164); + } + return withFormatting ? formattedNumber + : normalizeDiallableCharsOnly(formattedNumber); + } + + /** + * Formats a phone number for out-of-country dialing purposes. If no regionCallingFrom is + * supplied, we format the number in its INTERNATIONAL format. If the country calling code is the + * same as that of the region where the number is from, then NATIONAL formatting will be applied. + * + * <p>If the number itself has a country calling code of zero or an otherwise invalid country + * calling code, then we return the number with no formatting applied. + * + * <p>Note this function takes care of the case for calling inside of NANPA and between Russia and + * Kazakhstan (who share the same country calling code). In those cases, no international prefix + * is used. For regions which have multiple international prefixes, the number in its + * INTERNATIONAL format will be returned instead. + * + * @param number the phone number to be formatted + * @param regionCallingFrom the region where the call is being placed + * @return the formatted phone number + */ + public String formatOutOfCountryCallingNumber(PhoneNumber number, + String regionCallingFrom) { + if (!isValidRegionCode(regionCallingFrom)) { + logger.log(Level.WARNING, + "Trying to format number from invalid region " + + regionCallingFrom + + ". International formatting applied."); + return format(number, PhoneNumberFormat.INTERNATIONAL); + } + int countryCallingCode = number.getCountryCode(); + String nationalSignificantNumber = getNationalSignificantNumber(number); + if (!hasValidCountryCallingCode(countryCallingCode)) { + return nationalSignificantNumber; + } + if (countryCallingCode == NANPA_COUNTRY_CODE) { + if (isNANPACountry(regionCallingFrom)) { + // For NANPA regions, return the national format for these regions but prefix it with the + // country calling code. + return countryCallingCode + " " + format(number, PhoneNumberFormat.NATIONAL); + } + } else if (countryCallingCode == getCountryCodeForValidRegion(regionCallingFrom)) { + // If regions share a country calling code, the country calling code need not be dialled. + // This also applies when dialling within a region, so this if clause covers both these cases. + // Technically this is the case for dialling from La Reunion to other overseas departments of + // France (French Guiana, Martinique, Guadeloupe), but not vice versa - so we don't cover this + // edge case for now and for those cases return the version including country calling code. + // Details here: http://www.petitfute.com/voyage/225-info-pratiques-reunion + return format(number, PhoneNumberFormat.NATIONAL); + } + // Metadata cannot be null because we checked 'isValidRegionCode()' above. + PhoneMetadata metadataForRegionCallingFrom = getMetadataForRegion(regionCallingFrom); + String internationalPrefix = metadataForRegionCallingFrom.getInternationalPrefix(); + + // For regions that have multiple international prefixes, the international format of the + // number is returned, unless there is a preferred international prefix. + String internationalPrefixForFormatting = ""; + if (UNIQUE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches()) { + internationalPrefixForFormatting = internationalPrefix; + } else if (metadataForRegionCallingFrom.hasPreferredInternationalPrefix()) { + internationalPrefixForFormatting = + metadataForRegionCallingFrom.getPreferredInternationalPrefix(); + } + + String regionCode = getRegionCodeForCountryCode(countryCallingCode); + // Metadata cannot be null because the country calling code is valid. + PhoneMetadata metadataForRegion = + getMetadataForRegionOrCallingCode(countryCallingCode, regionCode); + String formattedNationalNumber = + formatNsn(nationalSignificantNumber, metadataForRegion, PhoneNumberFormat.INTERNATIONAL); + StringBuilder formattedNumber = new StringBuilder(formattedNationalNumber); + maybeAppendFormattedExtension(number, metadataForRegion, PhoneNumberFormat.INTERNATIONAL, + formattedNumber); + if (internationalPrefixForFormatting.length() > 0) { + formattedNumber.insert(0, " ").insert(0, countryCallingCode).insert(0, " ") + .insert(0, internationalPrefixForFormatting); + } else { + prefixNumberWithCountryCallingCode(countryCallingCode, + PhoneNumberFormat.INTERNATIONAL, + formattedNumber); + } + return formattedNumber.toString(); + } + + /** + * Formats a phone number using the original phone number format that the number is parsed from. + * The original format is embedded in the country_code_source field of the PhoneNumber object + * passed in. If such information is missing, the number will be formatted into the NATIONAL + * format by default. When the number contains a leading zero and this is unexpected for this + * country, or we don't have a formatting pattern for the number, the method returns the raw input + * when it is available. + * + * Note this method guarantees no digit will be inserted, removed or modified as a result of + * formatting. + * + * @param number the phone number that needs to be formatted in its original number format + * @param regionCallingFrom the region whose IDD needs to be prefixed if the original number + * has one + * @return the formatted phone number in its original number format + */ + public String formatInOriginalFormat(PhoneNumber number, String regionCallingFrom) { + if (number.hasRawInput() && + (hasUnexpectedItalianLeadingZero(number) || !hasFormattingPatternForNumber(number))) { + // We check if we have the formatting pattern because without that, we might format the number + // as a group without national prefix. + return number.getRawInput(); + } + if (!number.hasCountryCodeSource()) { + return format(number, PhoneNumberFormat.NATIONAL); + } + String formattedNumber; + switch (number.getCountryCodeSource()) { + case FROM_NUMBER_WITH_PLUS_SIGN: + formattedNumber = format(number, PhoneNumberFormat.INTERNATIONAL); + break; + case FROM_NUMBER_WITH_IDD: + formattedNumber = formatOutOfCountryCallingNumber(number, regionCallingFrom); + break; + case FROM_NUMBER_WITHOUT_PLUS_SIGN: + formattedNumber = format(number, PhoneNumberFormat.INTERNATIONAL).substring(1); + break; + case FROM_DEFAULT_COUNTRY: + // Fall-through to default case. + default: + String regionCode = getRegionCodeForCountryCode(number.getCountryCode()); + // We strip non-digits from the NDD here, and from the raw input later, so that we can + // compare them easily. + String nationalPrefix = getNddPrefixForRegion(regionCode, true /* strip non-digits */); + String nationalFormat = format(number, PhoneNumberFormat.NATIONAL); + if (nationalPrefix == null || nationalPrefix.length() == 0) { + // If the region doesn't have a national prefix at all, we can safely return the national + // format without worrying about a national prefix being added. + formattedNumber = nationalFormat; + break; + } + // Otherwise, we check if the original number was entered with a national prefix. + if (rawInputContainsNationalPrefix( + number.getRawInput(), nationalPrefix, regionCode)) { + // If so, we can safely return the national format. + formattedNumber = nationalFormat; + break; + } + // Metadata cannot be null here because getNddPrefixForRegion() (above) returns null if + // there is no metadata for the region. + PhoneMetadata metadata = getMetadataForRegion(regionCode); + String nationalNumber = getNationalSignificantNumber(number); + NumberFormat formatRule = + chooseFormattingPatternForNumber(metadata.numberFormats(), nationalNumber); + // The format rule could still be null here if the national number was 0 and there was no + // raw input (this should not be possible for numbers generated by the phonenumber library + // as they would also not have a country calling code and we would have exited earlier). + if (formatRule == null) { + formattedNumber = nationalFormat; + break; + } + // When the format we apply to this number doesn't contain national prefix, we can just + // return the national format. + // TODO: Refactor the code below with the code in + // isNationalPrefixPresentIfRequired. + String candidateNationalPrefixRule = formatRule.getNationalPrefixFormattingRule(); + // We assume that the first-group symbol will never be _before_ the national prefix. + int indexOfFirstGroup = candidateNationalPrefixRule.indexOf("$1"); + if (indexOfFirstGroup <= 0) { + formattedNumber = nationalFormat; + break; + } + candidateNationalPrefixRule = + candidateNationalPrefixRule.substring(0, indexOfFirstGroup); + candidateNationalPrefixRule = normalizeDigitsOnly(candidateNationalPrefixRule); + if (candidateNationalPrefixRule.length() == 0) { + // National prefix not used when formatting this number. + formattedNumber = nationalFormat; + break; + } + // Otherwise, we need to remove the national prefix from our output. + NumberFormat numFormatCopy = new NumberFormat(); + numFormatCopy.mergeFrom(formatRule); + numFormatCopy.clearNationalPrefixFormattingRule(); + List<NumberFormat> numberFormats = new ArrayList<NumberFormat>(1); + numberFormats.add(numFormatCopy); + formattedNumber = formatByPattern(number, PhoneNumberFormat.NATIONAL, numberFormats); + break; + } + String rawInput = number.getRawInput(); + // If no digit is inserted/removed/modified as a result of our formatting, we return the + // formatted phone number; otherwise we return the raw input the user entered. + if (formattedNumber != null && rawInput.length() > 0) { + String normalizedFormattedNumber = normalizeDiallableCharsOnly(formattedNumber); + String normalizedRawInput = normalizeDiallableCharsOnly(rawInput); + if (!normalizedFormattedNumber.equals(normalizedRawInput)) { + formattedNumber = rawInput; + } + } + return formattedNumber; + } + + // Check if rawInput, which is assumed to be in the national format, has a national prefix. The + // national prefix is assumed to be in digits-only form. + private boolean rawInputContainsNationalPrefix(String rawInput, String nationalPrefix, + String regionCode) { + String normalizedNationalNumber = normalizeDigitsOnly(rawInput); + if (normalizedNationalNumber.startsWith(nationalPrefix)) { + try { + // Some Japanese numbers (e.g. 00777123) might be mistaken to contain the national prefix + // when written without it (e.g. 0777123) if we just do prefix matching. To tackle that, we + // check the validity of the number if the assumed national prefix is removed (777123 won't + // be valid in Japan). + return isValidNumber( + parse(normalizedNationalNumber.substring(nationalPrefix.length()), regionCode)); + } catch (NumberParseException e) { + return false; + } + } + return false; + } + + /** + * Returns true if a number is from a region whose national significant number couldn't contain a + * leading zero, but has the italian_leading_zero field set to true. + */ + private boolean hasUnexpectedItalianLeadingZero(PhoneNumber number) { + return number.isItalianLeadingZero() && !isLeadingZeroPossible(number.getCountryCode()); + } + + private boolean hasFormattingPatternForNumber(PhoneNumber number) { + int countryCallingCode = number.getCountryCode(); + String phoneNumberRegion = getRegionCodeForCountryCode(countryCallingCode); + PhoneMetadata metadata = + getMetadataForRegionOrCallingCode(countryCallingCode, phoneNumberRegion); + if (metadata == null) { + return false; + } + String nationalNumber = getNationalSignificantNumber(number); + NumberFormat formatRule = + chooseFormattingPatternForNumber(metadata.numberFormats(), nationalNumber); + return formatRule != null; + } + + /** + * Formats a phone number for out-of-country dialing purposes. + * + * Note that in this version, if the number was entered originally using alpha characters and + * this version of the number is stored in raw_input, this representation of the number will be + * used rather than the digit representation. Grouping information, as specified by characters + * such as "-" and " ", will be retained. + * + * <p><b>Caveats:</b></p> + * <ul> + * <li> This will not produce good results if the country calling code is both present in the raw + * input _and_ is the start of the national number. This is not a problem in the regions + * which typically use alpha numbers. + * <li> This will also not produce good results if the raw input has any grouping information + * within the first three digits of the national number, and if the function needs to strip + * preceding digits/words in the raw input before these digits. Normally people group the + * first three digits together so this is not a huge problem - and will be fixed if it + * proves to be so. + * </ul> + * + * @param number the phone number that needs to be formatted + * @param regionCallingFrom the region where the call is being placed + * @return the formatted phone number + */ + public String formatOutOfCountryKeepingAlphaChars(PhoneNumber number, + String regionCallingFrom) { + String rawInput = number.getRawInput(); + // If there is no raw input, then we can't keep alpha characters because there aren't any. + // In this case, we return formatOutOfCountryCallingNumber. + if (rawInput.length() == 0) { + return formatOutOfCountryCallingNumber(number, regionCallingFrom); + } + int countryCode = number.getCountryCode(); + if (!hasValidCountryCallingCode(countryCode)) { + return rawInput; + } + // Strip any prefix such as country calling code, IDD, that was present. We do this by comparing + // the number in raw_input with the parsed number. + // To do this, first we normalize punctuation. We retain number grouping symbols such as " " + // only. + rawInput = normalizeHelper(rawInput, ALL_PLUS_NUMBER_GROUPING_SYMBOLS, true); + // Now we trim everything before the first three digits in the parsed number. We choose three + // because all valid alpha numbers have 3 digits at the start - if it does not, then we don't + // trim anything at all. Similarly, if the national number was less than three digits, we don't + // trim anything at all. + String nationalNumber = getNationalSignificantNumber(number); + if (nationalNumber.length() > 3) { + int firstNationalNumberDigit = rawInput.indexOf(nationalNumber.substring(0, 3)); + if (firstNationalNumberDigit != -1) { + rawInput = rawInput.substring(firstNationalNumberDigit); + } + } + PhoneMetadata metadataForRegionCallingFrom = getMetadataForRegion(regionCallingFrom); + if (countryCode == NANPA_COUNTRY_CODE) { + if (isNANPACountry(regionCallingFrom)) { + return countryCode + " " + rawInput; + } + } else if (metadataForRegionCallingFrom != null && + countryCode == getCountryCodeForValidRegion(regionCallingFrom)) { + NumberFormat formattingPattern = + chooseFormattingPatternForNumber(metadataForRegionCallingFrom.numberFormats(), + nationalNumber); + if (formattingPattern == null) { + // If no pattern above is matched, we format the original input. + return rawInput; + } + NumberFormat newFormat = new NumberFormat(); + newFormat.mergeFrom(formattingPattern); + // The first group is the first group of digits that the user wrote together. + newFormat.setPattern("(\\d+)(.*)"); + // Here we just concatenate them back together after the national prefix has been fixed. + newFormat.setFormat("$1$2"); + // Now we format using this pattern instead of the default pattern, but with the national + // prefix prefixed if necessary. + // This will not work in the cases where the pattern (and not the leading digits) decide + // whether a national prefix needs to be used, since we have overridden the pattern to match + // anything, but that is not the case in the metadata to date. + return formatNsnUsingPattern(rawInput, newFormat, PhoneNumberFormat.NATIONAL); + } + String internationalPrefixForFormatting = ""; + // If an unsupported region-calling-from is entered, or a country with multiple international + // prefixes, the international format of the number is returned, unless there is a preferred + // international prefix. + if (metadataForRegionCallingFrom != null) { + String internationalPrefix = metadataForRegionCallingFrom.getInternationalPrefix(); + internationalPrefixForFormatting = + UNIQUE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches() + ? internationalPrefix + : metadataForRegionCallingFrom.getPreferredInternationalPrefix(); + } + StringBuilder formattedNumber = new StringBuilder(rawInput); + String regionCode = getRegionCodeForCountryCode(countryCode); + // Metadata cannot be null because the country calling code is valid. + PhoneMetadata metadataForRegion = getMetadataForRegionOrCallingCode(countryCode, regionCode); + maybeAppendFormattedExtension(number, metadataForRegion, + PhoneNumberFormat.INTERNATIONAL, formattedNumber); + if (internationalPrefixForFormatting.length() > 0) { + formattedNumber.insert(0, " ").insert(0, countryCode).insert(0, " ") + .insert(0, internationalPrefixForFormatting); + } else { + // Invalid region entered as country-calling-from (so no metadata was found for it) or the + // region chosen has multiple international dialling prefixes. + logger.log(Level.WARNING, + "Trying to format number from invalid region " + + regionCallingFrom + + ". International formatting applied."); + prefixNumberWithCountryCallingCode(countryCode, + PhoneNumberFormat.INTERNATIONAL, + formattedNumber); + } + return formattedNumber.toString(); + } + + /** + * Gets the national significant number of the a phone number. Note a national significant number + * doesn't contain a national prefix or any formatting. + * + * @param number the phone number for which the national significant number is needed + * @return the national significant number of the PhoneNumber object passed in + */ + public String getNationalSignificantNumber(PhoneNumber number) { + // If leading zero(s) have been set, we prefix this now. Note this is not a national prefix. + StringBuilder nationalNumber = new StringBuilder(); + if (number.isItalianLeadingZero()) { + char[] zeros = new char[number.getNumberOfLeadingZeros()]; + Arrays.fill(zeros, '0'); + nationalNumber.append(new String(zeros)); + } + nationalNumber.append(number.getNationalNumber()); + return nationalNumber.toString(); + } + + /** + * A helper function that is used by format and formatByPattern. + */ + private void prefixNumberWithCountryCallingCode(int countryCallingCode, + PhoneNumberFormat numberFormat, + StringBuilder formattedNumber) { + switch (numberFormat) { + case E164: + formattedNumber.insert(0, countryCallingCode).insert(0, PLUS_SIGN); + return; + case INTERNATIONAL: + formattedNumber.insert(0, " ").insert(0, countryCallingCode).insert(0, PLUS_SIGN); + return; + case RFC3966: + formattedNumber.insert(0, "-").insert(0, countryCallingCode).insert(0, PLUS_SIGN) + .insert(0, RFC3966_PREFIX); + return; + case NATIONAL: + default: + return; + } + } + + // Simple wrapper of formatNsn for the common case of no carrier code. + private String formatNsn(String number, PhoneMetadata metadata, PhoneNumberFormat numberFormat) { + return formatNsn(number, metadata, numberFormat, null); + } + + // Note in some regions, the national number can be written in two completely different ways + // depending on whether it forms part of the NATIONAL format or INTERNATIONAL format. The + // numberFormat parameter here is used to specify which format to use for those cases. If a + // carrierCode is specified, this will be inserted into the formatted string to replace $CC. + private String formatNsn(String number, + PhoneMetadata metadata, + PhoneNumberFormat numberFormat, + String carrierCode) { + List<NumberFormat> intlNumberFormats = metadata.intlNumberFormats(); + // When the intlNumberFormats exists, we use that to format national number for the + // INTERNATIONAL format instead of using the numberDesc.numberFormats. + List<NumberFormat> availableFormats = + (intlNumberFormats.size() == 0 || numberFormat == PhoneNumberFormat.NATIONAL) + ? metadata.numberFormats() + : metadata.intlNumberFormats(); + NumberFormat formattingPattern = chooseFormattingPatternForNumber(availableFormats, number); + return (formattingPattern == null) + ? number + : formatNsnUsingPattern(number, formattingPattern, numberFormat, carrierCode); + } + + NumberFormat chooseFormattingPatternForNumber(List<NumberFormat> availableFormats, + String nationalNumber) { + for (NumberFormat numFormat : availableFormats) { + int size = numFormat.leadingDigitsPatternSize(); + if (size == 0 || regexCache.getPatternForRegex( + // We always use the last leading_digits_pattern, as it is the most detailed. + numFormat.getLeadingDigitsPattern(size - 1)).matcher(nationalNumber).lookingAt()) { + Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber); + if (m.matches()) { + return numFormat; + } + } + } + return null; + } + + // Simple wrapper of formatNsnUsingPattern for the common case of no carrier code. + String formatNsnUsingPattern(String nationalNumber, + NumberFormat formattingPattern, + PhoneNumberFormat numberFormat) { + return formatNsnUsingPattern(nationalNumber, formattingPattern, numberFormat, null); + } + + // Note that carrierCode is optional - if null or an empty string, no carrier code replacement + // will take place. + private String formatNsnUsingPattern(String nationalNumber, + NumberFormat formattingPattern, + PhoneNumberFormat numberFormat, + String carrierCode) { + String numberFormatRule = formattingPattern.getFormat(); + Matcher m = + regexCache.getPatternForRegex(formattingPattern.getPattern()).matcher(nationalNumber); + String formattedNationalNumber = ""; + if (numberFormat == PhoneNumberFormat.NATIONAL && + carrierCode != null && carrierCode.length() > 0 && + formattingPattern.getDomesticCarrierCodeFormattingRule().length() > 0) { + // Replace the $CC in the formatting rule with the desired carrier code. + String carrierCodeFormattingRule = formattingPattern.getDomesticCarrierCodeFormattingRule(); + carrierCodeFormattingRule = + CC_PATTERN.matcher(carrierCodeFormattingRule).replaceFirst(carrierCode); + // Now replace the $FG in the formatting rule with the first group and the carrier code + // combined in the appropriate way. + numberFormatRule = FIRST_GROUP_PATTERN.matcher(numberFormatRule) + .replaceFirst(carrierCodeFormattingRule); + formattedNationalNumber = m.replaceAll(numberFormatRule); + } else { + // Use the national prefix formatting rule instead. + String nationalPrefixFormattingRule = formattingPattern.getNationalPrefixFormattingRule(); + if (numberFormat == PhoneNumberFormat.NATIONAL && + nationalPrefixFormattingRule != null && + nationalPrefixFormattingRule.length() > 0) { + Matcher firstGroupMatcher = FIRST_GROUP_PATTERN.matcher(numberFormatRule); + formattedNationalNumber = + m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule)); + } else { + formattedNationalNumber = m.replaceAll(numberFormatRule); + } + } + if (numberFormat == PhoneNumberFormat.RFC3966) { + // Strip any leading punctuation. + Matcher matcher = SEPARATOR_PATTERN.matcher(formattedNationalNumber); + if (matcher.lookingAt()) { + formattedNationalNumber = matcher.replaceFirst(""); + } + // Replace the rest with a dash between each number group. + formattedNationalNumber = matcher.reset(formattedNationalNumber).replaceAll("-"); + } + return formattedNationalNumber; + } + + /** + * Gets a valid number for the specified region. + * + * @param regionCode the region for which an example number is needed + * @return a valid fixed-line number for the specified region. Returns null when the metadata + * does not contain such information, or the region 001 is passed in. For 001 (representing + * non-geographical numbers), call {@link #getExampleNumberForNonGeoEntity} instead. + */ + public PhoneNumber getExampleNumber(String regionCode) { + return getExampleNumberForType(regionCode, PhoneNumberType.FIXED_LINE); + } + + /** + * Gets a valid number for the specified region and number type. + * + * @param regionCode the region for which an example number is needed + * @param type the type of number that is needed + * @return a valid number for the specified region and type. Returns null when the metadata + * does not contain such information or if an invalid region or region 001 was entered. + * For 001 (representing non-geographical numbers), call + * {@link #getExampleNumberForNonGeoEntity} instead. + */ + public PhoneNumber getExampleNumberForType(String regionCode, PhoneNumberType type) { + // Check the region code is valid. + if (!isValidRegionCode(regionCode)) { + logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode); + return null; + } + PhoneNumberDesc desc = getNumberDescByType(getMetadataForRegion(regionCode), type); + try { + if (desc.hasExampleNumber()) { + return parse(desc.getExampleNumber(), regionCode); + } + } catch (NumberParseException e) { + logger.log(Level.SEVERE, e.toString()); + } + return null; + } + + /** + * Gets a valid number for the specified country calling code for a non-geographical entity. + * + * @param countryCallingCode the country calling code for a non-geographical entity + * @return a valid number for the non-geographical entity. Returns null when the metadata + * does not contain such information, or the country calling code passed in does not belong + * to a non-geographical entity. + */ + public PhoneNumber getExampleNumberForNonGeoEntity(int countryCallingCode) { + PhoneMetadata metadata = getMetadataForNonGeographicalRegion(countryCallingCode); + if (metadata != null) { + PhoneNumberDesc desc = metadata.getGeneralDesc(); + try { + if (desc.hasExampleNumber()) { + return parse("+" + countryCallingCode + desc.getExampleNumber(), "ZZ"); + } + } catch (NumberParseException e) { + logger.log(Level.SEVERE, e.toString()); + } + } else { + logger.log(Level.WARNING, + "Invalid or unknown country calling code provided: " + countryCallingCode); + } + return null; + } + + /** + * Appends the formatted extension of a phone number to formattedNumber, if the phone number had + * an extension specified. + */ + private void maybeAppendFormattedExtension(PhoneNumber number, PhoneMetadata metadata, + PhoneNumberFormat numberFormat, + StringBuilder formattedNumber) { + if (number.hasExtension() && number.getExtension().length() > 0) { + if (numberFormat == PhoneNumberFormat.RFC3966) { + formattedNumber.append(RFC3966_EXTN_PREFIX).append(number.getExtension()); + } else { + if (metadata.hasPreferredExtnPrefix()) { + formattedNumber.append(metadata.getPreferredExtnPrefix()).append(number.getExtension()); + } else { + formattedNumber.append(DEFAULT_EXTN_PREFIX).append(number.getExtension()); + } + } + } + } + + PhoneNumberDesc getNumberDescByType(PhoneMetadata metadata, PhoneNumberType type) { + switch (type) { + case PREMIUM_RATE: + return metadata.getPremiumRate(); + case TOLL_FREE: + return metadata.getTollFree(); + case MOBILE: + return metadata.getMobile(); + case FIXED_LINE: + case FIXED_LINE_OR_MOBILE: + return metadata.getFixedLine(); + case SHARED_COST: + return metadata.getSharedCost(); + case VOIP: + return metadata.getVoip(); + case PERSONAL_NUMBER: + return metadata.getPersonalNumber(); + case PAGER: + return metadata.getPager(); + case UAN: + return metadata.getUan(); + case VOICEMAIL: + return metadata.getVoicemail(); + default: + return metadata.getGeneralDesc(); + } + } + + /** + * Gets the type of a phone number. + * + * @param number the phone number that we want to know the type + * @return the type of the phone number + */ + public PhoneNumberType getNumberType(PhoneNumber number) { + String regionCode = getRegionCodeForNumber(number); + PhoneMetadata metadata = getMetadataForRegionOrCallingCode(number.getCountryCode(), regionCode); + if (metadata == null) { + return PhoneNumberType.UNKNOWN; + } + String nationalSignificantNumber = getNationalSignificantNumber(number); + return getNumberTypeHelper(nationalSignificantNumber, metadata); + } + + private PhoneNumberType getNumberTypeHelper(String nationalNumber, PhoneMetadata metadata) { + if (!isNumberMatchingDesc(nationalNumber, metadata.getGeneralDesc())) { + return PhoneNumberType.UNKNOWN; + } + + if (isNumberMatchingDesc(nationalNumber, metadata.getPremiumRate())) { + return PhoneNumberType.PREMIUM_RATE; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getTollFree())) { + return PhoneNumberType.TOLL_FREE; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getSharedCost())) { + return PhoneNumberType.SHARED_COST; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getVoip())) { + return PhoneNumberType.VOIP; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getPersonalNumber())) { + return PhoneNumberType.PERSONAL_NUMBER; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getPager())) { + return PhoneNumberType.PAGER; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getUan())) { + return PhoneNumberType.UAN; + } + if (isNumberMatchingDesc(nationalNumber, metadata.getVoicemail())) { + return PhoneNumberType.VOICEMAIL; + } + + boolean isFixedLine = isNumberMatchingDesc(nationalNumber, metadata.getFixedLine()); + if (isFixedLine) { + if (metadata.isSameMobileAndFixedLinePattern()) { + return PhoneNumberType.FIXED_LINE_OR_MOBILE; + } else if (isNumberMatchingDesc(nationalNumber, metadata.getMobile())) { + return PhoneNumberType.FIXED_LINE_OR_MOBILE; + } + return PhoneNumberType.FIXED_LINE; + } + // Otherwise, test to see if the number is mobile. Only do this if certain that the patterns for + // mobile and fixed line aren't the same. + if (!metadata.isSameMobileAndFixedLinePattern() && + isNumberMatchingDesc(nationalNumber, metadata.getMobile())) { + return PhoneNumberType.MOBILE; + } + return PhoneNumberType.UNKNOWN; + } + + /** + * Returns the metadata for the given region code or {@code null} if the region code is invalid + * or unknown. + */ + PhoneMetadata getMetadataForRegion(String regionCode) { + if (!isValidRegionCode(regionCode)) { + return null; + } + synchronized (regionToMetadataMap) { + if (!regionToMetadataMap.containsKey(regionCode)) { + // The regionCode here will be valid and won't be '001', so we don't need to worry about + // what to pass in for the country calling code. + loadMetadataFromFile(currentFilePrefix, regionCode, 0, metadataLoader); + } + } + return regionToMetadataMap.get(regionCode); + } + + PhoneMetadata getMetadataForNonGeographicalRegion(int countryCallingCode) { + synchronized (countryCodeToNonGeographicalMetadataMap) { + if (!countryCallingCodeToRegionCodeMap.containsKey(countryCallingCode)) { + return null; + } + if (!countryCodeToNonGeographicalMetadataMap.containsKey(countryCallingCode)) { + loadMetadataFromFile( + currentFilePrefix, REGION_CODE_FOR_NON_GEO_ENTITY, countryCallingCode, metadataLoader); + } + } + return countryCodeToNonGeographicalMetadataMap.get(countryCallingCode); + } + + boolean isNumberPossibleForDesc(String nationalNumber, PhoneNumberDesc numberDesc) { + Matcher possibleNumberPatternMatcher = + regexCache.getPatternForRegex(numberDesc.getPossibleNumberPattern()) + .matcher(nationalNumber); + return possibleNumberPatternMatcher.matches(); + } + + boolean isNumberMatchingDesc(String nationalNumber, PhoneNumberDesc numberDesc) { + Matcher nationalNumberPatternMatcher = + regexCache.getPatternForRegex(numberDesc.getNationalNumberPattern()) + .matcher(nationalNumber); + return isNumberPossibleForDesc(nationalNumber, numberDesc) && + nationalNumberPatternMatcher.matches(); + } + + /** + * Tests whether a phone number matches a valid pattern. Note this doesn't verify the number + * is actually in use, which is impossible to tell by just looking at a number itself. + * + * @param number the phone number that we want to validate + * @return a boolean that indicates whether the number is of a valid pattern + */ + public boolean isValidNumber(PhoneNumber number) { + String regionCode = getRegionCodeForNumber(number); + return isValidNumberForRegion(number, regionCode); + } + + /** + * Tests whether a phone number is valid for a certain region. Note this doesn't verify the number + * is actually in use, which is impossible to tell by just looking at a number itself. If the + * country calling code is not the same as the country calling code for the region, this + * immediately exits with false. After this, the specific number pattern rules for the region are + * examined. This is useful for determining for example whether a particular number is valid for + * Canada, rather than just a valid NANPA number. + * Warning: In most cases, you want to use {@link #isValidNumber} instead. For example, this + * method will mark numbers from British Crown dependencies such as the Isle of Man as invalid for + * the region "GB" (United Kingdom), since it has its own region code, "IM", which may be + * undesirable. + * + * @param number the phone number that we want to validate + * @param regionCode the region that we want to validate the phone number for + * @return a boolean that indicates whether the number is of a valid pattern + */ + public boolean isValidNumberForRegion(PhoneNumber number, String regionCode) { + int countryCode = number.getCountryCode(); + PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode); + if ((metadata == null) || + (!REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode) && + countryCode != getCountryCodeForValidRegion(regionCode))) { + // Either the region code was invalid, or the country calling code for this number does not + // match that of the region code. + return false; + } + String nationalSignificantNumber = getNationalSignificantNumber(number); + return getNumberTypeHelper(nationalSignificantNumber, metadata) != PhoneNumberType.UNKNOWN; + } + + /** + * Returns the region where a phone number is from. This could be used for geocoding at the region + * level. + * + * @param number the phone number whose origin we want to know + * @return the region where the phone number is from, or null if no region matches this calling + * code + */ + public String getRegionCodeForNumber(PhoneNumber number) { + int countryCode = number.getCountryCode(); + List<String> regions = countryCallingCodeToRegionCodeMap.get(countryCode); + if (regions == null) { + String numberString = getNationalSignificantNumber(number); + logger.log(Level.WARNING, + "Missing/invalid country_code (" + countryCode + ") for number " + numberString); + return null; + } + if (regions.size() == 1) { + return regions.get(0); + } else { + return getRegionCodeForNumberFromRegionList(number, regions); + } + } + + private String getRegionCodeForNumberFromRegionList(PhoneNumber number, + List<String> regionCodes) { + String nationalNumber = getNationalSignificantNumber(number); + for (String regionCode : regionCodes) { + // If leadingDigits is present, use this. Otherwise, do full validation. + // Metadata cannot be null because the region codes come from the country calling code map. + PhoneMetadata metadata = getMetadataForRegion(regionCode); + if (metadata.hasLeadingDigits()) { + if (regexCache.getPatternForRegex(metadata.getLeadingDigits()) + .matcher(nationalNumber).lookingAt()) { + return regionCode; + } + } else if (getNumberTypeHelper(nationalNumber, metadata) != PhoneNumberType.UNKNOWN) { + return regionCode; + } + } + return null; + } + + /** + * Returns the region code that matches the specific country calling code. In the case of no + * region code being found, ZZ will be returned. In the case of multiple regions, the one + * designated in the metadata as the "main" region for this calling code will be returned. If the + * countryCallingCode entered is valid but doesn't match a specific region (such as in the case of + * non-geographical calling codes like 800) the value "001" will be returned (corresponding to + * the value for World in the UN M.49 schema). + */ + public String getRegionCodeForCountryCode(int countryCallingCode) { + List<String> regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode); + return regionCodes == null ? UNKNOWN_REGION : regionCodes.get(0); + } + + /** + * Returns a list with the region codes that match the specific country calling code. For + * non-geographical country calling codes, the region code 001 is returned. Also, in the case + * of no region code being found, an empty list is returned. + */ + public List<String> getRegionCodesForCountryCode(int countryCallingCode) { + List<String> regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode); + return Collections.unmodifiableList(regionCodes == null ? new ArrayList<String>(0) + : regionCodes); + } + + /** + * Returns the country calling code for a specific region. For example, this would be 1 for the + * United States, and 64 for New Zealand. + * + * @param regionCode the region that we want to get the country calling code for + * @return the country calling code for the region denoted by regionCode + */ + public int getCountryCodeForRegion(String regionCode) { + if (!isValidRegionCode(regionCode)) { + logger.log(Level.WARNING, + "Invalid or missing region code (" + + ((regionCode == null) ? "null" : regionCode) + + ") provided."); + return 0; + } + return getCountryCodeForValidRegion(regionCode); + } + + /** + * Returns the country calling code for a specific region. For example, this would be 1 for the + * United States, and 64 for New Zealand. Assumes the region is already valid. + * + * @param regionCode the region that we want to get the country calling code for + * @return the country calling code for the region denoted by regionCode + * @throws IllegalArgumentException if the region is invalid + */ + private int getCountryCodeForValidRegion(String regionCode) { + PhoneMetadata metadata = getMetadataForRegion(regionCode); + if (metadata == null) { + throw new IllegalArgumentException("Invalid region code: " + regionCode); + } + return metadata.getCountryCode(); + } + + /** + * Returns the national dialling prefix for a specific region. For example, this would be 1 for + * the United States, and 0 for New Zealand. Set stripNonDigits to true to strip symbols like "~" + * (which indicates a wait for a dialling tone) from the prefix returned. If no national prefix is + * present, we return null. + * + * <p>Warning: Do not use this method for do-your-own formatting - for some regions, the + * national dialling prefix is used only for certain types of numbers. Use the library's + * formatting functions to prefix the national prefix when required. + * + * @param regionCode the region that we want to get the dialling prefix for + * @param stripNonDigits true to strip non-digits from the national dialling prefix + * @return the dialling prefix for the region denoted by regionCode + */ + public String getNddPrefixForRegion(String regionCode, boolean stripNonDigits) { + PhoneMetadata metadata = getMetadataForRegion(regionCode); + if (metadata == null) { + logger.log(Level.WARNING, + "Invalid or missing region code (" + + ((regionCode == null) ? "null" : regionCode) + + ") provided."); + return null; + } + String nationalPrefix = metadata.getNationalPrefix(); + // If no national prefix was found, we return null. + if (nationalPrefix.length() == 0) { + return null; + } + if (stripNonDigits) { + // Note: if any other non-numeric symbols are ever used in national prefixes, these would have + // to be removed here as well. + nationalPrefix = nationalPrefix.replace("~", ""); + } + return nationalPrefix; + } + + /** + * Checks if this is a region under the North American Numbering Plan Administration (NANPA). + * + * @return true if regionCode is one of the regions under NANPA + */ + public boolean isNANPACountry(String regionCode) { + return nanpaRegions.contains(regionCode); + } + + /** + * Checks whether the country calling code is from a region whose national significant number + * could contain a leading zero. An example of such a region is Italy. Returns false if no + * metadata for the country is found. + */ + boolean isLeadingZeroPossible(int countryCallingCode) { + PhoneMetadata mainMetadataForCallingCode = + getMetadataForRegionOrCallingCode(countryCallingCode, + getRegionCodeForCountryCode(countryCallingCode)); + if (mainMetadataForCallingCode == null) { + return false; + } + return mainMetadataForCallingCode.isLeadingZeroPossible(); + } + + /** + * Checks if the number is a valid vanity (alpha) number such as 800 MICROSOFT. A valid vanity + * number will start with at least 3 digits and will have three or more alpha characters. This + * does not do region-specific checks - to work out if this number is actually valid for a region, + * it should be parsed and methods such as {@link #isPossibleNumberWithReason} and + * {@link #isValidNumber} should be used. + * + * @param number the number that needs to be checked + * @return true if the number is a valid vanity number + */ + public boolean isAlphaNumber(String number) { + if (!isViablePhoneNumber(number)) { + // Number is too short, or doesn't match the basic phone number pattern. + return false; + } + StringBuilder strippedNumber = new StringBuilder(number); + maybeStripExtension(strippedNumber); + return VALID_ALPHA_PHONE_PATTERN.matcher(strippedNumber).matches(); + } + + /** + * Convenience wrapper around {@link #isPossibleNumberWithReason}. Instead of returning the reason + * for failure, this method returns a boolean value. + * @param number the number that needs to be checked + * @return true if the number is possible + */ + public boolean isPossibleNumber(PhoneNumber number) { + return isPossibleNumberWithReason(number) == ValidationResult.IS_POSSIBLE; + } + + /** + * Helper method to check a number against a particular pattern and determine whether it matches, + * or is too short or too long. Currently, if a number pattern suggests that numbers of length 7 + * and 10 are possible, and a number in between these possible lengths is entered, such as of + * length 8, this will return TOO_LONG. + */ + private ValidationResult testNumberLengthAgainstPattern(Pattern numberPattern, String number) { + Matcher numberMatcher = numberPattern.matcher(number); + if (numberMatcher.matches()) { + return ValidationResult.IS_POSSIBLE; + } + if (numberMatcher.lookingAt()) { + return ValidationResult.TOO_LONG; + } else { + return ValidationResult.TOO_SHORT; + } + } + + /** + * Helper method to check whether a number is too short to be a regular length phone number in a + * region. + */ + private boolean isShorterThanPossibleNormalNumber(PhoneMetadata regionMetadata, String number) { + Pattern possibleNumberPattern = regexCache.getPatternForRegex( + regionMetadata.getGeneralDesc().getPossibleNumberPattern()); + return testNumberLengthAgainstPattern(possibleNumberPattern, number) == + ValidationResult.TOO_SHORT; + } + + /** + * Check whether a phone number is a possible number. It provides a more lenient check than + * {@link #isValidNumber} in the following sense: + *<ol> + * <li> It only checks the length of phone numbers. In particular, it doesn't check starting + * digits of the number. + * <li> It doesn't attempt to figure out the type of the number, but uses general rules which + * applies to all types of phone numbers in a region. Therefore, it is much faster than + * isValidNumber. + * <li> For fixed line numbers, many regions have the concept of area code, which together with + * subscriber number constitute the national significant number. It is sometimes okay to dial + * the subscriber number only when dialing in the same area. This function will return + * true if the subscriber-number-only version is passed in. On the other hand, because + * isValidNumber validates using information on both starting digits (for fixed line + * numbers, that would most likely be area codes) and length (obviously includes the + * length of area codes for fixed line numbers), it will return false for the + * subscriber-number-only version. + * </ol> + * @param number the number that needs to be checked + * @return a ValidationResult object which indicates whether the number is possible + */ + public ValidationResult isPossibleNumberWithReason(PhoneNumber number) { + String nationalNumber = getNationalSignificantNumber(number); + int countryCode = number.getCountryCode(); + // Note: For Russian Fed and NANPA numbers, we just use the rules from the default region (US or + // Russia) since the getRegionCodeForNumber will not work if the number is possible but not + // valid. This would need to be revisited if the possible number pattern ever differed between + // various regions within those plans. + if (!hasValidCountryCallingCode(countryCode)) { + return ValidationResult.INVALID_COUNTRY_CODE; + } + String regionCode = getRegionCodeForCountryCode(countryCode); + // Metadata cannot be null because the country calling code is valid. + PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode); + Pattern possibleNumberPattern = + regexCache.getPatternForRegex(metadata.getGeneralDesc().getPossibleNumberPattern()); + return testNumberLengthAgainstPattern(possibleNumberPattern, nationalNumber); + } + + /** + * Check whether a phone number is a possible number given a number in the form of a string, and + * the region where the number could be dialed from. It provides a more lenient check than + * {@link #isValidNumber}. See {@link #isPossibleNumber(PhoneNumber)} for details. + * + * <p>This method first parses the number, then invokes {@link #isPossibleNumber(PhoneNumber)} + * with the resultant PhoneNumber object. + * + * @param number the number that needs to be checked, in the form of a string + * @param regionDialingFrom the region that we are expecting the number to be dialed from. + * Note this is different from the region where the number belongs. For example, the number + * +1 650 253 0000 is a number that belongs to US. When written in this form, it can be + * dialed from any region. When it is written as 00 1 650 253 0000, it can be dialed from any + * region which uses an international dialling prefix of 00. When it is written as + * 650 253 0000, it can only be dialed from within the US, and when written as 253 0000, it + * can only be dialed from within a smaller area in the US (Mountain View, CA, to be more + * specific). + * @return true if the number is possible + */ + public boolean isPossibleNumber(String number, String regionDialingFrom) { + try { + return isPossibleNumber(parse(number, regionDialingFrom)); + } catch (NumberParseException e) { + return false; + } + } + + /** + * Attempts to extract a valid number from a phone number that is too long to be valid, and resets + * the PhoneNumber object passed in to that valid version. If no valid number could be extracted, + * the PhoneNumber object passed in will not be modified. + * @param number a PhoneNumber object which contains a number that is too long to be valid. + * @return true if a valid phone number can be successfully extracted. + */ + public boolean truncateTooLongNumber(PhoneNumber number) { + if (isValidNumber(number)) { + return true; + } + PhoneNumber numberCopy = new PhoneNumber(); + numberCopy.mergeFrom(number); + long nationalNumber = number.getNationalNumber(); + do { + nationalNumber /= 10; + numberCopy.setNationalNumber(nationalNumber); + if (isPossibleNumberWithReason(numberCopy) == ValidationResult.TOO_SHORT || + nationalNumber == 0) { + return false; + } + } while (!isValidNumber(numberCopy)); + number.setNationalNumber(nationalNumber); + return true; + } + + /** + * Gets an {@link com.google.i18n.phonenumbers.AsYouTypeFormatter} for the specific region. + * + * @param regionCode the region where the phone number is being entered + * @return an {@link com.google.i18n.phonenumbers.AsYouTypeFormatter} object, which can be used + * to format phone numbers in the specific region "as you type" + */ + public AsYouTypeFormatter getAsYouTypeFormatter(String regionCode) { + return new AsYouTypeFormatter(regionCode); + } + + // Extracts country calling code from fullNumber, returns it and places the remaining number in + // nationalNumber. It assumes that the leading plus sign or IDD has already been removed. Returns + // 0 if fullNumber doesn't start with a valid country calling code, and leaves nationalNumber + // unmodified. + int extractCountryCode(StringBuilder fullNumber, StringBuilder nationalNumber) { + if ((fullNumber.length() == 0) || (fullNumber.charAt(0) == '0')) { + // Country codes do not begin with a '0'. + return 0; + } + int potentialCountryCode; + int numberLength = fullNumber.length(); + for (int i = 1; i <= MAX_LENGTH_COUNTRY_CODE && i <= numberLength; i++) { + potentialCountryCode = Integer.parseInt(fullNumber.substring(0, i)); + if (countryCallingCodeToRegionCodeMap.containsKey(potentialCountryCode)) { + nationalNumber.append(fullNumber.substring(i)); + return potentialCountryCode; + } + } + return 0; + } + + /** + * Tries to extract a country calling code from a number. This method will return zero if no + * country calling code is considered to be present. Country calling codes are extracted in the + * following ways: + * <ul> + * <li> by stripping the international dialing prefix of the region the person is dialing from, + * if this is present in the number, and looking at the next digits + * <li> by stripping the '+' sign if present and then looking at the next digits + * <li> by comparing the start of the number and the country calling code of the default region. + * If the number is not considered possible for the numbering plan of the default region + * initially, but starts with the country calling code of this region, validation will be + * reattempted after stripping this country calling code. If this number is considered a + * possible number, then the first digits will be considered the country calling code and + * removed as such. + * </ul> + * It will throw a NumberParseException if the number starts with a '+' but the country calling + * code supplied after this does not match that of any known region. + * + * @param number non-normalized telephone number that we wish to extract a country calling + * code from - may begin with '+' + * @param defaultRegionMetadata metadata about the region this number may be from + * @param nationalNumber a string buffer to store the national significant number in, in the case + * that a country calling code was extracted. The number is appended to any existing contents. + * If no country calling code was extracted, this will be left unchanged. + * @param keepRawInput true if the country_code_source and preferred_carrier_code fields of + * phoneNumber should be populated. + * @param phoneNumber the PhoneNumber object where the country_code and country_code_source need + * to be populated. Note the country_code is always populated, whereas country_code_source is + * only populated when keepCountryCodeSource is true. + * @return the country calling code extracted or 0 if none could be extracted + */ + // @VisibleForTesting + int maybeExtractCountryCode(String number, PhoneMetadata defaultRegionMetadata, + StringBuilder nationalNumber, boolean keepRawInput, + PhoneNumber phoneNumber) + throws NumberParseException { + if (number.length() == 0) { + return 0; + } + StringBuilder fullNumber = new StringBuilder(number); + // Set the default prefix to be something that will never match. + String possibleCountryIddPrefix = "NonMatch"; + if (defaultRegionMetadata != null) { + possibleCountryIddPrefix = defaultRegionMetadata.getInternationalPrefix(); + } + + CountryCodeSource countryCodeSource = + maybeStripInternationalPrefixAndNormalize(fullNumber, possibleCountryIddPrefix); + if (keepRawInput) { + phoneNumber.setCountryCodeSource(countryCodeSource); + } + if (countryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY) { + if (fullNumber.length() <= MIN_LENGTH_FOR_NSN) { + throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD, + "Phone number had an IDD, but after this was not " + + "long enough to be a viable phone number."); + } + int potentialCountryCode = extractCountryCode(fullNumber, nationalNumber); + if (potentialCountryCode != 0) { + phoneNumber.setCountryCode(potentialCountryCode); + return potentialCountryCode; + } + + // If this fails, they must be using a strange country calling code that we don't recognize, + // or that doesn't exist. + throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE, + "Country calling code supplied was not recognised."); + } else if (defaultRegionMetadata != null) { + // Check to see if the number starts with the country calling code for the default region. If + // so, we remove the country calling code, and do some checks on the validity of the number + // before and after. + int defaultCountryCode = defaultRegionMetadata.getCountryCode(); + String defaultCountryCodeString = String.valueOf(defaultCountryCode); + String normalizedNumber = fullNumber.toString(); + if (normalizedNumber.startsWith(defaultCountryCodeString)) { + StringBuilder potentialNationalNumber = + new StringBuilder(normalizedNumber.substring(defaultCountryCodeString.length())); + PhoneNumberDesc generalDesc = defaultRegionMetadata.getGeneralDesc(); + Pattern validNumberPattern = + regexCache.getPatternForRegex(generalDesc.getNationalNumberPattern()); + maybeStripNationalPrefixAndCarrierCode( + potentialNationalNumber, defaultRegionMetadata, null /* Don't need the carrier code */); + Pattern possibleNumberPattern = + regexCache.getPatternForRegex(generalDesc.getPossibleNumberPattern()); + // If the number was not valid before but is valid now, or if it was too long before, we + // consider the number with the country calling code stripped to be a better result and + // keep that instead. + if ((!validNumberPattern.matcher(fullNumber).matches() && + validNumberPattern.matcher(potentialNationalNumber).matches()) || + testNumberLengthAgainstPattern(possibleNumberPattern, fullNumber.toString()) + == ValidationResult.TOO_LONG) { + nationalNumber.append(potentialNationalNumber); + if (keepRawInput) { + phoneNumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN); + } + phoneNumber.setCountryCode(defaultCountryCode); + return defaultCountryCode; + } + } + } + // No country calling code present. + phoneNumber.setCountryCode(0); + return 0; + } + + /** + * Strips the IDD from the start of the number if present. Helper function used by + * maybeStripInternationalPrefixAndNormalize. + */ + private boolean parsePrefixAsIdd(Pattern iddPattern, StringBuilder number) { + Matcher m = iddPattern.matcher(number); + if (m.lookingAt()) { + int matchEnd = m.end(); + // Only strip this if the first digit after the match is not a 0, since country calling codes + // cannot begin with 0. + Matcher digitMatcher = CAPTURING_DIGIT_PATTERN.matcher(number.substring(matchEnd)); + if (digitMatcher.find()) { + String normalizedGroup = normalizeDigitsOnly(digitMatcher.group(1)); + if (normalizedGroup.equals("0")) { + return false; + } + } + number.delete(0, matchEnd); + return true; + } + return false; + } + + /** + * Strips any international prefix (such as +, 00, 011) present in the number provided, normalizes + * the resulting number, and indicates if an international prefix was present. + * + * @param number the non-normalized telephone number that we wish to strip any international + * dialing prefix from. + * @param possibleIddPrefix the international direct dialing prefix from the region we + * think this number may be dialed in + * @return the corresponding CountryCodeSource if an international dialing prefix could be + * removed from the number, otherwise CountryCodeSource.FROM_DEFAULT_COUNTRY if the number did + * not seem to be in international format. + */ + // @VisibleForTesting + CountryCodeSource maybeStripInternationalPrefixAndNormalize( + StringBuilder number, + String possibleIddPrefix) { + if (number.length() == 0) { + return CountryCodeSource.FROM_DEFAULT_COUNTRY; + } + // Check to see if the number begins with one or more plus signs. + Matcher m = PLUS_CHARS_PATTERN.matcher(number); + if (m.lookingAt()) { + number.delete(0, m.end()); + // Can now normalize the rest of the number since we've consumed the "+" sign at the start. + normalize(number); + return CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN; + } + // Attempt to parse the first digits as an international prefix. + Pattern iddPattern = regexCache.getPatternForRegex(possibleIddPrefix); + normalize(number); + return parsePrefixAsIdd(iddPattern, number) + ? CountryCodeSource.FROM_NUMBER_WITH_IDD + : CountryCodeSource.FROM_DEFAULT_COUNTRY; + } + + /** + * Strips any national prefix (such as 0, 1) present in the number provided. + * + * @param number the normalized telephone number that we wish to strip any national + * dialing prefix from + * @param metadata the metadata for the region that we think this number is from + * @param carrierCode a place to insert the carrier code if one is extracted + * @return true if a national prefix or carrier code (or both) could be extracted. + */ + // @VisibleForTesting + boolean maybeStripNationalPrefixAndCarrierCode( + StringBuilder number, PhoneMetadata metadata, StringBuilder carrierCode) { + int numberLength = number.length(); + String possibleNationalPrefix = metadata.getNationalPrefixForParsing(); + if (numberLength == 0 || possibleNationalPrefix.length() == 0) { + // Early return for numbers of zero length. + return false; + } + // Attempt to parse the first digits as a national prefix. + Matcher prefixMatcher = regexCache.getPatternForRegex(possibleNationalPrefix).matcher(number); + if (prefixMatcher.lookingAt()) { + Pattern nationalNumberRule = + regexCache.getPatternForRegex(metadata.getGeneralDesc().getNationalNumberPattern()); + // Check if the original number is viable. + boolean isViableOriginalNumber = nationalNumberRule.matcher(number).matches(); + // prefixMatcher.group(numOfGroups) == null implies nothing was captured by the capturing + // groups in possibleNationalPrefix; therefore, no transformation is necessary, and we just + // remove the national prefix. + int numOfGroups = prefixMatcher.groupCount(); + String transformRule = metadata.getNationalPrefixTransformRule(); + if (transformRule == null || transformRule.length() == 0 || + prefixMatcher.group(numOfGroups) == null) { + // If the original number was viable, and the resultant number is not, we return. + if (isViableOriginalNumber && + !nationalNumberRule.matcher(number.substring(prefixMatcher.end())).matches()) { + return false; + } + if (carrierCode != null && numOfGroups > 0 && prefixMatcher.group(numOfGroups) != null) { + carrierCode.append(prefixMatcher.group(1)); + } + number.delete(0, prefixMatcher.end()); + return true; + } else { + // Check that the resultant number is still viable. If not, return. Check this by copying + // the string buffer and making the transformation on the copy first. + StringBuilder transformedNumber = new StringBuilder(number); + transformedNumber.replace(0, numberLength, prefixMatcher.replaceFirst(transformRule)); + if (isViableOriginalNumber && + !nationalNumberRule.matcher(transformedNumber.toString()).matches()) { + return false; + } + if (carrierCode != null && numOfGroups > 1) { + carrierCode.append(prefixMatcher.group(1)); + } + number.replace(0, number.length(), transformedNumber.toString()); + return true; + } + } + return false; + } + + /** + * Strips any extension (as in, the part of the number dialled after the call is connected, + * usually indicated with extn, ext, x or similar) from the end of the number, and returns it. + * + * @param number the non-normalized telephone number that we wish to strip the extension from + * @return the phone extension + */ + // @VisibleForTesting + String maybeStripExtension(StringBuilder number) { + Matcher m = EXTN_PATTERN.matcher(number); + // If we find a potential extension, and the number preceding this is a viable number, we assume + // it is an extension. + if (m.find() && isViablePhoneNumber(number.substring(0, m.start()))) { + // The numbers are captured into groups in the regular expression. + for (int i = 1, length = m.groupCount(); i <= length; i++) { + if (m.group(i) != null) { + // We go through the capturing groups until we find one that captured some digits. If none + // did, then we will return the empty string. + String extension = m.group(i); + number.delete(m.start(), number.length()); + return extension; + } + } + } + return ""; + } + + /** + * Checks to see that the region code used is valid, or if it is not valid, that the number to + * parse starts with a + symbol so that we can attempt to infer the region from the number. + * Returns false if it cannot use the region provided and the region cannot be inferred. + */ + private boolean checkRegionForParsing(String numberToParse, String defaultRegion) { + if (!isValidRegionCode(defaultRegion)) { + // If the number is null or empty, we can't infer the region. + if ((numberToParse == null) || (numberToParse.length() == 0) || + !PLUS_CHARS_PATTERN.matcher(numberToParse).lookingAt()) { + return false; + } + } + return true; + } + + /** + * Parses a string and returns it in proto buffer format. This method will throw a + * {@link com.google.i18n.phonenumbers.NumberParseException} if the number is not considered to be + * a possible number. Note that validation of whether the number is actually a valid number for a + * particular region is not performed. This can be done separately with {@link #isValidNumber}. + * + * @param numberToParse number that we are attempting to parse. This can contain formatting + * such as +, ( and -, as well as a phone number extension. It can also + * be provided in RFC3966 format. + * @param defaultRegion region that we are expecting the number to be from. This is only used + * if the number being parsed is not written in international format. + * The country_code for the number in this case would be stored as that + * of the default region supplied. If the number is guaranteed to + * start with a '+' followed by the country calling code, then + * "ZZ" or null can be supplied. + * @return a phone number proto buffer filled with the parsed number + * @throws NumberParseException if the string is not considered to be a viable phone number or if + * no default region was supplied and the number is not in + * international format (does not start with +) + */ + public PhoneNumber parse(String numberToParse, String defaultRegion) + throws NumberParseException { + PhoneNumber phoneNumber = new PhoneNumber(); + parse(numberToParse, defaultRegion, phoneNumber); + return phoneNumber; + } + + /** + * Same as {@link #parse(String, String)}, but accepts mutable PhoneNumber as a parameter to + * decrease object creation when invoked many times. + */ + public void parse(String numberToParse, String defaultRegion, PhoneNumber phoneNumber) + throws NumberParseException { + parseHelper(numberToParse, defaultRegion, false, true, phoneNumber); + } + + /** + * Parses a string and returns it in proto buffer format. This method differs from {@link #parse} + * in that it always populates the raw_input field of the protocol buffer with numberToParse as + * well as the country_code_source field. + * + * @param numberToParse number that we are attempting to parse. This can contain formatting + * such as +, ( and -, as well as a phone number extension. + * @param defaultRegion region that we are expecting the number to be from. This is only used + * if the number being parsed is not written in international format. + * The country calling code for the number in this case would be stored + * as that of the default region supplied. + * @return a phone number proto buffer filled with the parsed number + * @throws NumberParseException if the string is not considered to be a viable phone number or if + * no default region was supplied + */ + public PhoneNumber parseAndKeepRawInput(String numberToParse, String defaultRegion) + throws NumberParseException { + PhoneNumber phoneNumber = new PhoneNumber(); + parseAndKeepRawInput(numberToParse, defaultRegion, phoneNumber); + return phoneNumber; + } + + /** + * Same as{@link #parseAndKeepRawInput(String, String)}, but accepts a mutable PhoneNumber as + * a parameter to decrease object creation when invoked many times. + */ + public void parseAndKeepRawInput(String numberToParse, String defaultRegion, + PhoneNumber phoneNumber) + throws NumberParseException { + parseHelper(numberToParse, defaultRegion, true, true, phoneNumber); + } + + /** + * Returns an iterable over all {@link PhoneNumberMatch PhoneNumberMatches} in {@code text}. This + * is a shortcut for {@link #findNumbers(CharSequence, String, Leniency, long) + * getMatcher(text, defaultRegion, Leniency.VALID, Long.MAX_VALUE)}. + * + * @param text the text to search for phone numbers, null for no text + * @param defaultRegion region that we are expecting the number to be from. This is only used + * if the number being parsed is not written in international format. The + * country_code for the number in this case would be stored as that of + * the default region supplied. May be null if only international + * numbers are expected. + */ + public Iterable<PhoneNumberMatch> findNumbers(CharSequence text, String defaultRegion) { + return findNumbers(text, defaultRegion, Leniency.VALID, Long.MAX_VALUE); + } + + /** + * Returns an iterable over all {@link PhoneNumberMatch PhoneNumberMatches} in {@code text}. + * + * @param text the text to search for phone numbers, null for no text + * @param defaultRegion region that we are expecting the number to be from. This is only used + * if the number being parsed is not written in international format. The + * country_code for the number in this case would be stored as that of + * the default region supplied. May be null if only international + * numbers are expected. + * @param leniency the leniency to use when evaluating candidate phone numbers + * @param maxTries the maximum number of invalid numbers to try before giving up on the + * text. This is to cover degenerate cases where the text has a lot of + * false positives in it. Must be {@code >= 0}. + */ + public Iterable<PhoneNumberMatch> findNumbers( + final CharSequence text, final String defaultRegion, final Leniency leniency, + final long maxTries) { + + return new Iterable<PhoneNumberMatch>() { + public Iterator<PhoneNumberMatch> iterator() { + return new PhoneNumberMatcher( + PhoneNumberUtil.this, text, defaultRegion, leniency, maxTries); + } + }; + } + + /** + * A helper function to set the values related to leading zeros in a PhoneNumber. + */ + static void setItalianLeadingZerosForPhoneNumber(String nationalNumber, PhoneNumber phoneNumber) { + if (nationalNumber.length() > 1 && nationalNumber.charAt(0) == '0') { + phoneNumber.setItalianLeadingZero(true); + int numberOfLeadingZeros = 1; + // Note that if the national number is all "0"s, the last "0" is not counted as a leading + // zero. + while (numberOfLeadingZeros < nationalNumber.length() - 1 && + nationalNumber.charAt(numberOfLeadingZeros) == '0') { + numberOfLeadingZeros++; + } + if (numberOfLeadingZeros != 1) { + phoneNumber.setNumberOfLeadingZeros(numberOfLeadingZeros); + } + } + } + + /** + * Parses a string and fills up the phoneNumber. This method is the same as the public + * parse() method, with the exception that it allows the default region to be null, for use by + * isNumberMatch(). checkRegion should be set to false if it is permitted for the default region + * to be null or unknown ("ZZ"). + */ + private void parseHelper(String numberToParse, String defaultRegion, boolean keepRawInput, + boolean checkRegion, PhoneNumber phoneNumber) + throws NumberParseException { + if (numberToParse == null) { + throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER, + "The phone number supplied was null."); + } else if (numberToParse.length() > MAX_INPUT_STRING_LENGTH) { + throw new NumberParseException(NumberParseException.ErrorType.TOO_LONG, + "The string supplied was too long to parse."); + } + + StringBuilder nationalNumber = new StringBuilder(); + buildNationalNumberForParsing(numberToParse, nationalNumber); + + if (!isViablePhoneNumber(nationalNumber.toString())) { + throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER, + "The string supplied did not seem to be a phone number."); + } + + // Check the region supplied is valid, or that the extracted number starts with some sort of + + // sign so the number's region can be determined. + if (checkRegion && !checkRegionForParsing(nationalNumber.toString(), defaultRegion)) { + throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE, + "Missing or invalid default region."); + } + + if (keepRawInput) { + phoneNumber.setRawInput(numberToParse); + } + // Attempt to parse extension first, since it doesn't require region-specific data and we want + // to have the non-normalised number here. + String extension = maybeStripExtension(nationalNumber); + if (extension.length() > 0) { + phoneNumber.setExtension(extension); + } + + PhoneMetadata regionMetadata = getMetadataForRegion(defaultRegion); + // Check to see if the number is given in international format so we know whether this number is + // from the default region or not. + StringBuilder normalizedNationalNumber = new StringBuilder(); + int countryCode = 0; + try { + // TODO: This method should really just take in the string buffer that has already + // been created, and just remove the prefix, rather than taking in a string and then + // outputting a string buffer. + countryCode = maybeExtractCountryCode(nationalNumber.toString(), regionMetadata, + normalizedNationalNumber, keepRawInput, phoneNumber); + } catch (NumberParseException e) { + Matcher matcher = PLUS_CHARS_PATTERN.matcher(nationalNumber.toString()); + if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE && + matcher.lookingAt()) { + // Strip the plus-char, and try again. + countryCode = maybeExtractCountryCode(nationalNumber.substring(matcher.end()), + regionMetadata, normalizedNationalNumber, + keepRawInput, phoneNumber); + if (countryCode == 0) { + throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE, + "Could not interpret numbers after plus-sign."); + } + } else { + throw new NumberParseException(e.getErrorType(), e.getMessage()); + } + } + if (countryCode != 0) { + String phoneNumberRegion = getRegionCodeForCountryCode(countryCode); + if (!phoneNumberRegion.equals(defaultRegion)) { + // Metadata cannot be null because the country calling code is valid. + regionMetadata = getMetadataForRegionOrCallingCode(countryCode, phoneNumberRegion); + } + } else { + // If no extracted country calling code, use the region supplied instead. The national number + // is just the normalized version of the number we were given to parse. + normalize(nationalNumber); + normalizedNationalNumber.append(nationalNumber); + if (defaultRegion != null) { + countryCode = regionMetadata.getCountryCode(); + phoneNumber.setCountryCode(countryCode); + } else if (keepRawInput) { + phoneNumber.clearCountryCodeSource(); + } + } + if (normalizedNationalNumber.length() < MIN_LENGTH_FOR_NSN) { + throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_NSN, + "The string supplied is too short to be a phone number."); + } + if (regionMetadata != null) { + StringBuilder carrierCode = new StringBuilder(); + StringBuilder potentialNationalNumber = new StringBuilder(normalizedNationalNumber); + maybeStripNationalPrefixAndCarrierCode(potentialNationalNumber, regionMetadata, carrierCode); + // We require that the NSN remaining after stripping the national prefix and carrier code be + // of a possible length for the region. Otherwise, we don't do the stripping, since the + // original number could be a valid short number. + if (!isShorterThanPossibleNormalNumber(regionMetadata, potentialNationalNumber.toString())) { + normalizedNationalNumber = potentialNationalNumber; + if (keepRawInput) { + phoneNumber.setPreferredDomesticCarrierCode(carrierCode.toString()); + } + } + } + int lengthOfNationalNumber = normalizedNationalNumber.length(); + if (lengthOfNationalNumber < MIN_LENGTH_FOR_NSN) { + throw new NumberParseException(NumberParseException.ErrorType.TOO_SHORT_NSN, + "The string supplied is too short to be a phone number."); + } + if (lengthOfNationalNumber > MAX_LENGTH_FOR_NSN) { + throw new NumberParseException(NumberParseException.ErrorType.TOO_LONG, + "The string supplied is too long to be a phone number."); + } + setItalianLeadingZerosForPhoneNumber(normalizedNationalNumber.toString(), phoneNumber); + phoneNumber.setNationalNumber(Long.parseLong(normalizedNationalNumber.toString())); + } + + /** + * Converts numberToParse to a form that we can parse and write it to nationalNumber if it is + * written in RFC3966; otherwise extract a possible number out of it and write to nationalNumber. + */ + private void buildNationalNumberForParsing(String numberToParse, StringBuilder nationalNumber) { + int indexOfPhoneContext = numberToParse.indexOf(RFC3966_PHONE_CONTEXT); + if (indexOfPhoneContext > 0) { + int phoneContextStart = indexOfPhoneContext + RFC3966_PHONE_CONTEXT.length(); + // If the phone context contains a phone number prefix, we need to capture it, whereas domains + // will be ignored. + if (numberToParse.charAt(phoneContextStart) == PLUS_SIGN) { + // Additional parameters might follow the phone context. If so, we will remove them here + // because the parameters after phone context are not important for parsing the + // phone number. + int phoneContextEnd = numberToParse.indexOf(';', phoneContextStart); + if (phoneContextEnd > 0) { + nationalNumber.append(numberToParse.substring(phoneContextStart, phoneContextEnd)); + } else { + nationalNumber.append(numberToParse.substring(phoneContextStart)); + } + } + + // Now append everything between the "tel:" prefix and the phone-context. This should include + // the national number, an optional extension or isdn-subaddress component. Note we also + // handle the case when "tel:" is missing, as we have seen in some of the phone number inputs. + // In that case, we append everything from the beginning. + int indexOfRfc3966Prefix = numberToParse.indexOf(RFC3966_PREFIX); + int indexOfNationalNumber = (indexOfRfc3966Prefix >= 0) ? + indexOfRfc3966Prefix + RFC3966_PREFIX.length() : 0; + nationalNumber.append(numberToParse.substring(indexOfNationalNumber, indexOfPhoneContext)); + } else { + // Extract a possible number from the string passed in (this strips leading characters that + // could not be the start of a phone number.) + nationalNumber.append(extractPossibleNumber(numberToParse)); + } + + // Delete the isdn-subaddress and everything after it if it is present. Note extension won't + // appear at the same time with isdn-subaddress according to paragraph 5.3 of the RFC3966 spec, + int indexOfIsdn = nationalNumber.indexOf(RFC3966_ISDN_SUBADDRESS); + if (indexOfIsdn > 0) { + nationalNumber.delete(indexOfIsdn, nationalNumber.length()); + } + // If both phone context and isdn-subaddress are absent but other parameters are present, the + // parameters are left in nationalNumber. This is because we are concerned about deleting + // content from a potential number string when there is no strong evidence that the number is + // actually written in RFC3966. + } + + /** + * Takes two phone numbers and compares them for equality. + * + * <p>Returns EXACT_MATCH if the country_code, NSN, presence of a leading zero for Italian numbers + * and any extension present are the same. + * Returns NSN_MATCH if either or both has no region specified, and the NSNs and extensions are + * the same. + * Returns SHORT_NSN_MATCH if either or both has no region specified, or the region specified is + * the same, and one NSN could be a shorter version of the other number. This includes the case + * where one has an extension specified, and the other does not. + * Returns NO_MATCH otherwise. + * For example, the numbers +1 345 657 1234 and 657 1234 are a SHORT_NSN_MATCH. + * The numbers +1 345 657 1234 and 345 657 are a NO_MATCH. + * + * @param firstNumberIn first number to compare + * @param secondNumberIn second number to compare + * + * @return NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH or EXACT_MATCH depending on the level of equality + * of the two numbers, described in the method definition. + */ + public MatchType isNumberMatch(PhoneNumber firstNumberIn, PhoneNumber secondNumberIn) { + // Make copies of the phone number so that the numbers passed in are not edited. + PhoneNumber firstNumber = new PhoneNumber(); + firstNumber.mergeFrom(firstNumberIn); + PhoneNumber secondNumber = new PhoneNumber(); + secondNumber.mergeFrom(secondNumberIn); + // First clear raw_input, country_code_source and preferred_domestic_carrier_code fields and any + // empty-string extensions so that we can use the proto-buffer equality method. + firstNumber.clearRawInput(); + firstNumber.clearCountryCodeSource(); + firstNumber.clearPreferredDomesticCarrierCode(); + secondNumber.clearRawInput(); + secondNumber.clearCountryCodeSource(); + secondNumber.clearPreferredDomesticCarrierCode(); + if (firstNumber.hasExtension() && + firstNumber.getExtension().length() == 0) { + firstNumber.clearExtension(); + } + if (secondNumber.hasExtension() && + secondNumber.getExtension().length() == 0) { + secondNumber.clearExtension(); + } + // Early exit if both had extensions and these are different. + if (firstNumber.hasExtension() && secondNumber.hasExtension() && + !firstNumber.getExtension().equals(secondNumber.getExtension())) { + return MatchType.NO_MATCH; + } + int firstNumberCountryCode = firstNumber.getCountryCode(); + int secondNumberCountryCode = secondNumber.getCountryCode(); + // Both had country_code specified. + if (firstNumberCountryCode != 0 && secondNumberCountryCode != 0) { + if (firstNumber.exactlySameAs(secondNumber)) { + return MatchType.EXACT_MATCH; + } else if (firstNumberCountryCode == secondNumberCountryCode && + isNationalNumberSuffixOfTheOther(firstNumber, secondNumber)) { + // A SHORT_NSN_MATCH occurs if there is a difference because of the presence or absence of + // an 'Italian leading zero', the presence or absence of an extension, or one NSN being a + // shorter variant of the other. + return MatchType.SHORT_NSN_MATCH; + } + // This is not a match. + return MatchType.NO_MATCH; + } + // Checks cases where one or both country_code fields were not specified. To make equality + // checks easier, we first set the country_code fields to be equal. + firstNumber.setCountryCode(secondNumberCountryCode); + // If all else was the same, then this is an NSN_MATCH. + if (firstNumber.exactlySameAs(secondNumber)) { + return MatchType.NSN_MATCH; + } + if (isNationalNumberSuffixOfTheOther(firstNumber, secondNumber)) { + return MatchType.SHORT_NSN_MATCH; + } + return MatchType.NO_MATCH; + } + + // Returns true when one national number is the suffix of the other or both are the same. + private boolean isNationalNumberSuffixOfTheOther(PhoneNumber firstNumber, + PhoneNumber secondNumber) { + String firstNumberNationalNumber = String.valueOf(firstNumber.getNationalNumber()); + String secondNumberNationalNumber = String.valueOf(secondNumber.getNationalNumber()); + // Note that endsWith returns true if the numbers are equal. + return firstNumberNationalNumber.endsWith(secondNumberNationalNumber) || + secondNumberNationalNumber.endsWith(firstNumberNationalNumber); + } + + /** + * Takes two phone numbers as strings and compares them for equality. This is a convenience + * wrapper for {@link #isNumberMatch(PhoneNumber, PhoneNumber)}. No default region is known. + * + * @param firstNumber first number to compare. Can contain formatting, and can have country + * calling code specified with + at the start. + * @param secondNumber second number to compare. Can contain formatting, and can have country + * calling code specified with + at the start. + * @return NOT_A_NUMBER, NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH, EXACT_MATCH. See + * {@link #isNumberMatch(PhoneNumber, PhoneNumber)} for more details. + */ + public MatchType isNumberMatch(String firstNumber, String secondNumber) { + try { + PhoneNumber firstNumberAsProto = parse(firstNumber, UNKNOWN_REGION); + return isNumberMatch(firstNumberAsProto, secondNumber); + } catch (NumberParseException e) { + if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE) { + try { + PhoneNumber secondNumberAsProto = parse(secondNumber, UNKNOWN_REGION); + return isNumberMatch(secondNumberAsProto, firstNumber); + } catch (NumberParseException e2) { + if (e2.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE) { + try { + PhoneNumber firstNumberProto = new PhoneNumber(); + PhoneNumber secondNumberProto = new PhoneNumber(); + parseHelper(firstNumber, null, false, false, firstNumberProto); + parseHelper(secondNumber, null, false, false, secondNumberProto); + return isNumberMatch(firstNumberProto, secondNumberProto); + } catch (NumberParseException e3) { + // Fall through and return MatchType.NOT_A_NUMBER. + } + } + } + } + } + // One or more of the phone numbers we are trying to match is not a viable phone number. + return MatchType.NOT_A_NUMBER; + } + + /** + * Takes two phone numbers and compares them for equality. This is a convenience wrapper for + * {@link #isNumberMatch(PhoneNumber, PhoneNumber)}. No default region is known. + * + * @param firstNumber first number to compare in proto buffer format. + * @param secondNumber second number to compare. Can contain formatting, and can have country + * calling code specified with + at the start. + * @return NOT_A_NUMBER, NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH, EXACT_MATCH. See + * {@link #isNumberMatch(PhoneNumber, PhoneNumber)} for more details. + */ + public MatchType isNumberMatch(PhoneNumber firstNumber, String secondNumber) { + // First see if the second number has an implicit country calling code, by attempting to parse + // it. + try { + PhoneNumber secondNumberAsProto = parse(secondNumber, UNKNOWN_REGION); + return isNumberMatch(firstNumber, secondNumberAsProto); + } catch (NumberParseException e) { + if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE) { + // The second number has no country calling code. EXACT_MATCH is no longer possible. + // We parse it as if the region was the same as that for the first number, and if + // EXACT_MATCH is returned, we replace this with NSN_MATCH. + String firstNumberRegion = getRegionCodeForCountryCode(firstNumber.getCountryCode()); + try { + if (!firstNumberRegion.equals(UNKNOWN_REGION)) { + PhoneNumber secondNumberWithFirstNumberRegion = parse(secondNumber, firstNumberRegion); + MatchType match = isNumberMatch(firstNumber, secondNumberWithFirstNumberRegion); + if (match == MatchType.EXACT_MATCH) { + return MatchType.NSN_MATCH; + } + return match; + } else { + // If the first number didn't have a valid country calling code, then we parse the + // second number without one as well. + PhoneNumber secondNumberProto = new PhoneNumber(); + parseHelper(secondNumber, null, false, false, secondNumberProto); + return isNumberMatch(firstNumber, secondNumberProto); + } + } catch (NumberParseException e2) { + // Fall-through to return NOT_A_NUMBER. + } + } + } + // One or more of the phone numbers we are trying to match is not a viable phone number. + return MatchType.NOT_A_NUMBER; + } + + /** + * Returns true if the number can be dialled from outside the region, or unknown. If the number + * can only be dialled from within the region, returns false. Does not check the number is a valid + * number. Note that, at the moment, this method does not handle short numbers. + * TODO: Make this method public when we have enough metadata to make it worthwhile. + * + * @param number the phone-number for which we want to know whether it is diallable from + * outside the region + */ + // @VisibleForTesting + boolean canBeInternationallyDialled(PhoneNumber number) { + PhoneMetadata metadata = getMetadataForRegion(getRegionCodeForNumber(number)); + if (metadata == null) { + // Note numbers belonging to non-geographical entities (e.g. +800 numbers) are always + // internationally diallable, and will be caught here. + return true; + } + String nationalSignificantNumber = getNationalSignificantNumber(number); + return !isNumberMatchingDesc(nationalSignificantNumber, metadata.getNoInternationalDialling()); + } + + /** + * Returns true if the supplied region supports mobile number portability. Returns false for + * invalid, unknown or regions that don't support mobile number portability. + * + * @param regionCode the region for which we want to know whether it supports mobile number + * portability or not. + */ + public boolean isMobileNumberPortableRegion(String regionCode) { + PhoneMetadata metadata = getMetadataForRegion(regionCode); + if (metadata == null) { + logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode); + return false; + } + return metadata.isMobileNumberPortableRegion(); + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java b/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java new file mode 100644 index 00000000..14904c5e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java @@ -0,0 +1,1053 @@ +/* + * Copyright (C) 2010 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Definition of the class representing metadata for international telephone numbers. This class is + * hand created based on the class file compiled from phonemetadata.proto. Please refer to that file + * for detailed descriptions of the meaning of each field. + */ + +package com.google.i18n.phonenumbers; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +public final class Phonemetadata { + private Phonemetadata() {} + public static class NumberFormat implements Externalizable { + private static final long serialVersionUID = 1; + public NumberFormat() {} + + /** + * Provides a dummy builder to 'emulate' the API of the code generated by the latest version of + * Protocol Buffers. This lets BuildMetadataFromXml class to build with both this hand created + * class and the one generated by the latest version of Protocol Buffers. + */ + public static final class Builder extends NumberFormat { + public NumberFormat build() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } + + // required string pattern = 1; + private boolean hasPattern; + private String pattern_ = ""; + public boolean hasPattern() { return hasPattern; } + public String getPattern() { return pattern_; } + public NumberFormat setPattern(String value) { + hasPattern = true; + pattern_ = value; + return this; + } + + // required string format = 2; + private boolean hasFormat; + private String format_ = ""; + public boolean hasFormat() { return hasFormat; } + public String getFormat() { return format_; } + public NumberFormat setFormat(String value) { + hasFormat = true; + format_ = value; + return this; + } + + // repeated string leading_digits_pattern = 3; + private java.util.List<String> leadingDigitsPattern_ = new java.util.ArrayList<String>(); + public java.util.List<String> leadingDigitPatterns() { + return leadingDigitsPattern_; + } + public int leadingDigitsPatternSize() { return leadingDigitsPattern_.size(); } + public String getLeadingDigitsPattern(int index) { + return leadingDigitsPattern_.get(index); + } + public NumberFormat addLeadingDigitsPattern(String value) { + if (value == null) { + throw new NullPointerException(); + } + leadingDigitsPattern_.add(value); + return this; + } + + // optional string national_prefix_formatting_rule = 4; + private boolean hasNationalPrefixFormattingRule; + private String nationalPrefixFormattingRule_ = ""; + public boolean hasNationalPrefixFormattingRule() { return hasNationalPrefixFormattingRule; } + public String getNationalPrefixFormattingRule() { return nationalPrefixFormattingRule_; } + public NumberFormat setNationalPrefixFormattingRule(String value) { + hasNationalPrefixFormattingRule = true; + nationalPrefixFormattingRule_ = value; + return this; + } + public NumberFormat clearNationalPrefixFormattingRule() { + hasNationalPrefixFormattingRule = false; + nationalPrefixFormattingRule_ = ""; + return this; + } + + // optional bool national_prefix_optional_when_formatting = 6; + private boolean hasNationalPrefixOptionalWhenFormatting; + private boolean nationalPrefixOptionalWhenFormatting_ = false; + public boolean hasNationalPrefixOptionalWhenFormatting() { + return hasNationalPrefixOptionalWhenFormatting; } + public boolean isNationalPrefixOptionalWhenFormatting() { + return nationalPrefixOptionalWhenFormatting_; } + public NumberFormat setNationalPrefixOptionalWhenFormatting(boolean value) { + hasNationalPrefixOptionalWhenFormatting = true; + nationalPrefixOptionalWhenFormatting_ = value; + return this; + } + + // optional string domestic_carrier_code_formatting_rule = 5; + private boolean hasDomesticCarrierCodeFormattingRule; + private String domesticCarrierCodeFormattingRule_ = ""; + public boolean hasDomesticCarrierCodeFormattingRule() { + return hasDomesticCarrierCodeFormattingRule; } + public String getDomesticCarrierCodeFormattingRule() { + return domesticCarrierCodeFormattingRule_; } + public NumberFormat setDomesticCarrierCodeFormattingRule(String value) { + hasDomesticCarrierCodeFormattingRule = true; + domesticCarrierCodeFormattingRule_ = value; + return this; + } + + public NumberFormat mergeFrom(NumberFormat other) { + if (other.hasPattern()) { + setPattern(other.getPattern()); + } + if (other.hasFormat()) { + setFormat(other.getFormat()); + } + int leadingDigitsPatternSize = other.leadingDigitsPatternSize(); + for (int i = 0; i < leadingDigitsPatternSize; i++) { + addLeadingDigitsPattern(other.getLeadingDigitsPattern(i)); + } + if (other.hasNationalPrefixFormattingRule()) { + setNationalPrefixFormattingRule(other.getNationalPrefixFormattingRule()); + } + if (other.hasDomesticCarrierCodeFormattingRule()) { + setDomesticCarrierCodeFormattingRule(other.getDomesticCarrierCodeFormattingRule()); + } + setNationalPrefixOptionalWhenFormatting(other.isNationalPrefixOptionalWhenFormatting()); + return this; + } + + public void writeExternal(ObjectOutput objectOutput) throws IOException { + objectOutput.writeUTF(pattern_); + objectOutput.writeUTF(format_); + int leadingDigitsPatternSize = leadingDigitsPatternSize(); + objectOutput.writeInt(leadingDigitsPatternSize); + for (int i = 0; i < leadingDigitsPatternSize; i++) { + objectOutput.writeUTF(leadingDigitsPattern_.get(i)); + } + + objectOutput.writeBoolean(hasNationalPrefixFormattingRule); + if (hasNationalPrefixFormattingRule) { + objectOutput.writeUTF(nationalPrefixFormattingRule_); + } + objectOutput.writeBoolean(hasDomesticCarrierCodeFormattingRule); + if (hasDomesticCarrierCodeFormattingRule) { + objectOutput.writeUTF(domesticCarrierCodeFormattingRule_); + } + objectOutput.writeBoolean(nationalPrefixOptionalWhenFormatting_); + } + + public void readExternal(ObjectInput objectInput) throws IOException { + setPattern(objectInput.readUTF()); + setFormat(objectInput.readUTF()); + int leadingDigitsPatternSize = objectInput.readInt(); + for (int i = 0; i < leadingDigitsPatternSize; i++) { + leadingDigitsPattern_.add(objectInput.readUTF()); + } + if (objectInput.readBoolean()) { + setNationalPrefixFormattingRule(objectInput.readUTF()); + } + if (objectInput.readBoolean()) { + setDomesticCarrierCodeFormattingRule(objectInput.readUTF()); + } + setNationalPrefixOptionalWhenFormatting(objectInput.readBoolean()); + } + } + + public static class PhoneNumberDesc implements Externalizable { + private static final long serialVersionUID = 1; + public PhoneNumberDesc() {} + + /** + * Provides a dummy builder. + * + * @see NumberFormat.Builder + */ + public static final class Builder extends PhoneNumberDesc { + public PhoneNumberDesc build() { + return this; + } + } + public static Builder newBuilder() { + return new Builder(); + } + + // optional string national_number_pattern = 2; + private boolean hasNationalNumberPattern; + private String nationalNumberPattern_ = ""; + public boolean hasNationalNumberPattern() { return hasNationalNumberPattern; } + public String getNationalNumberPattern() { return nationalNumberPattern_; } + public PhoneNumberDesc setNationalNumberPattern(String value) { + hasNationalNumberPattern = true; + nationalNumberPattern_ = value; + return this; + } + + // optional string possible_number_pattern = 3; + private boolean hasPossibleNumberPattern; + private String possibleNumberPattern_ = ""; + public boolean hasPossibleNumberPattern() { return hasPossibleNumberPattern; } + public String getPossibleNumberPattern() { return possibleNumberPattern_; } + public PhoneNumberDesc setPossibleNumberPattern(String value) { + hasPossibleNumberPattern = true; + possibleNumberPattern_ = value; + return this; + } + + // optional string example_number = 6; + private boolean hasExampleNumber; + private String exampleNumber_ = ""; + public boolean hasExampleNumber() { return hasExampleNumber; } + public String getExampleNumber() { return exampleNumber_; } + public PhoneNumberDesc setExampleNumber(String value) { + hasExampleNumber = true; + exampleNumber_ = value; + return this; + } + + public PhoneNumberDesc mergeFrom(PhoneNumberDesc other) { + if (other.hasNationalNumberPattern()) { + setNationalNumberPattern(other.getNationalNumberPattern()); + } + if (other.hasPossibleNumberPattern()) { + setPossibleNumberPattern(other.getPossibleNumberPattern()); + } + if (other.hasExampleNumber()) { + setExampleNumber(other.getExampleNumber()); + } + return this; + } + + public boolean exactlySameAs(PhoneNumberDesc other) { + return nationalNumberPattern_.equals(other.nationalNumberPattern_) && + possibleNumberPattern_.equals(other.possibleNumberPattern_) && + exampleNumber_.equals(other.exampleNumber_); + } + + public void writeExternal(ObjectOutput objectOutput) throws IOException { + objectOutput.writeBoolean(hasNationalNumberPattern); + if (hasNationalNumberPattern) { + objectOutput.writeUTF(nationalNumberPattern_); + } + + objectOutput.writeBoolean(hasPossibleNumberPattern); + if (hasPossibleNumberPattern) { + objectOutput.writeUTF(possibleNumberPattern_); + } + + objectOutput.writeBoolean(hasExampleNumber); + if (hasExampleNumber) { + objectOutput.writeUTF(exampleNumber_); + } + } + + public void readExternal(ObjectInput objectInput) throws IOException { + if (objectInput.readBoolean()) { + setNationalNumberPattern(objectInput.readUTF()); + } + + if (objectInput.readBoolean()) { + setPossibleNumberPattern(objectInput.readUTF()); + } + + if (objectInput.readBoolean()) { + setExampleNumber(objectInput.readUTF()); + } + } + } + + public static class PhoneMetadata implements Externalizable { + private static final long serialVersionUID = 1; + public PhoneMetadata() {} + + /** + * Provides a dummy builder. + * + * @see NumberFormat.Builder + */ + public static final class Builder extends PhoneMetadata { + public PhoneMetadata build() { + return this; + } + } + public static Builder newBuilder() { + return new Builder(); + } + + // optional PhoneNumberDesc general_desc = 1; + private boolean hasGeneralDesc; + private PhoneNumberDesc generalDesc_ = null; + public boolean hasGeneralDesc() { return hasGeneralDesc; } + public PhoneNumberDesc getGeneralDesc() { return generalDesc_; } + public PhoneMetadata setGeneralDesc(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasGeneralDesc = true; + generalDesc_ = value; + return this; + } + + // optional PhoneNumberDesc fixed_line = 2; + private boolean hasFixedLine; + private PhoneNumberDesc fixedLine_ = null; + public boolean hasFixedLine() { return hasFixedLine; } + public PhoneNumberDesc getFixedLine() { return fixedLine_; } + public PhoneMetadata setFixedLine(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasFixedLine = true; + fixedLine_ = value; + return this; + } + + // optional PhoneNumberDesc mobile = 3; + private boolean hasMobile; + private PhoneNumberDesc mobile_ = null; + public boolean hasMobile() { return hasMobile; } + public PhoneNumberDesc getMobile() { return mobile_; } + public PhoneMetadata setMobile(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasMobile = true; + mobile_ = value; + return this; + } + + // optional PhoneNumberDesc toll_free = 4; + private boolean hasTollFree; + private PhoneNumberDesc tollFree_ = null; + public boolean hasTollFree() { return hasTollFree; } + public PhoneNumberDesc getTollFree() { return tollFree_; } + public PhoneMetadata setTollFree(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasTollFree = true; + tollFree_ = value; + return this; + } + + // optional PhoneNumberDesc premium_rate = 5; + private boolean hasPremiumRate; + private PhoneNumberDesc premiumRate_ = null; + public boolean hasPremiumRate() { return hasPremiumRate; } + public PhoneNumberDesc getPremiumRate() { return premiumRate_; } + public PhoneMetadata setPremiumRate(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasPremiumRate = true; + premiumRate_ = value; + return this; + } + + // optional PhoneNumberDesc shared_cost = 6; + private boolean hasSharedCost; + private PhoneNumberDesc sharedCost_ = null; + public boolean hasSharedCost() { return hasSharedCost; } + public PhoneNumberDesc getSharedCost() { return sharedCost_; } + public PhoneMetadata setSharedCost(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasSharedCost = true; + sharedCost_ = value; + return this; + } + + // optional PhoneNumberDesc personal_number = 7; + private boolean hasPersonalNumber; + private PhoneNumberDesc personalNumber_ = null; + public boolean hasPersonalNumber() { return hasPersonalNumber; } + public PhoneNumberDesc getPersonalNumber() { return personalNumber_; } + public PhoneMetadata setPersonalNumber(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasPersonalNumber = true; + personalNumber_ = value; + return this; + } + + // optional PhoneNumberDesc voip = 8; + private boolean hasVoip; + private PhoneNumberDesc voip_ = null; + public boolean hasVoip() { return hasVoip; } + public PhoneNumberDesc getVoip() { return voip_; } + public PhoneMetadata setVoip(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasVoip = true; + voip_ = value; + return this; + } + + // optional PhoneNumberDesc pager = 21; + private boolean hasPager; + private PhoneNumberDesc pager_ = null; + public boolean hasPager() { return hasPager; } + public PhoneNumberDesc getPager() { return pager_; } + public PhoneMetadata setPager(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasPager = true; + pager_ = value; + return this; + } + + // optional PhoneNumberDesc uan = 25; + private boolean hasUan; + private PhoneNumberDesc uan_ = null; + public boolean hasUan() { return hasUan; } + public PhoneNumberDesc getUan() { return uan_; } + public PhoneMetadata setUan(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasUan = true; + uan_ = value; + return this; + } + + // optional PhoneNumberDesc emergency = 27; + private boolean hasEmergency; + private PhoneNumberDesc emergency_ = null; + public boolean hasEmergency() { return hasEmergency; } + public PhoneNumberDesc getEmergency() { return emergency_; } + public PhoneMetadata setEmergency(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasEmergency = true; + emergency_ = value; + return this; + } + + // optional PhoneNumberDesc voicemail = 28; + private boolean hasVoicemail; + private PhoneNumberDesc voicemail_ = null; + public boolean hasVoicemail() { return hasVoicemail; } + public PhoneNumberDesc getVoicemail() { return voicemail_; } + public PhoneMetadata setVoicemail(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasVoicemail = true; + voicemail_ = value; + return this; + } + + // optional PhoneNumberDesc short_code = 29; + private boolean hasShortCode; + private PhoneNumberDesc shortCode_ = null; + public boolean hasShortCode() { return hasShortCode; } + public PhoneNumberDesc getShortCode() { return shortCode_; } + public PhoneMetadata setShortCode(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasShortCode = true; + shortCode_ = value; + return this; + } + + // optional PhoneNumberDesc standard_rate = 30; + private boolean hasStandardRate; + private PhoneNumberDesc standardRate_ = null; + public boolean hasStandardRate() { return hasStandardRate; } + public PhoneNumberDesc getStandardRate() { return standardRate_; } + public PhoneMetadata setStandardRate(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasStandardRate = true; + standardRate_ = value; + return this; + } + + // optional PhoneNumberDesc carrier_specific = 31; + private boolean hasCarrierSpecific; + private PhoneNumberDesc carrierSpecific_ = null; + public boolean hasCarrierSpecific() { return hasCarrierSpecific; } + public PhoneNumberDesc getCarrierSpecific() { return carrierSpecific_; } + public PhoneMetadata setCarrierSpecific(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasCarrierSpecific = true; + carrierSpecific_ = value; + return this; + } + + // optional PhoneNumberDesc noInternationalDialling = 24; + private boolean hasNoInternationalDialling; + private PhoneNumberDesc noInternationalDialling_ = null; + public boolean hasNoInternationalDialling() { return hasNoInternationalDialling; } + public PhoneNumberDesc getNoInternationalDialling() { return noInternationalDialling_; } + public PhoneMetadata setNoInternationalDialling(PhoneNumberDesc value) { + if (value == null) { + throw new NullPointerException(); + } + hasNoInternationalDialling = true; + noInternationalDialling_ = value; + return this; + } + + // required string id = 9; + private boolean hasId; + private String id_ = ""; + public boolean hasId() { return hasId; } + public String getId() { return id_; } + public PhoneMetadata setId(String value) { + hasId = true; + id_ = value; + return this; + } + + // optional int32 country_code = 10; + private boolean hasCountryCode; + private int countryCode_ = 0; + public boolean hasCountryCode() { return hasCountryCode; } + public int getCountryCode() { return countryCode_; } + public PhoneMetadata setCountryCode(int value) { + hasCountryCode = true; + countryCode_ = value; + return this; + } + + // optional string international_prefix = 11; + private boolean hasInternationalPrefix; + private String internationalPrefix_ = ""; + public boolean hasInternationalPrefix() { return hasInternationalPrefix; } + public String getInternationalPrefix() { return internationalPrefix_; } + public PhoneMetadata setInternationalPrefix(String value) { + hasInternationalPrefix = true; + internationalPrefix_ = value; + return this; + } + + // optional string preferred_international_prefix = 17; + private boolean hasPreferredInternationalPrefix; + private String preferredInternationalPrefix_ = ""; + public boolean hasPreferredInternationalPrefix() { return hasPreferredInternationalPrefix; } + public String getPreferredInternationalPrefix() { return preferredInternationalPrefix_; } + public PhoneMetadata setPreferredInternationalPrefix(String value) { + hasPreferredInternationalPrefix = true; + preferredInternationalPrefix_ = value; + return this; + } + + // optional string national_prefix = 12; + private boolean hasNationalPrefix; + private String nationalPrefix_ = ""; + public boolean hasNationalPrefix() { return hasNationalPrefix; } + public String getNationalPrefix() { return nationalPrefix_; } + public PhoneMetadata setNationalPrefix(String value) { + hasNationalPrefix = true; + nationalPrefix_ = value; + return this; + } + + // optional string preferred_extn_prefix = 13; + private boolean hasPreferredExtnPrefix; + private String preferredExtnPrefix_ = ""; + public boolean hasPreferredExtnPrefix() { return hasPreferredExtnPrefix; } + public String getPreferredExtnPrefix() { return preferredExtnPrefix_; } + public PhoneMetadata setPreferredExtnPrefix(String value) { + hasPreferredExtnPrefix = true; + preferredExtnPrefix_ = value; + return this; + } + + // optional string national_prefix_for_parsing = 15; + private boolean hasNationalPrefixForParsing; + private String nationalPrefixForParsing_ = ""; + public boolean hasNationalPrefixForParsing() { return hasNationalPrefixForParsing; } + public String getNationalPrefixForParsing() { return nationalPrefixForParsing_; } + public PhoneMetadata setNationalPrefixForParsing(String value) { + hasNationalPrefixForParsing = true; + nationalPrefixForParsing_ = value; + return this; + } + + // optional string national_prefix_transform_rule = 16; + private boolean hasNationalPrefixTransformRule; + private String nationalPrefixTransformRule_ = ""; + public boolean hasNationalPrefixTransformRule() { return hasNationalPrefixTransformRule; } + public String getNationalPrefixTransformRule() { return nationalPrefixTransformRule_; } + public PhoneMetadata setNationalPrefixTransformRule(String value) { + hasNationalPrefixTransformRule = true; + nationalPrefixTransformRule_ = value; + return this; + } + + // optional bool same_mobile_and_fixed_line_pattern = 18 [default = false]; + private boolean hasSameMobileAndFixedLinePattern; + private boolean sameMobileAndFixedLinePattern_ = false; + public boolean hasSameMobileAndFixedLinePattern() { return hasSameMobileAndFixedLinePattern; } + public boolean isSameMobileAndFixedLinePattern() { return sameMobileAndFixedLinePattern_; } + public PhoneMetadata setSameMobileAndFixedLinePattern(boolean value) { + hasSameMobileAndFixedLinePattern = true; + sameMobileAndFixedLinePattern_ = value; + return this; + } + + // repeated NumberFormat number_format = 19; + private java.util.List<NumberFormat> numberFormat_ = new java.util.ArrayList<NumberFormat>(); + public java.util.List<NumberFormat> numberFormats() { + return numberFormat_; + } + public int numberFormatSize() { return numberFormat_.size(); } + public NumberFormat getNumberFormat(int index) { + return numberFormat_.get(index); + } + public PhoneMetadata addNumberFormat(NumberFormat value) { + if (value == null) { + throw new NullPointerException(); + } + numberFormat_.add(value); + return this; + } + + // repeated NumberFormat intl_number_format = 20; + private java.util.List<NumberFormat> intlNumberFormat_ = + new java.util.ArrayList<NumberFormat>(); + public java.util.List<NumberFormat> intlNumberFormats() { + return intlNumberFormat_; + } + public int intlNumberFormatSize() { return intlNumberFormat_.size(); } + public NumberFormat getIntlNumberFormat(int index) { + return intlNumberFormat_.get(index); + } + + public PhoneMetadata addIntlNumberFormat(NumberFormat value) { + if (value == null) { + throw new NullPointerException(); + } + intlNumberFormat_.add(value); + return this; + } + public PhoneMetadata clearIntlNumberFormat() { + intlNumberFormat_.clear(); + return this; + } + + // optional bool main_country_for_code = 22 [default = false]; + private boolean hasMainCountryForCode; + private boolean mainCountryForCode_ = false; + public boolean hasMainCountryForCode() { return hasMainCountryForCode; } + public boolean isMainCountryForCode() { return mainCountryForCode_; } + // Method that lets this class have the same interface as the one generated by Protocol Buffers + // which is used by C++ build tools. + public boolean getMainCountryForCode() { return mainCountryForCode_; } + public PhoneMetadata setMainCountryForCode(boolean value) { + hasMainCountryForCode = true; + mainCountryForCode_ = value; + return this; + } + + // optional string leading_digits = 23; + private boolean hasLeadingDigits; + private String leadingDigits_ = ""; + public boolean hasLeadingDigits() { return hasLeadingDigits; } + public String getLeadingDigits() { return leadingDigits_; } + public PhoneMetadata setLeadingDigits(String value) { + hasLeadingDigits = true; + leadingDigits_ = value; + return this; + } + + // optional bool leading_zero_possible = 26 [default = false]; + private boolean hasLeadingZeroPossible; + private boolean leadingZeroPossible_ = false; + public boolean hasLeadingZeroPossible() { return hasLeadingZeroPossible; } + public boolean isLeadingZeroPossible() { return leadingZeroPossible_; } + public PhoneMetadata setLeadingZeroPossible(boolean value) { + hasLeadingZeroPossible = true; + leadingZeroPossible_ = value; + return this; + } + + // optional bool mobile_number_portable_region = 32 [default = false]; + private boolean hasMobileNumberPortableRegion; + private boolean mobileNumberPortableRegion_ = false; + public boolean hasMobileNumberPortableRegion() { return hasMobileNumberPortableRegion; } + public boolean isMobileNumberPortableRegion() { return mobileNumberPortableRegion_; } + public PhoneMetadata setMobileNumberPortableRegion(boolean value) { + hasMobileNumberPortableRegion = true; + mobileNumberPortableRegion_ = value; + return this; + } + + public void writeExternal(ObjectOutput objectOutput) throws IOException { + objectOutput.writeBoolean(hasGeneralDesc); + if (hasGeneralDesc) { + generalDesc_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasFixedLine); + if (hasFixedLine) { + fixedLine_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasMobile); + if (hasMobile) { + mobile_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasTollFree); + if (hasTollFree) { + tollFree_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasPremiumRate); + if (hasPremiumRate) { + premiumRate_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasSharedCost); + if (hasSharedCost) { + sharedCost_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasPersonalNumber); + if (hasPersonalNumber) { + personalNumber_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasVoip); + if (hasVoip) { + voip_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasPager); + if (hasPager) { + pager_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasUan); + if (hasUan) { + uan_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasEmergency); + if (hasEmergency) { + emergency_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasVoicemail); + if (hasVoicemail) { + voicemail_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasShortCode); + if (hasShortCode) { + shortCode_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasStandardRate); + if (hasStandardRate) { + standardRate_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasCarrierSpecific); + if (hasCarrierSpecific) { + carrierSpecific_.writeExternal(objectOutput); + } + objectOutput.writeBoolean(hasNoInternationalDialling); + if (hasNoInternationalDialling) { + noInternationalDialling_.writeExternal(objectOutput); + } + + objectOutput.writeUTF(id_); + objectOutput.writeInt(countryCode_); + objectOutput.writeUTF(internationalPrefix_); + + objectOutput.writeBoolean(hasPreferredInternationalPrefix); + if (hasPreferredInternationalPrefix) { + objectOutput.writeUTF(preferredInternationalPrefix_); + } + + objectOutput.writeBoolean(hasNationalPrefix); + if (hasNationalPrefix) { + objectOutput.writeUTF(nationalPrefix_); + } + + objectOutput.writeBoolean(hasPreferredExtnPrefix); + if (hasPreferredExtnPrefix) { + objectOutput.writeUTF(preferredExtnPrefix_); + } + + objectOutput.writeBoolean(hasNationalPrefixForParsing); + if (hasNationalPrefixForParsing) { + objectOutput.writeUTF(nationalPrefixForParsing_); + } + + objectOutput.writeBoolean(hasNationalPrefixTransformRule); + if (hasNationalPrefixTransformRule) { + objectOutput.writeUTF(nationalPrefixTransformRule_); + } + + objectOutput.writeBoolean(sameMobileAndFixedLinePattern_); + + int numberFormatSize = numberFormatSize(); + objectOutput.writeInt(numberFormatSize); + for (int i = 0; i < numberFormatSize; i++) { + numberFormat_.get(i).writeExternal(objectOutput); + } + + int intlNumberFormatSize = intlNumberFormatSize(); + objectOutput.writeInt(intlNumberFormatSize); + for (int i = 0; i < intlNumberFormatSize; i++) { + intlNumberFormat_.get(i).writeExternal(objectOutput); + } + + objectOutput.writeBoolean(mainCountryForCode_); + + objectOutput.writeBoolean(hasLeadingDigits); + if (hasLeadingDigits) { + objectOutput.writeUTF(leadingDigits_); + } + + objectOutput.writeBoolean(leadingZeroPossible_); + + objectOutput.writeBoolean(mobileNumberPortableRegion_); + } + + public void readExternal(ObjectInput objectInput) throws IOException { + boolean hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setGeneralDesc(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setFixedLine(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setMobile(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setTollFree(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setPremiumRate(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setSharedCost(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setPersonalNumber(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setVoip(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setPager(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setUan(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setEmergency(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setVoicemail(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setShortCode(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setStandardRate(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setCarrierSpecific(desc); + } + hasDesc = objectInput.readBoolean(); + if (hasDesc) { + PhoneNumberDesc desc = new PhoneNumberDesc(); + desc.readExternal(objectInput); + setNoInternationalDialling(desc); + } + + setId(objectInput.readUTF()); + setCountryCode(objectInput.readInt()); + setInternationalPrefix(objectInput.readUTF()); + + boolean hasString = objectInput.readBoolean(); + if (hasString) { + setPreferredInternationalPrefix(objectInput.readUTF()); + } + + hasString = objectInput.readBoolean(); + if (hasString) { + setNationalPrefix(objectInput.readUTF()); + } + + hasString = objectInput.readBoolean(); + if (hasString) { + setPreferredExtnPrefix(objectInput.readUTF()); + } + + hasString = objectInput.readBoolean(); + if (hasString) { + setNationalPrefixForParsing(objectInput.readUTF()); + } + + hasString = objectInput.readBoolean(); + if (hasString) { + setNationalPrefixTransformRule(objectInput.readUTF()); + } + + setSameMobileAndFixedLinePattern(objectInput.readBoolean()); + + int nationalFormatSize = objectInput.readInt(); + for (int i = 0; i < nationalFormatSize; i++) { + NumberFormat numFormat = new NumberFormat(); + numFormat.readExternal(objectInput); + numberFormat_.add(numFormat); + } + + int intlNumberFormatSize = objectInput.readInt(); + for (int i = 0; i < intlNumberFormatSize; i++) { + NumberFormat numFormat = new NumberFormat(); + numFormat.readExternal(objectInput); + intlNumberFormat_.add(numFormat); + } + + setMainCountryForCode(objectInput.readBoolean()); + + hasString = objectInput.readBoolean(); + if (hasString) { + setLeadingDigits(objectInput.readUTF()); + } + + setLeadingZeroPossible(objectInput.readBoolean()); + + setMobileNumberPortableRegion(objectInput.readBoolean()); + } + } + + public static class PhoneMetadataCollection implements Externalizable { + private static final long serialVersionUID = 1; + public PhoneMetadataCollection() {} + + /** + * Provides a dummy builder. + * + * @see NumberFormat.Builder + */ + public static final class Builder extends PhoneMetadataCollection { + public PhoneMetadataCollection build() { + return this; + } + } + public static Builder newBuilder() { + return new Builder(); + } + + // repeated PhoneMetadata metadata = 1; + private java.util.List<PhoneMetadata> metadata_ = new java.util.ArrayList<PhoneMetadata>(); + + public java.util.List<PhoneMetadata> getMetadataList() { + return metadata_; + } + public int getMetadataCount() { return metadata_.size(); } + + public PhoneMetadataCollection addMetadata(PhoneMetadata value) { + if (value == null) { + throw new NullPointerException(); + } + metadata_.add(value); + return this; + } + + public void writeExternal(ObjectOutput objectOutput) throws IOException { + int size = getMetadataCount(); + objectOutput.writeInt(size); + for (int i = 0; i < size; i++) { + metadata_.get(i).writeExternal(objectOutput); + } + } + + public void readExternal(ObjectInput objectInput) throws IOException { + int size = objectInput.readInt(); + for (int i = 0; i < size; i++) { + PhoneMetadata metadata = new PhoneMetadata(); + metadata.readExternal(objectInput); + metadata_.add(metadata); + } + } + + public PhoneMetadataCollection clear() { + metadata_.clear(); + return this; + } + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java b/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java new file mode 100644 index 00000000..6ac5b83d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2010 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Definition of the class representing international telephone numbers. This class is hand-created + * based on the class file compiled from phonenumber.proto. Please refer to that file for detailed + * descriptions of the meaning of each field. + */ + +package com.google.i18n.phonenumbers; + +import java.io.Serializable; + +public final class Phonenumber { + private Phonenumber() {} + public static class PhoneNumber implements Serializable { + private static final long serialVersionUID = 1L; + public enum CountryCodeSource { + FROM_NUMBER_WITH_PLUS_SIGN, + FROM_NUMBER_WITH_IDD, + FROM_NUMBER_WITHOUT_PLUS_SIGN, + FROM_DEFAULT_COUNTRY + } + + public PhoneNumber() { + countryCodeSource_ = CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN; + } + + // required int32 country_code = 1; + private boolean hasCountryCode; + private int countryCode_ = 0; + public boolean hasCountryCode() { return hasCountryCode; } + public int getCountryCode() { return countryCode_; } + public PhoneNumber setCountryCode(int value) { + hasCountryCode = true; + countryCode_ = value; + return this; + } + public PhoneNumber clearCountryCode() { + hasCountryCode = false; + countryCode_ = 0; + return this; + } + + // required uint64 national_number = 2; + private boolean hasNationalNumber; + private long nationalNumber_ = 0L; + public boolean hasNationalNumber() { return hasNationalNumber; } + public long getNationalNumber() { return nationalNumber_; } + public PhoneNumber setNationalNumber(long value) { + hasNationalNumber = true; + nationalNumber_ = value; + return this; + } + public PhoneNumber clearNationalNumber() { + hasNationalNumber = false; + nationalNumber_ = 0L; + return this; + } + + // optional string extension = 3; + private boolean hasExtension; + private java.lang.String extension_ = ""; + public boolean hasExtension() { return hasExtension; } + public String getExtension() { return extension_; } + public PhoneNumber setExtension(String value) { + if (value == null) { + throw new NullPointerException(); + } + hasExtension = true; + extension_ = value; + return this; + } + public PhoneNumber clearExtension() { + hasExtension = false; + extension_ = ""; + return this; + } + + // optional bool italian_leading_zero = 4; + private boolean hasItalianLeadingZero; + private boolean italianLeadingZero_ = false; + public boolean hasItalianLeadingZero() { return hasItalianLeadingZero; } + public boolean isItalianLeadingZero() { return italianLeadingZero_; } + public PhoneNumber setItalianLeadingZero(boolean value) { + hasItalianLeadingZero = true; + italianLeadingZero_ = value; + return this; + } + public PhoneNumber clearItalianLeadingZero() { + hasItalianLeadingZero = false; + italianLeadingZero_ = false; + return this; + } + + // optional int32 number_of_leading_zeros = 8 [default = 1]; + private boolean hasNumberOfLeadingZeros; + private int numberOfLeadingZeros_ = 1; + public boolean hasNumberOfLeadingZeros() { return hasNumberOfLeadingZeros; } + public int getNumberOfLeadingZeros() { return numberOfLeadingZeros_; } + public PhoneNumber setNumberOfLeadingZeros(int value) { + hasNumberOfLeadingZeros = true; + numberOfLeadingZeros_ = value; + return this; + } + public PhoneNumber clearNumberOfLeadingZeros() { + hasNumberOfLeadingZeros = false; + numberOfLeadingZeros_ = 1; + return this; + } + + // optional string raw_input = 5; + private boolean hasRawInput; + private String rawInput_ = ""; + public boolean hasRawInput() { return hasRawInput; } + public String getRawInput() { return rawInput_; } + public PhoneNumber setRawInput(String value) { + if (value == null) { + throw new NullPointerException(); + } + hasRawInput = true; + rawInput_ = value; + return this; + } + public PhoneNumber clearRawInput() { + hasRawInput = false; + rawInput_ = ""; + return this; + } + + // optional CountryCodeSource country_code_source = 6; + private boolean hasCountryCodeSource; + private CountryCodeSource countryCodeSource_; + public boolean hasCountryCodeSource() { return hasCountryCodeSource; } + public CountryCodeSource getCountryCodeSource() { return countryCodeSource_; } + public PhoneNumber setCountryCodeSource(CountryCodeSource value) { + if (value == null) { + throw new NullPointerException(); + } + hasCountryCodeSource = true; + countryCodeSource_ = value; + return this; + } + public PhoneNumber clearCountryCodeSource() { + hasCountryCodeSource = false; + countryCodeSource_ = CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN; + return this; + } + + // optional string preferred_domestic_carrier_code = 7; + private boolean hasPreferredDomesticCarrierCode; + private java.lang.String preferredDomesticCarrierCode_ = ""; + public boolean hasPreferredDomesticCarrierCode() { return hasPreferredDomesticCarrierCode; } + public String getPreferredDomesticCarrierCode() { return preferredDomesticCarrierCode_; } + public PhoneNumber setPreferredDomesticCarrierCode(String value) { + if (value == null) { + throw new NullPointerException(); + } + hasPreferredDomesticCarrierCode = true; + preferredDomesticCarrierCode_ = value; + return this; + } + public PhoneNumber clearPreferredDomesticCarrierCode() { + hasPreferredDomesticCarrierCode = false; + preferredDomesticCarrierCode_ = ""; + return this; + } + + public final PhoneNumber clear() { + clearCountryCode(); + clearNationalNumber(); + clearExtension(); + clearItalianLeadingZero(); + clearNumberOfLeadingZeros(); + clearRawInput(); + clearCountryCodeSource(); + clearPreferredDomesticCarrierCode(); + return this; + } + + public PhoneNumber mergeFrom(PhoneNumber other) { + if (other.hasCountryCode()) { + setCountryCode(other.getCountryCode()); + } + if (other.hasNationalNumber()) { + setNationalNumber(other.getNationalNumber()); + } + if (other.hasExtension()) { + setExtension(other.getExtension()); + } + if (other.hasItalianLeadingZero()) { + setItalianLeadingZero(other.isItalianLeadingZero()); + } + if (other.hasNumberOfLeadingZeros()) { + setNumberOfLeadingZeros(other.getNumberOfLeadingZeros()); + } + if (other.hasRawInput()) { + setRawInput(other.getRawInput()); + } + if (other.hasCountryCodeSource()) { + setCountryCodeSource(other.getCountryCodeSource()); + } + if (other.hasPreferredDomesticCarrierCode()) { + setPreferredDomesticCarrierCode(other.getPreferredDomesticCarrierCode()); + } + return this; + } + + public boolean exactlySameAs(PhoneNumber other) { + if (other == null) { + return false; + } + if (this == other) { + return true; + } + return (countryCode_ == other.countryCode_ && nationalNumber_ == other.nationalNumber_ && + extension_.equals(other.extension_) && italianLeadingZero_ == other.italianLeadingZero_ && + numberOfLeadingZeros_ == other.numberOfLeadingZeros_ && + rawInput_.equals(other.rawInput_) && countryCodeSource_ == other.countryCodeSource_ && + preferredDomesticCarrierCode_.equals(other.preferredDomesticCarrierCode_) && + hasPreferredDomesticCarrierCode() == other.hasPreferredDomesticCarrierCode()); + } + + @Override + public boolean equals(Object that) { + return (that instanceof PhoneNumber) && exactlySameAs((PhoneNumber) that); + } + + @Override + public int hashCode() { + // Simplified rendition of the hashCode function automatically generated from the proto + // compiler with java_generate_equals_and_hash set to true. We are happy with unset values to + // be considered equal to their explicitly-set equivalents, so don't check if any value is + // unknown. The only exception to this is the preferred domestic carrier code. + int hash = 41; + hash = (53 * hash) + getCountryCode(); + hash = (53 * hash) + Long.valueOf(getNationalNumber()).hashCode(); + hash = (53 * hash) + getExtension().hashCode(); + hash = (53 * hash) + (isItalianLeadingZero() ? 1231 : 1237); + hash = (53 * hash) + getNumberOfLeadingZeros(); + hash = (53 * hash) + getRawInput().hashCode(); + hash = (53 * hash) + getCountryCodeSource().hashCode(); + hash = (53 * hash) + getPreferredDomesticCarrierCode().hashCode(); + hash = (53 * hash) + (hasPreferredDomesticCarrierCode() ? 1231 : 1237); + return hash; + } + + @Override + public String toString() { + StringBuilder outputString = new StringBuilder(); + outputString.append("Country Code: ").append(countryCode_); + outputString.append(" National Number: ").append(nationalNumber_); + if (hasItalianLeadingZero() && isItalianLeadingZero()) { + outputString.append(" Leading Zero(s): true"); + } + if (hasNumberOfLeadingZeros()) { + outputString.append(" Number of leading zeros: ").append(numberOfLeadingZeros_); + } + if (hasExtension()) { + outputString.append(" Extension: ").append(extension_); + } + if (hasCountryCodeSource()) { + outputString.append(" Country Code Source: ").append(countryCodeSource_); + } + if (hasPreferredDomesticCarrierCode()) { + outputString.append(" Preferred Domestic Carrier Code: "). + append(preferredDomesticCarrierCode_); + } + return outputString.toString(); + } + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/RegexCache.java b/libphonenumber/src/com/google/i18n/phonenumbers/RegexCache.java new file mode 100644 index 00000000..a9ff7e02 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/RegexCache.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * LRU Cache for compiled regular expressions used by the libphonenumbers libary. + * + * @author Shaopeng Jia + */ +public class RegexCache { + private LRUCache<String, Pattern> cache; + + public RegexCache(int size) { + cache = new LRUCache<String, Pattern>(size); + } + + public Pattern getPatternForRegex(String regex) { + Pattern pattern = cache.get(regex); + if (pattern == null) { + pattern = Pattern.compile(regex); + cache.put(regex, pattern); + } + return pattern; + } + + // This method is used for testing. + boolean containsRegex(String regex) { + return cache.containsKey(regex); + } + + private static class LRUCache<K, V> { + // LinkedHashMap offers a straightforward implementation of LRU cache. + private LinkedHashMap<K, V> map; + private int size; + + @SuppressWarnings("serial") + public LRUCache(int size) { + this.size = size; + map = new LinkedHashMap<K, V>(size * 4 / 3 + 1, 0.75f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { + return size() > LRUCache.this.size; + } + }; + } + + public synchronized V get(K key) { + return map.get(key); + } + + public synchronized void put(K key, V value) { + map.put(key, value); + } + + public synchronized boolean containsKey(K key) { + return map.containsKey(key); + } + } +} + diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java b/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java new file mode 100644 index 00000000..401d260d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java @@ -0,0 +1,587 @@ +/* + * Copyright (C) 2013 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import com.google.i18n.phonenumbers.internal.MatcherApi; +import com.google.i18n.phonenumbers.internal.RegexBasedMatcher; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Methods for getting information about short phone numbers, such as short codes and emergency + * numbers. Note that most commercial short numbers are not handled here, but by the + * {@link PhoneNumberUtil}. + * + * @author Shaopeng Jia + * @author David Yonge-Mallo + */ +public class ShortNumberInfo { + private static final Logger logger = Logger.getLogger(ShortNumberInfo.class.getName()); + + private static final ShortNumberInfo INSTANCE = + new ShortNumberInfo(RegexBasedMatcher.create()); + + // In these countries, if extra digits are added to an emergency number, it no longer connects + // to the emergency service. + private static final Set<String> REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT = + new HashSet<String>(); + static { + REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.add("BR"); + REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.add("CL"); + REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.add("NI"); + } + + /** Cost categories of short numbers. */ + public enum ShortNumberCost { + TOLL_FREE, + STANDARD_RATE, + PREMIUM_RATE, + UNKNOWN_COST + } + + /** Returns the singleton instance of the ShortNumberInfo. */ + public static ShortNumberInfo getInstance() { + return INSTANCE; + } + + // MatcherApi supports the basic matching method for checking if a given national number matches + // a national number patten or a possible number patten defined in the given + // {@code PhoneNumberDesc}. + private final MatcherApi matcherApi; + + // A mapping from a country calling code to the region codes which denote the region represented + // by that country calling code. In the case of multiple regions sharing a calling code, such as + // the NANPA regions, the one indicated with "isMainCountryForCode" in the metadata should be + // first. + private final Map<Integer, List<String>> countryCallingCodeToRegionCodeMap; + + // @VisibleForTesting + ShortNumberInfo(MatcherApi matcherApi) { + this.matcherApi = matcherApi; + // TODO: Create ShortNumberInfo for a given map + this.countryCallingCodeToRegionCodeMap = + CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap(); + } + + /** + * Returns a list with the region codes that match the specific country calling code. For + * non-geographical country calling codes, the region code 001 is returned. Also, in the case + * of no region code being found, an empty list is returned. + */ + private List<String> getRegionCodesForCountryCode(int countryCallingCode) { + List<String> regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode); + return Collections.unmodifiableList(regionCodes == null ? new ArrayList<String>(0) + : regionCodes); + } + + /** + * Check whether a short number is a possible number when dialled from a region, given the number + * in the form of a string, and the region where the number is dialed from. This provides a more + * lenient check than {@link #isValidShortNumberForRegion}. + * + * @param shortNumber the short number to check as a string + * @param regionDialingFrom the region from which the number is dialed + * @return whether the number is a possible short number + * @deprecated Anyone who was using it and passing in a string with whitespace (or other + * formatting characters) would have been getting the wrong result. You should parse + * the string to PhoneNumber and use the method + * {@code #isPossibleShortNumberForRegion(PhoneNumber, String)}. This method will be + * removed in the next release. + */ + @Deprecated + public boolean isPossibleShortNumberForRegion(String shortNumber, String regionDialingFrom) { + PhoneMetadata phoneMetadata = + MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); + if (phoneMetadata == null) { + return false; + } + return matcherApi.matchesPossibleNumber(shortNumber, phoneMetadata.getGeneralDesc()); + } + + /** + * Check whether a short number is a possible number when dialed from the given region. This + * provides a more lenient check than {@link #isValidShortNumberForRegion}. + * + * @param number the short number to check + * @param regionDialingFrom the region from which the number is dialed + * @return whether the number is a possible short number + */ + public boolean isPossibleShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { + PhoneMetadata phoneMetadata = + MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); + if (phoneMetadata == null) { + return false; + } + return matcherApi.matchesPossibleNumber(getNationalSignificantNumber(number), + phoneMetadata.getGeneralDesc()); + } + + /** + * Check whether a short number is a possible number. If a country calling code is shared by + * multiple regions, this returns true if it's possible in any of them. This provides a more + * lenient check than {@link #isValidShortNumber}. See {@link + * #isPossibleShortNumberForRegion(PhoneNumber, String)} for details. + * + * @param number the short number to check + * @return whether the number is a possible short number + */ + public boolean isPossibleShortNumber(PhoneNumber number) { + List<String> regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); + String shortNumber = getNationalSignificantNumber(number); + for (String region : regionCodes) { + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(region); + if (matcherApi.matchesPossibleNumber(shortNumber, phoneMetadata.getGeneralDesc())) { + return true; + } + } + return false; + } + + /** + * Tests whether a short number matches a valid pattern in a region. Note that this doesn't verify + * the number is actually in use, which is impossible to tell by just looking at the number + * itself. + * + * @param shortNumber the short number to check as a string + * @param regionDialingFrom the region from which the number is dialed + * @return whether the short number matches a valid pattern + * @deprecated Anyone who was using it and passing in a string with whitespace (or other + * formatting characters) would have been getting the wrong result. You should parse + * the string to PhoneNumber and use the method + * {@code #isValidShortNumberForRegion(PhoneNumber, String)}. This method will be + * removed in the next release. + */ + @Deprecated + public boolean isValidShortNumberForRegion(String shortNumber, String regionDialingFrom) { + PhoneMetadata phoneMetadata = + MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); + if (phoneMetadata == null) { + return false; + } + PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc(); + if (!matchesPossibleNumberAndNationalNumber(shortNumber, generalDesc)) { + return false; + } + PhoneNumberDesc shortNumberDesc = phoneMetadata.getShortCode(); + return matchesPossibleNumberAndNationalNumber(shortNumber, shortNumberDesc); + } + + /** + * Tests whether a short number matches a valid pattern in a region. Note that this doesn't verify + * the number is actually in use, which is impossible to tell by just looking at the number + * itself. + * + * @param number the short number for which we want to test the validity + * @param regionDialingFrom the region from which the number is dialed + * @return whether the short number matches a valid pattern + */ + public boolean isValidShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { + PhoneMetadata phoneMetadata = + MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); + if (phoneMetadata == null) { + return false; + } + String shortNumber = getNationalSignificantNumber(number); + PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc(); + if (!matchesPossibleNumberAndNationalNumber(shortNumber, generalDesc)) { + return false; + } + PhoneNumberDesc shortNumberDesc = phoneMetadata.getShortCode(); + return matchesPossibleNumberAndNationalNumber(shortNumber, shortNumberDesc); + } + + /** + * Tests whether a short number matches a valid pattern. If a country calling code is shared by + * multiple regions, this returns true if it's valid in any of them. Note that this doesn't verify + * the number is actually in use, which is impossible to tell by just looking at the number + * itself. See {@link #isValidShortNumberForRegion(PhoneNumber, String)} for details. + * + * @param number the short number for which we want to test the validity + * @return whether the short number matches a valid pattern + */ + public boolean isValidShortNumber(PhoneNumber number) { + List<String> regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); + String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes); + if (regionCodes.size() > 1 && regionCode != null) { + // If a matching region had been found for the phone number from among two or more regions, + // then we have already implicitly verified its validity for that region. + return true; + } + return isValidShortNumberForRegion(number, regionCode); + } + + /** + * Gets the expected cost category of a short number when dialled from a region (however, nothing + * is implied about its validity). If it is important that the number is valid, then its validity + * must first be checked using {@link isValidShortNumberForRegion}. Note that emergency numbers + * are always considered toll-free. Example usage: + * <pre>{@code + * ShortNumberInfo shortInfo = ShortNumberInfo.getInstance(); + * String shortNumber = "110"; + * String regionCode = "FR"; + * if (shortInfo.isValidShortNumberForRegion(shortNumber, regionCode)) { + * ShortNumberInfo.ShortNumberCost cost = shortInfo.getExpectedCostForRegion(shortNumber, + * regionCode); + * // Do something with the cost information here. + * }}</pre> + * + * @param shortNumber the short number for which we want to know the expected cost category, + * as a string + * @param regionDialingFrom the region from which the number is dialed + * @return the expected cost category for that region of the short number. Returns UNKNOWN_COST if + * the number does not match a cost category. Note that an invalid number may match any cost + * category. + * @deprecated Anyone who was using it and passing in a string with whitespace (or other + * formatting characters) would have been getting the wrong result. You should parse + * the string to PhoneNumber and use the method + * {@code #getExpectedCostForRegion(PhoneNumber, String)}. This method will be + * removed in the next release. + */ + @Deprecated + public ShortNumberCost getExpectedCostForRegion(String shortNumber, String regionDialingFrom) { + // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null. + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion( + regionDialingFrom); + if (phoneMetadata == null) { + return ShortNumberCost.UNKNOWN_COST; + } + + // The cost categories are tested in order of decreasing expense, since if for some reason the + // patterns overlap the most expensive matching cost category should be returned. + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getPremiumRate())) { + return ShortNumberCost.PREMIUM_RATE; + } + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getStandardRate())) { + return ShortNumberCost.STANDARD_RATE; + } + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getTollFree())) { + return ShortNumberCost.TOLL_FREE; + } + if (isEmergencyNumber(shortNumber, regionDialingFrom)) { + // Emergency numbers are implicitly toll-free. + return ShortNumberCost.TOLL_FREE; + } + return ShortNumberCost.UNKNOWN_COST; + } + + /** + * Gets the expected cost category of a short number when dialed from a region (however, nothing + * is implied about its validity). If it is important that the number is valid, then its validity + * must first be checked using {@link #isValidShortNumberForRegion}. Note that emergency numbers + * are always considered toll-free. Example usage: + * <pre>{@code + * // The region for which the number was parsed and the region we subsequently check against + * // need not be the same. Here we parse the number in the US and check it for Canada. + * PhoneNumber number = phoneUtil.parse("110", "US"); + * ... + * String regionCode = "CA"; + * ShortNumberInfo shortInfo = ShortNumberInfo.getInstance(); + * if (shortInfo.isValidShortNumberForRegion(shortNumber, regionCode)) { + * ShortNumberCost cost = shortInfo.getExpectedCostForRegion(number, regionCode); + * // Do something with the cost information here. + * }}</pre> + * + * @param number the short number for which we want to know the expected cost category + * @param regionDialingFrom the region from which the number is dialed + * @return the expected cost category for that region of the short number. Returns UNKNOWN_COST if + * the number does not match a cost category. Note that an invalid number may match any cost + * category. + */ + public ShortNumberCost getExpectedCostForRegion(PhoneNumber number, String regionDialingFrom) { + // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null. + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion( + regionDialingFrom); + if (phoneMetadata == null) { + return ShortNumberCost.UNKNOWN_COST; + } + + String shortNumber = getNationalSignificantNumber(number); + + // The cost categories are tested in order of decreasing expense, since if for some reason the + // patterns overlap the most expensive matching cost category should be returned. + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getPremiumRate())) { + return ShortNumberCost.PREMIUM_RATE; + } + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getStandardRate())) { + return ShortNumberCost.STANDARD_RATE; + } + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getTollFree())) { + return ShortNumberCost.TOLL_FREE; + } + if (isEmergencyNumber(shortNumber, regionDialingFrom)) { + // Emergency numbers are implicitly toll-free. + return ShortNumberCost.TOLL_FREE; + } + return ShortNumberCost.UNKNOWN_COST; + } + + /** + * Gets the expected cost category of a short number (however, nothing is implied about its + * validity). If the country calling code is unique to a region, this method behaves exactly the + * same as {@link #getExpectedCostForRegion(PhoneNumber, String)}. However, if the country + * calling code is shared by multiple regions, then it returns the highest cost in the sequence + * PREMIUM_RATE, UNKNOWN_COST, STANDARD_RATE, TOLL_FREE. The reason for the position of + * UNKNOWN_COST in this order is that if a number is UNKNOWN_COST in one region but STANDARD_RATE + * or TOLL_FREE in another, its expected cost cannot be estimated as one of the latter since it + * might be a PREMIUM_RATE number. + * <p> + * For example, if a number is STANDARD_RATE in the US, but TOLL_FREE in Canada, the expected + * cost returned by this method will be STANDARD_RATE, since the NANPA countries share the same + * country calling code. + * <p> + * Note: If the region from which the number is dialed is known, it is highly preferable to call + * {@link #getExpectedCostForRegion(PhoneNumber, String)} instead. + * + * @param number the short number for which we want to know the expected cost category + * @return the highest expected cost category of the short number in the region(s) with the given + * country calling code + */ + public ShortNumberCost getExpectedCost(PhoneNumber number) { + List<String> regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); + if (regionCodes.size() == 0) { + return ShortNumberCost.UNKNOWN_COST; + } + if (regionCodes.size() == 1) { + return getExpectedCostForRegion(number, regionCodes.get(0)); + } + ShortNumberCost cost = ShortNumberCost.TOLL_FREE; + for (String regionCode : regionCodes) { + ShortNumberCost costForRegion = getExpectedCostForRegion(number, regionCode); + switch (costForRegion) { + case PREMIUM_RATE: + return ShortNumberCost.PREMIUM_RATE; + case UNKNOWN_COST: + cost = ShortNumberCost.UNKNOWN_COST; + break; + case STANDARD_RATE: + if (cost != ShortNumberCost.UNKNOWN_COST) { + cost = ShortNumberCost.STANDARD_RATE; + } + break; + case TOLL_FREE: + // Do nothing. + break; + default: + logger.log(Level.SEVERE, "Unrecognised cost for region: " + costForRegion); + } + } + return cost; + } + + // Helper method to get the region code for a given phone number, from a list of possible region + // codes. If the list contains more than one region, the first region for which the number is + // valid is returned. + private String getRegionCodeForShortNumberFromRegionList(PhoneNumber number, + List<String> regionCodes) { + if (regionCodes.size() == 0) { + return null; + } else if (regionCodes.size() == 1) { + return regionCodes.get(0); + } + String nationalNumber = getNationalSignificantNumber(number); + for (String regionCode : regionCodes) { + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); + if (phoneMetadata != null + && matchesPossibleNumberAndNationalNumber(nationalNumber, phoneMetadata.getShortCode())) { + // The number is valid for this region. + return regionCode; + } + } + return null; + } + + /** + * Convenience method to get a list of what regions the library has metadata for. + */ + Set<String> getSupportedRegions() { + return Collections.unmodifiableSet(MetadataManager.getShortNumberMetadataSupportedRegions()); + } + + /** + * Gets a valid short number for the specified region. + * + * @param regionCode the region for which an example short number is needed + * @return a valid short number for the specified region. Returns an empty string when the + * metadata does not contain such information. + */ + // @VisibleForTesting + String getExampleShortNumber(String regionCode) { + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); + if (phoneMetadata == null) { + return ""; + } + PhoneNumberDesc desc = phoneMetadata.getShortCode(); + if (desc.hasExampleNumber()) { + return desc.getExampleNumber(); + } + return ""; + } + + /** + * Gets a valid short number for the specified cost category. + * + * @param regionCode the region for which an example short number is needed + * @param cost the cost category of number that is needed + * @return a valid short number for the specified region and cost category. Returns an empty + * string when the metadata does not contain such information, or the cost is UNKNOWN_COST. + */ + // @VisibleForTesting + String getExampleShortNumberForCost(String regionCode, ShortNumberCost cost) { + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); + if (phoneMetadata == null) { + return ""; + } + PhoneNumberDesc desc = null; + switch (cost) { + case TOLL_FREE: + desc = phoneMetadata.getTollFree(); + break; + case STANDARD_RATE: + desc = phoneMetadata.getStandardRate(); + break; + case PREMIUM_RATE: + desc = phoneMetadata.getPremiumRate(); + break; + default: + // UNKNOWN_COST numbers are computed by the process of elimination from the other cost + // categories. + } + if (desc != null && desc.hasExampleNumber()) { + return desc.getExampleNumber(); + } + return ""; + } + + /** + * Returns true if the given number, exactly as dialed, might be used to connect to an emergency + * service in the given region. + * <p> + * This method accepts a string, rather than a PhoneNumber, because it needs to distinguish + * cases such as "+1 911" and "911", where the former may not connect to an emergency service in + * all cases but the latter would. This method takes into account cases where the number might + * contain formatting, or might have additional digits appended (when it is okay to do that in + * the specified region). + * + * @param number the phone number to test + * @param regionCode the region where the phone number is being dialed + * @return whether the number might be used to connect to an emergency service in the given region + */ + public boolean connectsToEmergencyNumber(String number, String regionCode) { + return matchesEmergencyNumberHelper(number, regionCode, true /* allows prefix match */); + } + + /** + * Returns true if the given number exactly matches an emergency service number in the given + * region. + * <p> + * This method takes into account cases where the number might contain formatting, but doesn't + * allow additional digits to be appended. Note that {@code isEmergencyNumber(number, region)} + * implies {@code connectsToEmergencyNumber(number, region)}. + * + * @param number the phone number to test + * @param regionCode the region where the phone number is being dialed + * @return whether the number exactly matches an emergency services number in the given region + */ + public boolean isEmergencyNumber(String number, String regionCode) { + return matchesEmergencyNumberHelper(number, regionCode, false /* doesn't allow prefix match */); + } + + private boolean matchesEmergencyNumberHelper(String number, String regionCode, + boolean allowPrefixMatch) { + number = PhoneNumberUtil.extractPossibleNumber(number); + if (PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(number).lookingAt()) { + // Returns false if the number starts with a plus sign. We don't believe dialing the country + // code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can + // add additional logic here to handle it. + return false; + } + PhoneMetadata metadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); + if (metadata == null || !metadata.hasEmergency()) { + return false; + } + + String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number); + PhoneNumberDesc emergencyDesc = metadata.getEmergency(); + boolean allowPrefixMatchForRegion = + allowPrefixMatch && !REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.contains(regionCode); + return matcherApi.matchesNationalNumber(normalizedNumber, emergencyDesc, + allowPrefixMatchForRegion); + } + + /** + * Given a valid short number, determines whether it is carrier-specific (however, nothing is + * implied about its validity). If it is important that the number is valid, then its validity + * must first be checked using {@link #isValidShortNumber} or + * {@link #isValidShortNumberForRegion}. + * + * @param number the valid short number to check + * @return whether the short number is carrier-specific (assuming the input was a valid short + * number). + */ + public boolean isCarrierSpecific(PhoneNumber number) { + List<String> regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); + String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes); + String nationalNumber = getNationalSignificantNumber(number); + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); + return (phoneMetadata != null) + && (matchesPossibleNumberAndNationalNumber(nationalNumber, + phoneMetadata.getCarrierSpecific())); + } + + /** + * Gets the national significant number of the a phone number. Note a national significant number + * doesn't contain a national prefix or any formatting. + * <p> + * This is a temporary duplicate of the {@code getNationalSignificantNumber} method from + * {@code PhoneNumberUtil}. Ultimately a canonical static version should exist in a separate + * utility class (to prevent {@code ShortNumberInfo} needing to depend on PhoneNumberUtil). + * + * @param number the phone number for which the national significant number is needed + * @return the national significant number of the PhoneNumber object passed in + */ + private static String getNationalSignificantNumber(PhoneNumber number) { + // If leading zero(s) have been set, we prefix this now. Note this is not a national prefix. + StringBuilder nationalNumber = new StringBuilder(); + if (number.isItalianLeadingZero()) { + char[] zeros = new char[number.getNumberOfLeadingZeros()]; + Arrays.fill(zeros, '0'); + nationalNumber.append(new String(zeros)); + } + nationalNumber.append(number.getNationalNumber()); + return nationalNumber.toString(); + } + + // TODO: Once we have benchmarked ShortNumberInfo, consider if it is worth keeping + // this performance optimization, and if so move this into the matcher implementation. + private boolean matchesPossibleNumberAndNationalNumber(String number, + PhoneNumberDesc numberDesc) { + return matcherApi.matchesPossibleNumber(number, numberDesc) + && matcherApi.matchesNationalNumber(number, numberDesc, false); + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java b/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java new file mode 100644 index 00000000..5ea1a91f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers; + +import java.util.Set; + +/* + * Utility for international short phone numbers, such as short codes and emergency numbers. Note + * most commercial short numbers are not handled here, but by the PhoneNumberUtil. + * + * @deprecated("As of release 5.8, replaced by ShortNumberInfo.") + * + * @author Shaopeng Jia + * @author David Yonge-Mallo + */ +@Deprecated public class ShortNumberUtil { + + /** + * Cost categories of short numbers. + */ + public enum ShortNumberCost { + TOLL_FREE, + STANDARD_RATE, + PREMIUM_RATE, + UNKNOWN_COST + } + + public ShortNumberUtil() { + } + + /** + * Convenience method to get a list of what regions the library has metadata for. + */ + public Set<String> getSupportedRegions() { + return ShortNumberInfo.getInstance().getSupportedRegions(); + } + + /** + * Returns true if the number might be used to connect to an emergency service in the given + * region. + * + * This method takes into account cases where the number might contain formatting, or might have + * additional digits appended (when it is okay to do that in the region specified). + * + * @param number the phone number to test + * @param regionCode the region where the phone number is being dialed + * @return if the number might be used to connect to an emergency service in the given region. + */ + public boolean connectsToEmergencyNumber(String number, String regionCode) { + return ShortNumberInfo.getInstance().connectsToEmergencyNumber(number, regionCode); + } + + /** + * Returns true if the number exactly matches an emergency service number in the given region. + * + * This method takes into account cases where the number might contain formatting, but doesn't + * allow additional digits to be appended. + * + * @param number the phone number to test + * @param regionCode the region where the phone number is being dialed + * @return if the number exactly matches an emergency services number in the given region. + */ + public boolean isEmergencyNumber(String number, String regionCode) { + return ShortNumberInfo.getInstance().isEmergencyNumber(number, regionCode); + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumbersRegionCodeSet.java b/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumbersRegionCodeSet.java new file mode 100644 index 00000000..9f3a9273 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumbersRegionCodeSet.java @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2013 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file is automatically generated by {@link BuildMetadataProtoFromXml}. + * Please don't modify it directly. + */ + +package com.google.i18n.phonenumbers; + +import java.util.HashSet; +import java.util.Set; + +public class ShortNumbersRegionCodeSet { + // A set of all region codes for which data is available. + static Set<String> getRegionCodeSet() { + // The capacity is set to 309 as there are 232 different entries, + // and this offers a load factor of roughly 0.75. + Set<String> regionCodeSet = new HashSet<String>(309); + + regionCodeSet.add("AC"); + regionCodeSet.add("AD"); + regionCodeSet.add("AE"); + regionCodeSet.add("AF"); + regionCodeSet.add("AG"); + regionCodeSet.add("AI"); + regionCodeSet.add("AL"); + regionCodeSet.add("AM"); + regionCodeSet.add("AO"); + regionCodeSet.add("AR"); + regionCodeSet.add("AS"); + regionCodeSet.add("AT"); + regionCodeSet.add("AU"); + regionCodeSet.add("AW"); + regionCodeSet.add("AX"); + regionCodeSet.add("AZ"); + regionCodeSet.add("BA"); + regionCodeSet.add("BB"); + regionCodeSet.add("BD"); + regionCodeSet.add("BE"); + regionCodeSet.add("BF"); + regionCodeSet.add("BG"); + regionCodeSet.add("BH"); + regionCodeSet.add("BI"); + regionCodeSet.add("BJ"); + regionCodeSet.add("BL"); + regionCodeSet.add("BM"); + regionCodeSet.add("BN"); + regionCodeSet.add("BO"); + regionCodeSet.add("BQ"); + regionCodeSet.add("BR"); + regionCodeSet.add("BS"); + regionCodeSet.add("BT"); + regionCodeSet.add("BW"); + regionCodeSet.add("BY"); + regionCodeSet.add("BZ"); + regionCodeSet.add("CA"); + regionCodeSet.add("CC"); + regionCodeSet.add("CD"); + regionCodeSet.add("CH"); + regionCodeSet.add("CI"); + regionCodeSet.add("CK"); + regionCodeSet.add("CL"); + regionCodeSet.add("CM"); + regionCodeSet.add("CN"); + regionCodeSet.add("CO"); + regionCodeSet.add("CR"); + regionCodeSet.add("CU"); + regionCodeSet.add("CV"); + regionCodeSet.add("CW"); + regionCodeSet.add("CX"); + regionCodeSet.add("CY"); + regionCodeSet.add("CZ"); + regionCodeSet.add("DE"); + regionCodeSet.add("DJ"); + regionCodeSet.add("DK"); + regionCodeSet.add("DM"); + regionCodeSet.add("DO"); + regionCodeSet.add("DZ"); + regionCodeSet.add("EC"); + regionCodeSet.add("EE"); + regionCodeSet.add("EG"); + regionCodeSet.add("EH"); + regionCodeSet.add("ES"); + regionCodeSet.add("ET"); + regionCodeSet.add("FI"); + regionCodeSet.add("FJ"); + regionCodeSet.add("FK"); + regionCodeSet.add("FM"); + regionCodeSet.add("FO"); + regionCodeSet.add("FR"); + regionCodeSet.add("GA"); + regionCodeSet.add("GB"); + regionCodeSet.add("GD"); + regionCodeSet.add("GE"); + regionCodeSet.add("GF"); + regionCodeSet.add("GG"); + regionCodeSet.add("GH"); + regionCodeSet.add("GI"); + regionCodeSet.add("GL"); + regionCodeSet.add("GM"); + regionCodeSet.add("GN"); + regionCodeSet.add("GP"); + regionCodeSet.add("GR"); + regionCodeSet.add("GT"); + regionCodeSet.add("GU"); + regionCodeSet.add("GW"); + regionCodeSet.add("GY"); + regionCodeSet.add("HK"); + regionCodeSet.add("HN"); + regionCodeSet.add("HR"); + regionCodeSet.add("HT"); + regionCodeSet.add("HU"); + regionCodeSet.add("ID"); + regionCodeSet.add("IE"); + regionCodeSet.add("IL"); + regionCodeSet.add("IM"); + regionCodeSet.add("IN"); + regionCodeSet.add("IQ"); + regionCodeSet.add("IR"); + regionCodeSet.add("IS"); + regionCodeSet.add("IT"); + regionCodeSet.add("JE"); + regionCodeSet.add("JM"); + regionCodeSet.add("JO"); + regionCodeSet.add("JP"); + regionCodeSet.add("KE"); + regionCodeSet.add("KG"); + regionCodeSet.add("KH"); + regionCodeSet.add("KI"); + regionCodeSet.add("KM"); + regionCodeSet.add("KN"); + regionCodeSet.add("KR"); + regionCodeSet.add("KW"); + regionCodeSet.add("KY"); + regionCodeSet.add("KZ"); + regionCodeSet.add("LA"); + regionCodeSet.add("LB"); + regionCodeSet.add("LC"); + regionCodeSet.add("LI"); + regionCodeSet.add("LK"); + regionCodeSet.add("LR"); + regionCodeSet.add("LS"); + regionCodeSet.add("LT"); + regionCodeSet.add("LU"); + regionCodeSet.add("LV"); + regionCodeSet.add("LY"); + regionCodeSet.add("MA"); + regionCodeSet.add("MC"); + regionCodeSet.add("MD"); + regionCodeSet.add("ME"); + regionCodeSet.add("MF"); + regionCodeSet.add("MG"); + regionCodeSet.add("MH"); + regionCodeSet.add("MK"); + regionCodeSet.add("ML"); + regionCodeSet.add("MM"); + regionCodeSet.add("MN"); + regionCodeSet.add("MO"); + regionCodeSet.add("MP"); + regionCodeSet.add("MQ"); + regionCodeSet.add("MR"); + regionCodeSet.add("MS"); + regionCodeSet.add("MT"); + regionCodeSet.add("MU"); + regionCodeSet.add("MV"); + regionCodeSet.add("MW"); + regionCodeSet.add("MX"); + regionCodeSet.add("MY"); + regionCodeSet.add("MZ"); + regionCodeSet.add("NA"); + regionCodeSet.add("NC"); + regionCodeSet.add("NF"); + regionCodeSet.add("NG"); + regionCodeSet.add("NI"); + regionCodeSet.add("NL"); + regionCodeSet.add("NO"); + regionCodeSet.add("NP"); + regionCodeSet.add("NR"); + regionCodeSet.add("NU"); + regionCodeSet.add("NZ"); + regionCodeSet.add("OM"); + regionCodeSet.add("PA"); + regionCodeSet.add("PE"); + regionCodeSet.add("PF"); + regionCodeSet.add("PG"); + regionCodeSet.add("PH"); + regionCodeSet.add("PK"); + regionCodeSet.add("PL"); + regionCodeSet.add("PM"); + regionCodeSet.add("PR"); + regionCodeSet.add("PT"); + regionCodeSet.add("PW"); + regionCodeSet.add("PY"); + regionCodeSet.add("QA"); + regionCodeSet.add("RE"); + regionCodeSet.add("RO"); + regionCodeSet.add("RS"); + regionCodeSet.add("RU"); + regionCodeSet.add("RW"); + regionCodeSet.add("SA"); + regionCodeSet.add("SB"); + regionCodeSet.add("SC"); + regionCodeSet.add("SD"); + regionCodeSet.add("SE"); + regionCodeSet.add("SG"); + regionCodeSet.add("SH"); + regionCodeSet.add("SI"); + regionCodeSet.add("SJ"); + regionCodeSet.add("SK"); + regionCodeSet.add("SL"); + regionCodeSet.add("SM"); + regionCodeSet.add("SN"); + regionCodeSet.add("SR"); + regionCodeSet.add("ST"); + regionCodeSet.add("SV"); + regionCodeSet.add("SX"); + regionCodeSet.add("SY"); + regionCodeSet.add("SZ"); + regionCodeSet.add("TC"); + regionCodeSet.add("TD"); + regionCodeSet.add("TG"); + regionCodeSet.add("TH"); + regionCodeSet.add("TJ"); + regionCodeSet.add("TL"); + regionCodeSet.add("TM"); + regionCodeSet.add("TN"); + regionCodeSet.add("TO"); + regionCodeSet.add("TR"); + regionCodeSet.add("TT"); + regionCodeSet.add("TV"); + regionCodeSet.add("TW"); + regionCodeSet.add("TZ"); + regionCodeSet.add("UA"); + regionCodeSet.add("UG"); + regionCodeSet.add("US"); + regionCodeSet.add("UY"); + regionCodeSet.add("UZ"); + regionCodeSet.add("VA"); + regionCodeSet.add("VC"); + regionCodeSet.add("VE"); + regionCodeSet.add("VG"); + regionCodeSet.add("VI"); + regionCodeSet.add("VN"); + regionCodeSet.add("VU"); + regionCodeSet.add("WF"); + regionCodeSet.add("WS"); + regionCodeSet.add("YE"); + regionCodeSet.add("YT"); + regionCodeSet.add("ZA"); + regionCodeSet.add("ZM"); + regionCodeSet.add("ZW"); + + return regionCodeSet; + } +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_255 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_255 Binary files differnew file mode 100644 index 00000000..7c4f9daa --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_255 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_27 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_27 Binary files differnew file mode 100644 index 00000000..5ab6d03f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_27 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_30 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_30 Binary files differnew file mode 100644 index 00000000..4f6f50a5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_30 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_31 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_31 Binary files differnew file mode 100644 index 00000000..1999488e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_31 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_34 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_34 Binary files differnew file mode 100644 index 00000000..7c60d3d6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_34 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_350 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_350 Binary files differnew file mode 100644 index 00000000..e857d20e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_350 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_351 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_351 Binary files differnew file mode 100644 index 00000000..bd077e77 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_351 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_352 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_352 Binary files differnew file mode 100644 index 00000000..7ee05e92 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_352 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_358 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_358 Binary files differnew file mode 100644 index 00000000..dc7a5d13 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_358 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_359 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_359 Binary files differnew file mode 100644 index 00000000..6431d101 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_359 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_36 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_36 Binary files differnew file mode 100644 index 00000000..9284fb16 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_36 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_372 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_372 Binary files differnew file mode 100644 index 00000000..a16f968b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_372 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_373 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_373 Binary files differnew file mode 100644 index 00000000..6932076f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_373 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_375 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_375 Binary files differnew file mode 100644 index 00000000..b7d8cacd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_375 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_380 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_380 Binary files differnew file mode 100644 index 00000000..ef963276 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_380 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_381 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_381 Binary files differnew file mode 100644 index 00000000..37654d46 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_381 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_385 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_385 Binary files differnew file mode 100644 index 00000000..c6d79133 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_385 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_43 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_43 Binary files differnew file mode 100644 index 00000000..48addfeb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_43 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_44 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_44 Binary files differnew file mode 100644 index 00000000..4864eeb6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_44 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_49 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_49 Binary files differnew file mode 100644 index 00000000..54cc030a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_49 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_505 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_505 Binary files differnew file mode 100644 index 00000000..f8b78ffb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_505 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_506 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_506 Binary files differnew file mode 100644 index 00000000..1987a239 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_506 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_54 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_54 Binary files differnew file mode 100644 index 00000000..c401bf93 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_54 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_55 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_55 Binary files differnew file mode 100644 index 00000000..a2075952 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_55 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_58 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_58 Binary files differnew file mode 100644 index 00000000..da951398 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_58 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_595 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_595 Binary files differnew file mode 100644 index 00000000..8f4dfc66 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_595 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_61 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_61 Binary files differnew file mode 100644 index 00000000..7a0a3b81 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_61 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_62 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_62 Binary files differnew file mode 100644 index 00000000..8763d3c0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_62 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_63 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_63 Binary files differnew file mode 100644 index 00000000..84f5a53c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_63 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_66 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_66 Binary files differnew file mode 100644 index 00000000..bcf3abb9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_66 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_675 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_675 Binary files differnew file mode 100644 index 00000000..52d0a37d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_675 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_676 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_676 Binary files differnew file mode 100644 index 00000000..e7f5f11d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_676 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_679 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_679 Binary files differnew file mode 100644 index 00000000..15209d24 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_679 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_7 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_7 Binary files differnew file mode 100644 index 00000000..5d72f0be --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_7 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_81 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_81 Binary files differnew file mode 100644 index 00000000..efe9684b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_81 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_84 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_84 Binary files differnew file mode 100644 index 00000000..5c772332 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_84 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_855 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_855 Binary files differnew file mode 100644 index 00000000..e231e9d5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_855 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_90 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_90 Binary files differnew file mode 100644 index 00000000..94750712 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_90 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_91 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_91 Binary files differnew file mode 100644 index 00000000..f63b8ecf --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_91 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_94 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_94 Binary files differnew file mode 100644 index 00000000..69584350 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_94 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_95 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_95 Binary files differnew file mode 100644 index 00000000..a672784f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_95 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_971 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_971 Binary files differnew file mode 100644 index 00000000..31d4fe03 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_971 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_972 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_972 Binary files differnew file mode 100644 index 00000000..01d2cb9f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_972 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_995 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_995 Binary files differnew file mode 100644 index 00000000..81d6f13b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_995 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_800 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_800 Binary files differnew file mode 100644 index 00000000..03c5f19e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_800 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_808 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_808 Binary files differnew file mode 100644 index 00000000..683e159e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_808 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_870 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_870 Binary files differnew file mode 100644 index 00000000..954e72b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_870 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_878 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_878 Binary files differnew file mode 100644 index 00000000..f6eaf0aa --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_878 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_881 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_881 Binary files differnew file mode 100644 index 00000000..d750a33e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_881 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_882 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_882 Binary files differnew file mode 100644 index 00000000..a6e6f449 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_882 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_883 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_883 Binary files differnew file mode 100644 index 00000000..cc8cc35c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_883 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_888 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_888 Binary files differnew file mode 100644 index 00000000..11a52b1e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_888 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_979 b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_979 Binary files differnew file mode 100644 index 00000000..5fb8fb58 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_979 diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AC Binary files differnew file mode 100644 index 00000000..c1d98feb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AD Binary files differnew file mode 100644 index 00000000..24d4d001 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AE Binary files differnew file mode 100644 index 00000000..33d770f6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AF Binary files differnew file mode 100644 index 00000000..d80c5968 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AG Binary files differnew file mode 100644 index 00000000..6140377e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AI Binary files differnew file mode 100644 index 00000000..61bd0228 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AL Binary files differnew file mode 100644 index 00000000..54228be8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AM Binary files differnew file mode 100644 index 00000000..3c6b31bc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AO Binary files differnew file mode 100644 index 00000000..fe65c05e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR Binary files differnew file mode 100644 index 00000000..b9a27fdc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AS Binary files differnew file mode 100644 index 00000000..f2a61e94 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT Binary files differnew file mode 100644 index 00000000..143082d3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AU Binary files differnew file mode 100644 index 00000000..1212a887 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AW Binary files differnew file mode 100644 index 00000000..a7b06e98 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX Binary files differnew file mode 100644 index 00000000..8de12c46 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ Binary files differnew file mode 100644 index 00000000..11ee8681 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BA Binary files differnew file mode 100644 index 00000000..b3ed0bbf --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB Binary files differnew file mode 100644 index 00000000..8c45b2b6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD Binary files differnew file mode 100644 index 00000000..7b3a4f28 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BE Binary files differnew file mode 100644 index 00000000..8d2a5a27 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF Binary files differnew file mode 100644 index 00000000..2311f572 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG Binary files differnew file mode 100644 index 00000000..2d1787e0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH Binary files differnew file mode 100644 index 00000000..d930cfc1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BI Binary files differnew file mode 100644 index 00000000..26aaa656 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ Binary files differnew file mode 100644 index 00000000..290ec580 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BL Binary files differnew file mode 100644 index 00000000..94ba050e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BM Binary files differnew file mode 100644 index 00000000..0bef470f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BN Binary files differnew file mode 100644 index 00000000..cffdb8b6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO Binary files differnew file mode 100644 index 00000000..021c2274 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQ Binary files differnew file mode 100644 index 00000000..62f35c24 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR Binary files differnew file mode 100644 index 00000000..6b971763 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS Binary files differnew file mode 100644 index 00000000..f385d53a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BT Binary files differnew file mode 100644 index 00000000..e98b41a4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BW Binary files differnew file mode 100644 index 00000000..777d118e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BY Binary files differnew file mode 100644 index 00000000..c1be2b9d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZ Binary files differnew file mode 100644 index 00000000..831e7213 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CA Binary files differnew file mode 100644 index 00000000..b92641f6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CC Binary files differnew file mode 100644 index 00000000..4d94ee04 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CD Binary files differnew file mode 100644 index 00000000..b52fcca4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CF Binary files differnew file mode 100644 index 00000000..af516499 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CG Binary files differnew file mode 100644 index 00000000..52b7b7a8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CH Binary files differnew file mode 100644 index 00000000..6449451e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI Binary files differnew file mode 100644 index 00000000..972c334d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CK Binary files differnew file mode 100644 index 00000000..c084b84c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL Binary files differnew file mode 100644 index 00000000..14696510 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CM Binary files differnew file mode 100644 index 00000000..7e8dff07 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN Binary files differnew file mode 100644 index 00000000..ed06d7c9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO Binary files differnew file mode 100644 index 00000000..b86a88f7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR Binary files differnew file mode 100644 index 00000000..3857111b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CU Binary files differnew file mode 100644 index 00000000..fedae526 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CV b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CV Binary files differnew file mode 100644 index 00000000..0544c71f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CW Binary files differnew file mode 100644 index 00000000..c72f5590 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CX b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CX Binary files differnew file mode 100644 index 00000000..4462c5ba --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CY Binary files differnew file mode 100644 index 00000000..49fc8544 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ Binary files differnew file mode 100644 index 00000000..297fbe4d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE Binary files differnew file mode 100644 index 00000000..2afa77e2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ Binary files differnew file mode 100644 index 00000000..a9d3ddf8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK Binary files differnew file mode 100644 index 00000000..bd3a9d40 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM Binary files differnew file mode 100644 index 00000000..459a0f23 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DO Binary files differnew file mode 100644 index 00000000..8a4dace5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ Binary files differnew file mode 100644 index 00000000..92b247fb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC Binary files differnew file mode 100644 index 00000000..7d1eecca --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EE Binary files differnew file mode 100644 index 00000000..8f1881a6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG Binary files differnew file mode 100644 index 00000000..7511ce67 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EH Binary files differnew file mode 100644 index 00000000..f9a97fa7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ER b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ER Binary files differnew file mode 100644 index 00000000..0e1f43a8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ER diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES Binary files differnew file mode 100644 index 00000000..b895148c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ET b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ET Binary files differnew file mode 100644 index 00000000..cbf1c4c8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ET diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI Binary files differnew file mode 100644 index 00000000..44d04e05 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJ Binary files differnew file mode 100644 index 00000000..fe9f621e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FK Binary files differnew file mode 100644 index 00000000..7343c284 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FM Binary files differnew file mode 100644 index 00000000..714e4649 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO Binary files differnew file mode 100644 index 00000000..2fdbbfb8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR Binary files differnew file mode 100644 index 00000000..80e45dde --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA Binary files differnew file mode 100644 index 00000000..ffaca37a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GB b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GB Binary files differnew file mode 100644 index 00000000..c409f124 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD Binary files differnew file mode 100644 index 00000000..9849e748 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE Binary files differnew file mode 100644 index 00000000..62d6dacc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GF Binary files differnew file mode 100644 index 00000000..494984c7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GG Binary files differnew file mode 100644 index 00000000..eb89ae69 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH Binary files differnew file mode 100644 index 00000000..cd8b59a0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GI Binary files differnew file mode 100644 index 00000000..58279c9c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GL Binary files differnew file mode 100644 index 00000000..4a9150e6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GM Binary files differnew file mode 100644 index 00000000..bd678000 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GN Binary files differnew file mode 100644 index 00000000..b975a1d4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GP b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GP Binary files differnew file mode 100644 index 00000000..ca0192bb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQ Binary files differnew file mode 100644 index 00000000..13942357 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR Binary files differnew file mode 100644 index 00000000..c9c43ddc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GT Binary files differnew file mode 100644 index 00000000..cb729cd2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GU Binary files differnew file mode 100644 index 00000000..78a606de --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GW Binary files differnew file mode 100644 index 00000000..006de137 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GY Binary files differnew file mode 100644 index 00000000..a7b2ae13 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK Binary files differnew file mode 100644 index 00000000..7f3ff70a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN Binary files differnew file mode 100644 index 00000000..a66ea52c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HR Binary files differnew file mode 100644 index 00000000..7c3657b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HT Binary files differnew file mode 100644 index 00000000..438952c4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU Binary files differnew file mode 100644 index 00000000..0da84020 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID Binary files differnew file mode 100644 index 00000000..90d5487e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IE Binary files differnew file mode 100644 index 00000000..9db8f6ef --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL Binary files differnew file mode 100644 index 00000000..afe40ac5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IM Binary files differnew file mode 100644 index 00000000..216267c0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN Binary files differnew file mode 100644 index 00000000..43fc271c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IO Binary files differnew file mode 100644 index 00000000..a6caa036 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQ Binary files differnew file mode 100644 index 00000000..5436f0ab --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IR Binary files differnew file mode 100644 index 00000000..b66fcccb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IS Binary files differnew file mode 100644 index 00000000..ece7eb7e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT Binary files differnew file mode 100644 index 00000000..926ad1b5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JE Binary files differnew file mode 100644 index 00000000..15be96b2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JM Binary files differnew file mode 100644 index 00000000..17200e0f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO Binary files differnew file mode 100644 index 00000000..e2ff6b93 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP Binary files differnew file mode 100644 index 00000000..e3b61f1f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE Binary files differnew file mode 100644 index 00000000..6afb7b7d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KG Binary files differnew file mode 100644 index 00000000..08b01753 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH Binary files differnew file mode 100644 index 00000000..80a41a19 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI Binary files differnew file mode 100644 index 00000000..1be3aa87 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KM Binary files differnew file mode 100644 index 00000000..ab70e5ca --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN Binary files differnew file mode 100644 index 00000000..e185e763 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KP b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KP Binary files differnew file mode 100644 index 00000000..2713b6c3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR Binary files differnew file mode 100644 index 00000000..9e587ee0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW Binary files differnew file mode 100644 index 00000000..19da153e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KY Binary files differnew file mode 100644 index 00000000..720d62c9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ Binary files differnew file mode 100644 index 00000000..3ca2463a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA Binary files differnew file mode 100644 index 00000000..2b900017 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB Binary files differnew file mode 100644 index 00000000..39882264 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC Binary files differnew file mode 100644 index 00000000..b36be6b6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LI Binary files differnew file mode 100644 index 00000000..25255311 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK Binary files differnew file mode 100644 index 00000000..effd73cd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR Binary files differnew file mode 100644 index 00000000..428ad11d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LS Binary files differnew file mode 100644 index 00000000..7bec656b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT Binary files differnew file mode 100644 index 00000000..d9c46a38 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU Binary files differnew file mode 100644 index 00000000..fd878778 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV Binary files differnew file mode 100644 index 00000000..a0a53af2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LY Binary files differnew file mode 100644 index 00000000..2616120b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MA Binary files differnew file mode 100644 index 00000000..333d0870 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MC Binary files differnew file mode 100644 index 00000000..36bd6598 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MD Binary files differnew file mode 100644 index 00000000..a725e1f4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ME b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ME Binary files differnew file mode 100644 index 00000000..cdcb96db --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ME diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MF Binary files differnew file mode 100644 index 00000000..7a8f9173 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MG Binary files differnew file mode 100644 index 00000000..8599673b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MH Binary files differnew file mode 100644 index 00000000..1f20fa6b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MK Binary files differnew file mode 100644 index 00000000..95ebb144 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML Binary files differnew file mode 100644 index 00000000..b14c8bb6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MM Binary files differnew file mode 100644 index 00000000..c2cbbdf4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MN Binary files differnew file mode 100644 index 00000000..0a931c92 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MO Binary files differnew file mode 100644 index 00000000..04bbe12c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MP b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MP Binary files differnew file mode 100644 index 00000000..e0cbcf92 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQ Binary files differnew file mode 100644 index 00000000..07858595 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MR Binary files differnew file mode 100644 index 00000000..a00424d8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MS Binary files differnew file mode 100644 index 00000000..9cc97639 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MT Binary files differnew file mode 100644 index 00000000..8375e5f6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU Binary files differnew file mode 100644 index 00000000..63676ca2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV Binary files differnew file mode 100644 index 00000000..5d3a10ab --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW Binary files differnew file mode 100644 index 00000000..f4605620 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX Binary files differnew file mode 100644 index 00000000..7dd414a5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MY Binary files differnew file mode 100644 index 00000000..2e455305 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ Binary files differnew file mode 100644 index 00000000..65b2f1f1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA Binary files differnew file mode 100644 index 00000000..f8d70495 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NC Binary files differnew file mode 100644 index 00000000..6f3083ab --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE Binary files differnew file mode 100644 index 00000000..8d0e16c1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NF Binary files differnew file mode 100644 index 00000000..615256de --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NG Binary files differnew file mode 100644 index 00000000..384af71e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NI Binary files differnew file mode 100644 index 00000000..fd6a7c13 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL Binary files differnew file mode 100644 index 00000000..b9c52db0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NO Binary files differnew file mode 100644 index 00000000..71d187a3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NP b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NP Binary files differnew file mode 100644 index 00000000..49a9ff4c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NR Binary files differnew file mode 100644 index 00000000..7f9f74f4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NU Binary files differnew file mode 100644 index 00000000..be8fe367 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ Binary files differnew file mode 100644 index 00000000..ca431407 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OM Binary files differnew file mode 100644 index 00000000..88e9406f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA Binary files differnew file mode 100644 index 00000000..24a7a770 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PE Binary files differnew file mode 100644 index 00000000..2c9bbc5b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF Binary files differnew file mode 100644 index 00000000..b1536f4c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PG Binary files differnew file mode 100644 index 00000000..ab342f6b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PH Binary files differnew file mode 100644 index 00000000..6f565d6a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PK Binary files differnew file mode 100644 index 00000000..f569c5cd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL Binary files differnew file mode 100644 index 00000000..491de26c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PM Binary files differnew file mode 100644 index 00000000..df14f84a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PR Binary files differnew file mode 100644 index 00000000..7ce02f20 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PS Binary files differnew file mode 100644 index 00000000..821f17a3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PT Binary files differnew file mode 100644 index 00000000..5c15da8f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PW Binary files differnew file mode 100644 index 00000000..3a01a256 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY Binary files differnew file mode 100644 index 00000000..298e973c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QA Binary files differnew file mode 100644 index 00000000..24c88869 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RE Binary files differnew file mode 100644 index 00000000..8a1cb9ee --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO Binary files differnew file mode 100644 index 00000000..db604af0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS Binary files differnew file mode 100644 index 00000000..06de92e5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU Binary files differnew file mode 100644 index 00000000..c769356a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RW Binary files differnew file mode 100644 index 00000000..a6d7a148 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA Binary files differnew file mode 100644 index 00000000..48930210 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SB b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SB Binary files differnew file mode 100644 index 00000000..49974502 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC Binary files differnew file mode 100644 index 00000000..8762a536 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SD Binary files differnew file mode 100644 index 00000000..c56f4fbd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SE Binary files differnew file mode 100644 index 00000000..c23cf2f9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SG Binary files differnew file mode 100644 index 00000000..9204ad9f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH Binary files differnew file mode 100644 index 00000000..77d4a794 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SI Binary files differnew file mode 100644 index 00000000..a2607df1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJ Binary files differnew file mode 100644 index 00000000..4ca42737 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK Binary files differnew file mode 100644 index 00000000..19642c6b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SL Binary files differnew file mode 100644 index 00000000..f5d38fcd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM Binary files differnew file mode 100644 index 00000000..4294cf93 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN Binary files differnew file mode 100644 index 00000000..9cfc22eb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SO Binary files differnew file mode 100644 index 00000000..96ea1998 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SR Binary files differnew file mode 100644 index 00000000..7ea63edd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SS Binary files differnew file mode 100644 index 00000000..86e0518d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ST b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ST Binary files differnew file mode 100644 index 00000000..f364573a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ST diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV Binary files differnew file mode 100644 index 00000000..d1666974 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SX b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SX Binary files differnew file mode 100644 index 00000000..472486a2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SY Binary files differnew file mode 100644 index 00000000..7f03a188 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZ Binary files differnew file mode 100644 index 00000000..3cd853b3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TA Binary files differnew file mode 100644 index 00000000..769f6f09 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC Binary files differnew file mode 100644 index 00000000..409fe598 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TD b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TD Binary files differnew file mode 100644 index 00000000..b5401425 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TG Binary files differnew file mode 100644 index 00000000..0e90dbc1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH Binary files differnew file mode 100644 index 00000000..b2f44e25 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ Binary files differnew file mode 100644 index 00000000..02a73f61 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TK b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TK Binary files differnew file mode 100644 index 00000000..e20bb98d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TL b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TL Binary files differnew file mode 100644 index 00000000..11fd5af0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM Binary files differnew file mode 100644 index 00000000..9013b60d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TN Binary files differnew file mode 100644 index 00000000..a6441e8d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TO b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TO Binary files differnew file mode 100644 index 00000000..29d6dee5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR Binary files differnew file mode 100644 index 00000000..19d2338e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TT Binary files differnew file mode 100644 index 00000000..7d3b2e0e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TV b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TV Binary files differnew file mode 100644 index 00000000..ca2e8b86 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW Binary files differnew file mode 100644 index 00000000..de246f5e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ Binary files differnew file mode 100644 index 00000000..f9f553b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UA Binary files differnew file mode 100644 index 00000000..f700468f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG Binary files differnew file mode 100644 index 00000000..12d16a91 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US Binary files differnew file mode 100644 index 00000000..e8d8683c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UY b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UY Binary files differnew file mode 100644 index 00000000..e2f73886 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ Binary files differnew file mode 100644 index 00000000..1711a97c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA Binary files differnew file mode 100644 index 00000000..72c260fa --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC Binary files differnew file mode 100644 index 00000000..551e326e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE Binary files differnew file mode 100644 index 00000000..5e3db17e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VG b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VG Binary files differnew file mode 100644 index 00000000..28f0f02e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VI b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VI Binary files differnew file mode 100644 index 00000000..8454793e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN Binary files differnew file mode 100644 index 00000000..0fd97d47 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VU b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VU Binary files differnew file mode 100644 index 00000000..36fd3d80 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WF b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WF Binary files differnew file mode 100644 index 00000000..a0801df4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WS b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WS Binary files differnew file mode 100644 index 00000000..02cced67 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YE b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YE Binary files differnew file mode 100644 index 00000000..24f3bd2a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YT b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YT Binary files differnew file mode 100644 index 00000000..2f6153d9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZA b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZA Binary files differnew file mode 100644 index 00000000..8598631a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZM b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZM Binary files differnew file mode 100644 index 00000000..0ba0feef --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZW b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZW Binary files differnew file mode 100644 index 00000000..f295d2c1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AC Binary files differnew file mode 100644 index 00000000..0fb368e1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AD Binary files differnew file mode 100644 index 00000000..fe534033 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AE Binary files differnew file mode 100644 index 00000000..fb4894dd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AF Binary files differnew file mode 100644 index 00000000..6ea72a59 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AG Binary files differnew file mode 100644 index 00000000..d1b952a8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AI Binary files differnew file mode 100644 index 00000000..d0cf967c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AL Binary files differnew file mode 100644 index 00000000..b8948291 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AM Binary files differnew file mode 100644 index 00000000..40ae751f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AO Binary files differnew file mode 100644 index 00000000..2b7b5450 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AR Binary files differnew file mode 100644 index 00000000..4b38d722 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AS Binary files differnew file mode 100644 index 00000000..3a15688f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AT Binary files differnew file mode 100644 index 00000000..946641be --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AU Binary files differnew file mode 100644 index 00000000..8a14d4f8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AW Binary files differnew file mode 100644 index 00000000..933e7cca --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AX b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AX Binary files differnew file mode 100644 index 00000000..a52bc978 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AZ Binary files differnew file mode 100644 index 00000000..797d5294 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BA Binary files differnew file mode 100644 index 00000000..c1c073c1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BB b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BB Binary files differnew file mode 100644 index 00000000..048dea48 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BD Binary files differnew file mode 100644 index 00000000..18b73445 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BE Binary files differnew file mode 100644 index 00000000..1352acfc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BF Binary files differnew file mode 100644 index 00000000..2cb5251c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BG Binary files differnew file mode 100644 index 00000000..a454f3b8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BH Binary files differnew file mode 100644 index 00000000..4d857280 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BI Binary files differnew file mode 100644 index 00000000..a0eacfdf --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BJ Binary files differnew file mode 100644 index 00000000..153ec9ec --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BL Binary files differnew file mode 100644 index 00000000..3e4866ec --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BM Binary files differnew file mode 100644 index 00000000..155b7d52 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BN Binary files differnew file mode 100644 index 00000000..37ee404a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BO Binary files differnew file mode 100644 index 00000000..7a01bf81 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BQ Binary files differnew file mode 100644 index 00000000..d3b876e3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BR Binary files differnew file mode 100644 index 00000000..5d2d656b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BS Binary files differnew file mode 100644 index 00000000..aa460ff6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BT Binary files differnew file mode 100644 index 00000000..b4046502 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BW Binary files differnew file mode 100644 index 00000000..85fdfc0b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BY Binary files differnew file mode 100644 index 00000000..49bf8ab9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BZ Binary files differnew file mode 100644 index 00000000..bbd87bf7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CA Binary files differnew file mode 100644 index 00000000..87c09c94 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CC Binary files differnew file mode 100644 index 00000000..0a5f6751 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CD Binary files differnew file mode 100644 index 00000000..dfa9f7a1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CH Binary files differnew file mode 100644 index 00000000..821281fe --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CI Binary files differnew file mode 100644 index 00000000..81f7dccc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CK Binary files differnew file mode 100644 index 00000000..3c396905 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CL Binary files differnew file mode 100644 index 00000000..ecaa04f1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CM Binary files differnew file mode 100644 index 00000000..8df38012 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CN Binary files differnew file mode 100644 index 00000000..98054ff0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CO Binary files differnew file mode 100644 index 00000000..0c4eff1b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CR Binary files differnew file mode 100644 index 00000000..3411d7f1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CU Binary files differnew file mode 100644 index 00000000..ea834cb8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CV b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CV Binary files differnew file mode 100644 index 00000000..783da2e7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CW Binary files differnew file mode 100644 index 00000000..57187502 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CX b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CX Binary files differnew file mode 100644 index 00000000..ce8b75d8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CY Binary files differnew file mode 100644 index 00000000..c5962d38 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CZ Binary files differnew file mode 100644 index 00000000..4a644f3c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_CZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DE Binary files differnew file mode 100644 index 00000000..8fe45dd3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DJ Binary files differnew file mode 100644 index 00000000..8825c8b2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DK Binary files differnew file mode 100644 index 00000000..7cdaea8f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DM Binary files differnew file mode 100644 index 00000000..1a3604dd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DO Binary files differnew file mode 100644 index 00000000..34432f16 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DZ Binary files differnew file mode 100644 index 00000000..2a1c8a7c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_DZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EC Binary files differnew file mode 100644 index 00000000..47142711 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EE Binary files differnew file mode 100644 index 00000000..6ca452dd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EG Binary files differnew file mode 100644 index 00000000..8638f07e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EH Binary files differnew file mode 100644 index 00000000..87c38a91 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_EH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ES b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ES Binary files differnew file mode 100644 index 00000000..e086ffa1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ES diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ET b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ET Binary files differnew file mode 100644 index 00000000..e0594080 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ET diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FI Binary files differnew file mode 100644 index 00000000..4982038a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FJ Binary files differnew file mode 100644 index 00000000..2f2665e4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FK Binary files differnew file mode 100644 index 00000000..349ebe6c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FM Binary files differnew file mode 100644 index 00000000..24fba7ce --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FO Binary files differnew file mode 100644 index 00000000..f0901ac2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FR Binary files differnew file mode 100644 index 00000000..b91acd62 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_FR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GA Binary files differnew file mode 100644 index 00000000..958d8e99 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GB b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GB Binary files differnew file mode 100644 index 00000000..8be70a07 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GD Binary files differnew file mode 100644 index 00000000..208a7a78 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GE Binary files differnew file mode 100644 index 00000000..fb236a77 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GF Binary files differnew file mode 100644 index 00000000..d35588db --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GG Binary files differnew file mode 100644 index 00000000..ac284653 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GH Binary files differnew file mode 100644 index 00000000..9a8a4721 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GI Binary files differnew file mode 100644 index 00000000..c494df98 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GL Binary files differnew file mode 100644 index 00000000..177d6fdb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GM Binary files differnew file mode 100644 index 00000000..c890061a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GN Binary files differnew file mode 100644 index 00000000..6e2b7c9a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GP b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GP Binary files differnew file mode 100644 index 00000000..d199bed2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GR Binary files differnew file mode 100644 index 00000000..1f9b0b12 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GT Binary files differnew file mode 100644 index 00000000..53c1c04f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GU Binary files differnew file mode 100644 index 00000000..97b9bef4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GW Binary files differnew file mode 100644 index 00000000..e2966942 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GY Binary files differnew file mode 100644 index 00000000..b5977d98 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HK Binary files differnew file mode 100644 index 00000000..db5f3f8d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HN Binary files differnew file mode 100644 index 00000000..cd8a2108 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HR Binary files differnew file mode 100644 index 00000000..df743037 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HT Binary files differnew file mode 100644 index 00000000..6eedab01 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HU Binary files differnew file mode 100644 index 00000000..46498f6d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_HU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ID b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ID Binary files differnew file mode 100644 index 00000000..630d89bd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ID diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IE Binary files differnew file mode 100644 index 00000000..5db571af --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IL Binary files differnew file mode 100644 index 00000000..13567974 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IM Binary files differnew file mode 100644 index 00000000..51af3cd3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IN Binary files differnew file mode 100644 index 00000000..323d45c5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IQ Binary files differnew file mode 100644 index 00000000..5a711cbf --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IR Binary files differnew file mode 100644 index 00000000..f2b7611d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IS Binary files differnew file mode 100644 index 00000000..d9d473b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IT Binary files differnew file mode 100644 index 00000000..b4fb3215 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JE Binary files differnew file mode 100644 index 00000000..918ae8ce --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JM Binary files differnew file mode 100644 index 00000000..865b0ce8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JO Binary files differnew file mode 100644 index 00000000..e7afad28 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JP b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JP Binary files differnew file mode 100644 index 00000000..a881213d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_JP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KE Binary files differnew file mode 100644 index 00000000..31013f9f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KG Binary files differnew file mode 100644 index 00000000..be9ba991 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KH Binary files differnew file mode 100644 index 00000000..f92e2c38 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KI Binary files differnew file mode 100644 index 00000000..58942690 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KM Binary files differnew file mode 100644 index 00000000..282b9aff --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KN Binary files differnew file mode 100644 index 00000000..11f927b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KR Binary files differnew file mode 100644 index 00000000..6e009678 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KW Binary files differnew file mode 100644 index 00000000..a492b005 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KY Binary files differnew file mode 100644 index 00000000..2c7fa884 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KZ Binary files differnew file mode 100644 index 00000000..19f3e541 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_KZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LA Binary files differnew file mode 100644 index 00000000..fae89ce2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LB b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LB Binary files differnew file mode 100644 index 00000000..825a9ee1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LC Binary files differnew file mode 100644 index 00000000..a26db878 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LI Binary files differnew file mode 100644 index 00000000..4c5f9bf2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LK Binary files differnew file mode 100644 index 00000000..adb6cfc9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LR Binary files differnew file mode 100644 index 00000000..8d7a29ac --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LS Binary files differnew file mode 100644 index 00000000..3819b431 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LT Binary files differnew file mode 100644 index 00000000..8148ca74 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LU Binary files differnew file mode 100644 index 00000000..f099c4ba --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LV b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LV Binary files differnew file mode 100644 index 00000000..e6d922f2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LY Binary files differnew file mode 100644 index 00000000..f389f9c2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_LY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MA Binary files differnew file mode 100644 index 00000000..a00d409d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MC Binary files differnew file mode 100644 index 00000000..eae7953b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MD Binary files differnew file mode 100644 index 00000000..41b3e576 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ME b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ME Binary files differnew file mode 100644 index 00000000..e9d5f1d0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ME diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MF Binary files differnew file mode 100644 index 00000000..e6ee4a2e --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MG Binary files differnew file mode 100644 index 00000000..203b7250 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MH Binary files differnew file mode 100644 index 00000000..a3e55bea --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MK Binary files differnew file mode 100644 index 00000000..3702ec24 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ML b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ML Binary files differnew file mode 100644 index 00000000..eb61dd4a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ML diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MM Binary files differnew file mode 100644 index 00000000..7016f326 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MN Binary files differnew file mode 100644 index 00000000..097cbbb1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MO Binary files differnew file mode 100644 index 00000000..623e577d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MP b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MP Binary files differnew file mode 100644 index 00000000..2f4a6b6c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MQ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MQ Binary files differnew file mode 100644 index 00000000..690367fb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MQ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MR Binary files differnew file mode 100644 index 00000000..8e8d9922 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MS Binary files differnew file mode 100644 index 00000000..083f7fd4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MT Binary files differnew file mode 100644 index 00000000..f8345497 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MU Binary files differnew file mode 100644 index 00000000..a37fec1b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MV b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MV Binary files differnew file mode 100644 index 00000000..aeb03dd4 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MW Binary files differnew file mode 100644 index 00000000..8efd2c57 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MX b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MX Binary files differnew file mode 100644 index 00000000..7e666437 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MY Binary files differnew file mode 100644 index 00000000..5c25f4ae --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MZ Binary files differnew file mode 100644 index 00000000..fd9a38b2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_MZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NA Binary files differnew file mode 100644 index 00000000..24dbfc46 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NC Binary files differnew file mode 100644 index 00000000..3a506877 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NF Binary files differnew file mode 100644 index 00000000..65ca9ae5 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NG Binary files differnew file mode 100644 index 00000000..d6c02c30 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NI Binary files differnew file mode 100644 index 00000000..27e56139 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NL Binary files differnew file mode 100644 index 00000000..01dcf65b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NO Binary files differnew file mode 100644 index 00000000..f3f8843a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NP b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NP Binary files differnew file mode 100644 index 00000000..f937cc8a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NP diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NR Binary files differnew file mode 100644 index 00000000..4b6a0e43 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NU Binary files differnew file mode 100644 index 00000000..678a2827 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NZ Binary files differnew file mode 100644 index 00000000..70f10e15 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_OM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_OM Binary files differnew file mode 100644 index 00000000..76832fd9 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_OM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PA Binary files differnew file mode 100644 index 00000000..2358ea75 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PE Binary files differnew file mode 100644 index 00000000..819a123a --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PF Binary files differnew file mode 100644 index 00000000..91a65ed2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PG Binary files differnew file mode 100644 index 00000000..7d51ac94 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PH Binary files differnew file mode 100644 index 00000000..ef96a5a6 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PK Binary files differnew file mode 100644 index 00000000..678f4875 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PL Binary files differnew file mode 100644 index 00000000..ae1b6201 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PM Binary files differnew file mode 100644 index 00000000..ad1e7663 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PR Binary files differnew file mode 100644 index 00000000..bfefb4b1 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PT Binary files differnew file mode 100644 index 00000000..15fb4780 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PW Binary files differnew file mode 100644 index 00000000..a9f82943 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PY Binary files differnew file mode 100644 index 00000000..9bdea25c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_PY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_QA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_QA Binary files differnew file mode 100644 index 00000000..9a704435 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_QA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RE Binary files differnew file mode 100644 index 00000000..1be529fe --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RO Binary files differnew file mode 100644 index 00000000..4cc39ab0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RS Binary files differnew file mode 100644 index 00000000..28af2446 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RU Binary files differnew file mode 100644 index 00000000..d0a711bb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RW Binary files differnew file mode 100644 index 00000000..6319123b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_RW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SA Binary files differnew file mode 100644 index 00000000..dc227c70 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SB b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SB Binary files differnew file mode 100644 index 00000000..53f59a03 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SB diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SC Binary files differnew file mode 100644 index 00000000..be38ce85 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SD Binary files differnew file mode 100644 index 00000000..27a91d47 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SE Binary files differnew file mode 100644 index 00000000..d10dc143 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SG Binary files differnew file mode 100644 index 00000000..18f18130 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SH Binary files differnew file mode 100644 index 00000000..559091cb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SI Binary files differnew file mode 100644 index 00000000..0722842b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SJ Binary files differnew file mode 100644 index 00000000..72e937d8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SK b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SK Binary files differnew file mode 100644 index 00000000..ab81e665 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SK diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SL Binary files differnew file mode 100644 index 00000000..9a3e1398 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SM Binary files differnew file mode 100644 index 00000000..f7c73f14 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SN Binary files differnew file mode 100644 index 00000000..cb8ecc01 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SR Binary files differnew file mode 100644 index 00000000..16c24603 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ST b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ST Binary files differnew file mode 100644 index 00000000..51d2a9aa --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ST diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SV b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SV Binary files differnew file mode 100644 index 00000000..4c26fe4b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SX b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SX Binary files differnew file mode 100644 index 00000000..297cb68b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SX diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SY Binary files differnew file mode 100644 index 00000000..009ec93d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SZ Binary files differnew file mode 100644 index 00000000..7e5eb9fa --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TC Binary files differnew file mode 100644 index 00000000..818bc0ac --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TD b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TD Binary files differnew file mode 100644 index 00000000..ff036a2f --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TD diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TG Binary files differnew file mode 100644 index 00000000..e2d5c285 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TH b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TH Binary files differnew file mode 100644 index 00000000..60bd59bd --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TH diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TJ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TJ Binary files differnew file mode 100644 index 00000000..954c0f80 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TJ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TL b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TL Binary files differnew file mode 100644 index 00000000..1beee259 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TL diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TM Binary files differnew file mode 100644 index 00000000..83d453f2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TN Binary files differnew file mode 100644 index 00000000..7277d419 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TO b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TO Binary files differnew file mode 100644 index 00000000..735b30b0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TO diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TR b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TR Binary files differnew file mode 100644 index 00000000..c24e45d3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TR diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TT Binary files differnew file mode 100644 index 00000000..c68094eb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TV b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TV Binary files differnew file mode 100644 index 00000000..05f763fa --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TV diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TW Binary files differnew file mode 100644 index 00000000..ae252940 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TZ Binary files differnew file mode 100644 index 00000000..44f79df0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_TZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UA Binary files differnew file mode 100644 index 00000000..9603cb81 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UG Binary files differnew file mode 100644 index 00000000..78128a28 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_US b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_US Binary files differnew file mode 100644 index 00000000..7c0cfb76 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_US diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UY b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UY Binary files differnew file mode 100644 index 00000000..d0e5e72b --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UY diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UZ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UZ Binary files differnew file mode 100644 index 00000000..15f91a78 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_UZ diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VA Binary files differnew file mode 100644 index 00000000..8c2d76b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VC b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VC Binary files differnew file mode 100644 index 00000000..f91a7f52 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VC diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VE Binary files differnew file mode 100644 index 00000000..721c0ef3 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VG b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VG Binary files differnew file mode 100644 index 00000000..edea90f2 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VG diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VI b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VI Binary files differnew file mode 100644 index 00000000..56cce8c0 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VI diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VN b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VN Binary files differnew file mode 100644 index 00000000..d315c602 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VN diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VU b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VU Binary files differnew file mode 100644 index 00000000..6f9df3b7 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_VU diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_WF b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_WF Binary files differnew file mode 100644 index 00000000..973769fc --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_WF diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_WS b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_WS Binary files differnew file mode 100644 index 00000000..eaee6b8c --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_WS diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_YE b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_YE Binary files differnew file mode 100644 index 00000000..e5066d43 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_YE diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_YT b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_YT Binary files differnew file mode 100644 index 00000000..cb112c99 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_YT diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZA b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZA Binary files differnew file mode 100644 index 00000000..f0afb76d --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZA diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZM b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZM Binary files differnew file mode 100644 index 00000000..db15bda8 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZM diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZW b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZW Binary files differnew file mode 100644 index 00000000..1a97eb42 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZW diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java b/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java new file mode 100644 index 00000000..38319cbb --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers.internal; + +import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; + +/** + * Internal phonenumber matching API used to isolate the underlying implementation of the + * matcher and allow different implementations to be swapped in easily. + */ +public interface MatcherApi { + /** + * Returns whether the given national number (a string containing only decimal digits) matches + * the national number pattern defined in the given {@code PhoneNumberDesc} message. + */ + boolean matchesNationalNumber(String nationalNumber, PhoneNumberDesc numberDesc, + boolean allowPrefixMatch); + + /** + * Returns whether the given national number (a string containing only decimal digits) matches + * the possible number pattern defined in the given {@code PhoneNumberDesc} message. + */ + boolean matchesPossibleNumber(String nationalNumber, PhoneNumberDesc numberDesc); +} diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java b/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java new file mode 100644 index 00000000..125a1822 --- /dev/null +++ b/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 The Libphonenumber Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.i18n.phonenumbers.internal; + +import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; +import com.google.i18n.phonenumbers.RegexCache; + +import java.util.regex.Matcher; + +/** + * Implementation of the matcher API using the regular expressions in the PhoneNumberDesc + * proto message to match numbers. + */ +public final class RegexBasedMatcher implements MatcherApi { + public static MatcherApi create() { + return new RegexBasedMatcher(); + } + + private final RegexCache regexCache = new RegexCache(100); + + private RegexBasedMatcher() {} + + // @Override + public boolean matchesNationalNumber(String nationalNumber, PhoneNumberDesc numberDesc, + boolean allowPrefixMatch) { + Matcher nationalNumberPatternMatcher = regexCache.getPatternForRegex( + numberDesc.getNationalNumberPattern()).matcher(nationalNumber); + return nationalNumberPatternMatcher.matches() + || (allowPrefixMatch && nationalNumberPatternMatcher.lookingAt()); + } + + // @Override + public boolean matchesPossibleNumber(String nationalNumber, PhoneNumberDesc numberDesc) { + Matcher possibleNumberPatternMatcher = regexCache.getPatternForRegex( + numberDesc.getPossibleNumberPattern()).matcher(nationalNumber); + return possibleNumberPatternMatcher.matches(); + } +} |