diff --git a/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java b/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java index 5a7e1572c..270474740 100644 --- a/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java +++ b/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java @@ -17,6 +17,7 @@ package com.google.i18n.phonenumbers.geocoding; import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType; import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; import java.io.IOException; @@ -148,7 +149,9 @@ public class PhoneNumberOfflineGeocoder { * name of the geographical area the phone number is from if more detailed information is * available. * - *

This method assumes the validity of the number passed in has already been checked. + *

This method assumes the validity of the number passed in has already been checked, and that + * the number is suitable for geocoding. We consider fixed-line and mobile numbers possible + * candidates for geocoding. * * @param number a valid phone number for which we want to get a text description * @param languageCode the language code for which the description should be written @@ -211,8 +214,11 @@ public class PhoneNumberOfflineGeocoder { * string if the number passed in is invalid */ public String getDescriptionForNumber(PhoneNumber number, Locale languageCode) { - if (!phoneUtil.isValidNumber(number)) { + PhoneNumberType numberType = phoneUtil.getNumberType(number); + if (numberType == PhoneNumberType.UNKNOWN) { return ""; + } else if (!canBeGeocoded(numberType)) { + return getCountryNameForNumber(number, languageCode); } return getDescriptionForValidNumber(number, languageCode); } @@ -231,12 +237,21 @@ public class PhoneNumberOfflineGeocoder { */ public String getDescriptionForNumber(PhoneNumber number, Locale languageCode, String userRegion) { - if (!phoneUtil.isValidNumber(number)) { + PhoneNumberType numberType = phoneUtil.getNumberType(number); + if (numberType == PhoneNumberType.UNKNOWN) { return ""; + } else if (!canBeGeocoded(numberType)) { + return getCountryNameForNumber(number, languageCode); } return getDescriptionForValidNumber(number, languageCode, userRegion); } + private boolean canBeGeocoded(PhoneNumberType numberType) { + return (numberType == PhoneNumberType.FIXED_LINE || + numberType == PhoneNumberType.MOBILE || + numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE); + } + /** * Returns an area-level text description in the given language for the given phone number. * diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java index 3f3042ded..dfe49d455 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java @@ -50,11 +50,17 @@ public class AsYouTypeFormatter { // 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; - private boolean isInternationalFormatting = 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; @@ -78,6 +84,9 @@ public class AsYouTypeFormatter { 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 @@ -86,8 +95,8 @@ public class AsYouTypeFormatter { // The digits that have not been entered yet will be represented by a \u2008, the punctuation // space. - private String digitPlaceholder = "\u2008"; - private Pattern digitPattern = Pattern.compile(digitPlaceholder); + 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. @@ -99,6 +108,7 @@ public class AsYouTypeFormatter { // 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 nationalPrefixExtracted = ""; @@ -147,6 +157,9 @@ public class AsYouTypeFormatter { } 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; @@ -161,12 +174,15 @@ public class AsYouTypeFormatter { private void getAvailableFormats(String leadingThreeDigits) { List formatList = - (isInternationalFormatting && currentMetaData.intlNumberFormatSize() > 0) + (isCompleteNumber && currentMetaData.intlNumberFormatSize() > 0) ? currentMetaData.intlNumberFormats() : currentMetaData.numberFormats(); for (NumberFormat format : formatList) { - if (isFormatEligible(format.getFormat())) { - possibleFormats.add(format); + if (isCompleteNumber || format.isNationalPrefixOptionalWhenFormatting() || + phoneUtil.formattingRuleHasFirstGroupOnly(format.getNationalPrefixFormattingRule())) { + if (isFormatEligible(format.getFormat())) { + possibleFormats.add(format); + } } } narrowDownPossibleFormats(leadingThreeDigits); @@ -233,8 +249,8 @@ public class AsYouTypeFormatter { } // Formats the number according to numberFormat String template = aPhoneNumber.replaceAll(numberPattern, numberFormat); - // Replaces each digit with character digitPlaceholder - template = template.replaceAll("9", digitPlaceholder); + // Replaces each digit with character DIGIT_PLACEHOLDER + template = template.replaceAll("9", DIGIT_PLACEHOLDER); return template; } @@ -255,9 +271,10 @@ public class AsYouTypeFormatter { inputHasFormatting = false; positionToRemember = 0; originalPosition = 0; - isInternationalFormatting = false; + isCompleteNumber = false; isExpectingCountryCallingCode = false; possibleFormats.clear(); + shouldAddSpaceAfterNationalPrefix = false; if (!currentMetaData.equals(defaultMetaData)) { currentMetaData = getMetadataForRegion(defaultCountry); } @@ -314,8 +331,9 @@ public class AsYouTypeFormatter { } } else if (ableToExtractLongerNdd()) { // Add an additional space to separate long NDD and national significant number for - // readability. - prefixBeforeNationalNumber.append(" "); + // 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(); @@ -355,7 +373,7 @@ public class AsYouTypeFormatter { return inputAccruedNationalNumber(); } return ableToFormat - ? prefixBeforeNationalNumber + tempNationalNumber + ? appendNationalNumber(tempNationalNumber) : accruedInput.toString(); } else { return attemptToChooseFormattingPattern(); @@ -391,12 +409,19 @@ public class AsYouTypeFormatter { 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 numFormat : possibleFormats) { - Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber); + for (NumberFormat numberFormat : possibleFormats) { + Matcher m = regexCache.getPatternForRegex(numberFormat.getPattern()).matcher(nationalNumber); if (m.matches()) { - String formattedNumber = m.replaceAll(numFormat.getFormat()); - return prefixBeforeNationalNumber + formattedNumber; + shouldAddSpaceAfterNationalPrefix = + NATIONAL_PREFIX_SEPARATORS_PATTERN.matcher( + numberFormat.getNationalPrefixFormattingRule()).find(); + String formattedNumber = m.replaceAll(numberFormat.getFormat()); + return appendNationalNumber(formattedNumber); } } return ""; @@ -421,8 +446,30 @@ public class AsYouTypeFormatter { return currentOutputIndex; } - // Attempts to set the formatting template and returns a string which contains the formatted - // version of the digits entered so far. + /** + * 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 as least MIN_LEADING_DIGITS_LENGTH digits of national // number (excluding national prefix) have been entered. @@ -430,12 +477,14 @@ public class AsYouTypeFormatter { getAvailableFormats(nationalNumber.substring(0, MIN_LEADING_DIGITS_LENGTH)); return maybeCreateNewTemplate() ? inputAccruedNationalNumber() : accruedInput.toString(); } else { - return prefixBeforeNationalNumber + nationalNumber.toString(); + return appendNationalNumber(nationalNumber.toString()); } } - // Invokes inputDigitHelper on each digit of the national number accrued, and returns a formatted - // string in the end. + /** + * 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) { @@ -443,21 +492,32 @@ public class AsYouTypeFormatter { for (int i = 0; i < lengthOfNationalNumber; i++) { tempNationalNumber = inputDigitHelper(nationalNumber.charAt(i)); } - return ableToFormat - ? prefixBeforeNationalNumber + tempNationalNumber - : accruedInput.toString(); + 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 (currentMetaData.getCountryCode() == 1 && nationalNumber.charAt(0) == '1') { + if (isNanpaNumberWithNationalPrefix()) { startOfNationalNumber = 1; - prefixBeforeNationalNumber.append("1 "); - isInternationalFormatting = true; + prefixBeforeNationalNumber.append('1').append(SEPARATOR_BEFORE_NATIONAL_NUMBER); + isCompleteNumber = true; } else if (currentMetaData.hasNationalPrefixForParsing()) { Pattern nationalPrefixForParsing = regexCache.getPatternForRegex(currentMetaData.getNationalPrefixForParsing()); @@ -466,7 +526,7 @@ public class AsYouTypeFormatter { // 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. - isInternationalFormatting = true; + isCompleteNumber = true; startOfNationalNumber = m.end(); prefixBeforeNationalNumber.append(nationalNumber.substring(0, startOfNationalNumber)); } @@ -489,7 +549,7 @@ public class AsYouTypeFormatter { currentMetaData.getInternationalPrefix()); Matcher iddMatcher = internationalPrefix.matcher(accruedInputWithoutFormatting); if (iddMatcher.lookingAt()) { - isInternationalFormatting = true; + isCompleteNumber = true; int startOfCountryCallingCode = iddMatcher.end(); nationalNumber.setLength(0); nationalNumber.append(accruedInputWithoutFormatting.substring(startOfCountryCallingCode)); @@ -497,7 +557,7 @@ public class AsYouTypeFormatter { prefixBeforeNationalNumber.append( accruedInputWithoutFormatting.substring(0, startOfCountryCallingCode)); if (accruedInputWithoutFormatting.charAt(0) != PhoneNumberUtil.PLUS_SIGN) { - prefixBeforeNationalNumber.append(" "); + prefixBeforeNationalNumber.append(SEPARATOR_BEFORE_NATIONAL_NUMBER); } return true; } @@ -529,7 +589,7 @@ public class AsYouTypeFormatter { currentMetaData = getMetadataForRegion(newRegionCode); } String countryCodeString = Integer.toString(countryCode); - prefixBeforeNationalNumber.append(countryCodeString).append(" "); + prefixBeforeNationalNumber.append(countryCodeString).append(SEPARATOR_BEFORE_NATIONAL_NUMBER); return true; } @@ -556,7 +616,7 @@ public class AsYouTypeFormatter { } private String inputDigitHelper(char nextChar) { - Matcher digitMatcher = digitPattern.matcher(formattingTemplate); + Matcher digitMatcher = DIGIT_PATTERN.matcher(formattingTemplate); if (digitMatcher.find(lastMatchPosition)) { String tempTemplate = digitMatcher.replaceFirst(Character.toString(nextChar)); formattingTemplate.replace(0, tempTemplate.length(), tempTemplate); diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java index 8bcbc6ed4..b33231830 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java @@ -348,6 +348,11 @@ public class PhoneNumberUtil { 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; // A mapping from a region code to the PhoneMetadata for that region. @@ -922,6 +927,14 @@ public class PhoneNumberUtil { return instance; } + /** + * 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 FIRST_GROUP_ONLY_PREFIX_PATTERN.matcher(nationalPrefixFormattingRule).matches(); + } + /** * Helper function to check region code is not unknown or null. */ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java index 018a1fe44..db549c569 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java @@ -43,6 +43,7 @@ public final class Phonemetadata { return this; } } + public static Builder newBuilder() { return new Builder(); } diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR index e6e7fbbb8..84ab554de 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF index d8e916a39..370c7aca2 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG index ce23073fe..8ddd93713 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN index 9884b4477..ae35d25d4 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO index 60b58b8b9..2c6db0283 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ index 348a5c374..6162eed2e 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC index 409cea8fa..418d22604 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA index 1b4977150..5147cb6f9 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT index 04ee2d5f8..ef9ee0263 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP index e4032ead6..9f733000d 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW index 27a156e5b..2f5c83680 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX index 18e63613e..f530abff2 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF index 6990570bd..dbd1ebe3e 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU index 98d64cfdf..fd33ba0f8 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU differ diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM index 0c4fbb3d4..451daa865 100644 Binary files a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM differ diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java index 1e2e8fe30..c8143d921 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java @@ -88,6 +88,35 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase { assertEquals("+819012345678901", formatter.inputDigit('1')); } + public void testCountryWithSpaceInNationalPrefixFormattingRule() { + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.BY); + assertEquals("8", formatter.inputDigit('8')); + assertEquals("88", formatter.inputDigit('8')); + assertEquals("881", formatter.inputDigit('1')); + assertEquals("8 819", formatter.inputDigit('9')); + assertEquals("8 8190", formatter.inputDigit('0')); + // The formatting rule for 5 digit numbers states that no space should be present after the + // national prefix. + assertEquals("881 901", formatter.inputDigit('1')); + assertEquals("8 819 012", formatter.inputDigit('2')); + // Too long, no formatting rule applies. + assertEquals("88190123", formatter.inputDigit('3')); + } + + public void testCountryWithSpaceInNationalPrefixFormattingRuleAndLongNdd() { + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.BY); + assertEquals("9", formatter.inputDigit('9')); + assertEquals("99", formatter.inputDigit('9')); + assertEquals("999", formatter.inputDigit('9')); + assertEquals("9999", formatter.inputDigit('9')); + assertEquals("99999 ", formatter.inputDigit('9')); + assertEquals("99999 1", formatter.inputDigit('1')); + assertEquals("99999 12", formatter.inputDigit('2')); + assertEquals("99999 123", formatter.inputDigit('3')); + assertEquals("99999 1234", formatter.inputDigit('4')); + assertEquals("99999 12 345", formatter.inputDigit('5')); + } + public void testAYTFUS() { AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US); assertEquals("6", formatter.inputDigit('6')); @@ -753,7 +782,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase { } public void testAYTFLongIDD_AU() { - AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("AU"); + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.AU); // 0011 1 650 253 2250 assertEquals("0", formatter.inputDigit('0')); assertEquals("00", formatter.inputDigit('0')); @@ -810,7 +839,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase { } public void testAYTFLongIDD_KR() { - AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR"); + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR); // 00300 1 650 253 2222 assertEquals("0", formatter.inputDigit('0')); assertEquals("00", formatter.inputDigit('0')); @@ -831,7 +860,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase { } public void testAYTFLongNDD_KR() { - AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR"); + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR); // 08811-9876-7890 assertEquals("0", formatter.inputDigit('0')); assertEquals("08", formatter.inputDigit('8')); @@ -867,7 +896,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase { } public void testAYTFLongNDD_SG() { - AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("SG"); + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.SG); // 777777 9876 7890 assertEquals("7", formatter.inputDigit('7')); assertEquals("77", formatter.inputDigit('7')); @@ -884,4 +913,183 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase { assertEquals("777777 9876 789", formatter.inputDigit('9')); assertEquals("777777 9876 7890", formatter.inputDigit('0')); } + + public void testAYTFShortNumberFormattingFix_AU() { + // For Australia, the national prefix is not optional when formatting. + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.AU); + + // 1234567890 - For leading digit 1, the national prefix formatting rule has first group only. + assertEquals("1", formatter.inputDigit('1')); + assertEquals("12", formatter.inputDigit('2')); + assertEquals("123", formatter.inputDigit('3')); + assertEquals("1234", formatter.inputDigit('4')); + assertEquals("1234 5", formatter.inputDigit('5')); + assertEquals("1234 56", formatter.inputDigit('6')); + assertEquals("1234 567", formatter.inputDigit('7')); + assertEquals("1234 567 8", formatter.inputDigit('8')); + assertEquals("1234 567 89", formatter.inputDigit('9')); + assertEquals("1234 567 890", formatter.inputDigit('0')); + + // +61 1234 567 890 - Test the same number, but with the country code. + formatter.clear(); + assertEquals("+", formatter.inputDigit('+')); + assertEquals("+6", formatter.inputDigit('6')); + assertEquals("+61 ", formatter.inputDigit('1')); + assertEquals("+61 1", formatter.inputDigit('1')); + assertEquals("+61 12", formatter.inputDigit('2')); + assertEquals("+61 123", formatter.inputDigit('3')); + assertEquals("+61 1234", formatter.inputDigit('4')); + assertEquals("+61 1234 5", formatter.inputDigit('5')); + assertEquals("+61 1234 56", formatter.inputDigit('6')); + assertEquals("+61 1234 567", formatter.inputDigit('7')); + assertEquals("+61 1234 567 8", formatter.inputDigit('8')); + assertEquals("+61 1234 567 89", formatter.inputDigit('9')); + assertEquals("+61 1234 567 890", formatter.inputDigit('0')); + + // 212345678 - For leading digit 2, the national prefix formatting rule puts the national prefix + // before the first group. + formatter.clear(); + assertEquals("0", formatter.inputDigit('0')); + assertEquals("02", formatter.inputDigit('2')); + assertEquals("021", formatter.inputDigit('1')); + assertEquals("02 12", formatter.inputDigit('2')); + assertEquals("02 123", formatter.inputDigit('3')); + assertEquals("02 1234", formatter.inputDigit('4')); + assertEquals("02 1234 5", formatter.inputDigit('5')); + assertEquals("02 1234 56", formatter.inputDigit('6')); + assertEquals("02 1234 567", formatter.inputDigit('7')); + assertEquals("02 1234 5678", formatter.inputDigit('8')); + + // 212345678 - Test the same number, but without the leading 0. + formatter.clear(); + assertEquals("2", formatter.inputDigit('2')); + assertEquals("21", formatter.inputDigit('1')); + assertEquals("212", formatter.inputDigit('2')); + assertEquals("2123", formatter.inputDigit('3')); + assertEquals("21234", formatter.inputDigit('4')); + assertEquals("212345", formatter.inputDigit('5')); + assertEquals("2123456", formatter.inputDigit('6')); + assertEquals("21234567", formatter.inputDigit('7')); + assertEquals("212345678", formatter.inputDigit('8')); + + // +61 2 1234 5678 - Test the same number, but with the country code. + formatter.clear(); + assertEquals("+", formatter.inputDigit('+')); + assertEquals("+6", formatter.inputDigit('6')); + assertEquals("+61 ", formatter.inputDigit('1')); + assertEquals("+61 2", formatter.inputDigit('2')); + assertEquals("+61 21", formatter.inputDigit('1')); + assertEquals("+61 2 12", formatter.inputDigit('2')); + assertEquals("+61 2 123", formatter.inputDigit('3')); + assertEquals("+61 2 1234", formatter.inputDigit('4')); + assertEquals("+61 2 1234 5", formatter.inputDigit('5')); + assertEquals("+61 2 1234 56", formatter.inputDigit('6')); + assertEquals("+61 2 1234 567", formatter.inputDigit('7')); + assertEquals("+61 2 1234 5678", formatter.inputDigit('8')); + } + + public void testAYTFShortNumberFormattingFix_KR() { + // For Korea, the national prefix is not optional when formatting, and the national prefix + // formatting rule doesn't consist of only the first group. + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR); + + // 111 + assertEquals("1", formatter.inputDigit('1')); + assertEquals("11", formatter.inputDigit('1')); + assertEquals("111", formatter.inputDigit('1')); + + // 114 + formatter.clear(); + assertEquals("1", formatter.inputDigit('1')); + assertEquals("11", formatter.inputDigit('1')); + assertEquals("114", formatter.inputDigit('4')); + + // 13121234 - Test a mobile number without the national prefix. Even though it is not an + // emergency number, it should be formatted as a block. + formatter.clear(); + assertEquals("1", formatter.inputDigit('1')); + assertEquals("13", formatter.inputDigit('3')); + assertEquals("131", formatter.inputDigit('1')); + assertEquals("1312", formatter.inputDigit('2')); + assertEquals("13121", formatter.inputDigit('1')); + assertEquals("131212", formatter.inputDigit('2')); + assertEquals("1312123", formatter.inputDigit('3')); + assertEquals("13121234", formatter.inputDigit('4')); + + // +82 131-2-1234 - Test the same number, but with the country code. + formatter.clear(); + assertEquals("+", formatter.inputDigit('+')); + assertEquals("+8", formatter.inputDigit('8')); + assertEquals("+82 ", formatter.inputDigit('2')); + assertEquals("+82 1", formatter.inputDigit('1')); + assertEquals("+82 13", formatter.inputDigit('3')); + assertEquals("+82 131", formatter.inputDigit('1')); + assertEquals("+82 131-2", formatter.inputDigit('2')); + assertEquals("+82 131-2-1", formatter.inputDigit('1')); + assertEquals("+82 131-2-12", formatter.inputDigit('2')); + assertEquals("+82 131-2-123", formatter.inputDigit('3')); + assertEquals("+82 131-2-1234", formatter.inputDigit('4')); + } + + public void testAYTFShortNumberFormattingFix_MX() { + // For Mexico, the national prefix is optional when formatting. + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.MX); + + // 911 + assertEquals("9", formatter.inputDigit('9')); + assertEquals("91", formatter.inputDigit('1')); + assertEquals("911", formatter.inputDigit('1')); + + // 800 123 4567 - Test a toll-free number, which should have a formatting rule applied to it + // even though it doesn't begin with the national prefix. + formatter.clear(); + assertEquals("8", formatter.inputDigit('8')); + assertEquals("80", formatter.inputDigit('0')); + assertEquals("800", formatter.inputDigit('0')); + assertEquals("800 1", formatter.inputDigit('1')); + assertEquals("800 12", formatter.inputDigit('2')); + assertEquals("800 123", formatter.inputDigit('3')); + assertEquals("800 123 4", formatter.inputDigit('4')); + assertEquals("800 123 45", formatter.inputDigit('5')); + assertEquals("800 123 456", formatter.inputDigit('6')); + assertEquals("800 123 4567", formatter.inputDigit('7')); + + // +52 800 123 4567 - Test the same number, but with the country code. + formatter.clear(); + assertEquals("+", formatter.inputDigit('+')); + assertEquals("+5", formatter.inputDigit('5')); + assertEquals("+52 ", formatter.inputDigit('2')); + assertEquals("+52 8", formatter.inputDigit('8')); + assertEquals("+52 80", formatter.inputDigit('0')); + assertEquals("+52 800", formatter.inputDigit('0')); + assertEquals("+52 800 1", formatter.inputDigit('1')); + assertEquals("+52 800 12", formatter.inputDigit('2')); + assertEquals("+52 800 123", formatter.inputDigit('3')); + assertEquals("+52 800 123 4", formatter.inputDigit('4')); + assertEquals("+52 800 123 45", formatter.inputDigit('5')); + assertEquals("+52 800 123 456", formatter.inputDigit('6')); + assertEquals("+52 800 123 4567", formatter.inputDigit('7')); + } + + public void testAYTFShortNumberFormattingFix_US() { + // For the US, an initial 1 is treated specially. + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US); + + // 101 - Test that the initial 1 is not treated as a national prefix. + assertEquals("1", formatter.inputDigit('1')); + assertEquals("10", formatter.inputDigit('0')); + assertEquals("101", formatter.inputDigit('1')); + + // 112 - Test that the initial 1 is not treated as a national prefix. + formatter.clear(); + assertEquals("1", formatter.inputDigit('1')); + assertEquals("11", formatter.inputDigit('1')); + assertEquals("112", formatter.inputDigit('2')); + + // 122 - Test that the initial 1 is treated as a national prefix. + formatter.clear(); + assertEquals("1", formatter.inputDigit('1')); + assertEquals("12", formatter.inputDigit('2')); + assertEquals("1 22", formatter.inputDigit('2')); + } } diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java index b93b3bef1..f58748f96 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java @@ -31,10 +31,10 @@ public class CountryCodeToRegionCodeMapForTesting { // countries sharing a calling code, such as the NANPA countries, the one // indicated with "isMainCountryForCode" in the metadata should be first. static Map> getCountryCodeToRegionCodeMap() { - // The capacity is set to 24 as there are 18 different country codes, + // The capacity is set to 25 as there are 19 different country codes, // and this offers a load factor of roughly 0.75. Map> countryCodeToRegionCodeMap = - new HashMap>(24); + new HashMap>(25); ArrayList listWithRegionCode; @@ -100,6 +100,10 @@ public class CountryCodeToRegionCodeMapForTesting { listWithRegionCode.add("YT"); countryCodeToRegionCodeMap.put(262, listWithRegionCode); + listWithRegionCode = new ArrayList(1); + listWithRegionCode.add("BY"); + countryCodeToRegionCodeMap.put(375, listWithRegionCode); + listWithRegionCode = new ArrayList(1); listWithRegionCode.add("AD"); countryCodeToRegionCodeMap.put(376, listWithRegionCode); diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java index 6b3a4e7a8..c765aca49 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java @@ -29,6 +29,7 @@ final class RegionCode { static final String AU = "AU"; static final String BR = "BR"; static final String BS = "BS"; + static final String BY = "BY"; static final String CA = "CA"; static final String CN = "CN"; static final String CS = "CS"; diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR index d57658148..c65e3dca0 100644 Binary files a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR differ diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BY b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BY new file mode 100644 index 000000000..467bebec1 Binary files /dev/null and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BY differ diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX index 5fc1c365a..cab73c84d 100644 Binary files a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX differ diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US index f81927539..d587fbdbd 100644 Binary files a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US differ diff --git a/java/release_notes.txt b/java/release_notes.txt index 7e0d028b6..20f29c738 100644 --- a/java/release_notes.txt +++ b/java/release_notes.txt @@ -1,3 +1,11 @@ +Sep 3, 2012: libphonenumber-5.1 +* Code changes: + - Inserting a space after the national prefix in the AsYouTypeFormatter when formatting numbers in + national format, if the formatting rules for that country dictate that a space is appropriate. + - Format emergency numbers and short-codes as a block in the AsYouTypeFormatter. +* Metadata changes: + - Updated metadata for region code(s): BF, BG, DZ, GA, IT, JP, KW, PF + Aug 20, 2012: libphonenumber-5.0.3 * Metadata changes: - New alternate formatting data for country calling code(s): 43 @@ -19,13 +27,13 @@ July 26th, 2012: libphonenumber-5.0.1 July 12th, 2012: libphonenumber-5.0 * Code changes: - - Support for alternate formats when finding phone numbers. - - Allowing two-digit numbers to be parsed if they are entered in national-format with no - punctuation + - Support for alternate formats when finding phone numbers. + - Allowing two-digit numbers to be parsed if they are entered in national-format with no + punctuation * Metadata changes - - IL, GA + - IL, GA * Other - - Reflowed this file to 100 char width to make it unambiguous as to what the standard should be. + - Reflowed this file to 100 char width to make it unambiguous as to what the standard should be. July 6th, 2012: libphonenumber-4.9.1 * Metadata changes diff --git a/resources/PhoneNumberMetaData.xml b/resources/PhoneNumberMetaData.xml index fb5335994..45281326a 100644 --- a/resources/PhoneNumberMetaData.xml +++ b/resources/PhoneNumberMetaData.xml @@ -22,7 +22,7 @@ official short names in English according to ISO 3166-1. For more information on what each element represents, see - resources/phonemetadata.proto + java/com/google/i18n/phonenumbers/phonemetadata.proto Note that if you want to add validation metadata, the generalDesc nationalNumberPattern and possibleNumberPattern must be provided. If this is missing, then the country will be @@ -2471,13 +2471,14 @@ + Including 716 as well since many numbers seem to have this prefix. Including 65 as a + prefix for Airtel, since they have informed us they are using it. --> (?: 6(?: - 0\d| + [05]\d| 1[01]| - 6[0-4]| + 6[0-7]| 8[0-2] )| 7(?: @@ -2503,27 +2504,30 @@ + 29 - $1/$2 + $1 $2 2 - $1/$2 $3 + $1 $2 $3 43[124-7]| 70[1-9] - $1/$2 + $1 $2 43[124-7]| 70[1-9] - $1/$2 $3 + $1 $2 $3 [78]00 @@ -2536,7 +2540,7 @@ 8[1-6]| 9[1-7] - $1/$2 $3 + $1 $2 $3 @@ -2549,8 +2553,8 @@ - [23567]\d{5,7}| - [489]\d{6,8} + [23567]\d{5,7}| + [489]\d{6,8} \d{5,9} @@ -5978,13 +5982,17 @@ 12345678 - + (?: 5[56]| - 6[569]| 7[7-9] - )\d{7} + )\d{7}| + 6(?: + [569]\d| + 70 + )\d{6} \d{9} 551234567 @@ -7152,26 +7160,32 @@ - + - + + 1 + $1 $2 $3 $4 + + + 0 $1 $2 $3 $4 - [1-7]\d{6} - \d{7} + [01]\d{6,7} + \d{7,8} - + 1\d{6} 1441234 - [2-7]\d{6} - 6031234 + 0[2-7]\d{6} + 06031234 @@ -11234,8 +11248,11 @@ - - 0[26] + + + 0[26]| + 55 + $1 $2 $3 @@ -11250,15 +11267,33 @@ 0[13-57-9][0159] $1 $2 $3 - - 0[13-57-9][0159] + + + 0[13-57-9][0159]| + 8(?: + 03| + 4[17]| + 9[245] + ) + + + 0[13-57-9][0159]| + 8(?: + 03| + 4[17]| + 9(?: + 2| + [45][0-4] + ) + ) + $1 $2 0[13-57-9][2-46-8] $1 $2 $3 - + 0[13-57-9][2-46-8] $1 $2 @@ -11267,29 +11302,36 @@ [13]| 8(?: 00| - 4[78]| - 99 + 4[08]| + 9[59] ) - $1 $2 $3 - - - 3 - $1 $2 $3 - - + [13]| 8(?: - 03| - 92 + 00| + 4[08]| + 9(?: + 5[5-9]| + 9 + ) ) + $1 $2 $3 + + + 894 + 894[5-9] $1 $2 + + 3 + $1 $2 $3 + - [0189]\d{5,10}| + [01589]\d{5,10}| 3(?: [12457-9]\d{8}| [36]\d{7,9} @@ -11298,18 +11340,75 @@ \d{6,11} - 848\d{6,7} - \d{9,10} - 8481234567 + 848\d{6} + \d{9} + 848123456 + 0(?: [26]\d{4,9}| - [13-57-9](?: - [0159]\d{4,8}| - [2-46-8]\d{5,8} - ) + (?: + 1(?: + [0159]\d| + [27][1-5]| + 31| + 4[1-4]| + 6[1356]| + 8[2-57] + )| + 3(?: + [0159]\d| + 2[1-4]| + 3[12]| + [48][1-6]| + 6[2-59]| + 7[1-7] + )| + 4(?: + [0159]\d| + [23][1-9]| + 4[245]| + 6[1-5]| + 7[1-4]| + 81 + )| + 5(?: + [0159]\d| + 2[1-5]| + 3[2-6]| + 4[1-79]| + 6[4-6]| + 7[1-578]| + 8[3-8] + )| + 7(?: + [0159]\d| + 2[12]| + 3[1-7]| + 4[2346]| + 6[13569]| + 7[13-6]| + 8[1-59] + )| + 8(?: + [0159]\d| + 2[34578]| + 3[1-356]| + [6-8][1-5] + )| + 9(?: + [0159]\d| + [238][1-5]| + 4[12]| + 6[1-8]| + 7[1-6] + ) + )\d{2,7} ) \d{6,11} @@ -11352,26 +11451,80 @@ )\d{6}| 89(?: 2\d{3}| + 4(?: + [0-4]\d{2}| + [5-9]\d{4} + )| + 5(?: + [0-4]\d{2}| + [5-9]\d{6} + )| 9\d{6} ) - \d{6,9} + \d{6,10} 899123456 - 84[78]\d{6,7} - \d{9,10} - 8481234567 + + 84(?: + [08]\d{6}| + [17]\d{3} + ) + + \d{6,9} + 848123456 - - 178\d{6,7} + + 1(?: + 78\d| + 99 + )\d{6} + \d{9,10} 1781234567 + + 55\d{8} + \d{10} + 5512345678 + + + + + 1(?: + 1(?: + [47]| + 6\d{3} + )| + 2\d{2}| + 4(?: + 82| + 9\d{1,3} + )| + 5(?: + 00| + 1[58]| + 2[25]| + 3[03]| + 44 + )| + 86| + 9(?: + 2(?: + [01]\d{2}| + [2-9]\d + )| + 4\d| + 696 + ) + ) + + \d{3,6} + 114 + 11[2358] \d{3} @@ -11909,8 +12062,40 @@ 088 $1-$2-$3 - - 037 + + + 0(?: + 37| + 66 + ) + + $1-$2-$3 + + + + 0(?: + 37| + 66 + ) + + $1-$2-$3 + + + + 0(?: + 37| + 66 + ) + + $1-$2-$3 + + + + 0(?: + 37| + 66 + ) + $1-$2-$3 0(?: - 37\d{8}| + 37\d{6,13}| + 66\d{6,13}| 777(?: [01]\d{2}| 5\d{3}| @@ -12701,7 +12887,7 @@ 882[1245]\d{4} ) - \d{7,11} + \d{7,16} 0777012 @@ -12767,11 +12953,20 @@ + http://tm.softbank.jp/english/business/phone_service/freecall_sp/index.html + http://eonet.jp/home/denwa/service/access.html + http://ci.fusioncom.co.jp/feature/ + http://www.auhikari.jp/service/tel/connection/index.html --> + 120\d{6}| 800\d{7}| 0(?: + 37\d{6,13}| + 66\d{6,13}| 777(?: [01]\d{2}| 5\d{3}| @@ -12780,7 +12975,7 @@ 882[1245]\d{4} ) - \d{7,10} + \d{7,16} 120123456 @@ -12794,13 +12989,8 @@ 601234567 - - (?: - 037| - 50 - )\d{8} - - \d{10,11} + 50\d{8} + \d{10} 5012345678 @@ -13634,7 +13824,7 @@ (?: 5(?: - 0[0-2568]| + 0[0-25-9]| 11| 5\d )| @@ -18338,7 +18528,7 @@ (?: [27]\d{2}| - 3[0-59]\d| + 3[0-79]\d| 411 )\d{3} diff --git a/resources/PhoneNumberMetaDataForTesting.xml b/resources/PhoneNumberMetaDataForTesting.xml index 588a2d73d..73440cf9a 100644 --- a/resources/PhoneNumberMetaDataForTesting.xml +++ b/resources/PhoneNumberMetaDataForTesting.xml @@ -177,6 +177,39 @@ + + + + + + + [1-8] + $1 + + + + [1-8] + $1 $2 + + + [1-8] + $1 $2 + + + + + [1-9]\d{5} + \d{6} + + + 112345 + + + @@ -701,11 +734,10 @@ - + + mainCountryForCode="true" nationalPrefixOptionalWhenFormatting="true"> $1 $2 diff --git a/tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java b/tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java index 67298ac2d..15fd2b747 100644 --- a/tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java +++ b/tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java @@ -211,7 +211,7 @@ public class BuildMetadataFromXml { // @VisibleForTesting static boolean loadInternationalFormat(PhoneMetadata.Builder metadata, Element numberFormatElement, - String nationalFormat) { + NumberFormat nationalFormat) { NumberFormat.Builder intlFormat = NumberFormat.newBuilder(); setLeadingDigitsPatterns(numberFormatElement, intlFormat); intlFormat.setPattern(numberFormatElement.getAttribute(PATTERN)); @@ -226,7 +226,7 @@ public class BuildMetadataFromXml { metadata.getId()); } else if (intlFormatPattern.getLength() == 0) { // Default to use the same as the national pattern if none is defined. - intlFormat.setFormat(nationalFormat); + intlFormat.mergeFrom(nationalFormat); } else { String intlFormatPatternValue = intlFormatPattern.item(0).getFirstChild().getNodeValue(); if (!intlFormatPatternValue.equals("NA")) { @@ -245,11 +245,10 @@ public class BuildMetadataFromXml { * Extracts the pattern for the national format. * * @throws RuntimeException if multiple or no formats have been encountered. - * @return the national format string. */ // @VisibleForTesting - static String loadNationalFormat(PhoneMetadata.Builder metadata, Element numberFormatElement, - NumberFormat.Builder format) { + static void loadNationalFormat(PhoneMetadata.Builder metadata, Element numberFormatElement, + NumberFormat.Builder format) { setLeadingDigitsPatterns(numberFormatElement, format); format.setPattern(validateRE(numberFormatElement.getAttribute(PATTERN))); @@ -260,9 +259,7 @@ public class BuildMetadataFromXml { throw new RuntimeException("Invalid number of format patterns for country: " + metadata.getId()); } - String nationalFormat = formatPattern.item(0).getFirstChild().getNodeValue(); - format.setFormat(nationalFormat); - return nationalFormat; + format.setFormat(formatPattern.item(0).getFirstChild().getNodeValue()); } /** @@ -306,11 +303,10 @@ public class BuildMetadataFromXml { } else { format.setDomesticCarrierCodeFormattingRule(carrierCodeFormattingRule); } - String nationalFormat = - loadNationalFormat(metadata, numberFormatElement, format); + loadNationalFormat(metadata, numberFormatElement, format); metadata.addNumberFormat(format); - if (loadInternationalFormat(metadata, numberFormatElement, nationalFormat)) { + if (loadInternationalFormat(metadata, numberFormatElement, format.build())) { hasExplicitIntlFormatDefined = true; } } diff --git a/tools/java/common/test/com/google/i18n/phonenumbers/BuildMetadataFromXmlTest.java b/tools/java/common/test/com/google/i18n/phonenumbers/BuildMetadataFromXmlTest.java index bed22b79d..c716bae81 100644 --- a/tools/java/common/test/com/google/i18n/phonenumbers/BuildMetadataFromXmlTest.java +++ b/tools/java/common/test/com/google/i18n/phonenumbers/BuildMetadataFromXmlTest.java @@ -153,7 +153,7 @@ public class BuildMetadataFromXmlTest extends TestCase { String xmlInput = "" + intlFormat + ""; Element numberFormatElement = parseXmlString(xmlInput); PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); - String nationalFormat = ""; + NumberFormat nationalFormat = NumberFormat.newBuilder().build(); assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, nationalFormat)); @@ -166,10 +166,11 @@ public class BuildMetadataFromXmlTest extends TestCase { String xmlInput = "" + intlFormat + ""; Element numberFormatElement = parseXmlString(xmlInput); PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); - String nationalFormat = "$1"; + NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); + nationalFormat.setFormat("$1"); assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, - nationalFormat)); + nationalFormat.build())); assertEquals(intlFormat, metadata.getIntlNumberFormat(0).getFormat()); } @@ -181,7 +182,8 @@ public class BuildMetadataFromXmlTest extends TestCase { // Should throw an exception as multiple intlFormats are provided. try { - BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, ""); + BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, + NumberFormat.newBuilder().build()); fail(); } catch (RuntimeException e) { // Test passed. @@ -193,14 +195,29 @@ public class BuildMetadataFromXmlTest extends TestCase { String xmlInput = ""; Element numberFormatElement = parseXmlString(xmlInput); PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); - String nationalFormat = "$1 $2 $3"; + NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); + String nationalPattern = "$1 $2 $3"; + nationalFormat.setFormat(nationalPattern); + + assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, + nationalFormat.build())); + assertEquals(nationalPattern, metadata.getIntlNumberFormat(0).getFormat()); + } + + public void testLoadInternationalFormatCopiesNationalFormatData() + throws ParserConfigurationException, SAXException, IOException { + String xmlInput = ""; + Element numberFormatElement = parseXmlString(xmlInput); + PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); + NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); + nationalFormat.setFormat("$1-$2"); + nationalFormat.setNationalPrefixOptionalWhenFormatting(true); assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, - nationalFormat)); - assertEquals(nationalFormat, metadata.getIntlNumberFormat(0).getFormat()); + nationalFormat.build())); + assertTrue(metadata.getIntlNumberFormat(0).isNationalPrefixOptionalWhenFormatting()); } - // Tests loadNationalFormat(). public void testLoadNationalFormat() throws ParserConfigurationException, SAXException, IOException { String nationalFormat = "$1 $2"; @@ -210,9 +227,8 @@ public class BuildMetadataFromXmlTest extends TestCase { PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); NumberFormat.Builder numberFormat = NumberFormat.newBuilder(); - assertEquals(nationalFormat, - BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, - numberFormat)); + BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat); + assertEquals(nationalFormat, numberFormat.getFormat()); } public void testLoadNationalFormatRequiresFormat() @@ -337,9 +353,11 @@ public class BuildMetadataFromXmlTest extends TestCase { String xmlInput = "NA"; Element numberFormatElement = parseXmlString(xmlInput); PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder(); - String nationalFormat = "$1 $2"; + NumberFormat.Builder nationalFormat = NumberFormat.newBuilder(); + nationalFormat.setFormat("$1 $2"); - BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, nationalFormat); + BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, + nationalFormat.build()); assertEquals(0, metadata.intlNumberFormatSize()); } diff --git a/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar b/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar index a73e47202..bcff17f13 100644 Binary files a/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar and b/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar differ diff --git a/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar b/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar index 041695278..76bb8e26b 100644 Binary files a/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar and b/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar differ