summaryrefslogtreecommitdiffstats
path: root/java/libphonenumber
diff options
context:
space:
mode:
Diffstat (limited to 'java/libphonenumber')
-rw-r--r--java/libphonenumber/build.xml175
-rw-r--r--java/libphonenumber/pom.xml205
-rw-r--r--java/libphonenumber/release_notes.txt361
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java574
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java898
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java63
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java125
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java446
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java2790
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java941
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java260
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/RegexCache.java78
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java94
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ACbin0 -> 240 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ADbin0 -> 380 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AEbin0 -> 597 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AFbin0 -> 349 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AGbin0 -> 519 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AIbin0 -> 446 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ALbin0 -> 736 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AMbin0 -> 612 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ANbin0 -> 583 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AObin0 -> 317 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ARbin0 -> 2621 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ASbin0 -> 428 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ATbin0 -> 1091 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AUbin0 -> 1158 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AWbin0 -> 423 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AXbin0 -> 534 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZbin0 -> 1010 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BAbin0 -> 406 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BBbin0 -> 428 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BDbin0 -> 1059 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BEbin0 -> 724 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BFbin0 -> 394 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BGbin0 -> 890 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BHbin0 -> 514 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BIbin0 -> 342 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJbin0 -> 389 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BLbin0 -> 292 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BMbin0 -> 462 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BNbin0 -> 292 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BObin0 -> 558 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BRbin0 -> 811 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BSbin0 -> 607 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BTbin0 -> 420 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BWbin0 -> 596 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BYbin0 -> 755 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZbin0 -> 411 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CAbin0 -> 714 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CCbin0 -> 501 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CDbin0 -> 375 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CFbin0 -> 315 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CGbin0 -> 362 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CHbin0 -> 535 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CIbin0 -> 420 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CKbin0 -> 308 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CLbin0 -> 944 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CMbin0 -> 411 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CNbin0 -> 2689 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CObin0 -> 871 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CRbin0 -> 505 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CUbin0 -> 463 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CVbin0 -> 343 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CXbin0 -> 501 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CYbin0 -> 402 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZbin0 -> 524 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DEbin0 -> 1681 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJbin0 -> 301 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DKbin0 -> 382 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DMbin0 -> 484 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DObin0 -> 749 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZbin0 -> 617 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ECbin0 -> 637 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EEbin0 -> 834 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EGbin0 -> 798 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ERbin0 -> 331 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ESbin0 -> 530 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ETbin0 -> 974 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FIbin0 -> 751 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJbin0 -> 436 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FKbin0 -> 239 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FMbin0 -> 336 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FObin0 -> 422 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FRbin0 -> 589 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GAbin0 -> 584 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GBbin0 -> 2853 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GDbin0 -> 524 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GEbin0 -> 543 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GFbin0 -> 403 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GGbin0 -> 607 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GHbin0 -> 451 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GIbin0 -> 348 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GLbin0 -> 360 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GMbin0 -> 383 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GNbin0 -> 401 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GPbin0 -> 414 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQbin0 -> 432 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GRbin0 -> 868 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GTbin0 -> 420 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GUbin0 -> 806 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GWbin0 -> 325 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GYbin0 -> 423 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HKbin0 -> 512 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HNbin0 -> 487 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HRbin0 -> 967 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HTbin0 -> 361 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HUbin0 -> 527 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IDbin0 -> 1091 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IEbin0 -> 1250 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ILbin0 -> 876 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IMbin0 -> 522 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_INbin0 -> 3984 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IObin0 -> 258 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQbin0 -> 455 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IRbin0 -> 1017 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ISbin0 -> 675 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ITbin0 -> 982 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JEbin0 -> 705 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JMbin0 -> 673 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JObin0 -> 567 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JPbin0 -> 4967 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KEbin0 -> 476 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KGbin0 -> 703 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KHbin0 -> 605 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KIbin0 -> 291 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KMbin0 -> 343 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KNbin0 -> 468 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KPbin0 -> 477 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KRbin0 -> 1394 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KWbin0 -> 488 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KYbin0 -> 554 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZbin0 -> 855 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LAbin0 -> 424 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LBbin0 -> 537 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LCbin0 -> 506 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LIbin0 -> 792 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LKbin0 -> 424 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LRbin0 -> 578 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LSbin0 -> 306 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LTbin0 -> 599 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LUbin0 -> 1494 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LVbin0 -> 333 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LYbin0 -> 335 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MAbin0 -> 757 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MCbin0 -> 492 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MDbin0 -> 649 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MEbin0 -> 683 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MFbin0 -> 302 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MGbin0 -> 398 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MHbin0 -> 323 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MKbin0 -> 620 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MLbin0 -> 438 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MMbin0 -> 612 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MNbin0 -> 721 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MObin0 -> 309 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MPbin0 -> 592 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQbin0 -> 398 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MRbin0 -> 408 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MSbin0 -> 402 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MTbin0 -> 451 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MUbin0 -> 518 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MVbin0 -> 495 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MWbin0 -> 542 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MXbin0 -> 1803 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MYbin0 -> 736 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZbin0 -> 415 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NAbin0 -> 858 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NCbin0 -> 333 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NEbin0 -> 472 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NFbin0 -> 351 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NGbin0 -> 865 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NIbin0 -> 294 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NLbin0 -> 651 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NObin0 -> 603 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NPbin0 -> 565 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NRbin0 -> 292 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NUbin0 -> 236 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZbin0 -> 797 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OMbin0 -> 428 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PAbin0 -> 875 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PEbin0 -> 599 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PFbin0 -> 380 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PGbin0 -> 456 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PHbin0 -> 999 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PKbin0 -> 1773 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PLbin0 -> 617 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PMbin0 -> 293 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PRbin0 -> 428 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PSbin0 -> 551 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PTbin0 -> 520 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PWbin0 -> 374 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PYbin0 -> 861 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QAbin0 -> 393 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_REbin0 -> 436 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RObin0 -> 477 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RSbin0 -> 716 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RUbin0 -> 603 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RWbin0 -> 478 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SAbin0 -> 633 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SBbin0 -> 390 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SCbin0 -> 546 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SDbin0 -> 320 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SEbin0 -> 2314 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SGbin0 -> 599 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SHbin0 -> 273 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SIbin0 -> 684 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJbin0 -> 436 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SKbin0 -> 586 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SLbin0 -> 351 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SMbin0 -> 609 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SNbin0 -> 431 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SObin0 -> 482 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SRbin0 -> 447 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_STbin0 -> 276 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SVbin0 -> 479 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SXbin0 -> 427 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SYbin0 -> 462 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZbin0 -> 439 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TCbin0 -> 495 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TDbin0 -> 359 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TGbin0 -> 344 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_THbin0 -> 584 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJbin0 -> 660 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TKbin0 -> 234 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TLbin0 -> 354 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TMbin0 -> 339 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TNbin0 -> 338 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TObin0 -> 469 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TRbin0 -> 736 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TTbin0 -> 556 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TVbin0 -> 242 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TWbin0 -> 440 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZbin0 -> 539 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UAbin0 -> 1091 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UGbin0 -> 555 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_USbin0 -> 1633 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UYbin0 -> 482 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZbin0 -> 1824 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VAbin0 -> 276 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VCbin0 -> 519 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VEbin0 -> 423 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VGbin0 -> 523 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VIbin0 -> 624 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VNbin0 -> 988 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VUbin0 -> 387 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WFbin0 -> 304 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WSbin0 -> 378 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YEbin0 -> 451 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YTbin0 -> 292 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZAbin0 -> 705 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZMbin0 -> 402 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZWbin0 -> 1586 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java203
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java108
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java94
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java263
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/MappingFileProvider.java229
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java217
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1201_enbin0 -> 325 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1202_enbin0 -> 40 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1203_enbin0 -> 1377 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1204_enbin0 -> 1914 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1205_enbin0 -> 918 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1206_enbin0 -> 741 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1207_enbin0 -> 1460 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1208_enbin0 -> 1947 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1209_enbin0 -> 1049 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1210_enbin0 -> 40 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1212_enbin0 -> 37 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1213_enbin0 -> 40 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1214_enbin0 -> 933 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1215_enbin0 -> 1422 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1216_enbin0 -> 449 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1217_enbin0 -> 2045 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1218_enbin0 -> 1707 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1219_enbin0 -> 769 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1224_enbin0 -> 60 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1225_enbin0 -> 590 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1226_enbin0 -> 52 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1228_enbin0 -> 285 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1229_enbin0 -> 1059 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1231_enbin0 -> 1043 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1234_enbin0 -> 29 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1239_enbin0 -> 662 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1240_enbin0 -> 210 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1248_enbin0 -> 633 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1250_enbin0 -> 2042 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1251_enbin0 -> 705 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1252_enbin0 -> 983 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1253_enbin0 -> 374 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1254_enbin0 -> 1185 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1256_enbin0 -> 1280 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1260_enbin0 -> 937 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1262_enbin0 -> 650 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1267_enbin0 -> 179 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1269_enbin0 -> 1051 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1270_enbin0 -> 1655 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1276_enbin0 -> 531 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1281_enbin0 -> 895 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1289_enbin0 -> 216 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1301_enbin0 -> 937 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1302_enbin0 -> 566 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1303_enbin0 -> 585 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1304_enbin0 -> 1678 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1305_enbin0 -> 647 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1306_enbin0 -> 2112 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1307_enbin0 -> 890 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1308_enbin0 -> 1386 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1309_enbin0 -> 1490 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1310_enbin0 -> 415 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1312_enbin0 -> 36 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1313_enbin0 -> 502 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1314_enbin0 -> 497 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1315_enbin0 -> 1557 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1316_enbin0 -> 600 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1317_enbin0 -> 1072 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1318_enbin0 -> 1339 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1319_enbin0 -> 1548 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1320_enbin0 -> 1319 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1321_enbin0 -> 232 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1323_enbin0 -> 511 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1325_enbin0 -> 927 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1330_enbin0 -> 1447 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1331_enbin0 -> 33 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1334_enbin0 -> 1262 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1336_enbin0 -> 1316 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1337_enbin0 -> 1006 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1339_enbin0 -> 38 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1347_enbin0 -> 55 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1351_enbin0 -> 38 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1352_enbin0 -> 665 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1360_enbin0 -> 1626 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1361_enbin0 -> 1171 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1385_enbin0 -> 29 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1386_enbin0 -> 440 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1401_enbin0 -> 524 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1402_enbin0 -> 2590 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1403_enbin0 -> 1852 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1404_enbin0 -> 763 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1405_enbin0 -> 1378 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1406_enbin0 -> 1997 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1407_enbin0 -> 772 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1408_enbin0 -> 790 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1409_enbin0 -> 681 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1410_enbin0 -> 1327 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1412_enbin0 -> 617 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1413_enbin0 -> 826 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1414_enbin0 -> 561 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1415_enbin0 -> 1233 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1416_enbin0 -> 219 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1417_enbin0 -> 1409 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1418_enbin0 -> 2123 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1419_enbin0 -> 2181 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1423_enbin0 -> 1192 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1424_enbin0 -> 82 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1425_enbin0 -> 259 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1430_enbin0 -> 30 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1432_enbin0 -> 621 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1434_enbin0 -> 747 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1435_enbin0 -> 624 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1438_enbin0 -> 32 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1440_enbin0 -> 662 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1443_enbin0 -> 278 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1450_enbin0 -> 1678 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1469_enbin0 -> 100 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1478_enbin0 -> 699 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1479_enbin0 -> 872 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1480_enbin0 -> 185 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1484_enbin0 -> 199 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1501_enbin0 -> 840 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1502_enbin0 -> 1015 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1503_enbin0 -> 1317 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1504_enbin0 -> 567 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1505_enbin0 -> 1299 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1506_enbin0 -> 586 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1507_enbin0 -> 2039 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1508_enbin0 -> 1294 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1509_enbin0 -> 1778 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1510_enbin0 -> 679 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1512_enbin0 -> 1105 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1513_enbin0 -> 919 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1514_enbin0 -> 198 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1515_enbin0 -> 959 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1516_enbin0 -> 160 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1517_enbin0 -> 970 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1518_enbin0 -> 1132 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1519_enbin0 -> 2451 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1520_enbin0 -> 1082 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1530_enbin0 -> 1338 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1540_enbin0 -> 1414 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1541_enbin0 -> 2230 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1551_enbin0 -> 35 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1559_enbin0 -> 1355 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1561_enbin0 -> 547 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1562_enbin0 -> 383 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1563_enbin0 -> 1013 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1567_enbin0 -> 29 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1570_enbin0 -> 1191 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1571_enbin0 -> 55 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1573_enbin0 -> 1905 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1574_enbin0 -> 789 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1575_enbin0 -> 1018 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1580_enbin0 -> 1749 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1585_enbin0 -> 1036 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1586_enbin0 -> 142 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1587_enbin0 -> 32 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1601_enbin0 -> 1526 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1602_enbin0 -> 656 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1603_enbin0 -> 1260 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1604_enbin0 -> 603 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1605_enbin0 -> 2108 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1606_enbin0 -> 1043 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1607_enbin0 -> 855 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1608_enbin0 -> 1816 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1609_enbin0 -> 555 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1610_enbin0 -> 786 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1612_enbin0 -> 517 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1613_enbin0 -> 1018 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1614_enbin0 -> 527 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1615_enbin0 -> 1209 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1616_enbin0 -> 629 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1617_enbin0 -> 1043 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1618_enbin0 -> 1697 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1619_enbin0 -> 783 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1620_enbin0 -> 2051 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1623_enbin0 -> 88 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1626_enbin0 -> 184 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1630_enbin0 -> 361 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1631_enbin0 -> 215 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1636_enbin0 -> 522 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1641_enbin0 -> 1454 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1646_enbin0 -> 191 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1647_enbin0 -> 32 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1650_enbin0 -> 274 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1651_enbin0 -> 370 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1657_enbin0 -> 35 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1660_enbin0 -> 1172 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1661_enbin0 -> 866 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1662_enbin0 -> 1598 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1678_enbin0 -> 207 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1682_enbin0 -> 73 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1701_enbin0 -> 1932 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1702_enbin0 -> 719 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1703_enbin0 -> 748 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1704_enbin0 -> 1423 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1705_enbin0 -> 1750 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1706_enbin0 -> 1600 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1707_enbin0 -> 1273 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1708_enbin0 -> 321 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1709_enbin0 -> 545 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1712_enbin0 -> 2033 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1713_enbin0 -> 1775 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1714_enbin0 -> 326 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1715_enbin0 -> 2069 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1716_enbin0 -> 908 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1717_enbin0 -> 1197 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1718_enbin0 -> 33 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1719_enbin0 -> 1377 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1720_enbin0 -> 136 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1724_enbin0 -> 1179 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1726_enbin0 -> 36 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1727_enbin0 -> 182 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1730_enbin0 -> 39 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1731_enbin0 -> 978 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1732_enbin0 -> 353 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1734_enbin0 -> 607 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1740_enbin0 -> 1685 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1754_enbin0 -> 32 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1757_enbin0 -> 1072 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1760_enbin0 -> 1139 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1763_enbin0 -> 188 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1765_enbin0 -> 1436 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1769_enbin0 -> 36 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1770_enbin0 -> 620 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1772_enbin0 -> 389 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1773_enbin0 -> 36 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1774_enbin0 -> 78 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1775_enbin0 -> 638 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1778_enbin0 -> 252 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1779_enbin0 -> 33 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1780_enbin0 -> 2061 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1781_enbin0 -> 979 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1785_enbin0 -> 1982 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1786_enbin0 -> 89 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1801_enbin0 -> 573 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1802_enbin0 -> 931 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1803_enbin0 -> 1398 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1804_enbin0 -> 911 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1805_enbin0 -> 888 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1806_enbin0 -> 1651 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1807_enbin0 -> 663 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1808_enbin0 -> 1192 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1810_enbin0 -> 665 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1812_enbin0 -> 1778 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1813_enbin0 -> 769 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1814_enbin0 -> 1526 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1815_enbin0 -> 1851 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1816_enbin0 -> 975 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1817_enbin0 -> 675 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1818_enbin0 -> 359 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1819_enbin0 -> 1289 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1828_enbin0 -> 959 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1830_enbin0 -> 951 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1831_enbin0 -> 485 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1832_enbin0 -> 210 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1838_enbin0 -> 38 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1843_enbin0 -> 1398 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1845_enbin0 -> 747 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1847_enbin0 -> 421 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1848_enbin0 -> 35 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1850_enbin0 -> 1390 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1851_enbin0 -> 38 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1856_enbin0 -> 481 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1857_enbin0 -> 74 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1858_enbin0 -> 599 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1859_enbin0 -> 777 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1860_enbin0 -> 1073 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1862_enbin0 -> 35 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1863_enbin0 -> 722 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1864_enbin0 -> 1020 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1865_enbin0 -> 697 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1867_enbin0 -> 358 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1870_enbin0 -> 2041 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1872_enbin0 -> 36 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1878_enbin0 -> 37 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1888_enbin0 -> 36 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1901_enbin0 -> 708 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1902_enbin0 -> 1344 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1903_enbin0 -> 1841 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1904_enbin0 -> 1189 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1905_enbin0 -> 2330 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1906_enbin0 -> 524 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1907_enbin0 -> 995 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1908_enbin0 -> 362 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1909_enbin0 -> 570 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1910_enbin0 -> 1055 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1912_enbin0 -> 1109 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1913_enbin0 -> 485 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1914_enbin0 -> 403 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1915_enbin0 -> 490 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1916_enbin0 -> 776 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1917_enbin0 -> 113 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1918_enbin0 -> 1857 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1919_enbin0 -> 1113 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1920_enbin0 -> 1492 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1925_enbin0 -> 543 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1928_enbin0 -> 776 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1931_enbin0 -> 1199 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1936_enbin0 -> 708 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1937_enbin0 -> 1319 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1940_enbin0 -> 1008 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1941_enbin0 -> 570 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1947_enbin0 -> 57 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1949_enbin0 -> 252 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1951_enbin0 -> 498 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1952_enbin0 -> 95 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1954_enbin0 -> 126 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1956_enbin0 -> 700 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1970_enbin0 -> 1604 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1971_enbin0 -> 53 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1972_enbin0 -> 1042 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1973_enbin0 -> 571 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1978_enbin0 -> 1105 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1979_enbin0 -> 831 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1980_enbin0 -> 62 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1985_enbin0 -> 635 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1989_enbin0 -> 1589 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/20_enbin0 -> 408 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_enbin0 -> 1233 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_frbin0 -> 604 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/213_enbin0 -> 250 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/216_enbin0 -> 321 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/220_enbin0 -> 96 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/221_enbin0 -> 49 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_enbin0 -> 181 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_frbin0 -> 31 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/224_enbin0 -> 303 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_enbin0 -> 174 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_frbin0 -> 174 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/226_enbin0 -> 280 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_enbin0 -> 129 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_esbin0 -> 142 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_frbin0 -> 149 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_enbin0 -> 639 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_frbin0 -> 161 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_enbin0 -> 126 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_esbin0 -> 76 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_frbin0 -> 76 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/232_enbin0 -> 66 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/233_enbin0 -> 772 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_enbin0 -> 1047 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_ptbin0 -> 1047 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_enbin0 -> 315 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_ptbin0 -> 54 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_enbin0 -> 140 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_frbin0 -> 140 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_enbin0 -> 184 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_frbin0 -> 94 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_enbin0 -> 488 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_ptbin0 -> 95 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_enbin0 -> 325 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_ptbin0 -> 325 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/247_enbin0 -> 118 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/249_enbin0 -> 171 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/251_enbin0 -> 10810 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/252_enbin0 -> 66 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/254_enbin0 -> 373 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/256_enbin0 -> 198 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_enbin0 -> 161 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_ptbin0 -> 32 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/260_enbin0 -> 274 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/261_enbin0 -> 394 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/263_enbin0 -> 924 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/264_enbin0 -> 349 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/266_enbin0 -> 31 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/267_enbin0 -> 310 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/268_enbin0 -> 995 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_enbin0 -> 195 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_frbin0 -> 195 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/27_enbin0 -> 601 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_enbin0 -> 96 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_frbin0 -> 64 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/299_enbin0 -> 376 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_elbin0 -> 5597 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_enbin0 -> 2303 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_enbin0 -> 1735 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_nlbin0 -> 33 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_enbin0 -> 63146 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_frbin0 -> 132 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_enbin0 -> 1018 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_esbin0 -> 124 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_enbin0 -> 823 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_ptbin0 -> 31 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_debin0 -> 326 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_enbin0 -> 669 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/354_enbin0 -> 123 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/355_enbin0 -> 893 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_enbin0 -> 210 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_fibin0 -> 112 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_sebin0 -> 211 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_enbin0 -> 799 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_hubin0 -> 433 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/370_enbin0 -> 746 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/371_enbin0 -> 495 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/372_enbin0 -> 276 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_enbin0 -> 637 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_robin0 -> 331 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_rubin0 -> 965 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/374_enbin0 -> 1949 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_enbin0 -> 495 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_srbin0 -> 188 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_enbin0 -> 1647 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_itbin0 -> 2506 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_debin0 -> 138 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_enbin0 -> 319 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_frbin0 -> 97 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_itbin0 -> 183 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/420_enbin0 -> 431 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/421_enbin0 -> 422 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_debin0 -> 3003 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_enbin0 -> 18727 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/44_enbin0 -> 12980 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_enbin0 -> 4010 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_svbin0 -> 34 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_enbin0 -> 725 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_plbin0 -> 242 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_debin0 -> 1164 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_enbin0 -> 98456 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/51_enbin0 -> 354 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/53_enbin0 -> 396 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_enbin0 -> 5536 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_esbin0 -> 179 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_enbin0 -> 1385 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_ptbin0 -> 1385 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_enbin0 -> 342 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_esbin0 -> 342 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_enbin0 -> 809 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_esbin0 -> 84 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/7_enbin0 -> 1639 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_enbin0 -> 16654 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_jabin0 -> 14298 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_enbin0 -> 227 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_kobin0 -> 215 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zhbin0 -> 284 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hantbin0 -> 284 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_enbin0 -> 1477 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_vibin0 -> 1125 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_enbin0 -> 7147 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_zhbin0 -> 8472 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_enbin0 -> 241 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zhbin0 -> 237 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hantbin0 -> 237 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_enbin0 -> 1735 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_trbin0 -> 882 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/94_enbin0 -> 510 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/configbin0 -> 4863 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java867
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java109
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java176
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java72
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java935
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java1968
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/PhonenumberTest.java112
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/RegexCacheTest.java55
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java47
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java148
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java.orig76
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_ADbin0 -> 159 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AObin0 -> 314 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_ARbin0 -> 852 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AUbin0 -> 373 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BRbin0 -> 184 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BSbin0 -> 384 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DEbin0 -> 735 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GBbin0 -> 535 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_ITbin0 -> 471 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_JPbin0 -> 552 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KRbin0 -> 1582 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MXbin0 -> 975 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_NZbin0 -> 550 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_PLbin0 -> 320 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_REbin0 -> 403 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_SGbin0 -> 423 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_USbin0 -> 565 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_YTbin0 -> 277 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java192
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorageTest.java107
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/MappingFileProviderTest.java93
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java123
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_debin0 -> 35 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_enbin0 -> 27 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1212_enbin0 -> 49 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1617_enbin0 -> 35 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_debin0 -> 36 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_enbin0 -> 54 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1989_enbin0 -> 27 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_enbin0 -> 227 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_kobin0 -> 203 bytes
-rw-r--r--java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/configbin0 -> 94 bytes
740 files changed, 13204 insertions, 0 deletions
diff --git a/java/libphonenumber/build.xml b/java/libphonenumber/build.xml
new file mode 100644
index 0000000..172c265
--- /dev/null
+++ b/java/libphonenumber/build.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" ?>
+
+<project name="libphonenumber" default="compile">
+ <property name="src.dir" value="src"/>
+ <property name="test.dir" value="test"/>
+ <property name="build.dir" value="build"/>
+ <property name="classes.dir" value="${build.dir}/classes"/>
+ <property name="jar.dir" value="${build.dir}/jar"/>
+ <property name="lib.dir" value="../lib"/>
+ <property name="report.dir" value="${build.dir}/junitreport"/>
+ <property name="resources.dir" value="../../resources/"/>
+ <property name="javascript.dir" value="../../javascript/"/>
+ <property name="build.tools.jar"
+ value="../../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar"/>
+
+ <path id="classpath">
+ <fileset dir="${lib.dir}" includes="**/*.jar"/>
+ </path>
+ <path id="test.classpath">
+ <pathelement location="${classes.dir}"/>
+ <pathelement location="${lib.dir}/junit-4.8.1.jar"/>
+ <pathelement location="${jar.dir}/${ant.project.name}-test.jar"/>
+ <fileset dir="${lib.dir}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="build-metadata">
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="BuildMetadataProtoFromXml"/>
+ <arg value="${resources.dir}/PhoneNumberMetaData.xml"/>
+ <arg value="src"/>
+ <arg value="false"/> <!-- Not for testing. -->
+ <arg value="false"/> <!-- No lite metadata. -->
+ </exec>
+ </target>
+
+ <target name="build-test-metadata">
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="BuildMetadataProtoFromXml"/>
+ <arg value="${resources.dir}/PhoneNumberMetaDataForTesting.xml"/>
+ <arg value="test"/>
+ <arg value="true"/> <!-- For testing. -->
+ <arg value="false"/> <!-- No lite metadata. -->
+ </exec>
+ </target>
+
+ <target name="build-geo-data">
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="GenerateAreaCodeData"/>
+ <arg value="${resources.dir}/geocoding/"/>
+ <arg value="src/com/google/i18n/phonenumbers/geocoding/data"/>
+ </exec>
+ </target>
+
+ <target name="build-geo-test-data">
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="GenerateAreaCodeData"/>
+ <arg value="${resources.dir}/test/geocoding/"/>
+ <arg value="test/com/google/i18n/phonenumbers/geocoding/testing_data"/>
+ </exec>
+ </target>
+
+ <target name="build-js-metadata">
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="BuildMetadataJsonFromXml"/>
+ <arg value="${resources.dir}/PhoneNumberMetaData.xml"/>
+ <arg value="${javascript.dir}/i18n/phonenumbers/metadata.js"/>
+ </exec>
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="BuildMetadataJsonFromXml"/>
+ <arg value="${resources.dir}/PhoneNumberMetaData.xml"/>
+ <arg value="${javascript.dir}/i18n/phonenumbers/metadatalite.js"/>
+ <arg value="true"/> <!-- Lite metadata. -->
+ </exec>
+ <exec executable="java">
+ <arg value="-jar" />
+ <arg value="${build.tools.jar}"/>
+ <arg value="BuildMetadataJsonFromXml"/>
+ <arg value="${resources.dir}/PhoneNumberMetaDataForTesting.xml"/>
+ <arg value="${javascript.dir}/i18n/phonenumbers/metadatafortesting.js"/>
+ </exec>
+ </target>
+
+ <target name="compile" description="Compile Java source."
+ depends="build-metadata,build-geo-data">
+ <mkdir dir="${classes.dir}"/>
+ <javac srcdir="${src.dir}" destdir="${classes.dir}"
+ classpathref="classpath" includeAntRuntime="false"/>
+ <javac srcdir="${test.dir}" destdir="${classes.dir}"
+ classpathref="classpath" debug="on" includeAntRuntime="false"/>
+ </target>
+
+ <target name="jar" depends="compile">
+ <mkdir dir="${jar.dir}"/>
+ <jar destfile="${jar.dir}/${ant.project.name}.jar">
+ <fileset dir="${classes.dir}">
+ <include name="**/*.class"/>
+ <exclude name="**/*Test*"/>
+ <exclude name="**/BuildMetadata*"/>
+ <exclude name="**/geocoding/*"/>
+ </fileset>
+ <fileset dir="${src.dir}">
+ <include name="**/PhoneNumberMetadataProto*"/>
+ </fileset>
+ </jar>
+ <jar destfile="${jar.dir}/offline-geocoder.jar">
+ <fileset dir="${classes.dir}">
+ <include name="**/geocoding/*.class"/>
+ <exclude name="**/*Test*"/>
+ <exclude name="**/geocoding/GenerateAreaCodeData*"/>
+ </fileset>
+ <fileset dir="${src.dir}">
+ <include name="**/geocoding/data/*"/>
+ </fileset>
+ </jar>
+ </target>
+
+ <target name="test-jar"
+ depends="compile,build-test-metadata,build-geo-test-data">
+ <mkdir dir="${jar.dir}"/>
+ <jar destfile="${jar.dir}/${ant.project.name}-test.jar">
+ <fileset dir="${classes.dir}">
+ <include name="**/*.class"/>
+ <exclude name="**/*Test*"/>
+ </fileset>
+ <fileset dir="${src.dir}">
+ <include name="**/PhoneNumberMetadataProto*"/>
+ </fileset>
+ <fileset dir="${test.dir}">
+ <include name="**/PhoneNumberMetadataProtoForTesting*"/>
+ </fileset>
+ <fileset dir="${test.dir}">
+ <include name="**/geocoding/testing_data/*"/>
+ </fileset>
+ </jar>
+ </target>
+
+ <target name="junit" depends="test-jar">
+ <mkdir dir="${report.dir}"/>
+ <junit printsummary="yes">
+ <classpath refid="test.classpath"/>
+ <formatter type="xml"/>
+ <batchtest fork="no" todir="${report.dir}">
+ <fileset dir="${test.dir}" includes="**/*Test.java"/>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="junitreport">
+ <junitreport todir="${report.dir}">
+ <fileset dir="${report.dir}" includes="TEST-*.xml"/>
+ <report todir="${report.dir}"/>
+ </junitreport>
+ </target>
+
+ <target name="clean" description="Remove generated files.">
+ <delete dir="${build.dir}"/>
+ </target>
+
+ <target name="clean-build" depends="clean,jar"/>
+</project>
+
diff --git a/java/libphonenumber/pom.xml b/java/libphonenumber/pom.xml
new file mode 100644
index 0000000..2a4a9ae
--- /dev/null
+++ b/java/libphonenumber/pom.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.googlecode.libphonenumber</groupId>
+ <artifactId>libphonenumber</artifactId>
+ <version>4.3-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>libphonenumber</name>
+ <url>http://code.google.com/p/libphonenumber/</url>
+
+ <parent>
+ <groupId>org.sonatype.oss</groupId>
+ <artifactId>oss-parent</artifactId>
+ <version>7</version>
+ </parent>
+
+ <description>
+ Google's common Java library for parsing, formatting, storing and validating international phone numbers.
+ Optimized for running on smartphones.
+ </description>
+
+ <organization>
+ <name>Google</name>
+ <url>http://www.google.com/</url>
+ </organization>
+
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+
+ <scm>
+ <connection>scm:svn:http://libphonenumber.googlecode.com/svn/trunk/java/</connection>
+ <developerConnection>scm:svn:https://libphonenumber.googlecode.com/svn/trunk/java/</developerConnection>
+ <url>scm:svn:http://libphonenumber.googlecode.com/svn/trunk/java/</url>
+ </scm>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <developers>
+ <developer>
+ <id>jia.shao.peng</id>
+ <name>Shaopeng Jia</name>
+ <email>jia.shao.peng@gmail.com</email>
+ <organization>Google</organization>
+ <roles>
+ <role>owner</role>
+ <role>developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>lararennie</id>
+ <name>Lara Rennie</name>
+ <email>lararennie@google.com</email>
+ <organization>Google</organization>
+ <roles>
+ <role>developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <contributors>
+ <contributor>
+ <name>tronikos</name>
+ <email>tronikos@gmail.com</email>
+ </contributor>
+ <contributor>
+ <name>g1smd.email</name>
+ <email>g1smd.email@gmail.com</email>
+ </contributor>
+ <contributor>
+ <name>Philippe Liard</name>
+ <email>philip.liard@gmail.com</email>
+ </contributor>
+ </contributors>
+
+ <build>
+ <sourceDirectory>src</sourceDirectory>
+ <testSourceDirectory>test</testSourceDirectory>
+ <resources>
+ <resource>
+ <directory>src/com/google/i18n/phonenumbers/data</directory>
+ <targetPath>com/google/i18n/phonenumbers/data</targetPath>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>test/com/google/i18n/phonenumbers/data</directory>
+ <targetPath>com/google/i18n/phonenumbers/data</targetPath>
+ </testResource>
+ <testResource>
+ <directory>test/com/google/i18n/phonenumbers/geocoding/testing_data</directory>
+ <targetPath>com/google/i18n/phonenumbers/geocoding/testing_data</targetPath>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <excludes>
+ <exclude>**/geocoding/</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.10</version>
+ <configuration>
+ <forkMode>never</forkMode>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.2</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.7</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.0-beta-7</version>
+ <configuration>
+ <tagBase>
+ https://libphonenumber.googlecode.com/svn/tags/
+ </tagBase>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>release-sign-artifacts</id>
+ <activation>
+ <property>
+ <name>performRelease</name>
+ <value>true</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/java/libphonenumber/release_notes.txt b/java/libphonenumber/release_notes.txt
new file mode 100644
index 0000000..0fb5dc6
--- /dev/null
+++ b/java/libphonenumber/release_notes.txt
@@ -0,0 +1,361 @@
+November 10th, 2011: libphonenumber-4.2
+* Code changes
+ - Providing an "exact match" isEmergencyNumber method
+ - Improvement to PhoneNumberMatcher: requires national prefix to be present
+ when matching national-format numbers, unless matching for a region where it
+ is explicitly marked in the metadata that they may be omitted. Applies to
+ leniency level VALID and higher.
+ - Change formatNumberForMobileDialing not to modify the phoneNumber passed in.
+
+* Metadata changes
+ - Emergency numbers added for all remaining countries
+ - Collected data on which numbers we format with a national prefix are
+ commonly written without one and added this
+ - Updates for AR, AT, BH, CZ, GR, IR, KM, LT, MX, PT, SE, SO, UG
+ - Addition of SX (Sint Maarten)
+
+October 19th, 2011: libphonenumber-4.1
+* Code changes
+ - Update code and metadata for countries with IDD "8~10" to accept phone
+ numbers where the "~" is omitted.
+ - Modify formatInOriginalFormat to use raw_input (when present) when the number
+ is considered as invalid by the library.
+ - Add ShortNumberUtil to deal with international short phone numbers, such as
+ short codes and emergency numbers.
+ - Increase the maximum phone-number length accepted when parsing (now set to
+ 16).
+
+* Metadata changes
+ - Updates: BF, BN, CN, DE, DK, DO, FR, IN, KI, KW, MC, MD, ML, PA, QA, SB, UK,
+ WS
+ - Emergency number information also added to: AE, AF, AL, AM, AR, AT, AU, BA,
+ BB, BD, BE, BG, BH, BO, BR, BY, CA, CH, CL, CN, CO, CR, CY, CZ, DE, DJ, DK,
+ DO, DZ, EC, EE, EG, ES, FI, FJ, FO, FR, GB, GE, GF, GH, GI, GL, GR, GT, GY,
+ HK, HN, HR, HU, ID, IE, IL, IN, IR, IS, IT, JM, JO, JP, KR, KW, KY, KZ, LB,
+ LK, LT, LU, LV, MA, MC, MD, ME, MK, ML, MM, MN, MO, MT, MU, MV, MX, MY, NG,
+ NI, NL, NO, NP, OM, PA, PE, PH, PK, PL, PM, PT, PY, QA, RO, RS, RU, RW, SA,
+ SB, SD, SE, SG, SI, SK, SL, SM, SR, SV, SY, TD, TH, TJ, TM, TN, TR, TT, TW,
+ UA, UG, US, UY, UZ, VA, VE, VN, VU, ZA, ZM, ZW
+
+October 6th, 2011: libphonenumber-4.0
+* Code changes
+ - New function formatNumberForMobileDialing, which attempts to format a number in
+ such a way that the call can be connected from a mobile phone. If this is
+ impossible, for example for numbers that cannot be internationally dialled,
+ then an empty string is returned.
+ - Fallback functionality to English for non-CJK languages for geocoding
+
+* Metadata changes
+ - Collecting data for emergency numbers
+ - Updates: AR, AU, BR, CN, CZ, EG, GD, IE, IL, JM, KW, KH, SD, SO, TR, UG, UZ
+ - Geocoding data changes: AO, AR, AT, BJ, BR, CD, CG, CI, CL, CN, CV, DE, ES,
+ FR, GR, GW, HU, KM, MR, MZ, NL, PL, PT, SE, ST, SZ
+
+September 13th, 2011: libphonenumber-3.9
+* Code changes
+ - Enable AsYouTypeFormatter to handle long IDD and NDD.
+ - Allow the presence of an IDD following a +.
+ - Fix formatting of phone numbers which contain only 0s in the national number.
+ - Refactored some code in geocoding including AreaCodeMap and the storage
+ strategies.
+
+* Metadata changes
+ - Updates: AM, BE, BH, BJ, BR, BT, BZ, CI, CL, CN, DE, DK, DM, DZ, EC, EG, FJ,
+ GR, HR, HT, IN, IQ, IS, JM, KE, KG, KH, KR, LA, LB, LR, MA, MD, ML, MO, MX,
+ MY, NE, NG, PG, PH, PK, PY, QA, SA, SD, SG, SN, TD, TG, TH, TN, TT, UG, YE,
+ ZA, ZM
+ - New geocoding data for: AC, CG, CU, CV, EG, ET, FI, FI, FI, GL, JP, KM, MA,
+ MA, MU, MU, MU, MZ, RS, SH, SH, SL, SO, ST, TG, TG, TG, UG, ZM
+ - Updated geocoding data for: AR, DE
+
+August 11th, 2011: libphonenumber-3.8
+* Code changes
+ - Fix to demo to not throw null-ptr exceptions for invalid NANPA numbers
+ - Fixed AYTF to not accept plus signs in the middle of input
+ - PhoneNumberMatcher improvements - added STRICT_GROUPING and EXACT_GROUPING
+ levels, numbers followed/preceded by a currency symbol will not match,
+ multiple numbers separated by phone-number punctuation will now match. ", "
+ is no longer accepted as an extension symbol when matching, only when
+ parsing. "x" is only accepted as a carrier code or extension marker, not
+ otherwise.
+ - Changes to handling of leading zeroes - these will not be silently ignored
+ anymore, but will be stored as part of the number.
+ - PhoneNumberOfflineGeocoder - new method to get the description of a number that assumes
+ the validity of the number has already been checked and will not re-verify it.
+ - Split geocoding US binary data into multiple files.
+
+* Metadata changes
+ - Updates: AR, AT, AU, AZ, BE, BF, BH, BY, CA, CN, CO, CR, HT, HU, IT, KG, KH,
+ LB, LI, ME, NC, RS, SE, TT, US, VG, ZA
+ - New geocoding data for: AL, AM, AO, BF, BJ, BW, CD, CI, CZ, DZ, EE, GH, GM,
+ GN, GR, GW, HU, IS, KE, LK, LS, LT, LU, LV, MD, MG, MR, NA, PE, QN, SD, SK,
+ SN, SZ, TN, VE, VN, ZA, ZW
+ - Updated geocoding data for: GB, PT, US
+ - Revised sorting of geocoding data
+
+July 5th, 2011
+* Code changes
+ - Refactored AreaCodeMap to minimize binary and memory footprint by using 2 different strategies.
+ - Refactored BuildMetadataFromXml.java and added unittests.
+
+* Metadata changes
+ - Regenerate binaries for all existing area code mapping data with smaller sizes.
+ - Added city-level area code data mapping for US and Canada.
+
+June 29th, 2011
+* Code changes
+ - Fixed issue 38, issue 39, issue 41 and issue 43
+
+* Metadata changes
+ - Added phone number area mapping files for
+ - JP in Japanese
+ - FR in French
+ - TW in English, Simplified and Traditional Chinese
+ - RU in English
+ - IT in English and Italian
+ - PT in Portuguese
+ - TR in English and Turkish
+ - CH in English, German, French and Italian
+ - Updates: CR, GE, IT, JP, KW, MH, MP, MU, PE, PM, RW, TG, TJ, TK
+
+June 14th, 2011
+* Code changes
+ - Added PhoneNumberOfflineGeocoder, supporting classes and their unittests.
+ - Added GenerateAreaCodeData to transform phone number area mapping files from text files to binary
+ files.
+ - Modified PhoneNumberParserServlet.java and phonenumberparser.jsp to incorporate
+ PhoneNumberOfflineGeocoding in the appengine demo.
+
+* Metadata changes
+ - Added phone number area mapping files for NANPA countries and GB in English, NL in Dutch, AR, CL
+ and ES in Spanish, AT and DE in German, SE in Swedish, BR in Portuguese, KR in English, Korean,
+ Simplified and Traditional Chinese, and CN in Simplified Chinese.
+
+June 10th, 2011
+* Code changes:
+ - Fixes for PhoneNumberMatcher to be more restrictive in valid mode and not match numbers
+ surrounded by Latin characters. This ensures, for example, the string abc123456789acg will not be
+ marked as a phone numbers.
+ - Enable PhoneNumberUtil to handle all digits, rather than a subset
+ - Fix for AYTF issue36 and improvement for US AYTF behaviour.
+* Metadata changes:
+ - Updates: BG, EG, ES, GH, PF, SC, SY, VA
+
+May 24th, 2011
+* Code changes:
+ - Phonenumber now implements Serializable.
+ - findNumbers doesn't accept numbers with mis-matched brackets as phone-numbers
+ - An offline phone number geocoder has been added. The current implementation just returns the
+ region name for the phone number; more detailed geocoding will be added later.
+* Metadata changes:
+ - New countries: GF, KP, NC, PA, PF, PW, PY, SB, SR, TO, UY, VU
+ - Updates: CY, CZ, ES, GB, GQ, JM, MQ, TN, VI
+
+May 9th, 2011
+* Code changes:
+ - Fixed potential for a null-ptr exception in getExampleNumber
+ - Potential speed improvement with replacement of StringBuffer with StringBuilder
+* Metadata changes
+ - Changed way that international formats are specified to make it easier to do so
+ - New countries: AX, CC, CX, WF
+ - Updates: AM, AR, AU, AW, CN, CO, CR, DM, EC, ET, FI, FJ, GH, IN, JP, KE, KM,
+ KN, LR, MD, MQ, MX, NP, PH, SC, SE, SM, SN, SY, UG, US, VC, VI, ZM
+
+Apr 26th, 2011
+* Code changes:
+ - Improved PhoneNumberMatcher for cases with other numbers before or after the phone number.
+ - Improved AsYouTypeFormatter not to use formatting rules containing non-formatting characters
+ (e.g. '*' in Israeli star numbers).
+* Metadata changes:
+ - New countries: FJ, FM, GY, NF, NI, NR, TV.
+ - Updates: AM, AZ, BF, BW, BZ, CI, CR, GB, GP, HK, JM, KH, LB, LY, MV, PE, PK, SZ, TJ, US.
+* Minor documentation updates
+
+Apr 11th, 2011
+* Bug fixes:
+ - Adding date exclusion pattern in PhoneNumberMatcher.
+ - Fixing bug with selecting a suitable region for numbers with leading zeros where mutiple regions
+ for that country code are possible.
+* Metadata changes:
+ - Updates: AG, AI, AS, BB, BM, BS, CA, DM, DO, ET, FO, GD, GE, GU, IN, JM, KN, KY, LC, MN, MP, MR,
+ MS, NO, PR, TC, TR, TT, US, VC, VG, VI
+ - New countries: CK, FK, GT, IO, KI, SJ, SV
+* Documentation updates and some small refactoring to AsYouTypeFormatter
+
+Mar 31st, 2011
+* New functionality:
+ - Can parse and format numbers in RFC-3966 format.
+ - Added isAlphaNumber to check to see if a number is a "vanity" or "alpha" number
+ - Can format a number made up of alpha-characters in an "out-of-country" format (e.g. 0011 1
+ 800-SIX-FLAG to dial an American alpha-number from Australia).
+* Code changes:
+ - Renamed private vars, private methods and fixed comments to try and differentiate between country
+ (calling) codes and region codes.
+ == Non-backwards-compatible API changes: ==
+ - Renamed getSupportedCountries to getSupportedRegions, as this more accurately reflects that the
+ library is based around region codes.
+ - getNationalSignificantNumber is no longer a static method, but is instead an instance method.
+* Metadata changes:
+ - Bug-fixes and updates for AU, AZ, EE, FI, IN, JO, KW, KZ, MV, RU, RR, VA
+ - New country: ME
+
+Mar 22nd, 2011
+* Metadata changes:
+ - New mobile-number pattern for AU
+
+Mar 10th, 2011
+* New functionality:
+ - New function to format a number with the preferred domestic carrier code used when parsing,
+ falling back to a default calling code otherwise (formatNationalNumberWithPreferredCarrierCode).
+ - We now store the preferred domestic carrier code used when the user calls parseAndKeepRawInput
+ - New functionality to extract phone-numbers from text (findNumbers). This is just the first
+ version - it does not extract ALPHA numbers such as 0800 CALL ME, or numbers where alternate
+ endings are specified (such as 03-331 6005/6006).
+* Code changes:
+ - Tidying up the test file to use several pre-defined phone number constants
+ - Fixing several lint errors
+ - Added javadoc to formatNationalNumberWithCarrierCode
+ - Fixed bug where a null pointer exception was thrown when getAsYouTypeFormatter was called with an
+ invalid region code
+ - Improved AsYouTypeFormatter to deal with countries with variable-length patterns such as LU
+* Metadata changes:
+ - Bug-fixes and updates for the following countries: BF, BO, BR, CL, CO, CR, DK, FO, GE, KR, KW,
+ LA, LU, MU, SC, SH, TR, VE
+ - New country: SH
+
+Mar 10th, 2011
+* Code changes:
+ - releasing the code to run the demo on localhost or appengine.
+
+Mar 7th, 2011
+* Metadata changes:
+ - Adding support for AC
+
+Feb 11th, 2011
+* Metadata changes:
+ - Update UAN number ranges for IM and JE.
+
+Feb 9th, 2011
+* Code changes:
+ - Better isNumberMatch method. This will now recognise numbers starting with a national prefix as
+ an NSN_MATCH, instead of SHORT_NSN_MATCH.
+ == Note Non-backwards-compatible API change here! ==
+ This will no longer throw a NumberParseException - instead we will return NOT_A_NUMBER if one
+ or other of the numbers provided do not match.
+ - New number-type UAN now supported in the code. This represents Company Numbers or Universally
+ Accessible Numbers.
+* Metadata changes:
+ - Bug-fixes and updates for the following countries: AG, AZ, BA, BE, CA, CU, ES, FI, GB, GD, GG,
+ IE, IL, IM, IN, IR, IT, JE, JP, KR, KW, NG, NZ, PK, PS, PT, RU, SE, SG, SY, US
+ - New countries: CO, LU, LY, MC, SM
+ - Addition of "Personal Number" ranges to all NANPA countries
+
+Jan 31st, 2011
+* Code changes:
+ - Introducing equals() and hashCode() methods for the Phonenumber.PhoneNumber class
+
+Jan 28th, 2011
+* Code changes:
+ - Fixing critical bug with non-Android-compatible code. isEmpty() was being used and CANON_EQ in
+ reg-ex matches.
+
+Jan 20th, 2011
+* Code improvements:
+ - Handle null phone-numbers when parsing by throwing a NumberParseException.
+ - Handle extension written with an accented "o", as per Spanish, when parsing.
+ - Handle U+30FC dashes as phone-number punctuation.
+ - Allow "ZZ" or null regions to be specified for numbers starting with a full-width "+" symbol, or
+ with other characters (such as whitespace) before the leading +.
+ - new getLengthOfNationalDestinationCode function
+* Metadata changes:
+ - New types of numbers introduced: UAN (universal or "company" numbers) and short codes. Note that
+ "generalDesc" patterns do not encompass short-codes. No code-support for these has been
+ introduced as of yet. We are also now enabling the collection of data for information such as
+ area-code-optional, and no-international-dialling ranges.
+ - Data updates as per ITU notifications/bug fixes for the following countries: AM, BH, CD, CG, CR,
+ DE, DJ, EE, GB, GN, HU, IE, JO, JP, LB, LR, MA, MK, MN, MR, NA, PG, SC, SG, SO, SZ, VN, ZA, ZW
+ - Data added for the following countries: BZ, CU, EC, FO, GI, HN, HT, LK, MT, MV, NU, PS, SD
+ - Indentation fixes in reg-exes for the following countries: BG, GB
+ - Allow nationalPrefixForParsing to be specified for countries with no national prefix, to handle
+ possible carrier prefixes
+
+Jan 3rd, 2011
+* Metadata changes:
+ - Updates to JE
+ - Updated comments for GB/GG/IM/JE
+
+November 25th, 2010
+* Metadata changes:
+ - Updates to existing countries: AD, AG, AI, AN, AS, BB, BG, BM, BS, BW, CA, DM, DO, GD, GH, GM,
+ GU, IN, JM, KN, KY, KZ, LB, LC, MP, MS, PR, SY, TC, TT, TZ, US, VC, VG, VI.
+ - Reorganize reg-exes for better readability.
+ - Updated comments.
+
+October 22nd, 2010
+* Metadata changes:
+ - Updates to existing countries: AE, GB, GG, IM, JE
+
+October 15th, 2010
+* Code improvements:
+ - Allowed parsing of numbers that start with "++" or a full-width "+" symbol
+ - Allowed reg-exes for national and possible number patterns to have white space in them in the
+ source XML file
+ - Added a more useful toString method for the phone number proto class
+* Metadata changes:
+ - Updates to existing countries: AF, BF, BO, ES, GB, GG, IM, IS, JE, JE, JP, KR, PE, PT, RU, SE,
+ TT, ZW
+* Bug fixes:
+ - Parsing empty strings with invalid region codes no longer throws a null pointer exception
+
+September 4th, 2010
+* Code improvement:
+ - Added new phone number type: pager
+* Metadata change:
+ - update to existing country: GG, IM, JE, RS, RU
+* Bug fixes:
+ - ArrayOutOfBoundException in AsYouTypeFormatter.getRememberedPosition()
+ - AsYouTypeFormatter for UK childline number
+
+September 1st, 2010
+* Bug fix on KZ metadata.
+
+August 17th, 2010
+* Code improvement:
+ - Refactored BuildMetadataProtoFromXml.java into BuildMetadataFromXml.java and
+ BuildMetadataProtoFromXml.java
+ - Added BuildMetadataProtoFromXml.java and JSArrayBuilder.java
+ - Refactored CountryCodeToRegionCodeMap and CountryCodeToRegionCodeMapForTesting into separate
+ files.
+
+August 16th, 2010
+* Bug fixes
+ - AsYouTypeFormatter for formatting Chinese geographical numbers entered in national format.
+ - AsYouTypeFormatter for formatting Chinese 400/800 numbers entered in national format.
+* Metadata change:
+ - new countries: AM, AN, BH, GL, IS
+ - adding national prefix 1 to all NANPA countries.
+ - update to existing countries: BF, FR, UK, PK, RE
+
+August 4th, 2010
+* Further improve startup performance
+ - Preload no country specific metadata at startup.
+ - Stop creating the file containing mapping from country calling code to region code
+ and loading it at startup; instead, do the initialization in PhoneNumberUtil.
+
+July 31th, 2010
+
+* Improve startup performance
+ - Separate generated metadata binary file to one file per region
+ - Preload US at start up, and load other region at the time when needed
+ - Create a file containing mapping from country calling code to region code,
+ and load it at startup
+ - Same change also applied to unittests
+
+July 30th, 2010
+* Metadata change:
+ - new country: TL
+ - update to existing country: AZ, CN, FR, GH, JO, LA, PG, PK, QA, SZ, UA, VN
+
+* Code improvement
+ - China local number formatting for AsYouTypeFormatter
+ - improve extension parsing to handle number in the form of +1 (645) 123 1234 ext. 910#
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
new file mode 100644
index 0000000..80eae06
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
@@ -0,0 +1,574 @@
+/*
+ * 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;
+ private boolean isInternationalFormatting = false;
+ private boolean isExpectingCountryCallingCode = false;
+ private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
+ private String defaultCountry;
+
+ 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 + "]*)+");
+
+ // 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 String digitPlaceholder = "\u2008";
+ private Pattern digitPattern = Pattern.compile(digitPlaceholder);
+ 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();
+ // This contains the national prefix that has been extracted. It contains only digits without
+ // formatting.
+ private String nationalPrefixExtracted = "";
+ 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;
+ // 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 leadingThreeDigits) {
+ List<NumberFormat> formatList =
+ (isInternationalFormatting && currentMetaData.intlNumberFormatSize() > 0)
+ ? currentMetaData.intlNumberFormats()
+ : currentMetaData.numberFormats();
+ for (NumberFormat format : formatList) {
+ if (isFormatEligible(format.getFormat())) {
+ possibleFormats.add(format);
+ }
+ }
+ narrowDownPossibleFormats(leadingThreeDigits);
+ }
+
+ 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() > indexOfLeadingDigitsPattern) {
+ Pattern leadingDigitsPattern =
+ regexCache.getPatternForRegex(
+ format.getLeadingDigitsPattern(indexOfLeadingDigitsPattern));
+ Matcher m = leadingDigitsPattern.matcher(leadingDigits);
+ if (!m.lookingAt()) {
+ it.remove();
+ }
+ } // else the particular format has no more specific leadingDigitsPattern, and it should be
+ // retained.
+ }
+ }
+
+ 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 digitPlaceholder
+ template = template.replaceAll("9", digitPlaceholder);
+ 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);
+ nationalPrefixExtracted = "";
+ nationalNumber.setLength(0);
+ ableToFormat = true;
+ inputHasFormatting = false;
+ positionToRemember = 0;
+ originalPosition = 0;
+ isInternationalFormatting = false;
+ isExpectingCountryCallingCode = false;
+ possibleFormats.clear();
+ 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.
+ prefixBeforeNationalNumber.append(" ");
+ 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.
+ nationalPrefixExtracted = removeNationalPrefixFromNationalNumber();
+ return attemptToChooseFormattingPattern();
+ }
+ default:
+ if (isExpectingCountryCallingCode) {
+ if (attemptToExtractCountryCallingCode()) {
+ isExpectingCountryCallingCode = false;
+ }
+ return prefixBeforeNationalNumber + nationalNumber.toString();
+ }
+ if (possibleFormats.size() > 0) { // The formatting pattern is 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
+ ? prefixBeforeNationalNumber + tempNationalNumber
+ : tempNationalNumber;
+ } else {
+ return attemptToChooseFormattingPattern();
+ }
+ }
+ }
+
+ private String attemptToChoosePatternWithPrefixExtracted() {
+ ableToFormat = true;
+ isExpectingCountryCallingCode = false;
+ possibleFormats.clear();
+ return attemptToChooseFormattingPattern();
+ }
+
+ // 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 (nationalPrefixExtracted.length() > 0) {
+ // Put the extracted NDD back to the national number before attempting to extract a new NDD.
+ nationalNumber.insert(0, nationalPrefixExtracted);
+ // Remove the previously extracted NDD from prefixBeforeNationalNumber. We cannot simply set
+ // it to empty string because people sometimes enter national prefix after country code, e.g
+ // +44 (0)20-1234-5678.
+ int indexOfPreviousNdd = prefixBeforeNationalNumber.lastIndexOf(nationalPrefixExtracted);
+ prefixBeforeNationalNumber.setLength(indexOfPreviousNdd);
+ }
+ return !nationalPrefixExtracted.equals(removeNationalPrefixFromNationalNumber());
+ }
+
+ private boolean isDigitOrLeadingPlusSign(char nextChar) {
+ return Character.isDigit(nextChar) ||
+ (accruedInput.length() == 1 &&
+ PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(Character.toString(nextChar)).matches());
+ }
+
+ String attemptToFormatAccruedDigits() {
+ for (NumberFormat numFormat : possibleFormats) {
+ Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber);
+ if (m.matches()) {
+ String formattedNumber = m.replaceAll(numFormat.getFormat());
+ return prefixBeforeNationalNumber + 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;
+ }
+
+ // 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.
+ if (nationalNumber.length() >= MIN_LEADING_DIGITS_LENGTH) {
+ getAvailableFormats(nationalNumber.substring(0, MIN_LEADING_DIGITS_LENGTH));
+ maybeCreateNewTemplate();
+ return inputAccruedNationalNumber();
+ } else {
+ return prefixBeforeNationalNumber + 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
+ ? prefixBeforeNationalNumber + tempNationalNumber
+ : tempNationalNumber;
+ } else {
+ return prefixBeforeNationalNumber.toString();
+ }
+ }
+
+ // 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') {
+ startOfNationalNumber = 1;
+ prefixBeforeNationalNumber.append("1 ");
+ isInternationalFormatting = true;
+ } else if (currentMetaData.hasNationalPrefixForParsing()) {
+ Pattern nationalPrefixForParsing =
+ regexCache.getPatternForRegex(currentMetaData.getNationalPrefixForParsing());
+ Matcher m = nationalPrefixForParsing.matcher(nationalNumber);
+ if (m.lookingAt()) {
+ // 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;
+ 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()) {
+ isInternationalFormatting = 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(" ");
+ }
+ 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 (!newRegionCode.equals(defaultCountry)) {
+ currentMetaData = getMetadataForRegion(newRegionCode);
+ }
+ String countryCodeString = Integer.toString(countryCode);
+ prefixBeforeNationalNumber.append(countryCodeString).append(" ");
+ 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 = digitPattern.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/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java
new file mode 100644
index 0000000..b69c3ca
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java
@@ -0,0 +1,898 @@
+/*
+ * 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 273 as there are 205 different country codes,
+ // and this offers a load factor of roughly 0.75.
+ Map<Integer, List<String>> countryCodeToRegionCodeMap =
+ new HashMap<Integer, List<String>>(273);
+
+ 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("MA");
+ 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>(1);
+ listWithRegionCode.add("SH");
+ 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>(1);
+ listWithRegionCode.add("AN");
+ 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("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("BD");
+ countryCodeToRegionCodeMap.put(880, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("TW");
+ countryCodeToRegionCodeMap.put(886, 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("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/java/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java
new file mode 100644
index 0000000..7d2bb30
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/NumberParseException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ * @author Lara Rennie
+ */
+@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/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java
new file mode 100644
index 0000000..5e19b48
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatch.java
@@ -0,0 +1,125 @@
+/*
+ * 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>
+ *
+ * @author Tom Hofmann
+ */
+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/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
new file mode 100644
index 0000000..62586f1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
@@ -0,0 +1,446 @@
+/*
+ * 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.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.
+ *
+ * @author Tom Hofmann
+ */
+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}");
+
+ /**
+ * 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;
+
+ /**
+ * Matches white-space, which may indicate the end of a phone number and the start of something
+ * else (such as a neighbouring zip-code). If white-space is found, continues to match all
+ * characters that are not typically used to start a phone number.
+ */
+ private static final Pattern GROUP_SEPARATOR;
+
+ /**
+ * 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);
+ GROUP_SEPARATOR = Pattern.compile("\\p{Z}" + "[^" + leadClassChars + "\\p{Nd}]*");
+
+ /* 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;
+ }
+
+ 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;
+ }
+
+ /**
+ * 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 isCurrencySymbol(char character) {
+ return 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 a publication page reference or a date.
+ if (PUB_PAGES.matcher(candidate).find() || SLASH_SEPARATED_DATES.matcher(candidate).find()) {
+ 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) {
+ // Try removing either the first or last "group" in the number and see if this gives a result.
+ // We consider white space to be a possible indication of the start or end of the phone number.
+ Matcher groupMatcher = GROUP_SEPARATOR.matcher(candidate);
+
+ if (groupMatcher.find()) {
+ // Try the first group by itself.
+ CharSequence firstGroupOnly = candidate.substring(0, groupMatcher.start());
+ firstGroupOnly = trimAfterFirstMatch(PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN,
+ firstGroupOnly);
+ PhoneNumberMatch match = parseAndVerify(firstGroupOnly.toString(), offset);
+ if (match != null) {
+ return match;
+ }
+ maxTries--;
+
+ int withoutFirstGroupStart = groupMatcher.end();
+ // Try the rest of the candidate without the first group.
+ CharSequence withoutFirstGroup = candidate.substring(withoutFirstGroupStart);
+ withoutFirstGroup = trimAfterFirstMatch(PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN,
+ withoutFirstGroup);
+ match = parseAndVerify(withoutFirstGroup.toString(), offset + withoutFirstGroupStart);
+ if (match != null) {
+ return match;
+ }
+ maxTries--;
+
+ if (maxTries > 0) {
+ int lastGroupStart = withoutFirstGroupStart;
+ while (groupMatcher.find()) {
+ // Find the last group.
+ lastGroupStart = groupMatcher.start();
+ }
+ CharSequence withoutLastGroup = candidate.substring(0, lastGroupStart);
+ withoutLastGroup = trimAfterFirstMatch(PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN,
+ withoutLastGroup);
+ if (withoutLastGroup.equals(firstGroupOnly)) {
+ // If there are only two groups, then the group "without the last group" is the same as
+ // the first group. In these cases, we don't want to re-check the number group, so we exit
+ // already.
+ return null;
+ }
+ match = parseAndVerify(withoutLastGroup.toString(), offset);
+ 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()) {
+ 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 a currency symbol.
+ if (isCurrencySymbol(previousChar) || isLatinLetter(previousChar)) {
+ return null;
+ }
+ }
+ int lastCharIndex = offset + candidate.length();
+ if (lastCharIndex < text.length()) {
+ char nextChar = text.charAt(lastCharIndex);
+ if (isCurrencySymbol(nextChar) || isLatinLetter(nextChar)) {
+ return null;
+ }
+ }
+ }
+
+ PhoneNumber number = phoneUtil.parseAndKeepRawInput(candidate, preferredRegion);
+ 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;
+ }
+
+ /**
+ * Always throws {@link UnsupportedOperationException} as removal is not supported.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
new file mode 100644
index 0000000..a600334
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
@@ -0,0 +1,2790 @@
+/*
+ * 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.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/english_country_names_and_code_elements
+ *
+ * @author Shaopeng Jia
+ * @author Lara Rennie
+ */
+public class PhoneNumberUtil {
+ /** 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 = 3;
+ // The ITU says the maximum length should be 15, but we have found longer numbers in Germany.
+ static final int MAX_LENGTH_FOR_NSN = 16;
+ // The maximum length of the country calling code.
+ static final int MAX_LENGTH_COUNTRY_CODE = 3;
+ static final String META_DATA_FILE_PREFIX =
+ "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto";
+ private String currentFilePrefix = META_DATA_FILE_PREFIX;
+ private static final Logger LOGGER = Logger.getLogger(PhoneNumberUtil.class.getName());
+
+ // 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 Map<Integer, List<String>> countryCallingCodeToRegionCodeMap = null;
+
+ // The set of regions the library supports.
+ // There are roughly 220 of them and we set the initial capacity of the HashSet to 300 to offer a
+ // load factor of roughly 0.75.
+ private final Set<String> supportedRegions = new HashSet<String>(300);
+
+ // Region-code for the unknown region.
+ private static final String UNKNOWN_REGION = "ZZ";
+
+ // The set of regions that share country calling code 1.
+ // There are roughly 26 regions and 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);
+ 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";
+
+ // The PLUS_SIGN signifies the international prefix.
+ static final char PLUS_SIGN = '+';
+
+ private static final String RFC3966_EXTN_PREFIX = ";ext=";
+
+ // 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 {
+ // 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> 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\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:
+ // plus_sign*([punctuation]*[digits]){3,}([punctuation]|[digits]|[alpha])*
+ // Note VALID_PUNCTUATION starts with a -, so must be the first in the range.
+ private static final String VALID_PHONE_NUMBER =
+ "[" + PLUS_CHARS + "]*(?:[" + VALID_PUNCTUATION + "]*" + DIGITS + "){3,}[" +
+ VALID_PUNCTUATION + 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,]*" +
+ "(?:ext(?: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);
+
+ private 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");
+
+ private static PhoneNumberUtil instance = null;
+
+ // A mapping from a region code to the PhoneMetadata for that region.
+ private final Map<String, PhoneMetadata> regionToMetadataMap =
+ Collections.synchronizedMap(new HashMap<String, PhoneMetadata>());
+
+ // A cache for frequently used region-specific regular expressions.
+ // As most people use phone numbers primarily from one to two countries, and there are roughly 60
+ // regular expressions needed, the initial capacity of 100 offers a rough load factor of 0.75.
+ private RegexCache regexCache = new RegexCache(100);
+
+ /**
+ * 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=".
+ *
+ * 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,
+ // 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.PhoneNumber) possible}, but not
+ * necessarily {@linkplain PhoneNumberUtil#isValidNumber(Phonenumber.PhoneNumber) valid}.
+ */
+ POSSIBLE {
+ @Override
+ boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) {
+ return util.isPossibleNumber(number);
+ }
+ },
+ /**
+ * Phone numbers accepted are
+ * {@linkplain PhoneNumberUtil#isPossibleNumber(Phonenumber.PhoneNumber) possible} and
+ * {@linkplain PhoneNumberUtil#isValidNumber(Phonenumber.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) ||
+ !containsOnlyValidXChars(number, candidate, util)) {
+ return false;
+ }
+ return 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 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) ||
+ !containsOnlyValidXChars(number, candidate, util) ||
+ containsMoreThanOneSlash(candidate) ||
+ !isNationalPrefixPresentIfRequired(number, util)) {
+ return false;
+ }
+ // TODO: Evaluate how this works for other locales (testing has been
+ // limited to NANPA regions) and optimise if necessary.
+ String[] formattedNumberGroups = getNationalNumberGroups(util, number);
+ StringBuilder normalizedCandidate = normalizeDigits(candidate,
+ true /* keep strip non-digits */);
+ int fromIndex = 0;
+ // Check each group of consecutive digits are not broken into separate groups in the
+ // {@code candidate} string.
+ for (int i = 0; i < formattedNumberGroups.length; i++) {
+ // Fails if the substring of {@code candidate} 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.
+ if (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.
+ 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());
+ }
+ },
+ /**
+ * 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) ||
+ !containsOnlyValidXChars(number, candidate, util) ||
+ containsMoreThanOneSlash(candidate) ||
+ !isNationalPrefixPresentIfRequired(number, util)) {
+ return false;
+ }
+ // TODO: Evaluate how this works for other locales (testing has been
+ // limited to NANPA regions) and optimise if necessary.
+ StringBuilder normalizedCandidate = normalizeDigits(candidate,
+ true /* keep strip non-digits */);
+ String[] candidateGroups =
+ 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;
+ }
+ String[] formattedNumberGroups = getNationalNumberGroups(util, number);
+ // 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) {
+ // 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("-");
+ }
+
+ private static boolean containsMoreThanOneSlash(String candidate) {
+ int firstSlashIndex = candidate.indexOf('/');
+ return (firstSlashIndex > 0 && candidate.substring(firstSlashIndex + 1).contains("/"));
+ }
+
+ private 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;
+ }
+
+ private 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;
+ }
+ // Remove the first-group symbol.
+ String candidateNationalPrefixRule = formatRule.getNationalPrefixFormattingRule();
+ // We assume that the first-group symbol will never be _before_ the national prefix.
+ candidateNationalPrefixRule =
+ candidateNationalPrefixRule.substring(0, candidateNationalPrefixRule.indexOf("$1"));
+ candidateNationalPrefixRule = util.normalizeDigitsOnly(candidateNationalPrefixRule);
+ if (candidateNationalPrefixRule.length() == 0) {
+ // National Prefix not needed for this number.
+ return true;
+ }
+ // Normalize the remainder.
+ String rawInputCopy = util.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;
+ }
+
+ /** Returns true if {@code number} is a verified number according to this leniency. */
+ abstract boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util);
+ }
+
+ /**
+ * This class implements a singleton, so the only constructor is private.
+ */
+ private PhoneNumberUtil() {
+ }
+
+ private void init(String filePrefix) {
+ currentFilePrefix = filePrefix;
+ for (List<String> regionCodes : countryCallingCodeToRegionCodeMap.values()) {
+ supportedRegions.addAll(regionCodes);
+ }
+ nanpaRegions.addAll(countryCallingCodeToRegionCodeMap.get(NANPA_COUNTRY_CODE));
+ }
+
+ private void loadMetadataForRegionFromFile(String filePrefix, String regionCode) {
+ InputStream source =
+ PhoneNumberUtil.class.getResourceAsStream(filePrefix + "_" + regionCode);
+ ObjectInputStream in = null;
+ try {
+ in = new ObjectInputStream(source);
+ PhoneMetadataCollection metadataCollection = new PhoneMetadataCollection();
+ metadataCollection.readExternal(in);
+ for (PhoneMetadata metadata : metadataCollection.getMetadataList()) {
+ regionToMetadataMap.put(regionCode, metadata);
+ }
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, e.toString());
+ } finally {
+ close(in);
+ }
+ }
+
+ private static void close(InputStream in) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, e.toString());
+ }
+ }
+ }
+
+ /**
+ * 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 3 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();
+ }
+
+ private 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;
+ }
+
+ /**
+ * 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 in the {@code nationalNumber_} field of 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.
+ * <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) {
+ String regionCode = getRegionCodeForNumber(number);
+ if (!isValidRegionCode(regionCode)) {
+ return 0;
+ }
+ PhoneMetadata metadata = getMetadataForRegion(regionCode);
+ if (!metadata.hasNationalPrefix()) {
+ return 0;
+ }
+
+ PhoneNumberType type = getNumberTypeHelper(getNationalSignificantNumber(number),
+ metadata);
+ // Most numbers other than the two types below have to be dialled in full.
+ if (type != PhoneNumberType.FIXED_LINE && type != PhoneNumberType.FIXED_LINE_OR_MOBILE) {
+ 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 (getRegionCodeForCountryCode(number.getCountryCode()).equals("AR") &&
+ getNumberType(number) == PhoneNumberType.MOBILE) {
+ // 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 1 for
+ // the digit 9, which also forms part of the national significant number.
+ //
+ // TODO: Investigate the possibility of better modeling the metadata to make it
+ // easier to obtain the NDC.
+ return numberGroups[3].length() + 1;
+ }
+ return numberGroups[2].length();
+ }
+
+ /**
+ * 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());
+ char[] numberAsCharArray = number.toCharArray();
+ for (char character : numberAsCharArray) {
+ 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();
+ }
+
+ static synchronized PhoneNumberUtil getInstance(
+ String baseFileLocation,
+ Map<Integer, List<String>> countryCallingCodeToRegionCodeMap) {
+ if (instance == null) {
+ instance = new PhoneNumberUtil();
+ instance.countryCallingCodeToRegionCodeMap = countryCallingCodeToRegionCodeMap;
+ instance.init(baseFileLocation);
+ }
+ return instance;
+ }
+
+ /**
+ * Used for testing purposes only to reset the PhoneNumberUtil singleton to null.
+ */
+ static synchronized void resetInstance() {
+ instance = null;
+ }
+
+ /**
+ * Convenience method to get a list of what regions the library has metadata for.
+ */
+ public Set<String> getSupportedRegions() {
+ return supportedRegions;
+ }
+
+ /**
+ * 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) {
+ return getInstance(META_DATA_FILE_PREFIX,
+ CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap());
+ }
+ return instance;
+ }
+
+ /**
+ * 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 region code is not unknown or null and log an error message. The
+ * {@code countryCallingCode} and {@code number} supplied is used only for the resultant log
+ * message.
+ */
+ private boolean hasValidRegionCode(String regionCode,
+ int countryCallingCode, String number) {
+ if (!isValidRegionCode(regionCode)) {
+ LOGGER.log(Level.WARNING,
+ "Number " + number + " has invalid or missing country calling code ("
+ + countryCallingCode + ")");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 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()) {
+ 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.PhoneNumber, PhoneNumberUtil.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 since no formatting of the national number needs to be applied.
+ // Extensions are not formatted.
+ formattedNumber.append(nationalSignificantNumber);
+ formatNumberByFormat(countryCallingCode, PhoneNumberFormat.E164, formattedNumber);
+ 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);
+ if (!isValidRegionCode(regionCode)) {
+ formattedNumber.append(nationalSignificantNumber);
+ return;
+ }
+
+ formattedNumber.append(formatNationalNumber(nationalSignificantNumber,
+ regionCode, numberFormat));
+ maybeGetFormattedExtension(number, regionCode, numberFormat, formattedNumber);
+ formatNumberByFormat(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);
+ // 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);
+ if (!hasValidRegionCode(regionCode, countryCallingCode, nationalSignificantNumber)) {
+ return nationalSignificantNumber;
+ }
+ List<NumberFormat> userDefinedFormatsCopy =
+ new ArrayList<NumberFormat>(userDefinedFormats.size());
+ for (NumberFormat numFormat : userDefinedFormats) {
+ String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
+ if (nationalPrefixFormattingRule.length() > 0) {
+ // 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.
+ NumberFormat numFormatCopy = new NumberFormat();
+ numFormatCopy.mergeFrom(numFormat);
+ String nationalPrefix = getMetadataForRegion(regionCode).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();
+ }
+ userDefinedFormatsCopy.add(numFormatCopy);
+ } else {
+ // Otherwise, we just add the original rule to the modified list of formats.
+ userDefinedFormatsCopy.add(numFormat);
+ }
+ }
+
+ StringBuilder formattedNumber =
+ new StringBuilder(formatAccordingToFormats(nationalSignificantNumber,
+ userDefinedFormatsCopy,
+ numberFormat));
+ maybeGetFormattedExtension(number, regionCode, numberFormat, formattedNumber);
+ formatNumberByFormat(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);
+ // 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);
+ if (!hasValidRegionCode(regionCode, countryCallingCode, nationalSignificantNumber)) {
+ return nationalSignificantNumber;
+ }
+
+ StringBuilder formattedNumber = new StringBuilder(20);
+ formattedNumber.append(formatNationalNumber(nationalSignificantNumber,
+ regionCode,
+ PhoneNumberFormat.NATIONAL,
+ carrierCode));
+ maybeGetFormattedExtension(number, regionCode, PhoneNumberFormat.NATIONAL, formattedNumber);
+ formatNumberByFormat(countryCallingCode, PhoneNumberFormat.NATIONAL, formattedNumber);
+ return formattedNumber.toString();
+ }
+
+ /**
+ * 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) {
+ String regionCode = getRegionCodeForNumber(number);
+ if (!isValidRegionCode(regionCode)) {
+ 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();
+ PhoneNumberType numberType = getNumberType(numberNoExt);
+ if ((regionCode.equals("CO")) && (regionCallingFrom.equals("CO")) &&
+ (numberType == PhoneNumberType.FIXED_LINE)) {
+ formattedNumber =
+ formatNationalNumberWithCarrierCode(numberNoExt, COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX);
+ } else if ((regionCode.equals("BR")) && (regionCallingFrom.equals("BR")) &&
+ ((numberType == PhoneNumberType.FIXED_LINE) || (numberType == PhoneNumberType.MOBILE) ||
+ (numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE))) {
+ formattedNumber = numberNoExt.hasPreferredDomesticCarrierCode()
+ ? 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 (canBeInternationallyDialled(numberNoExt)) {
+ return withFormatting ? format(numberNoExt, PhoneNumberFormat.INTERNATIONAL)
+ : format(numberNoExt, PhoneNumberFormat.E164);
+ } else {
+ formattedNumber = (regionCallingFrom.equals(regionCode))
+ ? format(numberNoExt, PhoneNumberFormat.NATIONAL) : "";
+ }
+ return withFormatting ? formattedNumber : normalizeDigitsOnly(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)) {
+ return format(number, PhoneNumberFormat.INTERNATIONAL);
+ }
+ int countryCallingCode = number.getCountryCode();
+ String regionCode = getRegionCodeForCountryCode(countryCallingCode);
+ String nationalSignificantNumber = getNationalSignificantNumber(number);
+ if (!hasValidRegionCode(regionCode, countryCallingCode, nationalSignificantNumber)) {
+ 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 == getCountryCodeForRegion(regionCallingFrom)) {
+ // For regions that 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);
+ }
+ String formattedNationalNumber =
+ formatNationalNumber(nationalSignificantNumber,
+ regionCode, PhoneNumberFormat.INTERNATIONAL);
+ PhoneMetadata metadata = getMetadataForRegion(regionCallingFrom);
+ String internationalPrefix = metadata.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 (metadata.hasPreferredInternationalPrefix()) {
+ internationalPrefixForFormatting = metadata.getPreferredInternationalPrefix();
+ }
+
+ StringBuilder formattedNumber = new StringBuilder(formattedNationalNumber);
+ maybeGetFormattedExtension(number, regionCode, PhoneNumberFormat.INTERNATIONAL,
+ formattedNumber);
+ if (internationalPrefixForFormatting.length() > 0) {
+ formattedNumber.insert(0, " ").insert(0, countryCallingCode).insert(0, " ")
+ .insert(0, internationalPrefixForFormatting);
+ } else {
+ formatNumberByFormat(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 is an invalid number, the method returns the raw input when
+ * it is available.
+ *
+ * @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() && !isValidNumber(number)) {
+ return number.getRawInput();
+ }
+ if (!number.hasCountryCodeSource()) {
+ return format(number, PhoneNumberFormat.NATIONAL);
+ }
+ switch (number.getCountryCodeSource()) {
+ case FROM_NUMBER_WITH_PLUS_SIGN:
+ return format(number, PhoneNumberFormat.INTERNATIONAL);
+ case FROM_NUMBER_WITH_IDD:
+ return formatOutOfCountryCallingNumber(number, regionCallingFrom);
+ case FROM_NUMBER_WITHOUT_PLUS_SIGN:
+ return format(number, PhoneNumberFormat.INTERNATIONAL).substring(1);
+ case FROM_DEFAULT_COUNTRY:
+ default:
+ return format(number, PhoneNumberFormat.NATIONAL);
+ }
+ }
+
+ /**
+ * 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();
+ String regionCode = getRegionCodeForCountryCode(countryCode);
+ if (!hasValidRegionCode(regionCode, countryCode, rawInput)) {
+ 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 metadata = getMetadataForRegion(regionCallingFrom);
+ if (countryCode == NANPA_COUNTRY_CODE) {
+ if (isNANPACountry(regionCallingFrom)) {
+ return countryCode + " " + rawInput;
+ }
+ } else if (countryCode == getCountryCodeForRegion(regionCallingFrom)) {
+ // Here we copy the formatting rules so we can modify the pattern we expect to match against.
+ List<NumberFormat> availableFormats =
+ new ArrayList<NumberFormat>(metadata.numberFormatSize());
+ for (NumberFormat format : metadata.numberFormats()) {
+ NumberFormat newFormat = new NumberFormat();
+ newFormat.mergeFrom(format);
+ // The first group is the first group of digits that the user determined.
+ newFormat.setPattern("(\\d+)(.*)");
+ // Here we just concatenate them back together after the national prefix has been fixed.
+ newFormat.setFormat("$1$2");
+ availableFormats.add(newFormat);
+ }
+ // Now we format using these patterns instead of the default pattern, but with the national
+ // prefix prefixed if necessary, by choosing the format rule based on the leading digits
+ // present in the unformatted national number.
+ // 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 formatAccordingToFormats(rawInput, availableFormats, PhoneNumberFormat.NATIONAL);
+ }
+ String internationalPrefix = metadata.getInternationalPrefix();
+ // For countries that have multiple international prefixes, the international format of the
+ // number is returned, unless there is a preferred international prefix.
+ String internationalPrefixForFormatting =
+ UNIQUE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches()
+ ? internationalPrefix
+ : metadata.getPreferredInternationalPrefix();
+ StringBuilder formattedNumber = new StringBuilder(rawInput);
+ maybeGetFormattedExtension(number, regionCode, PhoneNumberFormat.INTERNATIONAL,
+ formattedNumber);
+ if (internationalPrefixForFormatting.length() > 0) {
+ formattedNumber.insert(0, " ").insert(0, countryCode).insert(0, " ")
+ .insert(0, internationalPrefixForFormatting);
+ } else {
+ formatNumberByFormat(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 a leading zero has been set, we prefix this now. Note this is not a national prefix.
+ StringBuilder nationalNumber = new StringBuilder(number.isItalianLeadingZero() ? "0" : "");
+ nationalNumber.append(number.getNationalNumber());
+ return nationalNumber.toString();
+ }
+
+ /**
+ * A helper function that is used by format and formatByPattern.
+ */
+ private void formatNumberByFormat(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);
+ return;
+ case NATIONAL:
+ default:
+ return;
+ }
+ }
+
+ // Simple wrapper of formatNationalNumber for the common case of no carrier code.
+ private String formatNationalNumber(String number,
+ String regionCode,
+ PhoneNumberFormat numberFormat) {
+ return formatNationalNumber(number, regionCode, 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 formatNationalNumber(String number,
+ String regionCode,
+ PhoneNumberFormat numberFormat,
+ String carrierCode) {
+ PhoneMetadata metadata = getMetadataForRegion(regionCode);
+ 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();
+ String formattedNationalNumber =
+ formatAccordingToFormats(number, availableFormats, numberFormat, carrierCode);
+ if (numberFormat == PhoneNumberFormat.RFC3966) {
+ formattedNationalNumber =
+ SEPARATOR_PATTERN.matcher(formattedNationalNumber).replaceAll("-");
+ }
+ return formattedNationalNumber;
+ }
+
+ private 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 formatAccordingToFormats for the common case of no carrier code.
+ private String formatAccordingToFormats(String nationalNumber,
+ List<NumberFormat> availableFormats,
+ PhoneNumberFormat numberFormat) {
+ return formatAccordingToFormats(nationalNumber, availableFormats, numberFormat, null);
+ }
+
+ // Note that carrierCode is optional - if NULL or an empty string, no carrier code replacement
+ // will take place.
+ private String formatAccordingToFormats(String nationalNumber,
+ List<NumberFormat> availableFormats,
+ PhoneNumberFormat numberFormat,
+ String carrierCode) {
+ NumberFormat numFormat = chooseFormattingPatternForNumber(availableFormats, nationalNumber);
+ if (numFormat == null) {
+ // If no pattern above is matched, we format the number as a whole.
+ return nationalNumber;
+ }
+ String numberFormatRule = numFormat.getFormat();
+ Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber);
+ if (numberFormat == PhoneNumberFormat.NATIONAL &&
+ carrierCode != null && carrierCode.length() > 0 &&
+ numFormat.getDomesticCarrierCodeFormattingRule().length() > 0) {
+ // Replace the $CC in the formatting rule with the desired carrier code.
+ String carrierCodeFormattingRule = numFormat.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);
+ return m.replaceAll(numberFormatRule);
+ } else {
+ // Use the national prefix formatting rule instead.
+ String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
+ if (numberFormat == PhoneNumberFormat.NATIONAL &&
+ nationalPrefixFormattingRule != null &&
+ nationalPrefixFormattingRule.length() > 0) {
+ Matcher firstGroupMatcher = FIRST_GROUP_PATTERN.matcher(numberFormatRule);
+ return m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule));
+ } else {
+ return m.replaceAll(numberFormatRule);
+ }
+ }
+ }
+
+ /**
+ * 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.
+ */
+ 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 was entered.
+ */
+ public PhoneNumber getExampleNumberForType(String regionCode, PhoneNumberType type) {
+ // Check the region code is valid.
+ if (!isValidRegionCode(regionCode)) {
+ LOGGER.log(Level.SEVERE, "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;
+ }
+
+ /**
+ * Appends the formatted extension of a phone number to formattedNumber, if the phone number had
+ * an extension specified.
+ */
+ private void maybeGetFormattedExtension(PhoneNumber number, String regionCode,
+ PhoneNumberFormat numberFormat,
+ StringBuilder formattedNumber) {
+ if (number.hasExtension() && number.getExtension().length() > 0) {
+ if (numberFormat == PhoneNumberFormat.RFC3966) {
+ formattedNumber.append(RFC3966_EXTN_PREFIX).append(number.getExtension());
+ } else {
+ formatExtension(number.getExtension(), regionCode, formattedNumber);
+ }
+ }
+ }
+
+ /**
+ * Formats the extension part of the phone number by prefixing it with the appropriate extension
+ * prefix. This will be the default extension prefix, unless overridden by a preferred
+ * extension prefix for this region.
+ */
+ private void formatExtension(String extensionDigits, String regionCode,
+ StringBuilder extension) {
+ PhoneMetadata metadata = getMetadataForRegion(regionCode);
+ if (metadata.hasPreferredExtnPrefix()) {
+ extension.append(metadata.getPreferredExtnPrefix()).append(extensionDigits);
+ } else {
+ extension.append(DEFAULT_EXTN_PREFIX).append(extensionDigits);
+ }
+ }
+
+ 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();
+ 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);
+ if (!isValidRegionCode(regionCode)) {
+ return PhoneNumberType.UNKNOWN;
+ }
+ String nationalSignificantNumber = getNationalSignificantNumber(number);
+ return getNumberTypeHelper(nationalSignificantNumber, getMetadataForRegion(regionCode));
+ }
+
+ private PhoneNumberType getNumberTypeHelper(String nationalNumber, PhoneMetadata metadata) {
+ PhoneNumberDesc generalNumberDesc = metadata.getGeneralDesc();
+ if (!generalNumberDesc.hasNationalNumberPattern() ||
+ !isNumberMatchingDesc(nationalNumber, generalNumberDesc)) {
+ 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;
+ }
+
+ 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;
+ }
+
+ PhoneMetadata getMetadataForRegion(String regionCode) {
+ if (!isValidRegionCode(regionCode)) {
+ return null;
+ }
+ synchronized (regionToMetadataMap) {
+ if (!regionToMetadataMap.containsKey(regionCode)) {
+ loadMetadataForRegionFromFile(currentFilePrefix, regionCode);
+ }
+ }
+ return regionToMetadataMap.get(regionCode);
+ }
+
+ private boolean isNumberMatchingDesc(String nationalNumber, PhoneNumberDesc numberDesc) {
+ Matcher possibleNumberPatternMatcher =
+ regexCache.getPatternForRegex(numberDesc.getPossibleNumberPattern())
+ .matcher(nationalNumber);
+ Matcher nationalNumberPatternMatcher =
+ regexCache.getPatternForRegex(numberDesc.getNationalNumberPattern())
+ .matcher(nationalNumber);
+ return possibleNumberPatternMatcher.matches() && 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 (isValidRegionCode(regionCode) && 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.
+ *
+ * @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) {
+ if (number.getCountryCode() != getCountryCodeForRegion(regionCode)) {
+ return false;
+ }
+ PhoneMetadata metadata = getMetadataForRegion(regionCode);
+ PhoneNumberDesc generalNumDesc = metadata.getGeneralDesc();
+ String nationalSignificantNumber = getNationalSignificantNumber(number);
+
+ // For regions where we don't have metadata for PhoneNumberDesc, we treat any number passed in
+ // as a valid number if its national significant number is between the minimum and maximum
+ // lengths defined by ITU for a national significant number.
+ if (!generalNumDesc.hasNationalNumberPattern()) {
+ int numberLength = nationalSignificantNumber.length();
+ return numberLength > MIN_LENGTH_FOR_NSN && numberLength <= MAX_LENGTH_FOR_NSN;
+ }
+ 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) {
+ 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.
+ 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.
+ */
+ public String getRegionCodeForCountryCode(int countryCallingCode) {
+ List<String> regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode);
+ return regionCodes == null ? UNKNOWN_REGION : regionCodes.get(0);
+ }
+
+ /**
+ * 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)) {
+ return 0;
+ }
+ PhoneMetadata metadata = getMetadataForRegion(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) {
+ if (!isValidRegionCode(regionCode)) {
+ LOGGER.log(Level.SEVERE, "Invalid or missing region code provided.");
+ return null;
+ }
+ PhoneMetadata metadata = getMetadataForRegion(regionCode);
+ 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 = getMetadataForRegion(
+ 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;
+ }
+ }
+
+ /**
+ * 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.
+ String regionCode = getRegionCodeForCountryCode(countryCode);
+ if (!isValidRegionCode(regionCode)) {
+ return ValidationResult.INVALID_COUNTRY_CODE;
+ }
+ PhoneNumberDesc generalNumDesc = getMetadataForRegion(regionCode).getGeneralDesc();
+ // Handling case of numbers with no metadata.
+ if (!generalNumDesc.hasNationalNumberPattern()) {
+ LOGGER.log(Level.FINER, "Checking if number is possible with incomplete metadata.");
+ int numberLength = nationalNumber.length();
+ if (numberLength < MIN_LENGTH_FOR_NSN) {
+ return ValidationResult.TOO_SHORT;
+ } else if (numberLength > MAX_LENGTH_FOR_NSN) {
+ return ValidationResult.TOO_LONG;
+ } else {
+ return ValidationResult.IS_POSSIBLE;
+ }
+ }
+ Pattern possibleNumberPattern =
+ regexCache.getPatternForRegex(generalNumDesc.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.PhoneNumber)} for details.
+ *
+ * <p>This method first parses the number, then invokes
+ * {@link #isPossibleNumber(Phonenumber.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.
+ * @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);
+ }
+ };
+ }
+
+ /**
+ * 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.");
+ }
+ // Extract a possible number from the string passed in (this strips leading characters that
+ // could not be the start of a phone number.)
+ String number = extractPossibleNumber(numberToParse);
+ if (!isViablePhoneNumber(number)) {
+ 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(number, defaultRegion)) {
+ throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ "Missing or invalid default region.");
+ }
+
+ if (keepRawInput) {
+ phoneNumber.setRawInput(numberToParse);
+ }
+ StringBuilder nationalNumber = new StringBuilder(number);
+ // 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)) {
+ regionMetadata = getMetadataForRegion(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();
+ maybeStripNationalPrefixAndCarrierCode(normalizedNationalNumber, regionMetadata, carrierCode);
+ 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.");
+ }
+ if (normalizedNationalNumber.charAt(0) == '0') {
+ phoneNumber.setItalianLeadingZero(true);
+ }
+ phoneNumber.setNationalNumber(Long.parseLong(normalizedNationalNumber.toString()));
+ }
+
+ /**
+ * 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, 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, 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, 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, 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 only be dialled from within the region. If unknown, or the
+ * number can be dialled from outside the region as well, returns false. Does not check the
+ * number is a valid number.
+ * TODO: Make this method public when we have enough metadata to make it worthwhile. Currently
+ * visible for testing purposes only.
+ *
+ * @param number the phone-number for which we want to know whether it is only diallable from
+ * within the region
+ */
+ boolean canBeInternationallyDialled(PhoneNumber number) {
+ String regionCode = getRegionCodeForNumber(number);
+ String nationalSignificantNumber = getNationalSignificantNumber(number);
+ if (!hasValidRegionCode(regionCode, number.getCountryCode(), nationalSignificantNumber)) {
+ return true;
+ }
+ PhoneMetadata metadata = getMetadataForRegion(regionCode);
+ return !isNumberMatchingDesc(nationalSignificantNumber, metadata.getNoInternationalDialling());
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java
new file mode 100644
index 0000000..cb3f8b5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.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.
+ */
+
+/**
+ * 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();
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ // required 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;
+ }
+
+ 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(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_);
+ }
+
+ 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);
+ 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());
+ }
+ }
+
+ 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/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java
new file mode 100644
index 0000000..4ed1563
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/Phonenumber.java
@@ -0,0 +1,260 @@
+/*
+ * 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 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();
+ 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.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_ &&
+ 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) + 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: true");
+ }
+ 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/java/libphonenumber/src/com/google/i18n/phonenumbers/RegexCache.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/RegexCache.java
new file mode 100644
index 0000000..a9ff7e0
--- /dev/null
+++ b/java/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/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java
new file mode 100644
index 0000000..2a23d7c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberUtil.java
@@ -0,0 +1,94 @@
+/*
+ * 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.Phonemetadata.PhoneMetadata;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
+
+import java.util.regex.Pattern;
+
+/*
+ * 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.
+ *
+ * @author Shaopeng Jia
+ */
+public class ShortNumberUtil {
+
+ private final PhoneNumberUtil phoneUtil;
+
+ public ShortNumberUtil() {
+ phoneUtil = PhoneNumberUtil.getInstance();
+ }
+
+ // @VisibleForTesting
+ ShortNumberUtil(PhoneNumberUtil util) {
+ phoneUtil = util;
+ }
+
+ /**
+ * 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 matchesEmergencyNumberHelper(number, regionCode, true /* allows prefix match */);
+ }
+
+ /**
+ * 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 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 = phoneUtil.getMetadataForRegion(regionCode);
+ if (metadata == null || !metadata.hasEmergency()) {
+ return false;
+ }
+ Pattern emergencyNumberPattern =
+ Pattern.compile(metadata.getEmergency().getNationalNumberPattern());
+ String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number);
+ // In Brazil, it is impossible to append additional digits to an emergency number to dial the
+ // number.
+ return (!allowPrefixMatch || regionCode.equals("BR"))
+ ? emergencyNumberPattern.matcher(normalizedNumber).matches()
+ : emergencyNumberPattern.matcher(normalizedNumber).lookingAt();
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AC
new file mode 100644
index 0000000..63a0784
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AD
new file mode 100644
index 0000000..5651404
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AE
new file mode 100644
index 0000000..5ce6bd9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AF
new file mode 100644
index 0000000..ce0b677
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AG
new file mode 100644
index 0000000..0fb852a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AI
new file mode 100644
index 0000000..5ec108b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AL
new file mode 100644
index 0000000..e7f2d42
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AM
new file mode 100644
index 0000000..5af20f5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN
new file mode 100644
index 0000000..27c2ae3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AO
new file mode 100644
index 0000000..77b08cb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
new file mode 100644
index 0000000..a39c601
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AS
new file mode 100644
index 0000000..3b38675
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT
new file mode 100644
index 0000000..c38a56c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AU
new file mode 100644
index 0000000..2fa06cf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AW
new file mode 100644
index 0000000..fb3aad4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX
new file mode 100644
index 0000000..c0dbabf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ
new file mode 100644
index 0000000..e4b14a6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BA
new file mode 100644
index 0000000..ad4662f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB
new file mode 100644
index 0000000..982cff9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BB
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD
new file mode 100644
index 0000000..b6c204a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BE
new file mode 100644
index 0000000..b37f61f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BE
Binary files 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
new file mode 100644
index 0000000..48d20e7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
Binary files 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
new file mode 100644
index 0000000..2b3c0ae
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH
new file mode 100644
index 0000000..841ea9a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BI
new file mode 100644
index 0000000..293ebbc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ
new file mode 100644
index 0000000..e3c5863
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BL
new file mode 100644
index 0000000..4987820
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BM
new file mode 100644
index 0000000..d014b2a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BN
new file mode 100644
index 0000000..c257c58
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO
new file mode 100644
index 0000000..f5919ff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
new file mode 100644
index 0000000..ec29af2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
new file mode 100644
index 0000000..f52796e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BT
new file mode 100644
index 0000000..e549cd7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BW
new file mode 100644
index 0000000..21fd265
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BY
new file mode 100644
index 0000000..a679105
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZ
new file mode 100644
index 0000000..5a4d052
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CA
new file mode 100644
index 0000000..5bf386d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CC
new file mode 100644
index 0000000..2f2f8aa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CD
new file mode 100644
index 0000000..cf7bba2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CF
new file mode 100644
index 0000000..e3ce491
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CG
new file mode 100644
index 0000000..2b4128d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CH
new file mode 100644
index 0000000..409254a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI
new file mode 100644
index 0000000..98198b8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CK
new file mode 100644
index 0000000..2f6fe63
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL
new file mode 100644
index 0000000..0e90d89
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CM
new file mode 100644
index 0000000..4018df4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CM
Binary files 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
new file mode 100644
index 0000000..67a7f5e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN
Binary files 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
new file mode 100644
index 0000000..b1dbb84
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
new file mode 100644
index 0000000..cbc064b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CU
new file mode 100644
index 0000000..97e9838
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CV b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CV
new file mode 100644
index 0000000..4517244
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CV
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CX b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CX
new file mode 100644
index 0000000..cb8dfd9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CX
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CY
new file mode 100644
index 0000000..de1e004
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ
new file mode 100644
index 0000000..5c41a79
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE
new file mode 100644
index 0000000..cfc5b19
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ
new file mode 100644
index 0000000..5511381
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK
new file mode 100644
index 0000000..0082966
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM
new file mode 100644
index 0000000..723ea80
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DO
new file mode 100644
index 0000000..0305f76
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DO
Binary files 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
new file mode 100644
index 0000000..4107335
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ
Binary files 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
new file mode 100644
index 0000000..343743d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EE
new file mode 100644
index 0000000..28bd9fb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG
new file mode 100644
index 0000000..38e39b3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ER b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ER
new file mode 100644
index 0000000..ae89200
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ER
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES
new file mode 100644
index 0000000..9b855f1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ES
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ET b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ET
new file mode 100644
index 0000000..8843e54
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ET
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI
new file mode 100644
index 0000000..604d7ff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJ
new file mode 100644
index 0000000..cdd713c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FK
new file mode 100644
index 0000000..6c19901
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FM
new file mode 100644
index 0000000..b4031f0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO
new file mode 100644
index 0000000..46dac92
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR
new file mode 100644
index 0000000..66d244e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FR
Binary files 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
new file mode 100644
index 0000000..dddd714
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GB b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GB
new file mode 100644
index 0000000..bd6e72a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GB
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD
new file mode 100644
index 0000000..e120fa5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE
new file mode 100644
index 0000000..ac5bb57
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GF
new file mode 100644
index 0000000..da17df2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GG
new file mode 100644
index 0000000..0e6809f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH
new file mode 100644
index 0000000..dea89c7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GI
new file mode 100644
index 0000000..7dcc9ff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GL
new file mode 100644
index 0000000..d327b75
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GM
new file mode 100644
index 0000000..3bf3e41
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GN
new file mode 100644
index 0000000..b0b7406
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GP b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GP
new file mode 100644
index 0000000..e03584b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GP
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQ
new file mode 100644
index 0000000..424b068
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GQ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR
new file mode 100644
index 0000000..655b5b4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GT
new file mode 100644
index 0000000..a2a20cf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GU
new file mode 100644
index 0000000..9a006f1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GW
new file mode 100644
index 0000000..77b6398
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GY
new file mode 100644
index 0000000..eb36761
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK
new file mode 100644
index 0000000..dfd2d09
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN
new file mode 100644
index 0000000..6dd47c0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HR
new file mode 100644
index 0000000..27a0c8a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HT
new file mode 100644
index 0000000..245ee93
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU
new file mode 100644
index 0000000..6ef1306
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID
new file mode 100644
index 0000000..3d0f8cc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ID
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IE
new file mode 100644
index 0000000..12bc792
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL
new file mode 100644
index 0000000..a0f1071
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IM
new file mode 100644
index 0000000..8d8c881
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
new file mode 100644
index 0000000..05b4b50
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IO
new file mode 100644
index 0000000..a9aa569
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQ
new file mode 100644
index 0000000..4009946
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IQ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IR
new file mode 100644
index 0000000..9edbc87
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IS
new file mode 100644
index 0000000..d281347
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IS
Binary files 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
new file mode 100644
index 0000000..d5c2c71
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JE
new file mode 100644
index 0000000..1908b64
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JM
new file mode 100644
index 0000000..81be1e1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO
new file mode 100644
index 0000000..47058ad
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO
Binary files 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
new file mode 100644
index 0000000..9db7e6e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE
new file mode 100644
index 0000000..68de57a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KG
new file mode 100644
index 0000000..617ce07
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH
new file mode 100644
index 0000000..9f757d4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI
new file mode 100644
index 0000000..82bdb90
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KM
new file mode 100644
index 0000000..21570ae
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN
new file mode 100644
index 0000000..5a5f4e8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KP b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KP
new file mode 100644
index 0000000..42a4b26
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KP
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR
new file mode 100644
index 0000000..47f4390
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KR
Binary files 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
new file mode 100644
index 0000000..77f805a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KY
new file mode 100644
index 0000000..cfd2678
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ
new file mode 100644
index 0000000..b129ff6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA
new file mode 100644
index 0000000..62db7dc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB
new file mode 100644
index 0000000..65b3c94
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC
new file mode 100644
index 0000000..c8a6ad5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LI
new file mode 100644
index 0000000..c29d890
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK
new file mode 100644
index 0000000..a9a9d2e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR
new file mode 100644
index 0000000..f1ce4be
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LS
new file mode 100644
index 0000000..e04c603
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT
new file mode 100644
index 0000000..0c11315
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU
new file mode 100644
index 0000000..4ffc791
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV
new file mode 100644
index 0000000..a76eab9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LY
new file mode 100644
index 0000000..8fc1ee7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MA
new file mode 100644
index 0000000..ef1522a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MC
new file mode 100644
index 0000000..79fac1a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MD
new file mode 100644
index 0000000..b17e4af
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ME b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ME
new file mode 100644
index 0000000..24937fd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ME
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MF
new file mode 100644
index 0000000..3813149
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MG
new file mode 100644
index 0000000..072379f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MH
new file mode 100644
index 0000000..fc64213
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MK
new file mode 100644
index 0000000..3bbd43e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML
new file mode 100644
index 0000000..5cce562
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ML
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MM
new file mode 100644
index 0000000..4f3ea91
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MN
new file mode 100644
index 0000000..0a7e31a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MO
new file mode 100644
index 0000000..4cf9625
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MP b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MP
new file mode 100644
index 0000000..0f9476d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MP
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQ
new file mode 100644
index 0000000..c48db34
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MQ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MR
new file mode 100644
index 0000000..36db9e4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MS
new file mode 100644
index 0000000..969cafc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MT
new file mode 100644
index 0000000..c2aaa53
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU
new file mode 100644
index 0000000..d69bd68
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV
new file mode 100644
index 0000000..8841a29
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW
new file mode 100644
index 0000000..7bf7d43
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW
Binary files 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
new file mode 100644
index 0000000..fa3cb40
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MY
new file mode 100644
index 0000000..07b6b85
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ
new file mode 100644
index 0000000..3d0967a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA
new file mode 100644
index 0000000..86d10bc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NC
new file mode 100644
index 0000000..6e5d3f7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE
new file mode 100644
index 0000000..b9cd0ac
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NF
new file mode 100644
index 0000000..622d39f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NG
new file mode 100644
index 0000000..0f478ca
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NI
new file mode 100644
index 0000000..64d3eb0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL
new file mode 100644
index 0000000..aaefdd9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NO
new file mode 100644
index 0000000..6838854
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NP b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NP
new file mode 100644
index 0000000..2868f9c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NP
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NR
new file mode 100644
index 0000000..c8ec23e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NU
new file mode 100644
index 0000000..50dbafd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ
new file mode 100644
index 0000000..6c3535b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OM
new file mode 100644
index 0000000..84cded4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_OM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA
new file mode 100644
index 0000000..2c032e6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PE
new file mode 100644
index 0000000..6b89b38
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PE
Binary files 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
new file mode 100644
index 0000000..60c6d30
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PG
new file mode 100644
index 0000000..9fbb7bc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PH
new file mode 100644
index 0000000..56a53cb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PK
new file mode 100644
index 0000000..e1114b6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL
new file mode 100644
index 0000000..69d172c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PM
new file mode 100644
index 0000000..f8da61b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PR
new file mode 100644
index 0000000..3b8c4a2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PS
new file mode 100644
index 0000000..da7d297
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PT
new file mode 100644
index 0000000..6baccc7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PW
new file mode 100644
index 0000000..45398fa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY
new file mode 100644
index 0000000..6bc931e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QA
new file mode 100644
index 0000000..8ec44a0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_QA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RE
new file mode 100644
index 0000000..e2af509
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO
new file mode 100644
index 0000000..a55d60f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS
new file mode 100644
index 0000000..5a803f9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS
Binary files 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
new file mode 100644
index 0000000..28bb82d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RW
new file mode 100644
index 0000000..cb6329e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA
new file mode 100644
index 0000000..aefd945
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SB b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SB
new file mode 100644
index 0000000..e35361f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SB
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC
new file mode 100644
index 0000000..f012a55
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SD
new file mode 100644
index 0000000..060bd91
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SE
new file mode 100644
index 0000000..e5850c7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SG
new file mode 100644
index 0000000..e8dfd31
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH
new file mode 100644
index 0000000..dcf690a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SI
new file mode 100644
index 0000000..ca7c517
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJ
new file mode 100644
index 0000000..17122cc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK
new file mode 100644
index 0000000..48323b5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SL
new file mode 100644
index 0000000..e942566
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SL
Binary files 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
new file mode 100644
index 0000000..9432784
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN
new file mode 100644
index 0000000..549ff61
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SO
new file mode 100644
index 0000000..0b4edc7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SR
new file mode 100644
index 0000000..a7260aa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ST b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ST
new file mode 100644
index 0000000..265f3af
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ST
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV
new file mode 100644
index 0000000..436b979
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SX b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SX
new file mode 100644
index 0000000..50b2362
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SX
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SY
new file mode 100644
index 0000000..4a6a7b8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZ
new file mode 100644
index 0000000..c1ed388
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC
new file mode 100644
index 0000000..dc62e4c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TD b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TD
new file mode 100644
index 0000000..b92127f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TD
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TG
new file mode 100644
index 0000000..176b9bf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH
new file mode 100644
index 0000000..8b56a1f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ
new file mode 100644
index 0000000..efce54e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TK b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TK
new file mode 100644
index 0000000..849f1c7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TK
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TL b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TL
new file mode 100644
index 0000000..46a855f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TL
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM
new file mode 100644
index 0000000..cf1c21d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TN
new file mode 100644
index 0000000..50a7217
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TO b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TO
new file mode 100644
index 0000000..e2cd8de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TO
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR
new file mode 100644
index 0000000..060cc34
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TT
new file mode 100644
index 0000000..945011b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TV b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TV
new file mode 100644
index 0000000..3b53210
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TV
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW
new file mode 100644
index 0000000..acda89f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ
new file mode 100644
index 0000000..5450858
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UA
new file mode 100644
index 0000000..5019f02
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG
new file mode 100644
index 0000000..d154f24
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US
new file mode 100644
index 0000000..1046ec6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UY b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UY
new file mode 100644
index 0000000..f9e4805
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UY
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ
new file mode 100644
index 0000000..f894a1f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UZ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA
new file mode 100644
index 0000000..42367de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC
new file mode 100644
index 0000000..294335d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE
new file mode 100644
index 0000000..645c9a5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VG b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VG
new file mode 100644
index 0000000..bda87e4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VG
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VI
new file mode 100644
index 0000000..987acec
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN
new file mode 100644
index 0000000..ad1e62b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VU b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VU
new file mode 100644
index 0000000..26ecb82
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VU
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WF
new file mode 100644
index 0000000..2337ed6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WS
new file mode 100644
index 0000000..03fa87f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_WS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YE b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YE
new file mode 100644
index 0000000..be646a1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YE
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YT b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YT
new file mode 100644
index 0000000..e5eb105
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_YT
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZA b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZA
new file mode 100644
index 0000000..c742d5c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZA
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZM b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZM
new file mode 100644
index 0000000..dd3dea3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZM
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZW
new file mode 100644
index 0000000..2766b3c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ZW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java
new file mode 100644
index 0000000..10f9535
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java
@@ -0,0 +1,203 @@
+/*
+ * 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.geocoding;
+
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.logging.Logger;
+
+/**
+ * A utility that maps phone number prefixes to a string describing the geographical area the prefix
+ * covers.
+ *
+ * @author Shaopeng Jia
+ */
+public class AreaCodeMap implements Externalizable {
+ private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
+ private static final Logger LOGGER = Logger.getLogger(AreaCodeMap.class.getName());
+
+ private AreaCodeMapStorageStrategy areaCodeMapStorage;
+
+ // @VisibleForTesting
+ AreaCodeMapStorageStrategy getAreaCodeMapStorage() {
+ return areaCodeMapStorage;
+ }
+
+ /**
+ * Creates an empty {@link AreaCodeMap}. The default constructor is necessary for implementing
+ * {@link Externalizable}. The empty map could later be populated by
+ * {@link #readAreaCodeMap(java.util.SortedMap)} or {@link #readExternal(java.io.ObjectInput)}.
+ */
+ public AreaCodeMap() {}
+
+ /**
+ * Gets the size of the provided area code map storage. The map storage passed-in will be filled
+ * as a result.
+ */
+ private static int getSizeOfAreaCodeMapStorage(AreaCodeMapStorageStrategy mapStorage,
+ SortedMap<Integer, String> areaCodeMap) throws IOException {
+ mapStorage.readFromSortedMap(areaCodeMap);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ mapStorage.writeExternal(objectOutputStream);
+ objectOutputStream.flush();
+ int sizeOfStorage = byteArrayOutputStream.size();
+ objectOutputStream.close();
+ return sizeOfStorage;
+ }
+
+ private AreaCodeMapStorageStrategy createDefaultMapStorage() {
+ return new DefaultMapStorage();
+ }
+
+ private AreaCodeMapStorageStrategy createFlyweightMapStorage() {
+ return new FlyweightMapStorage();
+ }
+
+ /**
+ * Gets the smaller area code map storage strategy according to the provided area code map. It
+ * actually uses (outputs the data to a stream) both strategies and retains the best one which
+ * make this method quite expensive.
+ */
+ // @VisibleForTesting
+ AreaCodeMapStorageStrategy getSmallerMapStorage(SortedMap<Integer, String> areaCodeMap) {
+ try {
+ AreaCodeMapStorageStrategy flyweightMapStorage = createFlyweightMapStorage();
+ int sizeOfFlyweightMapStorage = getSizeOfAreaCodeMapStorage(flyweightMapStorage, areaCodeMap);
+
+ AreaCodeMapStorageStrategy defaultMapStorage = createDefaultMapStorage();
+ int sizeOfDefaultMapStorage = getSizeOfAreaCodeMapStorage(defaultMapStorage, areaCodeMap);
+
+ return sizeOfFlyweightMapStorage < sizeOfDefaultMapStorage
+ ? flyweightMapStorage : defaultMapStorage;
+ } catch (IOException e) {
+ LOGGER.severe(e.getMessage());
+ return createFlyweightMapStorage();
+ }
+ }
+
+ /**
+ * Creates an {@link AreaCodeMap} initialized with {@code sortedAreaCodeMap}. Note that the
+ * underlying implementation of this method is expensive thus should not be called by
+ * time-critical applications.
+ *
+ * @param sortedAreaCodeMap a map from phone number prefixes to descriptions of corresponding
+ * geographical areas, sorted in ascending order of the phone number prefixes as integers.
+ */
+ public void readAreaCodeMap(SortedMap<Integer, String> sortedAreaCodeMap) {
+ areaCodeMapStorage = getSmallerMapStorage(sortedAreaCodeMap);
+ }
+
+ /**
+ * Supports Java Serialization.
+ */
+ public void readExternal(ObjectInput objectInput) throws IOException {
+ // Read the area code map storage strategy flag.
+ boolean useFlyweightMapStorage = objectInput.readBoolean();
+ if (useFlyweightMapStorage) {
+ areaCodeMapStorage = new FlyweightMapStorage();
+ } else {
+ areaCodeMapStorage = new DefaultMapStorage();
+ }
+ areaCodeMapStorage.readExternal(objectInput);
+ }
+
+ /**
+ * Supports Java Serialization.
+ */
+ public void writeExternal(ObjectOutput objectOutput) throws IOException {
+ objectOutput.writeBoolean(areaCodeMapStorage instanceof FlyweightMapStorage);
+ areaCodeMapStorage.writeExternal(objectOutput);
+ }
+
+ /**
+ * Returns the description of the geographical area the {@code number} corresponds to. This method
+ * distinguishes the case of an invalid prefix and a prefix for which the name is not available in
+ * the current language. If the description is not available in the current language an empty
+ * string is returned. If no description was found for the provided number, null is returned.
+ *
+ * @param number the phone number to look up
+ * @return the description of the geographical area
+ */
+ String lookup(PhoneNumber number) {
+ int numOfEntries = areaCodeMapStorage.getNumOfEntries();
+ if (numOfEntries == 0) {
+ return null;
+ }
+ long phonePrefix =
+ Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number));
+ int currentIndex = numOfEntries - 1;
+ SortedSet<Integer> currentSetOfLengths = areaCodeMapStorage.getPossibleLengths();
+ while (currentSetOfLengths.size() > 0) {
+ Integer possibleLength = currentSetOfLengths.last();
+ String phonePrefixStr = String.valueOf(phonePrefix);
+ if (phonePrefixStr.length() > possibleLength) {
+ phonePrefix = Long.parseLong(phonePrefixStr.substring(0, possibleLength));
+ }
+ currentIndex = binarySearch(0, currentIndex, phonePrefix);
+ if (currentIndex < 0) {
+ return null;
+ }
+ int currentPrefix = areaCodeMapStorage.getPrefix(currentIndex);
+ if (phonePrefix == currentPrefix) {
+ return areaCodeMapStorage.getDescription(currentIndex);
+ }
+ currentSetOfLengths = currentSetOfLengths.headSet(possibleLength);
+ }
+ return null;
+ }
+
+ /**
+ * Does a binary search for {@code value} in the provided array from {@code start} to {@code end}
+ * (inclusive). Returns the position if {@code value} is found; otherwise, returns the
+ * position which has the largest value that is less than {@code value}. This means if
+ * {@code value} is the smallest, -1 will be returned.
+ */
+ private int binarySearch(int start, int end, long value) {
+ int current = 0;
+ while (start <= end) {
+ current = (start + end) >>> 1;
+ int currentValue = areaCodeMapStorage.getPrefix(current);
+ if (currentValue == value) {
+ return current;
+ } else if (currentValue > value) {
+ current--;
+ end = current;
+ } else {
+ start = current + 1;
+ }
+ }
+ return current;
+ }
+
+ /**
+ * Dumps the mappings contained in the area code map.
+ */
+ @Override
+ public String toString() {
+ return areaCodeMapStorage.toString();
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java
new file mode 100644
index 0000000..0ef9b91
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java
@@ -0,0 +1,108 @@
+/*
+ * 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.geocoding;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.SortedMap;
+import java.util.TreeSet;
+
+/**
+ * Abstracts the way area code data is stored into memory and serialized to a stream. It is used by
+ * {@link AreaCodeMap} to support the most space-efficient storage strategy according to the
+ * provided data.
+ *
+ * @author Philippe Liard
+ */
+abstract class AreaCodeMapStorageStrategy {
+ protected int numOfEntries = 0;
+ protected final TreeSet<Integer> possibleLengths = new TreeSet<Integer>();
+
+ /**
+ * Gets the phone number prefix located at the provided {@code index}.
+ *
+ * @param index the index of the prefix that needs to be returned
+ * @return the phone number prefix at the provided index
+ */
+ public abstract int getPrefix(int index);
+
+ /**
+ * Gets the description corresponding to the phone number prefix located at the provided {@code
+ * index}. If the description is not available in the current language an empty string is
+ * returned.
+ *
+ * @param index the index of the phone number prefix that needs to be returned
+ * @return the description corresponding to the phone number prefix at the provided index
+ */
+ public abstract String getDescription(int index);
+
+ /**
+ * Sets the internal state of the underlying storage implementation from the provided {@code
+ * sortedAreaCodeMap} that maps phone number prefixes to description strings.
+ *
+ * @param sortedAreaCodeMap a sorted map that maps phone number prefixes including country
+ * calling code to description strings
+ */
+ public abstract void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap);
+
+ /**
+ * Sets the internal state of the underlying storage implementation reading the provided {@code
+ * objectInput}.
+ *
+ * @param objectInput the object input stream from which the area code map is read
+ * @throws IOException if an error occurred reading the provided input stream
+ */
+ public abstract void readExternal(ObjectInput objectInput) throws IOException;
+
+ /**
+ * Writes the internal state of the underlying storage implementation to the provided {@code
+ * objectOutput}.
+ *
+ * @param objectOutput the object output stream to which the area code map is written
+ * @throws IOException if an error occurred writing to the provided output stream
+ */
+ public abstract void writeExternal(ObjectOutput objectOutput) throws IOException;
+
+ /**
+ * @return the number of entries contained in the area code map
+ */
+ public int getNumOfEntries() {
+ return numOfEntries;
+ }
+
+ /**
+ * @return the set containing the possible lengths of prefixes
+ */
+ public TreeSet<Integer> getPossibleLengths() {
+ return possibleLengths;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+ int numOfEntries = getNumOfEntries();
+
+ for (int i = 0; i < numOfEntries; i++) {
+ output.append(getPrefix(i))
+ .append("|")
+ .append(getDescription(i))
+ .append("\n");
+ }
+ return output.toString();
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java
new file mode 100644
index 0000000..4242118
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java
@@ -0,0 +1,94 @@
+/*
+ * 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.geocoding;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.SortedMap;
+
+/**
+ * Default area code map storage strategy that is used for data not containing description
+ * duplications. It is mainly intended to avoid the overhead of the string table management when it
+ * is actually unnecessary (i.e no string duplication).
+ *
+ * @author Shaopeng Jia
+ */
+class DefaultMapStorage extends AreaCodeMapStorageStrategy {
+
+ public DefaultMapStorage() {}
+
+ private int[] phoneNumberPrefixes;
+ private String[] descriptions;
+
+ @Override
+ public int getPrefix(int index) {
+ return phoneNumberPrefixes[index];
+ }
+
+ @Override
+ public String getDescription(int index) {
+ return descriptions[index];
+ }
+
+ @Override
+ public void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap) {
+ numOfEntries = sortedAreaCodeMap.size();
+ phoneNumberPrefixes = new int[numOfEntries];
+ descriptions = new String[numOfEntries];
+ int index = 0;
+ for (int prefix : sortedAreaCodeMap.keySet()) {
+ phoneNumberPrefixes[index++] = prefix;
+ possibleLengths.add((int) Math.log10(prefix) + 1);
+ }
+ sortedAreaCodeMap.values().toArray(descriptions);
+ }
+
+ @Override
+ public void readExternal(ObjectInput objectInput) throws IOException {
+ numOfEntries = objectInput.readInt();
+ if (phoneNumberPrefixes == null || phoneNumberPrefixes.length < numOfEntries) {
+ phoneNumberPrefixes = new int[numOfEntries];
+ }
+ if (descriptions == null || descriptions.length < numOfEntries) {
+ descriptions = new String[numOfEntries];
+ }
+ for (int i = 0; i < numOfEntries; i++) {
+ phoneNumberPrefixes[i] = objectInput.readInt();
+ descriptions[i] = objectInput.readUTF();
+ }
+ int sizeOfLengths = objectInput.readInt();
+ possibleLengths.clear();
+ for (int i = 0; i < sizeOfLengths; i++) {
+ possibleLengths.add(objectInput.readInt());
+ }
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput objectOutput) throws IOException {
+ objectOutput.writeInt(numOfEntries);
+ for (int i = 0; i < numOfEntries; i++) {
+ objectOutput.writeInt(phoneNumberPrefixes[i]);
+ objectOutput.writeUTF(descriptions[i]);
+ }
+ int sizeOfLengths = possibleLengths.size();
+ objectOutput.writeInt(sizeOfLengths);
+ for (Integer length : possibleLengths) {
+ objectOutput.writeInt(length);
+ }
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java
new file mode 100644
index 0000000..54e9647
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java
@@ -0,0 +1,263 @@
+/*
+ * 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.geocoding;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Flyweight area code map storage strategy that uses a table to store unique strings and shorts to
+ * store the prefix and description indexes when possible. It is particularly space-efficient when
+ * the provided area code map contains a lot of redundant descriptions.
+ *
+ * @author Philippe Liard
+ */
+final class FlyweightMapStorage extends AreaCodeMapStorageStrategy {
+ // Size of short and integer types in bytes.
+ private static final int SHORT_NUM_BYTES = Short.SIZE / 8;
+ private static final int INT_NUM_BYTES = Integer.SIZE / 8;
+
+ // The number of bytes used to store a phone number prefix.
+ private int prefixSizeInBytes;
+ // The number of bytes used to store a description index. It is computed from the size of the
+ // description pool containing all the strings.
+ private int descIndexSizeInBytes;
+
+ private ByteBuffer phoneNumberPrefixes;
+ private ByteBuffer descriptionIndexes;
+
+ // Sorted string array of unique description strings.
+ private String[] descriptionPool;
+
+ @Override
+ public int getPrefix(int index) {
+ return readWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, index);
+ }
+
+ /**
+ * This implementation returns the same string (same identity) when called for multiple indexes
+ * corresponding to prefixes that have the same description.
+ */
+ @Override
+ public String getDescription(int index) {
+ int indexInDescriptionPool =
+ readWordFromBuffer(descriptionIndexes, descIndexSizeInBytes, index);
+ return descriptionPool[indexInDescriptionPool];
+ }
+
+ @Override
+ public void readFromSortedMap(SortedMap<Integer, String> areaCodeMap) {
+ SortedSet<String> descriptionsSet = new TreeSet<String>();
+ numOfEntries = areaCodeMap.size();
+ prefixSizeInBytes = getOptimalNumberOfBytesForValue(areaCodeMap.lastKey());
+ phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes);
+
+ // Fill the phone number prefixes byte buffer, the set of possible lengths of prefixes and the
+ // description set.
+ int index = 0;
+ for (Entry<Integer, String> entry : areaCodeMap.entrySet()) {
+ int prefix = entry.getKey();
+ storeWordInBuffer(phoneNumberPrefixes, prefixSizeInBytes, index, prefix);
+ possibleLengths.add((int) Math.log10(prefix) + 1);
+ descriptionsSet.add(entry.getValue());
+ ++index;
+ }
+ createDescriptionPool(descriptionsSet, areaCodeMap);
+ }
+
+ /**
+ * Creates the description pool from the provided set of string descriptions and area code map.
+ */
+ private void createDescriptionPool(SortedSet<String> descriptionsSet,
+ SortedMap<Integer, String> areaCodeMap) {
+ descIndexSizeInBytes = getOptimalNumberOfBytesForValue(descriptionsSet.size() - 1);
+ descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes);
+ descriptionPool = new String[descriptionsSet.size()];
+ descriptionsSet.toArray(descriptionPool);
+
+ // Map the phone number prefixes to the descriptions.
+ int index = 0;
+ for (int i = 0; i < numOfEntries; i++) {
+ int prefix = readWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, i);
+ String description = areaCodeMap.get(prefix);
+ int positionInDescriptionPool = Arrays.binarySearch(descriptionPool, description);
+ storeWordInBuffer(descriptionIndexes, descIndexSizeInBytes, index, positionInDescriptionPool);
+ ++index;
+ }
+ }
+
+ @Override
+ public void readExternal(ObjectInput objectInput) throws IOException {
+ // Read binary words sizes.
+ prefixSizeInBytes = objectInput.readInt();
+ descIndexSizeInBytes = objectInput.readInt();
+
+ // Read possible lengths.
+ int sizeOfLengths = objectInput.readInt();
+ possibleLengths.clear();
+ for (int i = 0; i < sizeOfLengths; i++) {
+ possibleLengths.add(objectInput.readInt());
+ }
+
+ // Read description pool size.
+ int descriptionPoolSize = objectInput.readInt();
+ // Read description pool.
+ if (descriptionPool == null || descriptionPool.length < descriptionPoolSize) {
+ descriptionPool = new String[descriptionPoolSize];
+ }
+ for (int i = 0; i < descriptionPoolSize; i++) {
+ String description = objectInput.readUTF();
+ descriptionPool[i] = description;
+ }
+ readEntries(objectInput);
+ }
+
+ /**
+ * Reads the area code entries from the provided input stream and stores them to the internal byte
+ * buffers.
+ */
+ private void readEntries(ObjectInput objectInput) throws IOException {
+ numOfEntries = objectInput.readInt();
+ if (phoneNumberPrefixes == null || phoneNumberPrefixes.capacity() < numOfEntries) {
+ phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes);
+ }
+ if (descriptionIndexes == null || descriptionIndexes.capacity() < numOfEntries) {
+ descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes);
+ }
+ for (int i = 0; i < numOfEntries; i++) {
+ readExternalWord(objectInput, prefixSizeInBytes, phoneNumberPrefixes, i);
+ readExternalWord(objectInput, descIndexSizeInBytes, descriptionIndexes, i);
+ }
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput objectOutput) throws IOException {
+ // Write binary words sizes.
+ objectOutput.writeInt(prefixSizeInBytes);
+ objectOutput.writeInt(descIndexSizeInBytes);
+
+ // Write possible lengths.
+ int sizeOfLengths = possibleLengths.size();
+ objectOutput.writeInt(sizeOfLengths);
+ for (Integer length : possibleLengths) {
+ objectOutput.writeInt(length);
+ }
+
+ // Write description pool size.
+ objectOutput.writeInt(descriptionPool.length);
+ // Write description pool.
+ for (String description : descriptionPool) {
+ objectOutput.writeUTF(description);
+ }
+
+ // Write entries.
+ objectOutput.writeInt(numOfEntries);
+ for (int i = 0; i < numOfEntries; i++) {
+ writeExternalWord(objectOutput, prefixSizeInBytes, phoneNumberPrefixes, i);
+ writeExternalWord(objectOutput, descIndexSizeInBytes, descriptionIndexes, i);
+ }
+ }
+
+ /**
+ * Gets the minimum number of bytes that can be used to store the provided {@code value}.
+ */
+ private static int getOptimalNumberOfBytesForValue(int value) {
+ return value <= Short.MAX_VALUE ? SHORT_NUM_BYTES : INT_NUM_BYTES;
+ }
+
+ /**
+ * Stores a value which is read from the provided {@code objectInput} to the provided byte {@code
+ * buffer} at the specified {@code index}.
+ *
+ * @param objectInput the object input stream from which the value is read
+ * @param wordSize the number of bytes used to store the value read from the stream
+ * @param outputBuffer the byte buffer to which the value is stored
+ * @param index the index where the value is stored in the buffer
+ * @throws IOException if an error occurred reading from the object input stream
+ */
+ private static void readExternalWord(ObjectInput objectInput, int wordSize,
+ ByteBuffer outputBuffer, int index) throws IOException {
+ int wordIndex = index * wordSize;
+ if (wordSize == SHORT_NUM_BYTES) {
+ outputBuffer.putShort(wordIndex, objectInput.readShort());
+ } else {
+ outputBuffer.putInt(wordIndex, objectInput.readInt());
+ }
+ }
+
+ /**
+ * Writes the value read from the provided byte {@code buffer} at the specified {@code index} to
+ * the provided {@code objectOutput}.
+ *
+ * @param objectOutput the object output stream to which the value is written
+ * @param wordSize the number of bytes used to store the value
+ * @param inputBuffer the byte buffer from which the value is read
+ * @param index the index of the value in the the byte buffer
+ * @throws IOException if an error occurred writing to the provided object output stream
+ */
+ private static void writeExternalWord(ObjectOutput objectOutput, int wordSize,
+ ByteBuffer inputBuffer, int index) throws IOException {
+ int wordIndex = index * wordSize;
+ if (wordSize == SHORT_NUM_BYTES) {
+ objectOutput.writeShort(inputBuffer.getShort(wordIndex));
+ } else {
+ objectOutput.writeInt(inputBuffer.getInt(wordIndex));
+ }
+ }
+
+ /**
+ * Reads the {@code value} at the specified {@code index} from the provided byte {@code buffer}.
+ * Note that only integer and short sizes are supported.
+ *
+ * @param buffer the byte buffer from which the value is read
+ * @param wordSize the number of bytes used to store the value
+ * @param index the index where the value is read from
+ *
+ * @return the value read from the buffer
+ */
+ private static int readWordFromBuffer(ByteBuffer buffer, int wordSize, int index) {
+ int wordIndex = index * wordSize;
+ return wordSize == SHORT_NUM_BYTES ? buffer.getShort(wordIndex) : buffer.getInt(wordIndex);
+ }
+
+ /**
+ * Stores the provided {@code value} to the provided byte {@code buffer} at the specified {@code
+ * index} using the provided {@code wordSize} in bytes. Note that only integer and short sizes are
+ * supported.
+ *
+ * @param buffer the byte buffer to which the value is stored
+ * @param wordSize the number of bytes used to store the provided value
+ * @param index the index to which the value is stored
+ * @param value the value that is stored assuming it does not require more than the specified
+ * number of bytes.
+ */
+ private static void storeWordInBuffer(ByteBuffer buffer, int wordSize, int index, int value) {
+ int wordIndex = index * wordSize;
+ if (wordSize == SHORT_NUM_BYTES) {
+ buffer.putShort(wordIndex, (short) value);
+ } else {
+ buffer.putInt(wordIndex, value);
+ }
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/MappingFileProvider.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/MappingFileProvider.java
new file mode 100644
index 0000000..d3aa3b0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/MappingFileProvider.java
@@ -0,0 +1,229 @@
+/*
+ * 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.geocoding;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * A utility which knows the data files that are available for the geocoder to use. The data files
+ * contain mappings from phone number prefixes to text descriptions, and are organized by country
+ * calling code and language that the text descriptions are in.
+ *
+ * @author Shaopeng Jia
+ */
+public class MappingFileProvider implements Externalizable {
+ private int numOfEntries = 0;
+ private int[] countryCallingCodes;
+ private List<Set<String>> availableLanguages;
+ private static final Map<String, String> LOCALE_NORMALIZATION_MAP;
+
+ static {
+ Map<String, String> normalizationMap = new HashMap<String, String>();
+ normalizationMap.put("zh_TW", "zh_Hant");
+ normalizationMap.put("zh_HK", "zh_Hant");
+ normalizationMap.put("zh_MO", "zh_Hant");
+
+ LOCALE_NORMALIZATION_MAP = Collections.unmodifiableMap(normalizationMap);
+ }
+
+ /**
+ * Creates an empty {@link MappingFileProvider}. The default constructor is necessary for
+ * implementing {@link Externalizable}. The empty provider could later be populated by
+ * {@link #readFileConfigs(java.util.SortedMap)} or {@link #readExternal(java.io.ObjectInput)}.
+ */
+ public MappingFileProvider() {
+ }
+
+ /**
+ * Initializes an {@link MappingFileProvider} with {@code availableDataFiles}.
+ *
+ * @param availableDataFiles a map from country calling codes to sets of languages in which data
+ * files are available for the specific country calling code. The map is sorted in ascending
+ * order of the country calling codes as integers.
+ */
+ public void readFileConfigs(SortedMap<Integer, Set<String>> availableDataFiles) {
+ numOfEntries = availableDataFiles.size();
+ countryCallingCodes = new int[numOfEntries];
+ availableLanguages = new ArrayList<Set<String>>(numOfEntries);
+ int index = 0;
+ for (int countryCallingCode : availableDataFiles.keySet()) {
+ countryCallingCodes[index++] = countryCallingCode;
+ availableLanguages.add(new HashSet<String>(availableDataFiles.get(countryCallingCode)));
+ }
+ }
+
+ /**
+ * Supports Java Serialization.
+ */
+ public void readExternal(ObjectInput objectInput) throws IOException {
+ numOfEntries = objectInput.readInt();
+ if (countryCallingCodes == null || countryCallingCodes.length < numOfEntries) {
+ countryCallingCodes = new int[numOfEntries];
+ }
+ if (availableLanguages == null) {
+ availableLanguages = new ArrayList<Set<String>>();
+ }
+ for (int i = 0; i < numOfEntries; i++) {
+ countryCallingCodes[i] = objectInput.readInt();
+ int numOfLangs = objectInput.readInt();
+ Set<String> setOfLangs = new HashSet<String>();
+ for (int j = 0; j < numOfLangs; j++) {
+ setOfLangs.add(objectInput.readUTF());
+ }
+ availableLanguages.add(setOfLangs);
+ }
+ }
+
+ /**
+ * Supports Java Serialization.
+ */
+ public void writeExternal(ObjectOutput objectOutput) throws IOException {
+ objectOutput.writeInt(numOfEntries);
+ for (int i = 0; i < numOfEntries; i++) {
+ objectOutput.writeInt(countryCallingCodes[i]);
+ Set<String> setOfLangs = availableLanguages.get(i);
+ int numOfLangs = setOfLangs.size();
+ objectOutput.writeInt(numOfLangs);
+ for (String lang : setOfLangs) {
+ objectOutput.writeUTF(lang);
+ }
+ }
+ }
+
+ /**
+ * Returns a string representing the data in this class. The string contains one line for each
+ * country calling code. The country calling code is followed by a '|' and then a list of
+ * comma-separated languages sorted in ascending order.
+ */
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+ for (int i = 0; i < numOfEntries; i++) {
+ output.append(countryCallingCodes[i]);
+ output.append('|');
+ SortedSet<String> sortedSetOfLangs = new TreeSet<String>(availableLanguages.get(i));
+ for (String lang : sortedSetOfLangs) {
+ output.append(lang);
+ output.append(',');
+ }
+ output.append('\n');
+ }
+ return output.toString();
+ }
+
+ /**
+ * Gets the name of the file that contains the mapping data for the {@code countryCallingCode} in
+ * the language specified.
+ *
+ * @param countryCallingCode the country calling code of phone numbers which the data file
+ * contains
+ * @param language two-letter lowercase ISO language codes as defined by ISO 639-1
+ * @param script four-letter titlecase (the first letter is uppercase and the rest of the letters
+ * are lowercase) ISO script codes as defined in ISO 15924
+ * @param region two-letter uppercase ISO country codes as defined by ISO 3166-1
+ * @return the name of the file, or empty string if no such file can be found
+ */
+ String getFileName(int countryCallingCode, String language, String script, String region) {
+ if (language.length() == 0) {
+ return "";
+ }
+ int index = Arrays.binarySearch(countryCallingCodes, countryCallingCode);
+ if (index < 0) {
+ return "";
+ }
+ Set<String> setOfLangs = availableLanguages.get(index);
+ if (setOfLangs.size() > 0) {
+ String languageCode = findBestMatchingLanguageCode(setOfLangs, language, script, region);
+ if (languageCode.length() > 0) {
+ StringBuilder fileName = new StringBuilder();
+ fileName.append(countryCallingCode).append('_').append(languageCode);
+ return fileName.toString();
+ }
+ }
+ return "";
+ }
+
+ private String findBestMatchingLanguageCode(
+ Set<String> setOfLangs, String language, String script, String region) {
+ StringBuilder fullLocale = constructFullLocale(language, script, region);
+ String fullLocaleStr = fullLocale.toString();
+ String normalizedLocale = LOCALE_NORMALIZATION_MAP.get(fullLocaleStr);
+ if (normalizedLocale != null) {
+ if (setOfLangs.contains(normalizedLocale)) {
+ return normalizedLocale;
+ }
+ }
+ if (setOfLangs.contains(fullLocaleStr)) {
+ return fullLocaleStr;
+ }
+
+ if (onlyOneOfScriptOrRegionIsEmpty(script, region)) {
+ if (setOfLangs.contains(language)) {
+ return language;
+ }
+ } else if (script.length() > 0 && region.length() > 0) {
+ StringBuilder langWithScript = new StringBuilder(language).append('_').append(script);
+ String langWithScriptStr = langWithScript.toString();
+ if (setOfLangs.contains(langWithScriptStr)) {
+ return langWithScriptStr;
+ }
+
+ StringBuilder langWithRegion = new StringBuilder(language).append('_').append(region);
+ String langWithRegionStr = langWithRegion.toString();
+ if (setOfLangs.contains(langWithRegionStr)) {
+ return langWithRegionStr;
+ }
+
+ if (setOfLangs.contains(language)) {
+ return language;
+ }
+ }
+ return "";
+ }
+
+ private boolean onlyOneOfScriptOrRegionIsEmpty(String script, String region) {
+ return (script.length() == 0 && region.length() > 0) ||
+ (region.length() == 0 && script.length() > 0);
+ }
+
+ private StringBuilder constructFullLocale(String language, String script, String region) {
+ StringBuilder fullLocale = new StringBuilder(language);
+ appendSubsequentLocalePart(script, fullLocale);
+ appendSubsequentLocalePart(region, fullLocale);
+ return fullLocale;
+ }
+
+ private void appendSubsequentLocalePart(String subsequentLocalePart, StringBuilder fullLocale) {
+ if (subsequentLocalePart.length() > 0) {
+ fullLocale.append('_').append(subsequentLocalePart);
+ }
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
new file mode 100644
index 0000000..1d074b7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
@@ -0,0 +1,217 @@
+/*
+ * 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.geocoding;
+
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * An offline geocoder which provides geographical information related to a phone number.
+ *
+ * @author Shaopeng Jia
+ */
+public class PhoneNumberOfflineGeocoder {
+ private static PhoneNumberOfflineGeocoder instance = null;
+ private static final String MAPPING_DATA_DIRECTORY =
+ "/com/google/i18n/phonenumbers/geocoding/data/";
+ private static final Logger LOGGER = Logger.getLogger(PhoneNumberOfflineGeocoder.class.getName());
+
+ private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
+ private final String phonePrefixDataDirectory;
+
+ // The mappingFileProvider knows for which combination of countryCallingCode and language a phone
+ // prefix mapping file is available in the file system, so that a file can be loaded when needed.
+ private MappingFileProvider mappingFileProvider = new MappingFileProvider();
+
+ // A mapping from countryCallingCode_lang to the corresponding phone prefix map that has been
+ // loaded.
+ private Map<String, AreaCodeMap> availablePhonePrefixMaps = new HashMap<String, AreaCodeMap>();
+
+ // @VisibleForTesting
+ PhoneNumberOfflineGeocoder(String phonePrefixDataDirectory) {
+ this.phonePrefixDataDirectory = phonePrefixDataDirectory;
+ loadMappingFileProvider();
+ }
+
+ private void loadMappingFileProvider() {
+ InputStream source =
+ PhoneNumberOfflineGeocoder.class.getResourceAsStream(phonePrefixDataDirectory + "config");
+ ObjectInputStream in = null;
+ try {
+ in = new ObjectInputStream(source);
+ mappingFileProvider.readExternal(in);
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, e.toString());
+ } finally {
+ close(in);
+ }
+ }
+
+ private AreaCodeMap getPhonePrefixDescriptions(
+ int prefixMapKey, String language, String script, String region) {
+ String fileName = mappingFileProvider.getFileName(prefixMapKey, language, script, region);
+ if (fileName.length() == 0) {
+ return null;
+ }
+ if (!availablePhonePrefixMaps.containsKey(fileName)) {
+ loadAreaCodeMapFromFile(fileName);
+ }
+ return availablePhonePrefixMaps.get(fileName);
+ }
+
+ private void loadAreaCodeMapFromFile(String fileName) {
+ InputStream source =
+ PhoneNumberOfflineGeocoder.class.getResourceAsStream(phonePrefixDataDirectory + fileName);
+ ObjectInputStream in = null;
+ try {
+ in = new ObjectInputStream(source);
+ AreaCodeMap map = new AreaCodeMap();
+ map.readExternal(in);
+ availablePhonePrefixMaps.put(fileName, map);
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, e.toString());
+ } finally {
+ close(in);
+ }
+ }
+
+ private static void close(InputStream in) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, e.toString());
+ }
+ }
+ }
+
+ /**
+ * Gets a {@link PhoneNumberOfflineGeocoder} instance to carry out international phone number
+ * geocoding.
+ *
+ * <p> The {@link PhoneNumberOfflineGeocoder} is implemented as a singleton. Therefore, calling
+ * this method multiple times will only result in one instance being created.
+ *
+ * @return a {@link PhoneNumberOfflineGeocoder} instance
+ */
+ public static synchronized PhoneNumberOfflineGeocoder getInstance() {
+ if (instance == null) {
+ instance = new PhoneNumberOfflineGeocoder(MAPPING_DATA_DIRECTORY);
+ }
+ return instance;
+ }
+
+ /**
+ * Returns the customary display name in the given language for the given territory the phone
+ * number is from.
+ */
+ private String getCountryNameForNumber(PhoneNumber number, Locale language) {
+ String regionCode = phoneUtil.getRegionCodeForNumber(number);
+ return (regionCode == null || regionCode.equals("ZZ"))
+ ? "" : new Locale("", regionCode).getDisplayCountry(language);
+ }
+
+ /**
+ * Returns a text description for the given language code for the given phone number. The
+ * description might consist of the name of the country where the phone number is from and/or the
+ * name of the geographical area the phone number is from. This method assumes the validity of the
+ * number passed in has already been checked.
+ *
+ * @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
+ * @return a text description for the given language code for the given phone number
+ */
+ public String getDescriptionForValidNumber(PhoneNumber number, Locale languageCode) {
+ String langStr = languageCode.getLanguage();
+ String scriptStr = ""; // No script is specified
+ String regionStr = languageCode.getCountry();
+
+ String areaDescription =
+ getAreaDescriptionForNumber(number, langStr, scriptStr, regionStr);
+ return (areaDescription.length() > 0)
+ ? areaDescription : getCountryNameForNumber(number, languageCode);
+ }
+
+ /**
+ * Returns a text description for the given language code for the given phone number. The
+ * description might consist of the name of the country where the phone number is from and/or the
+ * name of the geographical area the phone number is from. This method explictly checkes the
+ * validity of the number passed in.
+ *
+ * @param number the phone number for which we want to get a text description
+ * @param languageCode the language code for which the description should be written
+ * @return a text description for the given language code for the given phone number, or empty
+ * string if the number passed in is invalid
+ */
+ public String getDescriptionForNumber(PhoneNumber number, Locale languageCode) {
+ if (!phoneUtil.isValidNumber(number)) {
+ return "";
+ }
+ return getDescriptionForValidNumber(number, languageCode);
+ }
+
+ /**
+ * Returns an area-level text description in the given language for the given phone number.
+ *
+ * @param number the phone number for which we want to get a text description
+ * @param lang two-letter lowercase ISO language codes as defined by ISO 639-1
+ * @param script four-letter titlecase (the first letter is uppercase and the rest of the letters
+ * are lowercase) ISO script codes as defined in ISO 15924
+ * @param region two-letter uppercase ISO country codes as defined by ISO 3166-1
+ * @return an area-level text description in the given language for the given phone number, or an
+ * empty string if such a description is not available
+ */
+ private String getAreaDescriptionForNumber(
+ PhoneNumber number, String lang, String script, String region) {
+ int countryCallingCode = number.getCountryCode();
+ // As the NANPA data is split into multiple files covering 3-digit areas, use a phone number
+ // prefix of 4 digits for NANPA instead, e.g. 1650.
+ int phonePrefix = (countryCallingCode != 1) ?
+ countryCallingCode : (1000 + (int) (number.getNationalNumber() / 10000000));
+ AreaCodeMap phonePrefixDescriptions =
+ getPhonePrefixDescriptions(phonePrefix, lang, script, region);
+ String description = (phonePrefixDescriptions != null)
+ ? phonePrefixDescriptions.lookup(number)
+ : null;
+ // When a location is not available in the requested language, fall back to English.
+ if ((description == null || description.length() == 0) && mayFallBackToEnglish(lang)) {
+ AreaCodeMap defaultMap = getPhonePrefixDescriptions(phonePrefix, "en", "", "");
+ if (defaultMap == null) {
+ return "";
+ }
+ description = defaultMap.lookup(number);
+ }
+ return description != null ? description : "";
+ }
+
+ private boolean mayFallBackToEnglish(String lang) {
+ // Don't fall back to English if the requested language is among the following:
+ // - Chinese
+ // - Japanese
+ // - Korean
+ return !lang.equals("zh") && !lang.equals("ja") && !lang.equals("ko");
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1201_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1201_en
new file mode 100644
index 0000000..bb98273
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1201_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1202_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1202_en
new file mode 100644
index 0000000..306ce02
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1202_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1203_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1203_en
new file mode 100644
index 0000000..93786eb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1203_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1204_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1204_en
new file mode 100644
index 0000000..eaad437
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1204_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1205_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1205_en
new file mode 100644
index 0000000..8fb3949
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1205_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1206_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1206_en
new file mode 100644
index 0000000..e5ee177
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1206_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1207_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1207_en
new file mode 100644
index 0000000..4d720c3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1207_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1208_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1208_en
new file mode 100644
index 0000000..0c503bf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1208_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1209_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1209_en
new file mode 100644
index 0000000..f55fa82
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1209_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1210_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1210_en
new file mode 100644
index 0000000..519470d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1210_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1212_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1212_en
new file mode 100644
index 0000000..d4179c0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1212_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1213_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1213_en
new file mode 100644
index 0000000..e7315eb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1213_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1214_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1214_en
new file mode 100644
index 0000000..1a736df
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1214_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1215_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1215_en
new file mode 100644
index 0000000..9caefe3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1215_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1216_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1216_en
new file mode 100644
index 0000000..5305522
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1216_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1217_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1217_en
new file mode 100644
index 0000000..b6e2606
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1217_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1218_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1218_en
new file mode 100644
index 0000000..52851ba
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1218_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1219_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1219_en
new file mode 100644
index 0000000..5731a17
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1219_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1224_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1224_en
new file mode 100644
index 0000000..5af1238
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1224_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1225_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1225_en
new file mode 100644
index 0000000..32ee0d0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1225_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1226_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1226_en
new file mode 100644
index 0000000..7f2d4fa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1226_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1228_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1228_en
new file mode 100644
index 0000000..5440111
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1228_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1229_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1229_en
new file mode 100644
index 0000000..bd6c00f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1229_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1231_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1231_en
new file mode 100644
index 0000000..3a137ed
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1231_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1234_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1234_en
new file mode 100644
index 0000000..14906de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1234_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1239_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1239_en
new file mode 100644
index 0000000..ed594ca
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1239_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1240_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1240_en
new file mode 100644
index 0000000..8b054e1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1240_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1248_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1248_en
new file mode 100644
index 0000000..cc14c9e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1248_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1250_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1250_en
new file mode 100644
index 0000000..4f1f495
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1250_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1251_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1251_en
new file mode 100644
index 0000000..dd34251
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1251_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1252_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1252_en
new file mode 100644
index 0000000..d4243ab
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1252_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1253_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1253_en
new file mode 100644
index 0000000..ca292d9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1253_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1254_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1254_en
new file mode 100644
index 0000000..8c090c8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1254_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1256_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1256_en
new file mode 100644
index 0000000..b954f65
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1256_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1260_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1260_en
new file mode 100644
index 0000000..1d112d9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1260_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1262_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1262_en
new file mode 100644
index 0000000..a0ba4c0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1262_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1267_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1267_en
new file mode 100644
index 0000000..3c8fba6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1267_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1269_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1269_en
new file mode 100644
index 0000000..7111bf4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1269_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1270_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1270_en
new file mode 100644
index 0000000..81775d7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1270_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1276_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1276_en
new file mode 100644
index 0000000..95d98ab
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1276_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1281_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1281_en
new file mode 100644
index 0000000..67a497f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1281_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1289_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1289_en
new file mode 100644
index 0000000..a44c5b3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1289_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1301_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1301_en
new file mode 100644
index 0000000..fdec02f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1301_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1302_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1302_en
new file mode 100644
index 0000000..d9578c8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1302_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1303_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1303_en
new file mode 100644
index 0000000..2df62e6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1303_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1304_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1304_en
new file mode 100644
index 0000000..812f34b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1304_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1305_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1305_en
new file mode 100644
index 0000000..ddc522f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1305_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1306_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1306_en
new file mode 100644
index 0000000..35094f0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1306_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1307_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1307_en
new file mode 100644
index 0000000..9a851de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1307_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1308_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1308_en
new file mode 100644
index 0000000..b0545ca
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1308_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1309_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1309_en
new file mode 100644
index 0000000..d5029f8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1309_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1310_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1310_en
new file mode 100644
index 0000000..8340bba
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1310_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1312_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1312_en
new file mode 100644
index 0000000..9a2fdc6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1312_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1313_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1313_en
new file mode 100644
index 0000000..e09f6cd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1313_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1314_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1314_en
new file mode 100644
index 0000000..576ac1c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1314_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1315_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1315_en
new file mode 100644
index 0000000..c097de2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1315_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1316_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1316_en
new file mode 100644
index 0000000..eae6b38
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1316_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1317_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1317_en
new file mode 100644
index 0000000..e577222
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1317_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1318_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1318_en
new file mode 100644
index 0000000..3e48ecc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1318_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1319_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1319_en
new file mode 100644
index 0000000..f690c73
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1319_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1320_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1320_en
new file mode 100644
index 0000000..6441a1d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1320_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1321_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1321_en
new file mode 100644
index 0000000..a3e406e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1321_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1323_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1323_en
new file mode 100644
index 0000000..8571ced
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1323_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1325_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1325_en
new file mode 100644
index 0000000..e3f8595
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1325_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1330_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1330_en
new file mode 100644
index 0000000..a3f3b7e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1330_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1331_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1331_en
new file mode 100644
index 0000000..d5f7c6c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1331_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1334_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1334_en
new file mode 100644
index 0000000..2aab6a1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1334_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1336_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1336_en
new file mode 100644
index 0000000..a873afc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1336_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1337_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1337_en
new file mode 100644
index 0000000..6de57a4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1337_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1339_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1339_en
new file mode 100644
index 0000000..0c2e42b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1339_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1347_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1347_en
new file mode 100644
index 0000000..4b4c5dc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1347_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1351_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1351_en
new file mode 100644
index 0000000..eee213d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1351_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1352_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1352_en
new file mode 100644
index 0000000..ec62795
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1352_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1360_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1360_en
new file mode 100644
index 0000000..f9a5a8a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1360_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1361_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1361_en
new file mode 100644
index 0000000..5c221a9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1361_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1385_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1385_en
new file mode 100644
index 0000000..4a4c1bb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1385_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1386_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1386_en
new file mode 100644
index 0000000..45049ba
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1386_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1401_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1401_en
new file mode 100644
index 0000000..7293621
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1401_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1402_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1402_en
new file mode 100644
index 0000000..d93b8c9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1402_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1403_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1403_en
new file mode 100644
index 0000000..b606c26
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1403_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1404_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1404_en
new file mode 100644
index 0000000..bf273a3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1404_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1405_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1405_en
new file mode 100644
index 0000000..9722abc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1405_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1406_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1406_en
new file mode 100644
index 0000000..4874675
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1406_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1407_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1407_en
new file mode 100644
index 0000000..6acfc6a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1407_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1408_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1408_en
new file mode 100644
index 0000000..62ac82a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1408_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1409_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1409_en
new file mode 100644
index 0000000..15d8a3a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1409_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1410_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1410_en
new file mode 100644
index 0000000..2e3c4ac
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1410_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1412_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1412_en
new file mode 100644
index 0000000..ed26616
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1412_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1413_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1413_en
new file mode 100644
index 0000000..7cf4cee
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1413_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1414_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1414_en
new file mode 100644
index 0000000..717dbd7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1414_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1415_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1415_en
new file mode 100644
index 0000000..9079586
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1415_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1416_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1416_en
new file mode 100644
index 0000000..d6e6f96
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1416_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1417_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1417_en
new file mode 100644
index 0000000..ac551fd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1417_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1418_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1418_en
new file mode 100644
index 0000000..8667894
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1418_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1419_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1419_en
new file mode 100644
index 0000000..fb7548b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1419_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1423_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1423_en
new file mode 100644
index 0000000..9023400
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1423_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1424_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1424_en
new file mode 100644
index 0000000..bc3b1a5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1424_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1425_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1425_en
new file mode 100644
index 0000000..7d7084e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1425_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1430_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1430_en
new file mode 100644
index 0000000..eb8782d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1430_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1432_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1432_en
new file mode 100644
index 0000000..9c8a2ca
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1432_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1434_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1434_en
new file mode 100644
index 0000000..82fb900
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1434_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1435_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1435_en
new file mode 100644
index 0000000..db6c64f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1435_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1438_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1438_en
new file mode 100644
index 0000000..be39869
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1438_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1440_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1440_en
new file mode 100644
index 0000000..fd860de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1440_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1443_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1443_en
new file mode 100644
index 0000000..bf278f6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1443_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1450_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1450_en
new file mode 100644
index 0000000..4950cd8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1450_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1469_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1469_en
new file mode 100644
index 0000000..d1caf62
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1469_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1478_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1478_en
new file mode 100644
index 0000000..e5b09f9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1478_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1479_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1479_en
new file mode 100644
index 0000000..51ab912
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1479_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1480_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1480_en
new file mode 100644
index 0000000..8c259c0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1480_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1484_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1484_en
new file mode 100644
index 0000000..4bc0dfa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1484_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1501_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1501_en
new file mode 100644
index 0000000..7e118f6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1501_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1502_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1502_en
new file mode 100644
index 0000000..a7a5b99
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1502_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1503_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1503_en
new file mode 100644
index 0000000..48d05d4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1503_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1504_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1504_en
new file mode 100644
index 0000000..49c0b85
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1504_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1505_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1505_en
new file mode 100644
index 0000000..c4eb180
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1505_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1506_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1506_en
new file mode 100644
index 0000000..6a7b473
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1506_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1507_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1507_en
new file mode 100644
index 0000000..dc76325
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1507_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1508_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1508_en
new file mode 100644
index 0000000..3e9ce41
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1508_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1509_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1509_en
new file mode 100644
index 0000000..12fbdc6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1509_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1510_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1510_en
new file mode 100644
index 0000000..b342c22
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1510_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1512_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1512_en
new file mode 100644
index 0000000..63b9995
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1512_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1513_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1513_en
new file mode 100644
index 0000000..338c8f1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1513_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1514_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1514_en
new file mode 100644
index 0000000..8f5d124
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1514_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1515_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1515_en
new file mode 100644
index 0000000..fada095
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1515_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1516_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1516_en
new file mode 100644
index 0000000..39e0138
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1516_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1517_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1517_en
new file mode 100644
index 0000000..f017efc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1517_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1518_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1518_en
new file mode 100644
index 0000000..d57a9e0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1518_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1519_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1519_en
new file mode 100644
index 0000000..184ffbf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1519_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1520_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1520_en
new file mode 100644
index 0000000..1930d45
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1520_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1530_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1530_en
new file mode 100644
index 0000000..0ba769f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1530_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1540_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1540_en
new file mode 100644
index 0000000..2056d8f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1540_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1541_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1541_en
new file mode 100644
index 0000000..def6616
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1541_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1551_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1551_en
new file mode 100644
index 0000000..e36fbbc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1551_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1559_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1559_en
new file mode 100644
index 0000000..a798388
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1559_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1561_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1561_en
new file mode 100644
index 0000000..a5c4d8e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1561_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1562_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1562_en
new file mode 100644
index 0000000..ae32a56
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1562_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1563_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1563_en
new file mode 100644
index 0000000..1a6094f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1563_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1567_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1567_en
new file mode 100644
index 0000000..4c005b5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1567_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1570_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1570_en
new file mode 100644
index 0000000..c8491c1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1570_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1571_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1571_en
new file mode 100644
index 0000000..bd6dc00
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1571_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1573_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1573_en
new file mode 100644
index 0000000..e952524
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1573_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1574_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1574_en
new file mode 100644
index 0000000..2eb7589
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1574_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1575_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1575_en
new file mode 100644
index 0000000..5a8f792
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1575_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1580_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1580_en
new file mode 100644
index 0000000..fe11647
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1580_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1585_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1585_en
new file mode 100644
index 0000000..f55ba0f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1585_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1586_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1586_en
new file mode 100644
index 0000000..721c4d0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1586_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1587_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1587_en
new file mode 100644
index 0000000..71f8a24
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1587_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1601_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1601_en
new file mode 100644
index 0000000..45e0d3c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1601_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1602_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1602_en
new file mode 100644
index 0000000..b1d2266
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1602_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1603_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1603_en
new file mode 100644
index 0000000..dc28c76
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1603_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1604_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1604_en
new file mode 100644
index 0000000..6175abd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1604_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1605_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1605_en
new file mode 100644
index 0000000..6f80f31
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1605_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1606_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1606_en
new file mode 100644
index 0000000..30810b4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1606_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1607_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1607_en
new file mode 100644
index 0000000..70c77da
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1607_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1608_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1608_en
new file mode 100644
index 0000000..e29fcc2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1608_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1609_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1609_en
new file mode 100644
index 0000000..8819bb4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1609_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1610_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1610_en
new file mode 100644
index 0000000..ad86252
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1610_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1612_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1612_en
new file mode 100644
index 0000000..2fb4156
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1612_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1613_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1613_en
new file mode 100644
index 0000000..e1df260
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1613_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1614_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1614_en
new file mode 100644
index 0000000..f9d0201
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1614_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1615_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1615_en
new file mode 100644
index 0000000..5347dff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1615_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1616_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1616_en
new file mode 100644
index 0000000..b6bef4d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1616_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1617_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1617_en
new file mode 100644
index 0000000..6d47691
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1617_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1618_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1618_en
new file mode 100644
index 0000000..074da52
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1618_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1619_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1619_en
new file mode 100644
index 0000000..5781415
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1619_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1620_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1620_en
new file mode 100644
index 0000000..1428f52
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1620_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1623_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1623_en
new file mode 100644
index 0000000..fa04f3a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1623_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1626_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1626_en
new file mode 100644
index 0000000..8243d25
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1626_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1630_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1630_en
new file mode 100644
index 0000000..a545ba1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1630_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1631_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1631_en
new file mode 100644
index 0000000..a3e4b30
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1631_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1636_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1636_en
new file mode 100644
index 0000000..c6e31ce
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1636_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1641_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1641_en
new file mode 100644
index 0000000..09d37ff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1641_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1646_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1646_en
new file mode 100644
index 0000000..7029025
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1646_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1647_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1647_en
new file mode 100644
index 0000000..c000f64
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1647_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1650_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1650_en
new file mode 100644
index 0000000..349fdcf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1650_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1651_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1651_en
new file mode 100644
index 0000000..edd6f90
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1651_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1657_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1657_en
new file mode 100644
index 0000000..dd7858f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1657_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1660_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1660_en
new file mode 100644
index 0000000..84167e8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1660_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1661_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1661_en
new file mode 100644
index 0000000..163197a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1661_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1662_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1662_en
new file mode 100644
index 0000000..89104de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1662_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1678_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1678_en
new file mode 100644
index 0000000..287de14
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1678_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1682_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1682_en
new file mode 100644
index 0000000..f70ae44
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1682_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1701_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1701_en
new file mode 100644
index 0000000..402f3c2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1701_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1702_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1702_en
new file mode 100644
index 0000000..b5cb753
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1702_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1703_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1703_en
new file mode 100644
index 0000000..3196a8e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1703_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1704_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1704_en
new file mode 100644
index 0000000..65928c3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1704_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1705_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1705_en
new file mode 100644
index 0000000..441b558
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1705_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1706_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1706_en
new file mode 100644
index 0000000..988df79
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1706_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1707_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1707_en
new file mode 100644
index 0000000..37194ec
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1707_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1708_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1708_en
new file mode 100644
index 0000000..b68c3aa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1708_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1709_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1709_en
new file mode 100644
index 0000000..1047732
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1709_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1712_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1712_en
new file mode 100644
index 0000000..92a81f1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1712_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1713_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1713_en
new file mode 100644
index 0000000..5ca9b5e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1713_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1714_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1714_en
new file mode 100644
index 0000000..ffc4f85
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1714_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1715_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1715_en
new file mode 100644
index 0000000..0079c6b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1715_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1716_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1716_en
new file mode 100644
index 0000000..b393523
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1716_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1717_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1717_en
new file mode 100644
index 0000000..876a808
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1717_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1718_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1718_en
new file mode 100644
index 0000000..4a16abb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1718_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1719_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1719_en
new file mode 100644
index 0000000..dc6d6a7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1719_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1720_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1720_en
new file mode 100644
index 0000000..aa2deb2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1720_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1724_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1724_en
new file mode 100644
index 0000000..b95249e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1724_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1726_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1726_en
new file mode 100644
index 0000000..cb81e2d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1726_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1727_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1727_en
new file mode 100644
index 0000000..f59ce52
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1727_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1730_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1730_en
new file mode 100644
index 0000000..a2db58d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1730_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1731_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1731_en
new file mode 100644
index 0000000..e041cac
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1731_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1732_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1732_en
new file mode 100644
index 0000000..244a2c9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1732_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1734_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1734_en
new file mode 100644
index 0000000..06f2135
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1734_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1740_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1740_en
new file mode 100644
index 0000000..7ed9506
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1740_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1754_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1754_en
new file mode 100644
index 0000000..701f6a8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1754_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1757_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1757_en
new file mode 100644
index 0000000..97714b5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1757_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1760_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1760_en
new file mode 100644
index 0000000..40854a6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1760_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1763_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1763_en
new file mode 100644
index 0000000..971e1ac
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1763_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1765_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1765_en
new file mode 100644
index 0000000..1e87dcc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1765_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1769_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1769_en
new file mode 100644
index 0000000..7f5616a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1769_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1770_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1770_en
new file mode 100644
index 0000000..01bc96d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1770_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1772_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1772_en
new file mode 100644
index 0000000..3e6641b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1772_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1773_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1773_en
new file mode 100644
index 0000000..3b5cb28
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1773_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1774_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1774_en
new file mode 100644
index 0000000..47fe94a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1774_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1775_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1775_en
new file mode 100644
index 0000000..879e514
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1775_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1778_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1778_en
new file mode 100644
index 0000000..c6b9c96
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1778_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1779_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1779_en
new file mode 100644
index 0000000..fac0886
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1779_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1780_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1780_en
new file mode 100644
index 0000000..fdeddcc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1780_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1781_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1781_en
new file mode 100644
index 0000000..ea2f926
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1781_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1785_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1785_en
new file mode 100644
index 0000000..0ca48dd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1785_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1786_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1786_en
new file mode 100644
index 0000000..612dd69
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1786_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1801_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1801_en
new file mode 100644
index 0000000..c93ac1a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1801_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1802_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1802_en
new file mode 100644
index 0000000..8fd7eb6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1802_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1803_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1803_en
new file mode 100644
index 0000000..0732fbb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1803_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1804_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1804_en
new file mode 100644
index 0000000..6f70d2c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1804_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1805_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1805_en
new file mode 100644
index 0000000..47c5bf3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1805_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1806_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1806_en
new file mode 100644
index 0000000..4674327
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1806_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1807_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1807_en
new file mode 100644
index 0000000..86fde6d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1807_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1808_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1808_en
new file mode 100644
index 0000000..b810cfb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1808_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1810_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1810_en
new file mode 100644
index 0000000..c1e3af7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1810_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1812_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1812_en
new file mode 100644
index 0000000..0ba83df
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1812_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1813_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1813_en
new file mode 100644
index 0000000..7fb187f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1813_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1814_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1814_en
new file mode 100644
index 0000000..2c05f2f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1814_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1815_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1815_en
new file mode 100644
index 0000000..a80e7e8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1815_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1816_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1816_en
new file mode 100644
index 0000000..fbfc566
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1816_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1817_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1817_en
new file mode 100644
index 0000000..22f36cc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1817_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1818_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1818_en
new file mode 100644
index 0000000..78cef0c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1818_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1819_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1819_en
new file mode 100644
index 0000000..42ab96a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1819_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1828_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1828_en
new file mode 100644
index 0000000..a83f8fc
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1828_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1830_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1830_en
new file mode 100644
index 0000000..b9dd2bb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1830_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1831_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1831_en
new file mode 100644
index 0000000..2706c69
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1831_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1832_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1832_en
new file mode 100644
index 0000000..77a8d42
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1832_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1838_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1838_en
new file mode 100644
index 0000000..ff902ce
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1838_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1843_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1843_en
new file mode 100644
index 0000000..ec90963
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1843_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1845_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1845_en
new file mode 100644
index 0000000..7ad004c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1845_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1847_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1847_en
new file mode 100644
index 0000000..0531619
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1847_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1848_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1848_en
new file mode 100644
index 0000000..ca5aca7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1848_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1850_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1850_en
new file mode 100644
index 0000000..4157758
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1850_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1851_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1851_en
new file mode 100644
index 0000000..8523ef3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1851_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1856_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1856_en
new file mode 100644
index 0000000..d5ce6b3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1856_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1857_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1857_en
new file mode 100644
index 0000000..853bf5f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1857_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1858_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1858_en
new file mode 100644
index 0000000..d036af8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1858_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1859_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1859_en
new file mode 100644
index 0000000..82eae89
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1859_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1860_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1860_en
new file mode 100644
index 0000000..24f9897
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1860_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1862_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1862_en
new file mode 100644
index 0000000..8442816
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1862_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1863_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1863_en
new file mode 100644
index 0000000..37b26a9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1863_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1864_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1864_en
new file mode 100644
index 0000000..99aa6db
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1864_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1865_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1865_en
new file mode 100644
index 0000000..2fa95f3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1865_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1867_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1867_en
new file mode 100644
index 0000000..e390fa5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1867_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1870_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1870_en
new file mode 100644
index 0000000..626fe8e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1870_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1872_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1872_en
new file mode 100644
index 0000000..e851d4b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1872_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1878_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1878_en
new file mode 100644
index 0000000..676f678
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1878_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1888_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1888_en
new file mode 100644
index 0000000..47068cb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1888_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1901_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1901_en
new file mode 100644
index 0000000..d54c8b4
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1901_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1902_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1902_en
new file mode 100644
index 0000000..89897a9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1902_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1903_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1903_en
new file mode 100644
index 0000000..86d1f70
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1903_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1904_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1904_en
new file mode 100644
index 0000000..ad534ce
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1904_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1905_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1905_en
new file mode 100644
index 0000000..a445998
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1905_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1906_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1906_en
new file mode 100644
index 0000000..2919ad0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1906_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1907_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1907_en
new file mode 100644
index 0000000..04c63e2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1907_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1908_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1908_en
new file mode 100644
index 0000000..99c0e32
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1908_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1909_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1909_en
new file mode 100644
index 0000000..457e115
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1909_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1910_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1910_en
new file mode 100644
index 0000000..11e93fe
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1910_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1912_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1912_en
new file mode 100644
index 0000000..30ec7de
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1912_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1913_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1913_en
new file mode 100644
index 0000000..0272f76
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1913_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1914_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1914_en
new file mode 100644
index 0000000..e19a7bf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1914_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1915_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1915_en
new file mode 100644
index 0000000..6adc9ae
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1915_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1916_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1916_en
new file mode 100644
index 0000000..766cf63
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1916_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1917_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1917_en
new file mode 100644
index 0000000..72c9476
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1917_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1918_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1918_en
new file mode 100644
index 0000000..034ceea
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1918_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1919_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1919_en
new file mode 100644
index 0000000..66b5a93
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1919_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1920_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1920_en
new file mode 100644
index 0000000..5e75d99
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1920_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1925_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1925_en
new file mode 100644
index 0000000..defa317
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1925_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1928_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1928_en
new file mode 100644
index 0000000..cc06485
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1928_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1931_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1931_en
new file mode 100644
index 0000000..2cbd816
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1931_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1936_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1936_en
new file mode 100644
index 0000000..c8bdcff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1936_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1937_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1937_en
new file mode 100644
index 0000000..2698438
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1937_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1940_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1940_en
new file mode 100644
index 0000000..a100c66
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1940_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1941_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1941_en
new file mode 100644
index 0000000..30f5f87
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1941_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1947_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1947_en
new file mode 100644
index 0000000..314dd69
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1947_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1949_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1949_en
new file mode 100644
index 0000000..8dd0dd5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1949_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1951_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1951_en
new file mode 100644
index 0000000..9812455
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1951_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1952_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1952_en
new file mode 100644
index 0000000..86ddc13
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1952_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1954_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1954_en
new file mode 100644
index 0000000..1f79669
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1954_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1956_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1956_en
new file mode 100644
index 0000000..cfe7888
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1956_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1970_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1970_en
new file mode 100644
index 0000000..4a9fd6c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1970_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1971_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1971_en
new file mode 100644
index 0000000..053acd0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1971_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1972_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1972_en
new file mode 100644
index 0000000..3335253
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1972_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1973_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1973_en
new file mode 100644
index 0000000..d682cc7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1973_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1978_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1978_en
new file mode 100644
index 0000000..8f02daf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1978_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1979_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1979_en
new file mode 100644
index 0000000..9d9d449
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1979_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1980_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1980_en
new file mode 100644
index 0000000..f1d82a3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1980_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1985_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1985_en
new file mode 100644
index 0000000..73336d9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1985_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1989_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1989_en
new file mode 100644
index 0000000..42db96d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/1989_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/20_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/20_en
new file mode 100644
index 0000000..76b227e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/20_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_en
new file mode 100644
index 0000000..ad7f944
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_fr
new file mode 100644
index 0000000..9016b0d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/212_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/213_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/213_en
new file mode 100644
index 0000000..7a1379c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/213_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/216_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/216_en
new file mode 100644
index 0000000..9af2d13
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/216_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/220_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/220_en
new file mode 100644
index 0000000..29941e6
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/220_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/221_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/221_en
new file mode 100644
index 0000000..b876d30
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/221_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_en
new file mode 100644
index 0000000..7b4ec36
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_fr
new file mode 100644
index 0000000..ceb0870
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/222_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/224_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/224_en
new file mode 100644
index 0000000..e63507d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/224_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_en
new file mode 100644
index 0000000..e290e50
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_fr
new file mode 100644
index 0000000..e290e50
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/225_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/226_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/226_en
new file mode 100644
index 0000000..ed31886
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/226_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_en
new file mode 100644
index 0000000..192a5d7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_es b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_es
new file mode 100644
index 0000000..7c124ef
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_es
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_fr
new file mode 100644
index 0000000..884ca42
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/228_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_en
new file mode 100644
index 0000000..21b5b82
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_fr
new file mode 100644
index 0000000..6002a86
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/229_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_en
new file mode 100644
index 0000000..3cf3259
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_es b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_es
new file mode 100644
index 0000000..49f2050
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_es
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_fr
new file mode 100644
index 0000000..bf51072
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/230_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/232_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/232_en
new file mode 100644
index 0000000..9cb3996
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/232_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/233_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/233_en
new file mode 100644
index 0000000..aca1927
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/233_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_en
new file mode 100644
index 0000000..092d85a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_pt
new file mode 100644
index 0000000..092d85a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/238_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_en
new file mode 100644
index 0000000..37a5e89
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_pt
new file mode 100644
index 0000000..8610e0a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/239_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_en
new file mode 100644
index 0000000..86c316f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_fr
new file mode 100644
index 0000000..2ad2a1a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/242_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_en
new file mode 100644
index 0000000..14b51a0
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_fr
new file mode 100644
index 0000000..ac48d42
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/243_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_en
new file mode 100644
index 0000000..59c00b9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_pt
new file mode 100644
index 0000000..34cf12b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/244_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_en
new file mode 100644
index 0000000..2738fe8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_pt
new file mode 100644
index 0000000..2738fe8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/245_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/247_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/247_en
new file mode 100644
index 0000000..259944a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/247_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/249_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/249_en
new file mode 100644
index 0000000..d605df8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/249_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/251_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/251_en
new file mode 100644
index 0000000..e389d1c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/251_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/252_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/252_en
new file mode 100644
index 0000000..241ed68
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/252_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/254_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/254_en
new file mode 100644
index 0000000..b21858b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/254_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/256_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/256_en
new file mode 100644
index 0000000..6043317
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/256_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_en
new file mode 100644
index 0000000..6f11df7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_pt
new file mode 100644
index 0000000..18ddf2e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/258_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/260_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/260_en
new file mode 100644
index 0000000..b469b16
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/260_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/261_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/261_en
new file mode 100644
index 0000000..af8affb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/261_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/263_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/263_en
new file mode 100644
index 0000000..7ec8339
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/263_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/264_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/264_en
new file mode 100644
index 0000000..ef92fe5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/264_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/266_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/266_en
new file mode 100644
index 0000000..3fc9c6f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/266_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/267_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/267_en
new file mode 100644
index 0000000..4c52bd2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/267_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/268_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/268_en
new file mode 100644
index 0000000..16067ff
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/268_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_en
new file mode 100644
index 0000000..bbc053b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_fr
new file mode 100644
index 0000000..bbc053b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/269_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/27_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/27_en
new file mode 100644
index 0000000..c86a27c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/27_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_en
new file mode 100644
index 0000000..b65865d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_fr
new file mode 100644
index 0000000..a9df787
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/290_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/299_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/299_en
new file mode 100644
index 0000000..2e0fee5
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/299_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_el b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_el
new file mode 100644
index 0000000..3ae0b10
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_el
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_en
new file mode 100644
index 0000000..8211506
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/30_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_en
new file mode 100644
index 0000000..7565cac
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_nl b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_nl
new file mode 100644
index 0000000..78768ba
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/31_nl
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_en
new file mode 100644
index 0000000..7e9655f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_fr
new file mode 100644
index 0000000..85f2c6b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/33_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_en
new file mode 100644
index 0000000..3ec6b10
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_es b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_es
new file mode 100644
index 0000000..749b162
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/34_es
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_en
new file mode 100644
index 0000000..61f0da1
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_pt
new file mode 100644
index 0000000..eb08045
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/351_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_de b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_de
new file mode 100644
index 0000000..d20ebca
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_de
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_en
new file mode 100644
index 0000000..e510e7b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/352_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/354_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/354_en
new file mode 100644
index 0000000..2e85aa2
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/354_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/355_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/355_en
new file mode 100644
index 0000000..b903bcd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/355_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_en
new file mode 100644
index 0000000..3e9c6c3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_fi b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_fi
new file mode 100644
index 0000000..3824cfb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_fi
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_se b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_se
new file mode 100644
index 0000000..3c49760
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/358_se
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_en
new file mode 100644
index 0000000..d9f2a71
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_hu b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_hu
new file mode 100644
index 0000000..6eaf151
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/36_hu
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/370_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/370_en
new file mode 100644
index 0000000..52b47bd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/370_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/371_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/371_en
new file mode 100644
index 0000000..5273f0e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/371_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/372_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/372_en
new file mode 100644
index 0000000..aaaa338
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/372_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_en
new file mode 100644
index 0000000..9ef1b6e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_ro b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_ro
new file mode 100644
index 0000000..3ef4931
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_ro
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_ru b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_ru
new file mode 100644
index 0000000..b643821
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/373_ru
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/374_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/374_en
new file mode 100644
index 0000000..8bdf764
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/374_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_en
new file mode 100644
index 0000000..8cde57a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_sr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_sr
new file mode 100644
index 0000000..2a5deaa
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/381_sr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_en
new file mode 100644
index 0000000..fada2f3
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_it b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_it
new file mode 100644
index 0000000..db32682
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/39_it
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_de b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_de
new file mode 100644
index 0000000..e62c797
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_de
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_en
new file mode 100644
index 0000000..79ab086
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_fr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_fr
new file mode 100644
index 0000000..6fb2df8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_fr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_it b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_it
new file mode 100644
index 0000000..9cc1e5b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/41_it
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/420_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/420_en
new file mode 100644
index 0000000..6e39c43
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/420_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/421_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/421_en
new file mode 100644
index 0000000..5a5dc09
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/421_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_de b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_de
new file mode 100644
index 0000000..5687e97
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_de
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_en
new file mode 100644
index 0000000..050418d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/43_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/44_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/44_en
new file mode 100644
index 0000000..3a2d306
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/44_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_en
new file mode 100644
index 0000000..934bb3e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_sv b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_sv
new file mode 100644
index 0000000..31a27a8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/46_sv
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_en
new file mode 100644
index 0000000..969da0c
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_pl b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_pl
new file mode 100644
index 0000000..cd5eb5a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/48_pl
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_de b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_de
new file mode 100644
index 0000000..428b8bf
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_de
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_en
new file mode 100644
index 0000000..40b3748
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/49_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/51_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/51_en
new file mode 100644
index 0000000..7f84d3e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/51_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/53_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/53_en
new file mode 100644
index 0000000..5d15867
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/53_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_en
new file mode 100644
index 0000000..ae2fbdd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_es b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_es
new file mode 100644
index 0000000..afd958b
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/54_es
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_en
new file mode 100644
index 0000000..753576a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_pt b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_pt
new file mode 100644
index 0000000..753576a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/55_pt
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_en
new file mode 100644
index 0000000..9126f78
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_es b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_es
new file mode 100644
index 0000000..9126f78
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/56_es
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_en
new file mode 100644
index 0000000..9c7a787
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_es b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_es
new file mode 100644
index 0000000..8407816
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/58_es
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/7_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/7_en
new file mode 100644
index 0000000..7ac3c1d
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/7_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_en
new file mode 100644
index 0000000..f9d096f
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_ja b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_ja
new file mode 100644
index 0000000..7cc7384
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/81_ja
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_en
new file mode 100644
index 0000000..cd18ecb
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_ko b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_ko
new file mode 100644
index 0000000..cbc3017
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_ko
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh
new file mode 100644
index 0000000..d452ab7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant
new file mode 100644
index 0000000..a6a9452
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_en
new file mode 100644
index 0000000..5221729
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_vi b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_vi
new file mode 100644
index 0000000..1b0e2d7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/84_vi
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_en
new file mode 100644
index 0000000..b5b21b7
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_zh b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_zh
new file mode 100644
index 0000000..bbd7660
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/86_zh
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_en
new file mode 100644
index 0000000..497c293
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh
new file mode 100644
index 0000000..d04e3ab
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant
new file mode 100644
index 0000000..eb259e9
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_en
new file mode 100644
index 0000000..a3dfd81
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_tr b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_tr
new file mode 100644
index 0000000..cfcf99a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/90_tr
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/94_en b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/94_en
new file mode 100644
index 0000000..0794d2a
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/94_en
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/config b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/config
new file mode 100644
index 0000000..c7db9c8
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/geocoding/data/config
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
new file mode 100644
index 0000000..64171ac
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
@@ -0,0 +1,867 @@
+/*
+ * 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 junit.framework.TestCase;
+
+/**
+ * Unit tests for AsYouTypeFormatter.java
+ *
+ * Note that these tests use the metadata contained in the files with TEST_META_DATA_FILE_PREFIX,
+ * not the normal metadata files, so should not be used for regression test purposes - these tests
+ * are illustrative only and test functionality.
+ *
+ * @author Shaopeng Jia
+ */
+public class AsYouTypeFormatterTest extends TestCase {
+ private PhoneNumberUtil phoneUtil;
+
+ public AsYouTypeFormatterTest() {
+ phoneUtil = PhoneNumberUtilTest.initializePhoneUtilForTesting();
+ }
+
+ public void testInvalidRegion() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.ZZ);
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+4", formatter.inputDigit('4'));
+ assertEquals("+48 ", formatter.inputDigit('8'));
+ assertEquals("+48 8", formatter.inputDigit('8'));
+ assertEquals("+48 88", formatter.inputDigit('8'));
+ assertEquals("+48 88 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 12", formatter.inputDigit('2'));
+ assertEquals("+48 88 123", formatter.inputDigit('3'));
+ assertEquals("+48 88 123 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 123 12", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("6", formatter.inputDigit('6'));
+ assertEquals("65", formatter.inputDigit('5'));
+ assertEquals("650", formatter.inputDigit('0'));
+ assertEquals("6502", formatter.inputDigit('2'));
+ assertEquals("65025", formatter.inputDigit('5'));
+ assertEquals("650253", formatter.inputDigit('3'));
+ }
+
+ public void testInvalidPlusSign() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.ZZ);
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+4", formatter.inputDigit('4'));
+ assertEquals("+48 ", formatter.inputDigit('8'));
+ assertEquals("+48 8", formatter.inputDigit('8'));
+ assertEquals("+48 88", formatter.inputDigit('8'));
+ assertEquals("+48 88 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 12", formatter.inputDigit('2'));
+ assertEquals("+48 88 123", formatter.inputDigit('3'));
+ assertEquals("+48 88 123 1", formatter.inputDigit('1'));
+ // A plus sign can only appear at the beginning of the number; otherwise, no formatting is
+ // applied.
+ assertEquals("+48881231+", formatter.inputDigit('+'));
+ assertEquals("+48881231+2", formatter.inputDigit('2'));
+ }
+
+ public void testTooLongNumberMatchingMultipleLeadingDigits() {
+ // See http://code.google.com/p/libphonenumber/issues/detail?id=36
+ // The bug occurred last time for countries which have two formatting rules with exactly the
+ // same leading digits pattern but differ in length.
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.ZZ);
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+81 ", formatter.inputDigit('1'));
+ assertEquals("+81 9", formatter.inputDigit('9'));
+ assertEquals("+81 90", formatter.inputDigit('0'));
+ assertEquals("+81 90 1", formatter.inputDigit('1'));
+ assertEquals("+81 90 12", formatter.inputDigit('2'));
+ assertEquals("+81 90 123", formatter.inputDigit('3'));
+ assertEquals("+81 90 1234", formatter.inputDigit('4'));
+ assertEquals("+81 90 1234 5", formatter.inputDigit('5'));
+ assertEquals("+81 90 1234 56", formatter.inputDigit('6'));
+ assertEquals("+81 90 1234 567", formatter.inputDigit('7'));
+ assertEquals("+81 90 1234 5678", formatter.inputDigit('8'));
+ assertEquals("+81 90 12 345 6789", formatter.inputDigit('9'));
+ assertEquals("+81901234567890", formatter.inputDigit('0'));
+ }
+
+ public void testAYTFUS() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
+ assertEquals("6", formatter.inputDigit('6'));
+ assertEquals("65", formatter.inputDigit('5'));
+ assertEquals("650", formatter.inputDigit('0'));
+ assertEquals("650 2", formatter.inputDigit('2'));
+ assertEquals("650 25", formatter.inputDigit('5'));
+ assertEquals("650 253", formatter.inputDigit('3'));
+ // Note this is how a US local number (without area code) should be formatted.
+ assertEquals("650 2532", formatter.inputDigit('2'));
+ assertEquals("650 253 22", formatter.inputDigit('2'));
+ assertEquals("650 253 222", formatter.inputDigit('2'));
+ assertEquals("650 253 2222", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("1", formatter.inputDigit('1'));
+ assertEquals("16", formatter.inputDigit('6'));
+ assertEquals("1 65", formatter.inputDigit('5'));
+ assertEquals("1 650", formatter.inputDigit('0'));
+ assertEquals("1 650 2", formatter.inputDigit('2'));
+ assertEquals("1 650 25", formatter.inputDigit('5'));
+ assertEquals("1 650 253", formatter.inputDigit('3'));
+ assertEquals("1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("1 650 253 22", formatter.inputDigit('2'));
+ assertEquals("1 650 253 222", formatter.inputDigit('2'));
+ assertEquals("1 650 253 2222", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011 ", formatter.inputDigit('1'));
+ assertEquals("011 4", formatter.inputDigit('4'));
+ assertEquals("011 44 ", formatter.inputDigit('4'));
+ assertEquals("011 44 6", formatter.inputDigit('6'));
+ assertEquals("011 44 61", formatter.inputDigit('1'));
+ assertEquals("011 44 6 12", formatter.inputDigit('2'));
+ assertEquals("011 44 6 123", formatter.inputDigit('3'));
+ assertEquals("011 44 6 123 1", formatter.inputDigit('1'));
+ assertEquals("011 44 6 123 12", formatter.inputDigit('2'));
+ assertEquals("011 44 6 123 123", formatter.inputDigit('3'));
+ assertEquals("011 44 6 123 123 1", formatter.inputDigit('1'));
+ assertEquals("011 44 6 123 123 12", formatter.inputDigit('2'));
+ assertEquals("011 44 6 123 123 123", formatter.inputDigit('3'));
+
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011 ", formatter.inputDigit('1'));
+ assertEquals("011 5", formatter.inputDigit('5'));
+ assertEquals("011 54 ", formatter.inputDigit('4'));
+ assertEquals("011 54 9", formatter.inputDigit('9'));
+ assertEquals("011 54 91", formatter.inputDigit('1'));
+ assertEquals("011 54 9 11", formatter.inputDigit('1'));
+ assertEquals("011 54 9 11 2", formatter.inputDigit('2'));
+ assertEquals("011 54 9 11 23", formatter.inputDigit('3'));
+ assertEquals("011 54 9 11 231", formatter.inputDigit('1'));
+ assertEquals("011 54 9 11 2312", formatter.inputDigit('2'));
+ assertEquals("011 54 9 11 2312 1", formatter.inputDigit('1'));
+ assertEquals("011 54 9 11 2312 12", formatter.inputDigit('2'));
+ assertEquals("011 54 9 11 2312 123", formatter.inputDigit('3'));
+ assertEquals("011 54 9 11 2312 1234", formatter.inputDigit('4'));
+
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011 ", formatter.inputDigit('1'));
+ assertEquals("011 2", formatter.inputDigit('2'));
+ assertEquals("011 24", formatter.inputDigit('4'));
+ assertEquals("011 244 ", formatter.inputDigit('4'));
+ assertEquals("011 244 2", formatter.inputDigit('2'));
+ assertEquals("011 244 28", formatter.inputDigit('8'));
+ assertEquals("011 244 280", formatter.inputDigit('0'));
+ assertEquals("011 244 280 0", formatter.inputDigit('0'));
+ assertEquals("011 244 280 00", formatter.inputDigit('0'));
+ assertEquals("011 244 280 000", formatter.inputDigit('0'));
+ assertEquals("011 244 280 000 0", formatter.inputDigit('0'));
+ assertEquals("011 244 280 000 00", formatter.inputDigit('0'));
+ assertEquals("011 244 280 000 000", formatter.inputDigit('0'));
+
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+4", formatter.inputDigit('4'));
+ assertEquals("+48 ", formatter.inputDigit('8'));
+ assertEquals("+48 8", formatter.inputDigit('8'));
+ assertEquals("+48 88", formatter.inputDigit('8'));
+ assertEquals("+48 88 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 12", formatter.inputDigit('2'));
+ assertEquals("+48 88 123", formatter.inputDigit('3'));
+ assertEquals("+48 88 123 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 123 12", formatter.inputDigit('2'));
+ assertEquals("+48 88 123 12 1", formatter.inputDigit('1'));
+ assertEquals("+48 88 123 12 12", formatter.inputDigit('2'));
+ }
+
+ public void testAYTFUSFullWidthCharacters() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
+ assertEquals("\uFF16", formatter.inputDigit('\uFF16'));
+ assertEquals("\uFF16\uFF15", formatter.inputDigit('\uFF15'));
+ assertEquals("650", formatter.inputDigit('\uFF10'));
+ assertEquals("650 2", formatter.inputDigit('\uFF12'));
+ assertEquals("650 25", formatter.inputDigit('\uFF15'));
+ assertEquals("650 253", formatter.inputDigit('\uFF13'));
+ assertEquals("650 2532", formatter.inputDigit('\uFF12'));
+ assertEquals("650 253 22", formatter.inputDigit('\uFF12'));
+ assertEquals("650 253 222", formatter.inputDigit('\uFF12'));
+ assertEquals("650 253 2222", formatter.inputDigit('\uFF12'));
+ }
+
+ public void testAYTFUSMobileShortCode() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
+ assertEquals("*", formatter.inputDigit('*'));
+ assertEquals("*1", formatter.inputDigit('1'));
+ assertEquals("*12", formatter.inputDigit('2'));
+ assertEquals("*121", formatter.inputDigit('1'));
+ assertEquals("*121#", formatter.inputDigit('#'));
+ }
+
+ public void testAYTFUSVanityNumber() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
+ assertEquals("8", formatter.inputDigit('8'));
+ assertEquals("80", formatter.inputDigit('0'));
+ assertEquals("800", formatter.inputDigit('0'));
+ assertEquals("800 ", formatter.inputDigit(' '));
+ assertEquals("800 M", formatter.inputDigit('M'));
+ assertEquals("800 MY", formatter.inputDigit('Y'));
+ assertEquals("800 MY ", formatter.inputDigit(' '));
+ assertEquals("800 MY A", formatter.inputDigit('A'));
+ assertEquals("800 MY AP", formatter.inputDigit('P'));
+ assertEquals("800 MY APP", formatter.inputDigit('P'));
+ assertEquals("800 MY APPL", formatter.inputDigit('L'));
+ assertEquals("800 MY APPLE", formatter.inputDigit('E'));
+ }
+
+ public void testAYTFAndRememberPositionUS() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
+ assertEquals("1", formatter.inputDigitAndRememberPosition('1'));
+ assertEquals(1, formatter.getRememberedPosition());
+ assertEquals("16", formatter.inputDigit('6'));
+ assertEquals("1 65", formatter.inputDigit('5'));
+ assertEquals(1, formatter.getRememberedPosition());
+ assertEquals("1 650", formatter.inputDigitAndRememberPosition('0'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("1 650 2", formatter.inputDigit('2'));
+ assertEquals("1 650 25", formatter.inputDigit('5'));
+ // Note the remembered position for digit "0" changes from 4 to 5, because a space is now
+ // inserted in the front.
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("1 650 253", formatter.inputDigit('3'));
+ assertEquals("1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("1 650 253 22", formatter.inputDigit('2'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("1 650 253 222", formatter.inputDigitAndRememberPosition('2'));
+ assertEquals(13, formatter.getRememberedPosition());
+ assertEquals("1 650 253 2222", formatter.inputDigit('2'));
+ assertEquals(13, formatter.getRememberedPosition());
+ assertEquals("165025322222", formatter.inputDigit('2'));
+ assertEquals(10, formatter.getRememberedPosition());
+ assertEquals("1650253222222", formatter.inputDigit('2'));
+ assertEquals(10, formatter.getRememberedPosition());
+
+ formatter.clear();
+ assertEquals("1", formatter.inputDigit('1'));
+ assertEquals("16", formatter.inputDigitAndRememberPosition('6'));
+ assertEquals(2, formatter.getRememberedPosition());
+ assertEquals("1 65", formatter.inputDigit('5'));
+ assertEquals("1 650", formatter.inputDigit('0'));
+ assertEquals(3, formatter.getRememberedPosition());
+ assertEquals("1 650 2", formatter.inputDigit('2'));
+ assertEquals("1 650 25", formatter.inputDigit('5'));
+ assertEquals(3, formatter.getRememberedPosition());
+ assertEquals("1 650 253", formatter.inputDigit('3'));
+ assertEquals("1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("1 650 253 22", formatter.inputDigit('2'));
+ assertEquals(3, formatter.getRememberedPosition());
+ assertEquals("1 650 253 222", formatter.inputDigit('2'));
+ assertEquals("1 650 253 2222", formatter.inputDigit('2'));
+ assertEquals("165025322222", formatter.inputDigit('2'));
+ assertEquals(2, formatter.getRememberedPosition());
+ assertEquals("1650253222222", formatter.inputDigit('2'));
+ assertEquals(2, formatter.getRememberedPosition());
+
+ formatter.clear();
+ assertEquals("6", formatter.inputDigit('6'));
+ assertEquals("65", formatter.inputDigit('5'));
+ assertEquals("650", formatter.inputDigit('0'));
+ assertEquals("650 2", formatter.inputDigit('2'));
+ assertEquals("650 25", formatter.inputDigit('5'));
+ assertEquals("650 253", formatter.inputDigit('3'));
+ assertEquals("650 2532", formatter.inputDigitAndRememberPosition('2'));
+ assertEquals(8, formatter.getRememberedPosition());
+ assertEquals("650 253 22", formatter.inputDigit('2'));
+ assertEquals(9, formatter.getRememberedPosition());
+ assertEquals("650 253 222", formatter.inputDigit('2'));
+ // No more formatting when semicolon is entered.
+ assertEquals("650253222;", formatter.inputDigit(';'));
+ assertEquals(7, formatter.getRememberedPosition());
+ assertEquals("650253222;2", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("6", formatter.inputDigit('6'));
+ assertEquals("65", formatter.inputDigit('5'));
+ assertEquals("650", formatter.inputDigit('0'));
+ // No more formatting when users choose to do their own formatting.
+ assertEquals("650-", formatter.inputDigit('-'));
+ assertEquals("650-2", formatter.inputDigitAndRememberPosition('2'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("650-25", formatter.inputDigit('5'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("650-253", formatter.inputDigit('3'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("650-253-", formatter.inputDigit('-'));
+ assertEquals("650-253-2", formatter.inputDigit('2'));
+ assertEquals("650-253-22", formatter.inputDigit('2'));
+ assertEquals("650-253-222", formatter.inputDigit('2'));
+ assertEquals("650-253-2222", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011 ", formatter.inputDigit('1'));
+ assertEquals("011 4", formatter.inputDigitAndRememberPosition('4'));
+ assertEquals("011 48 ", formatter.inputDigit('8'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("011 48 8", formatter.inputDigit('8'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("011 48 88", formatter.inputDigit('8'));
+ assertEquals("011 48 88 1", formatter.inputDigit('1'));
+ assertEquals("011 48 88 12", formatter.inputDigit('2'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("011 48 88 123", formatter.inputDigit('3'));
+ assertEquals("011 48 88 123 1", formatter.inputDigit('1'));
+ assertEquals("011 48 88 123 12", formatter.inputDigit('2'));
+ assertEquals("011 48 88 123 12 1", formatter.inputDigit('1'));
+ assertEquals("011 48 88 123 12 12", formatter.inputDigit('2'));
+
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+1", formatter.inputDigit('1'));
+ assertEquals("+1 6", formatter.inputDigitAndRememberPosition('6'));
+ assertEquals("+1 65", formatter.inputDigit('5'));
+ assertEquals("+1 650", formatter.inputDigit('0'));
+ assertEquals(4, formatter.getRememberedPosition());
+ assertEquals("+1 650 2", formatter.inputDigit('2'));
+ assertEquals(4, formatter.getRememberedPosition());
+ assertEquals("+1 650 25", formatter.inputDigit('5'));
+ assertEquals("+1 650 253", formatter.inputDigitAndRememberPosition('3'));
+ assertEquals("+1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("+1 650 253 22", formatter.inputDigit('2'));
+ assertEquals("+1 650 253 222", formatter.inputDigit('2'));
+ assertEquals(10, formatter.getRememberedPosition());
+
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+1", formatter.inputDigit('1'));
+ assertEquals("+1 6", formatter.inputDigitAndRememberPosition('6'));
+ assertEquals("+1 65", formatter.inputDigit('5'));
+ assertEquals("+1 650", formatter.inputDigit('0'));
+ assertEquals(4, formatter.getRememberedPosition());
+ assertEquals("+1 650 2", formatter.inputDigit('2'));
+ assertEquals(4, formatter.getRememberedPosition());
+ assertEquals("+1 650 25", formatter.inputDigit('5'));
+ assertEquals("+1 650 253", formatter.inputDigit('3'));
+ assertEquals("+1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("+1 650 253 22", formatter.inputDigit('2'));
+ assertEquals("+1 650 253 222", formatter.inputDigit('2'));
+ assertEquals("+1650253222;", formatter.inputDigit(';'));
+ assertEquals(3, formatter.getRememberedPosition());
+ }
+
+ public void testAYTFGBFixedLine() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.GB);
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("02", formatter.inputDigit('2'));
+ assertEquals("020", formatter.inputDigit('0'));
+ assertEquals("020 7", formatter.inputDigitAndRememberPosition('7'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("020 70", formatter.inputDigit('0'));
+ assertEquals("020 703", formatter.inputDigit('3'));
+ assertEquals(5, formatter.getRememberedPosition());
+ assertEquals("020 7031", formatter.inputDigit('1'));
+ assertEquals("020 7031 3", formatter.inputDigit('3'));
+ assertEquals("020 7031 30", formatter.inputDigit('0'));
+ assertEquals("020 7031 300", formatter.inputDigit('0'));
+ assertEquals("020 7031 3000", formatter.inputDigit('0'));
+ }
+
+ public void testAYTFGBTollFree() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.GB);
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("08", formatter.inputDigit('8'));
+ assertEquals("080", formatter.inputDigit('0'));
+ assertEquals("080 7", formatter.inputDigit('7'));
+ assertEquals("080 70", formatter.inputDigit('0'));
+ assertEquals("080 703", formatter.inputDigit('3'));
+ assertEquals("080 7031", formatter.inputDigit('1'));
+ assertEquals("080 7031 3", formatter.inputDigit('3'));
+ assertEquals("080 7031 30", formatter.inputDigit('0'));
+ assertEquals("080 7031 300", formatter.inputDigit('0'));
+ assertEquals("080 7031 3000", formatter.inputDigit('0'));
+ }
+
+ public void testAYTFGBPremiumRate() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.GB);
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("09", formatter.inputDigit('9'));
+ assertEquals("090", formatter.inputDigit('0'));
+ assertEquals("090 7", formatter.inputDigit('7'));
+ assertEquals("090 70", formatter.inputDigit('0'));
+ assertEquals("090 703", formatter.inputDigit('3'));
+ assertEquals("090 7031", formatter.inputDigit('1'));
+ assertEquals("090 7031 3", formatter.inputDigit('3'));
+ assertEquals("090 7031 30", formatter.inputDigit('0'));
+ assertEquals("090 7031 300", formatter.inputDigit('0'));
+ assertEquals("090 7031 3000", formatter.inputDigit('0'));
+ }
+
+ public void testAYTFNZMobile() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.NZ);
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("02", formatter.inputDigit('2'));
+ assertEquals("021", formatter.inputDigit('1'));
+ assertEquals("02-11", formatter.inputDigit('1'));
+ assertEquals("02-112", formatter.inputDigit('2'));
+ // Note the unittest is using fake metadata which might produce non-ideal results.
+ assertEquals("02-112 3", formatter.inputDigit('3'));
+ assertEquals("02-112 34", formatter.inputDigit('4'));
+ assertEquals("02-112 345", formatter.inputDigit('5'));
+ assertEquals("02-112 3456", formatter.inputDigit('6'));
+ }
+
+ public void testAYTFDE() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.DE);
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("03", formatter.inputDigit('3'));
+ assertEquals("030", formatter.inputDigit('0'));
+ assertEquals("030/1", formatter.inputDigit('1'));
+ assertEquals("030/12", formatter.inputDigit('2'));
+ assertEquals("030/123", formatter.inputDigit('3'));
+ assertEquals("030/1234", formatter.inputDigit('4'));
+
+ // 04134 1234
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("04", formatter.inputDigit('4'));
+ assertEquals("041", formatter.inputDigit('1'));
+ assertEquals("041 3", formatter.inputDigit('3'));
+ assertEquals("041 34", formatter.inputDigit('4'));
+ assertEquals("04134 1", formatter.inputDigit('1'));
+ assertEquals("04134 12", formatter.inputDigit('2'));
+ assertEquals("04134 123", formatter.inputDigit('3'));
+ assertEquals("04134 1234", formatter.inputDigit('4'));
+
+ // 08021 2345
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("08", formatter.inputDigit('8'));
+ assertEquals("080", formatter.inputDigit('0'));
+ assertEquals("080 2", formatter.inputDigit('2'));
+ assertEquals("080 21", formatter.inputDigit('1'));
+ assertEquals("08021 2", formatter.inputDigit('2'));
+ assertEquals("08021 23", formatter.inputDigit('3'));
+ assertEquals("08021 234", formatter.inputDigit('4'));
+ assertEquals("08021 2345", formatter.inputDigit('5'));
+
+ // 00 1 650 253 2250
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("00", formatter.inputDigit('0'));
+ assertEquals("00 1 ", formatter.inputDigit('1'));
+ assertEquals("00 1 6", formatter.inputDigit('6'));
+ assertEquals("00 1 65", formatter.inputDigit('5'));
+ assertEquals("00 1 650", formatter.inputDigit('0'));
+ assertEquals("00 1 650 2", formatter.inputDigit('2'));
+ assertEquals("00 1 650 25", formatter.inputDigit('5'));
+ assertEquals("00 1 650 253", formatter.inputDigit('3'));
+ assertEquals("00 1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("00 1 650 253 22", formatter.inputDigit('2'));
+ assertEquals("00 1 650 253 222", formatter.inputDigit('2'));
+ assertEquals("00 1 650 253 2222", formatter.inputDigit('2'));
+ }
+
+ public void testAYTFAR() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.AR);
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011", formatter.inputDigit('1'));
+ assertEquals("011 7", formatter.inputDigit('7'));
+ assertEquals("011 70", formatter.inputDigit('0'));
+ assertEquals("011 703", formatter.inputDigit('3'));
+ assertEquals("011 7031", formatter.inputDigit('1'));
+ assertEquals("011 7031-3", formatter.inputDigit('3'));
+ assertEquals("011 7031-30", formatter.inputDigit('0'));
+ assertEquals("011 7031-300", formatter.inputDigit('0'));
+ assertEquals("011 7031-3000", formatter.inputDigit('0'));
+ }
+
+ public void testAYTFARMobile() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.AR);
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+5", formatter.inputDigit('5'));
+ assertEquals("+54 ", formatter.inputDigit('4'));
+ assertEquals("+54 9", formatter.inputDigit('9'));
+ assertEquals("+54 91", formatter.inputDigit('1'));
+ assertEquals("+54 9 11", formatter.inputDigit('1'));
+ assertEquals("+54 9 11 2", formatter.inputDigit('2'));
+ assertEquals("+54 9 11 23", formatter.inputDigit('3'));
+ assertEquals("+54 9 11 231", formatter.inputDigit('1'));
+ assertEquals("+54 9 11 2312", formatter.inputDigit('2'));
+ assertEquals("+54 9 11 2312 1", formatter.inputDigit('1'));
+ assertEquals("+54 9 11 2312 12", formatter.inputDigit('2'));
+ assertEquals("+54 9 11 2312 123", formatter.inputDigit('3'));
+ assertEquals("+54 9 11 2312 1234", formatter.inputDigit('4'));
+ }
+
+ public void testAYTFKR() {
+ // +82 51 234 5678
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR);
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+82 ", formatter.inputDigit('2'));
+ assertEquals("+82 5", formatter.inputDigit('5'));
+ assertEquals("+82 51", formatter.inputDigit('1'));
+ assertEquals("+82 51-2", formatter.inputDigit('2'));
+ assertEquals("+82 51-23", formatter.inputDigit('3'));
+ assertEquals("+82 51-234", formatter.inputDigit('4'));
+ assertEquals("+82 51-234-5", formatter.inputDigit('5'));
+ assertEquals("+82 51-234-56", formatter.inputDigit('6'));
+ assertEquals("+82 51-234-567", formatter.inputDigit('7'));
+ assertEquals("+82 51-234-5678", formatter.inputDigit('8'));
+
+ // +82 2 531 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+82 ", formatter.inputDigit('2'));
+ assertEquals("+82 2", formatter.inputDigit('2'));
+ assertEquals("+82 25", formatter.inputDigit('5'));
+ assertEquals("+82 2-53", formatter.inputDigit('3'));
+ assertEquals("+82 2-531", formatter.inputDigit('1'));
+ assertEquals("+82 2-531-5", formatter.inputDigit('5'));
+ assertEquals("+82 2-531-56", formatter.inputDigit('6'));
+ assertEquals("+82 2-531-567", formatter.inputDigit('7'));
+ assertEquals("+82 2-531-5678", formatter.inputDigit('8'));
+
+ // +82 2 3665 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+82 ", formatter.inputDigit('2'));
+ assertEquals("+82 2", formatter.inputDigit('2'));
+ assertEquals("+82 23", formatter.inputDigit('3'));
+ assertEquals("+82 2-36", formatter.inputDigit('6'));
+ assertEquals("+82 2-366", formatter.inputDigit('6'));
+ assertEquals("+82 2-3665", formatter.inputDigit('5'));
+ assertEquals("+82 2-3665-5", formatter.inputDigit('5'));
+ assertEquals("+82 2-3665-56", formatter.inputDigit('6'));
+ assertEquals("+82 2-3665-567", formatter.inputDigit('7'));
+ assertEquals("+82 2-3665-5678", formatter.inputDigit('8'));
+
+ // 02-114
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("02", formatter.inputDigit('2'));
+ assertEquals("021", formatter.inputDigit('1'));
+ assertEquals("02-11", formatter.inputDigit('1'));
+ assertEquals("02-114", formatter.inputDigit('4'));
+
+ // 02-1300
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("02", formatter.inputDigit('2'));
+ assertEquals("021", formatter.inputDigit('1'));
+ assertEquals("02-13", formatter.inputDigit('3'));
+ assertEquals("02-130", formatter.inputDigit('0'));
+ assertEquals("02-1300", formatter.inputDigit('0'));
+
+ // 011-456-7890
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011", formatter.inputDigit('1'));
+ assertEquals("011-4", formatter.inputDigit('4'));
+ assertEquals("011-45", formatter.inputDigit('5'));
+ assertEquals("011-456", formatter.inputDigit('6'));
+ assertEquals("011-456-7", formatter.inputDigit('7'));
+ assertEquals("011-456-78", formatter.inputDigit('8'));
+ assertEquals("011-456-789", formatter.inputDigit('9'));
+ assertEquals("011-456-7890", formatter.inputDigit('0'));
+
+ // 011-9876-7890
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("01", formatter.inputDigit('1'));
+ assertEquals("011", formatter.inputDigit('1'));
+ assertEquals("011-9", formatter.inputDigit('9'));
+ assertEquals("011-98", formatter.inputDigit('8'));
+ assertEquals("011-987", formatter.inputDigit('7'));
+ assertEquals("011-9876", formatter.inputDigit('6'));
+ assertEquals("011-9876-7", formatter.inputDigit('7'));
+ assertEquals("011-9876-78", formatter.inputDigit('8'));
+ assertEquals("011-9876-789", formatter.inputDigit('9'));
+ assertEquals("011-9876-7890", formatter.inputDigit('0'));
+ }
+
+ public void testAYTF_MX() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.MX);
+
+ // +52 800 123 4567
+ 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'));
+
+ // +52 55 1234 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+5", formatter.inputDigit('5'));
+ assertEquals("+52 ", formatter.inputDigit('2'));
+ assertEquals("+52 5", formatter.inputDigit('5'));
+ assertEquals("+52 55", formatter.inputDigit('5'));
+ assertEquals("+52 55 1", formatter.inputDigit('1'));
+ assertEquals("+52 55 12", formatter.inputDigit('2'));
+ assertEquals("+52 55 123", formatter.inputDigit('3'));
+ assertEquals("+52 55 1234", formatter.inputDigit('4'));
+ assertEquals("+52 55 1234 5", formatter.inputDigit('5'));
+ assertEquals("+52 55 1234 56", formatter.inputDigit('6'));
+ assertEquals("+52 55 1234 567", formatter.inputDigit('7'));
+ assertEquals("+52 55 1234 5678", formatter.inputDigit('8'));
+
+ // +52 212 345 6789
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+5", formatter.inputDigit('5'));
+ assertEquals("+52 ", formatter.inputDigit('2'));
+ assertEquals("+52 2", formatter.inputDigit('2'));
+ assertEquals("+52 21", formatter.inputDigit('1'));
+ assertEquals("+52 212", formatter.inputDigit('2'));
+ assertEquals("+52 212 3", formatter.inputDigit('3'));
+ assertEquals("+52 212 34", formatter.inputDigit('4'));
+ assertEquals("+52 212 345", formatter.inputDigit('5'));
+ assertEquals("+52 212 345 6", formatter.inputDigit('6'));
+ assertEquals("+52 212 345 67", formatter.inputDigit('7'));
+ assertEquals("+52 212 345 678", formatter.inputDigit('8'));
+ assertEquals("+52 212 345 6789", formatter.inputDigit('9'));
+
+ // +52 1 55 1234 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+5", formatter.inputDigit('5'));
+ assertEquals("+52 ", formatter.inputDigit('2'));
+ assertEquals("+52 1", formatter.inputDigit('1'));
+ assertEquals("+52 15", formatter.inputDigit('5'));
+ assertEquals("+52 1 55", formatter.inputDigit('5'));
+ assertEquals("+52 1 55 1", formatter.inputDigit('1'));
+ assertEquals("+52 1 55 12", formatter.inputDigit('2'));
+ assertEquals("+52 1 55 123", formatter.inputDigit('3'));
+ assertEquals("+52 1 55 1234", formatter.inputDigit('4'));
+ assertEquals("+52 1 55 1234 5", formatter.inputDigit('5'));
+ assertEquals("+52 1 55 1234 56", formatter.inputDigit('6'));
+ assertEquals("+52 1 55 1234 567", formatter.inputDigit('7'));
+ assertEquals("+52 1 55 1234 5678", formatter.inputDigit('8'));
+
+ // +52 1 541 234 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+5", formatter.inputDigit('5'));
+ assertEquals("+52 ", formatter.inputDigit('2'));
+ assertEquals("+52 1", formatter.inputDigit('1'));
+ assertEquals("+52 15", formatter.inputDigit('5'));
+ assertEquals("+52 1 54", formatter.inputDigit('4'));
+ assertEquals("+52 1 541", formatter.inputDigit('1'));
+ assertEquals("+52 1 541 2", formatter.inputDigit('2'));
+ assertEquals("+52 1 541 23", formatter.inputDigit('3'));
+ assertEquals("+52 1 541 234", formatter.inputDigit('4'));
+ assertEquals("+52 1 541 234 5", formatter.inputDigit('5'));
+ assertEquals("+52 1 541 234 56", formatter.inputDigit('6'));
+ assertEquals("+52 1 541 234 567", formatter.inputDigit('7'));
+ assertEquals("+52 1 541 234 5678", formatter.inputDigit('8'));
+ }
+
+ public void testAYTFMultipleLeadingDigitPatterns() {
+ // +81 50 2345 6789
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.JP);
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+81 ", formatter.inputDigit('1'));
+ assertEquals("+81 5", formatter.inputDigit('5'));
+ assertEquals("+81 50", formatter.inputDigit('0'));
+ assertEquals("+81 50 2", formatter.inputDigit('2'));
+ assertEquals("+81 50 23", formatter.inputDigit('3'));
+ assertEquals("+81 50 234", formatter.inputDigit('4'));
+ assertEquals("+81 50 2345", formatter.inputDigit('5'));
+ assertEquals("+81 50 2345 6", formatter.inputDigit('6'));
+ assertEquals("+81 50 2345 67", formatter.inputDigit('7'));
+ assertEquals("+81 50 2345 678", formatter.inputDigit('8'));
+ assertEquals("+81 50 2345 6789", formatter.inputDigit('9'));
+
+ // +81 222 12 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+81 ", formatter.inputDigit('1'));
+ assertEquals("+81 2", formatter.inputDigit('2'));
+ assertEquals("+81 22", formatter.inputDigit('2'));
+ assertEquals("+81 22 2", formatter.inputDigit('2'));
+ assertEquals("+81 22 21", formatter.inputDigit('1'));
+ assertEquals("+81 2221 2", formatter.inputDigit('2'));
+ assertEquals("+81 222 12 5", formatter.inputDigit('5'));
+ assertEquals("+81 222 12 56", formatter.inputDigit('6'));
+ assertEquals("+81 222 12 567", formatter.inputDigit('7'));
+ assertEquals("+81 222 12 5678", formatter.inputDigit('8'));
+
+ // +81 3332 2 5678
+ formatter.clear();
+ assertEquals("+", formatter.inputDigit('+'));
+ assertEquals("+8", formatter.inputDigit('8'));
+ assertEquals("+81 ", formatter.inputDigit('1'));
+ assertEquals("+81 3", formatter.inputDigit('3'));
+ assertEquals("+81 33", formatter.inputDigit('3'));
+ assertEquals("+81 33 3", formatter.inputDigit('3'));
+ assertEquals("+81 3332", formatter.inputDigit('2'));
+ assertEquals("+81 3332 2", formatter.inputDigit('2'));
+ assertEquals("+81 3332 2 5", formatter.inputDigit('5'));
+ assertEquals("+81 3332 2 56", formatter.inputDigit('6'));
+ assertEquals("+81 3332 2 567", formatter.inputDigit('7'));
+ assertEquals("+81 3332 2 5678", formatter.inputDigit('8'));
+ }
+
+ public void testAYTFLongIDD_AU() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("AU");
+ // 0011 1 650 253 2250
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("00", formatter.inputDigit('0'));
+ assertEquals("001", formatter.inputDigit('1'));
+ assertEquals("0011", formatter.inputDigit('1'));
+ assertEquals("0011 1 ", formatter.inputDigit('1'));
+ assertEquals("0011 1 6", formatter.inputDigit('6'));
+ assertEquals("0011 1 65", formatter.inputDigit('5'));
+ assertEquals("0011 1 650", formatter.inputDigit('0'));
+ assertEquals("0011 1 650 2", formatter.inputDigit('2'));
+ assertEquals("0011 1 650 25", formatter.inputDigit('5'));
+ assertEquals("0011 1 650 253", formatter.inputDigit('3'));
+ assertEquals("0011 1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("0011 1 650 253 22", formatter.inputDigit('2'));
+ assertEquals("0011 1 650 253 222", formatter.inputDigit('2'));
+ assertEquals("0011 1 650 253 2222", formatter.inputDigit('2'));
+
+ // 0011 81 3332 2 5678
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("00", formatter.inputDigit('0'));
+ assertEquals("001", formatter.inputDigit('1'));
+ assertEquals("0011", formatter.inputDigit('1'));
+ assertEquals("00118", formatter.inputDigit('8'));
+ assertEquals("0011 81 ", formatter.inputDigit('1'));
+ assertEquals("0011 81 3", formatter.inputDigit('3'));
+ assertEquals("0011 81 33", formatter.inputDigit('3'));
+ assertEquals("0011 81 33 3", formatter.inputDigit('3'));
+ assertEquals("0011 81 3332", formatter.inputDigit('2'));
+ assertEquals("0011 81 3332 2", formatter.inputDigit('2'));
+ assertEquals("0011 81 3332 2 5", formatter.inputDigit('5'));
+ assertEquals("0011 81 3332 2 56", formatter.inputDigit('6'));
+ assertEquals("0011 81 3332 2 567", formatter.inputDigit('7'));
+ assertEquals("0011 81 3332 2 5678", formatter.inputDigit('8'));
+
+ // 0011 244 250 253 222
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("00", formatter.inputDigit('0'));
+ assertEquals("001", formatter.inputDigit('1'));
+ assertEquals("0011", formatter.inputDigit('1'));
+ assertEquals("00112", formatter.inputDigit('2'));
+ assertEquals("001124", formatter.inputDigit('4'));
+ assertEquals("0011 244 ", formatter.inputDigit('4'));
+ assertEquals("0011 244 2", formatter.inputDigit('2'));
+ assertEquals("0011 244 25", formatter.inputDigit('5'));
+ assertEquals("0011 244 250", formatter.inputDigit('0'));
+ assertEquals("0011 244 250 2", formatter.inputDigit('2'));
+ assertEquals("0011 244 250 25", formatter.inputDigit('5'));
+ assertEquals("0011 244 250 253", formatter.inputDigit('3'));
+ assertEquals("0011 244 250 253 2", formatter.inputDigit('2'));
+ assertEquals("0011 244 250 253 22", formatter.inputDigit('2'));
+ assertEquals("0011 244 250 253 222", formatter.inputDigit('2'));
+ }
+
+ public void testAYTFLongIDD_KR() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR");
+ // 00300 1 650 253 2222
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("00", formatter.inputDigit('0'));
+ assertEquals("003", formatter.inputDigit('3'));
+ assertEquals("0030", formatter.inputDigit('0'));
+ assertEquals("00300", formatter.inputDigit('0'));
+ assertEquals("00300 1 ", formatter.inputDigit('1'));
+ assertEquals("00300 1 6", formatter.inputDigit('6'));
+ assertEquals("00300 1 65", formatter.inputDigit('5'));
+ assertEquals("00300 1 650", formatter.inputDigit('0'));
+ assertEquals("00300 1 650 2", formatter.inputDigit('2'));
+ assertEquals("00300 1 650 25", formatter.inputDigit('5'));
+ assertEquals("00300 1 650 253", formatter.inputDigit('3'));
+ assertEquals("00300 1 650 253 2", formatter.inputDigit('2'));
+ assertEquals("00300 1 650 253 22", formatter.inputDigit('2'));
+ assertEquals("00300 1 650 253 222", formatter.inputDigit('2'));
+ assertEquals("00300 1 650 253 2222", formatter.inputDigit('2'));
+ }
+
+ public void testAYTFLongNDD_KR() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR");
+ // 08811-9876-7890
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("08", formatter.inputDigit('8'));
+ assertEquals("088", formatter.inputDigit('8'));
+ assertEquals("0881", formatter.inputDigit('1'));
+ assertEquals("08811", formatter.inputDigit('1'));
+ assertEquals("08811-9", formatter.inputDigit('9'));
+ assertEquals("08811-98", formatter.inputDigit('8'));
+ assertEquals("08811-987", formatter.inputDigit('7'));
+ assertEquals("08811-9876", formatter.inputDigit('6'));
+ assertEquals("08811-9876-7", formatter.inputDigit('7'));
+ assertEquals("08811-9876-78", formatter.inputDigit('8'));
+ assertEquals("08811-9876-789", formatter.inputDigit('9'));
+ assertEquals("08811-9876-7890", formatter.inputDigit('0'));
+
+ // 08500 11-9876-7890
+ formatter.clear();
+ assertEquals("0", formatter.inputDigit('0'));
+ assertEquals("08", formatter.inputDigit('8'));
+ assertEquals("085", formatter.inputDigit('5'));
+ assertEquals("0850", formatter.inputDigit('0'));
+ assertEquals("08500 ", formatter.inputDigit('0'));
+ assertEquals("08500 1", formatter.inputDigit('1'));
+ assertEquals("08500 11", formatter.inputDigit('1'));
+ assertEquals("08500 11-9", formatter.inputDigit('9'));
+ assertEquals("08500 11-98", formatter.inputDigit('8'));
+ assertEquals("08500 11-987", formatter.inputDigit('7'));
+ assertEquals("08500 11-9876", formatter.inputDigit('6'));
+ assertEquals("08500 11-9876-7", formatter.inputDigit('7'));
+ assertEquals("08500 11-9876-78", formatter.inputDigit('8'));
+ assertEquals("08500 11-9876-789", formatter.inputDigit('9'));
+ assertEquals("08500 11-9876-7890", formatter.inputDigit('0'));
+ }
+
+ public void testAYTFLongNDD_SG() {
+ AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("SG");
+ // 777777 9876 7890
+ assertEquals("7", formatter.inputDigit('7'));
+ assertEquals("77", formatter.inputDigit('7'));
+ assertEquals("777", formatter.inputDigit('7'));
+ assertEquals("7777", formatter.inputDigit('7'));
+ assertEquals("77777", formatter.inputDigit('7'));
+ assertEquals("777777 ", formatter.inputDigit('7'));
+ assertEquals("777777 9", formatter.inputDigit('9'));
+ assertEquals("777777 98", formatter.inputDigit('8'));
+ assertEquals("777777 987", formatter.inputDigit('7'));
+ assertEquals("777777 9876", formatter.inputDigit('6'));
+ assertEquals("777777 9876 7", formatter.inputDigit('7'));
+ assertEquals("777777 9876 78", formatter.inputDigit('8'));
+ assertEquals("777777 9876 789", formatter.inputDigit('9'));
+ assertEquals("777777 9876 7890", formatter.inputDigit('0'));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
new file mode 100644
index 0000000..6d7417d
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
@@ -0,0 +1,109 @@
+/*
+ * 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 CountryCodeToRegionCodeMapForTesting {
+ // 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 21 as there are 16 different country codes,
+ // and this offers a load factor of roughly 0.75.
+ Map<Integer, List<String>> countryCodeToRegionCodeMap =
+ new HashMap<Integer, List<String>>(21);
+
+ ArrayList<String> listWithRegionCode;
+
+ listWithRegionCode = new ArrayList<String>(2);
+ listWithRegionCode.add("US");
+ listWithRegionCode.add("BS");
+ countryCodeToRegionCodeMap.put(1, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("IT");
+ countryCodeToRegionCodeMap.put(39, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("GB");
+ countryCodeToRegionCodeMap.put(44, 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("MX");
+ countryCodeToRegionCodeMap.put(52, 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("AU");
+ countryCodeToRegionCodeMap.put(61, 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("JP");
+ countryCodeToRegionCodeMap.put(81, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("KR");
+ countryCodeToRegionCodeMap.put(82, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("AO");
+ countryCodeToRegionCodeMap.put(244, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(2);
+ listWithRegionCode.add("RE");
+ listWithRegionCode.add("YT");
+ countryCodeToRegionCodeMap.put(262, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("AD");
+ countryCodeToRegionCodeMap.put(376, listWithRegionCode);
+
+ return countryCodeToRegionCodeMap;
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java
new file mode 100644
index 0000000..7c30588
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.PhoneNumberUtil.PhoneNumberType;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Lara Rennie
+ *
+ * Verifies all of the example numbers in the metadata are valid and of the correct type. If no
+ * example number exists for a particular type, the test still passes.
+ */
+public class ExampleNumbersTest extends TestCase {
+ private static final Logger LOGGER = Logger.getLogger(ExampleNumbersTest.class.getName());
+ private PhoneNumberUtil phoneNumberUtil;
+ private List<PhoneNumber> invalidCases = new ArrayList<PhoneNumber>();
+ private List<PhoneNumber> wrongTypeCases = new ArrayList<PhoneNumber>();
+
+ public ExampleNumbersTest() {
+ PhoneNumberUtil.resetInstance();
+ phoneNumberUtil = PhoneNumberUtil.getInstance();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ invalidCases.clear();
+ wrongTypeCases.clear();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * @param exampleNumberRequestedType type we are requesting an example number for
+ * @param possibleExpectedTypes acceptable types that this number should match, such as
+ * FIXED_LINE and FIXED_LINE_OR_MOBILE for a fixed line example number.
+ */
+ private void checkNumbersValidAndCorrectType(PhoneNumberType exampleNumberRequestedType,
+ Set<PhoneNumberType> possibleExpectedTypes) {
+ for (String regionCode : phoneNumberUtil.getSupportedRegions()) {
+ PhoneNumber exampleNumber =
+ phoneNumberUtil.getExampleNumberForType(regionCode, exampleNumberRequestedType);
+ if (exampleNumber != null) {
+ if (!phoneNumberUtil.isValidNumber(exampleNumber)) {
+ invalidCases.add(exampleNumber);
+ LOGGER.log(Level.SEVERE, "Failed validation for " + exampleNumber.toString());
+ } else {
+ // We know the number is valid, now we check the type.
+ PhoneNumberType exampleNumberType = phoneNumberUtil.getNumberType(exampleNumber);
+ if (!possibleExpectedTypes.contains(exampleNumberType)) {
+ wrongTypeCases.add(exampleNumber);
+ LOGGER.log(Level.SEVERE, "Wrong type for " +
+ exampleNumber.toString() +
+ ": got " + exampleNumberType);
+ LOGGER.log(Level.WARNING, "Expected types: ");
+ for (PhoneNumberType type : possibleExpectedTypes) {
+ LOGGER.log(Level.WARNING, type.toString());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void testFixedLine() throws Exception {
+ Set<PhoneNumberType> fixedLineTypes = EnumSet.of(PhoneNumberType.FIXED_LINE,
+ PhoneNumberType.FIXED_LINE_OR_MOBILE);
+ checkNumbersValidAndCorrectType(PhoneNumberType.FIXED_LINE, fixedLineTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testMobile() throws Exception {
+ Set<PhoneNumberType> mobileTypes = EnumSet.of(PhoneNumberType.MOBILE,
+ PhoneNumberType.FIXED_LINE_OR_MOBILE);
+ checkNumbersValidAndCorrectType(PhoneNumberType.MOBILE, mobileTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testTollFree() throws Exception {
+ Set<PhoneNumberType> tollFreeTypes = EnumSet.of(PhoneNumberType.TOLL_FREE);
+ checkNumbersValidAndCorrectType(PhoneNumberType.TOLL_FREE, tollFreeTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testPremiumRate() throws Exception {
+ Set<PhoneNumberType> premiumRateTypes = EnumSet.of(PhoneNumberType.PREMIUM_RATE);
+ checkNumbersValidAndCorrectType(PhoneNumberType.PREMIUM_RATE, premiumRateTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testVoip() throws Exception {
+ Set<PhoneNumberType> voipTypes = EnumSet.of(PhoneNumberType.VOIP);
+ checkNumbersValidAndCorrectType(PhoneNumberType.VOIP, voipTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testPager() throws Exception {
+ Set<PhoneNumberType> pagerTypes = EnumSet.of(PhoneNumberType.PAGER);
+ checkNumbersValidAndCorrectType(PhoneNumberType.PAGER, pagerTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testUan() throws Exception {
+ Set<PhoneNumberType> uanTypes = EnumSet.of(PhoneNumberType.UAN);
+ checkNumbersValidAndCorrectType(PhoneNumberType.UAN, uanTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testSharedCost() throws Exception {
+ Set<PhoneNumberType> sharedCostTypes = EnumSet.of(PhoneNumberType.SHARED_COST);
+ checkNumbersValidAndCorrectType(PhoneNumberType.SHARED_COST, sharedCostTypes);
+ assertEquals(0, invalidCases.size());
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testCanBeInternationallyDialled() throws Exception {
+ for (String regionCode : phoneNumberUtil.getSupportedRegions()) {
+ PhoneNumber exampleNumber = null;
+ PhoneNumberDesc desc =
+ phoneNumberUtil.getMetadataForRegion(regionCode).getNoInternationalDialling();
+ try {
+ if (desc.hasExampleNumber()) {
+ exampleNumber = phoneNumberUtil.parse(desc.getExampleNumber(), regionCode);
+ }
+ } catch (NumberParseException e) {
+ LOGGER.log(Level.SEVERE, e.toString());
+ }
+ if (exampleNumber != null && phoneNumberUtil.canBeInternationallyDialled(exampleNumber)) {
+ wrongTypeCases.add(exampleNumber);
+ }
+ }
+ assertEquals(0, wrongTypeCases.size());
+ }
+
+ public void testEveryRegionHasAnExampleNumber() throws Exception {
+ for (String regionCode : phoneNumberUtil.getSupportedRegions()) {
+ PhoneNumber exampleNumber = phoneNumberUtil.getExampleNumber(regionCode);
+ assertNotNull("None found for region " + regionCode, exampleNumber);
+ }
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java
new file mode 100644
index 0000000..899fc94
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatchTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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 junit.framework.TestCase;
+
+/**
+ * Tests for {@link PhoneNumberMatch}.
+ *
+ * @author Tom Hofmann
+ */
+public class PhoneNumberMatchTest extends TestCase {
+ /**
+ * Tests the value type semantics. Equality and hash code must be based on the covered range and
+ * corresponding phone number. Range and number correctness are tested by
+ * {@link PhoneNumberMatcherTest}.
+ */
+ public void testValueTypeSemantics() throws Exception {
+ PhoneNumber number = new PhoneNumber();
+ PhoneNumberMatch match1 = new PhoneNumberMatch(10, "1 800 234 45 67", number);
+ PhoneNumberMatch match2 = new PhoneNumberMatch(10, "1 800 234 45 67", number);
+
+ assertEquals(match1, match2);
+ assertEquals(match1.hashCode(), match2.hashCode());
+ assertEquals(match1.start(), match2.start());
+ assertEquals(match1.end(), match2.end());
+ assertEquals(match1.number(), match2.number());
+ assertEquals(match1.rawString(), match2.rawString());
+ assertEquals("1 800 234 45 67", match1.rawString());
+ }
+
+ /**
+ * Tests the value type semantics for matches with a null number.
+ */
+ public void testIllegalArguments() throws Exception {
+ try {
+ new PhoneNumberMatch(-110, "1 800 234 45 67", new PhoneNumber());
+ fail();
+ } catch (IllegalArgumentException e) { /* success */ }
+
+ try {
+ new PhoneNumberMatch(10, "1 800 234 45 67", null);
+ fail();
+ } catch (NullPointerException e) { /* success */ }
+
+ try {
+ new PhoneNumberMatch(10, null, new PhoneNumber());
+ fail();
+ } catch (NullPointerException e) { /* success */ }
+
+ try {
+ new PhoneNumberMatch(10, null, null);
+ fail();
+ } catch (NullPointerException e) { /* success */ }
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java
new file mode 100644
index 0000000..c23181d
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java
@@ -0,0 +1,935 @@
+/*
+ * 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.Phonenumber.PhoneNumber;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests for {@link PhoneNumberMatcher}. This only tests basic functionality based on test metadata.
+ *
+ * @author Tom Hofmann
+ * @see PhoneNumberUtilTest {@link PhoneNumberUtilTest} for the origin of the test data
+ */
+public class PhoneNumberMatcherTest extends TestCase {
+ private PhoneNumberUtil phoneUtil;
+
+ @Override
+ protected void setUp() throws Exception {
+ phoneUtil = PhoneNumberUtilTest.initializePhoneUtilForTesting();
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNationalNumber()}. */
+ public void testFindNationalNumber() throws Exception {
+ // same cases as in testParseNationalNumber
+ doTestFindInContext("033316005", RegionCode.NZ);
+ // ("33316005", RegionCode.NZ) is omitted since the national prefix is obligatory for these
+ // types of numbers in New Zealand.
+ // National prefix attached and some formatting present.
+ doTestFindInContext("03-331 6005", RegionCode.NZ);
+ doTestFindInContext("03 331 6005", RegionCode.NZ);
+ // Testing international prefixes.
+ // Should strip country code.
+ doTestFindInContext("0064 3 331 6005", RegionCode.NZ);
+ // Try again, but this time we have an international number with Region Code US. It should
+ // recognize the country code and parse accordingly.
+ doTestFindInContext("01164 3 331 6005", RegionCode.US);
+ doTestFindInContext("+64 3 331 6005", RegionCode.US);
+
+ doTestFindInContext("64(0)64123456", RegionCode.NZ);
+ // Check that using a "/" is fine in a phone number.
+ doTestFindInContext("123/45678", RegionCode.DE);
+ doTestFindInContext("123-456-7890", RegionCode.US);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseWithInternationalPrefixes()}. */
+ public void testFindWithInternationalPrefixes() throws Exception {
+ doTestFindInContext("+1 (650) 333-6000", RegionCode.NZ);
+ doTestFindInContext("1-650-333-6000", RegionCode.US);
+ // Calling the US number from Singapore by using different service providers
+ // 1st test: calling using SingTel IDD service (IDD is 001)
+ doTestFindInContext("0011-650-333-6000", RegionCode.SG);
+ // 2nd test: calling using StarHub IDD service (IDD is 008)
+ doTestFindInContext("0081-650-333-6000", RegionCode.SG);
+ // 3rd test: calling using SingTel V019 service (IDD is 019)
+ doTestFindInContext("0191-650-333-6000", RegionCode.SG);
+ // Calling the US number from Poland
+ doTestFindInContext("0~01-650-333-6000", RegionCode.PL);
+ // Using "++" at the start.
+ doTestFindInContext("++1 (650) 333-6000", RegionCode.PL);
+ // Using a full-width plus sign.
+ doTestFindInContext("\uFF0B1 (650) 333-6000", RegionCode.SG);
+ // The whole number, including punctuation, is here represented in full-width form.
+ doTestFindInContext("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
+ "\u3000\uFF13\uFF13\uFF13\uFF0D\uFF16\uFF10\uFF10\uFF10",
+ RegionCode.SG);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseWithLeadingZero()}. */
+ public void testFindWithLeadingZero() throws Exception {
+ doTestFindInContext("+39 02-36618 300", RegionCode.NZ);
+ doTestFindInContext("02-36618 300", RegionCode.IT);
+ doTestFindInContext("312 345 678", RegionCode.IT);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNationalNumberArgentina()}. */
+ public void testFindNationalNumberArgentina() throws Exception {
+ // Test parsing mobile numbers of Argentina.
+ doTestFindInContext("+54 9 343 555 1212", RegionCode.AR);
+ doTestFindInContext("0343 15 555 1212", RegionCode.AR);
+
+ doTestFindInContext("+54 9 3715 65 4320", RegionCode.AR);
+ doTestFindInContext("03715 15 65 4320", RegionCode.AR);
+
+ // Test parsing fixed-line numbers of Argentina.
+ doTestFindInContext("+54 11 3797 0000", RegionCode.AR);
+ doTestFindInContext("011 3797 0000", RegionCode.AR);
+
+ doTestFindInContext("+54 3715 65 4321", RegionCode.AR);
+ doTestFindInContext("03715 65 4321", RegionCode.AR);
+
+ doTestFindInContext("+54 23 1234 0000", RegionCode.AR);
+ doTestFindInContext("023 1234 0000", RegionCode.AR);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseWithXInNumber()}. */
+ public void testFindWithXInNumber() throws Exception {
+ doTestFindInContext("(0xx) 123456789", RegionCode.AR);
+ // A case where x denotes both carrier codes and extension symbol.
+ doTestFindInContext("(0xx) 123456789 x 1234", RegionCode.AR);
+
+ // This test is intentionally constructed such that the number of digit after xx is larger than
+ // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
+ // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
+ // code is written in the form of xx have a national significant number of length larger than 7.
+ doTestFindInContext("011xx5481429712", RegionCode.US);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNumbersMexico()}. */
+ public void testFindNumbersMexico() throws Exception {
+ // Test parsing fixed-line numbers of Mexico.
+ doTestFindInContext("+52 (449)978-0001", RegionCode.MX);
+ doTestFindInContext("01 (449)978-0001", RegionCode.MX);
+ doTestFindInContext("(449)978-0001", RegionCode.MX);
+
+ // Test parsing mobile numbers of Mexico.
+ doTestFindInContext("+52 1 33 1234-5678", RegionCode.MX);
+ doTestFindInContext("044 (33) 1234-5678", RegionCode.MX);
+ doTestFindInContext("045 33 1234-5678", RegionCode.MX);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseNumbersWithPlusWithNoRegion()}. */
+ public void testFindNumbersWithPlusWithNoRegion() throws Exception {
+ // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country code can be
+ // calculated.
+ doTestFindInContext("+64 3 331 6005", RegionCode.ZZ);
+ // Null is also allowed for the region code in these cases.
+ doTestFindInContext("+64 3 331 6005", null);
+ }
+
+ /** See {@link PhoneNumberUtilTest#testParseExtensions()}. */
+ public void testFindExtensions() throws Exception {
+ doTestFindInContext("03 331 6005 ext 3456", RegionCode.NZ);
+ doTestFindInContext("03-3316005x3456", RegionCode.NZ);
+ doTestFindInContext("03-3316005 int.3456", RegionCode.NZ);
+ doTestFindInContext("03 3316005 #3456", RegionCode.NZ);
+ doTestFindInContext("0~0 1800 7493 524", RegionCode.PL);
+ doTestFindInContext("(1800) 7493.524", RegionCode.US);
+ // Check that the last instance of an extension token is matched.
+ doTestFindInContext("0~0 1800 7493 524 ~1234", RegionCode.PL);
+ // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
+ // extracting the extension. Also verifying a few different cases of extensions.
+ doTestFindInContext("+44 2034567890x456", RegionCode.NZ);
+ doTestFindInContext("+44 2034567890x456", RegionCode.GB);
+ doTestFindInContext("+44 2034567890 x456", RegionCode.GB);
+ doTestFindInContext("+44 2034567890 X456", RegionCode.GB);
+ doTestFindInContext("+44 2034567890 X 456", RegionCode.GB);
+ doTestFindInContext("+44 2034567890 X 456", RegionCode.GB);
+ doTestFindInContext("+44 2034567890 X 456", RegionCode.GB);
+
+ doTestFindInContext("(800) 901-3355 x 7246433", RegionCode.US);
+ doTestFindInContext("(800) 901-3355 , ext 7246433", RegionCode.US);
+ doTestFindInContext("(800) 901-3355 ,extension 7246433", RegionCode.US);
+ // The next test differs from PhoneNumberUtil -> when matching we don't consider a lone comma to
+ // indicate an extension, although we accept it when parsing.
+ doTestFindInContext("(800) 901-3355 ,x 7246433", RegionCode.US);
+ doTestFindInContext("(800) 901-3355 ext: 7246433", RegionCode.US);
+ }
+
+ public void testFindInterspersedWithSpace() throws Exception {
+ doTestFindInContext("0 3 3 3 1 6 0 0 5", RegionCode.NZ);
+ }
+
+ /**
+ * Test matching behavior when starting in the middle of a phone number.
+ */
+ public void testIntermediateParsePositions() throws Exception {
+ String text = "Call 033316005 or 032316005!";
+ // | | | | | |
+ // 0 5 10 15 20 25
+
+ // Iterate over all possible indices.
+ for (int i = 0; i <= 5; i++) {
+ assertEqualRange(text, i, 5, 14);
+ }
+ // 7 and 8 digits in a row are still parsed as number.
+ assertEqualRange(text, 6, 6, 14);
+ assertEqualRange(text, 7, 7, 14);
+ // Anything smaller is skipped to the second instance.
+ for (int i = 8; i <= 19; i++) {
+ assertEqualRange(text, i, 19, 28);
+ }
+ }
+
+ public void testMatchWithSurroundingZipcodes() throws Exception {
+ String number = "415-666-7777";
+ String zipPreceding = "My address is CA 34215 - " + number + " is my number.";
+ PhoneNumber expectedResult = phoneUtil.parse(number, RegionCode.US);
+
+ Iterator<PhoneNumberMatch> iterator =
+ phoneUtil.findNumbers(zipPreceding, RegionCode.US).iterator();
+ PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
+ assertNotNull("Did not find a number in '" + zipPreceding + "'; expected " + number, match);
+ assertEquals(expectedResult, match.number());
+ assertEquals(number, match.rawString());
+
+ // Now repeat, but this time the phone number has spaces in it. It should still be found.
+ number = "(415) 666 7777";
+
+ String zipFollowing = "My number is " + number + ". 34215 is my zip-code.";
+ iterator = phoneUtil.findNumbers(zipFollowing, RegionCode.US).iterator();
+
+ PhoneNumberMatch matchWithSpaces = iterator.hasNext() ? iterator.next() : null;
+ assertNotNull("Did not find a number in '" + zipFollowing + "'; expected " + number,
+ matchWithSpaces);
+ assertEquals(expectedResult, matchWithSpaces.number());
+ assertEquals(number, matchWithSpaces.rawString());
+ }
+
+ public void testIsLatinLetter() throws Exception {
+ assertTrue(PhoneNumberMatcher.isLatinLetter('c'));
+ assertTrue(PhoneNumberMatcher.isLatinLetter('C'));
+ assertTrue(PhoneNumberMatcher.isLatinLetter('\u00C9'));
+ assertTrue(PhoneNumberMatcher.isLatinLetter('\u0301')); // Combining acute accent
+ // Punctuation, digits and white-space are not considered "latin letters".
+ assertFalse(PhoneNumberMatcher.isLatinLetter(':'));
+ assertFalse(PhoneNumberMatcher.isLatinLetter('5'));
+ assertFalse(PhoneNumberMatcher.isLatinLetter('-'));
+ assertFalse(PhoneNumberMatcher.isLatinLetter('.'));
+ assertFalse(PhoneNumberMatcher.isLatinLetter(' '));
+ assertFalse(PhoneNumberMatcher.isLatinLetter('\u6211')); // Chinese character
+ }
+
+ public void testMatchesWithSurroundingLatinChars() throws Exception {
+ ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>();
+ possibleOnlyContexts.add(new NumberContext("abc", "def"));
+ possibleOnlyContexts.add(new NumberContext("abc", ""));
+ possibleOnlyContexts.add(new NumberContext("", "def"));
+ // Latin capital letter e with an acute accent.
+ possibleOnlyContexts.add(new NumberContext("\u00C9", ""));
+ // e with an acute accent decomposed (with combining mark).
+ possibleOnlyContexts.add(new NumberContext("e\u0301", ""));
+
+ // Numbers should not be considered valid, if they are surrounded by Latin characters, but
+ // should be considered possible.
+ findMatchesInContexts(possibleOnlyContexts, false, true);
+ }
+
+ public void testMoneyNotSeenAsPhoneNumber() throws Exception {
+ ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>();
+ possibleOnlyContexts.add(new NumberContext("$", ""));
+ possibleOnlyContexts.add(new NumberContext("", "$"));
+ possibleOnlyContexts.add(new NumberContext("\u00A3", "")); // Pound sign
+ possibleOnlyContexts.add(new NumberContext("\u00A5", "")); // Yen sign
+ findMatchesInContexts(possibleOnlyContexts, false, true);
+ }
+
+ public void testPhoneNumberWithLeadingOrTrailingMoneyMatches() throws Exception {
+ // Because of the space after the 20 (or before the 100) these dollar amounts should not stop
+ // the actual number from being found.
+ ArrayList<NumberContext> contexts = new ArrayList<NumberContext>();
+ contexts.add(new NumberContext("$20 ", ""));
+ contexts.add(new NumberContext("", " 100$"));
+ findMatchesInContexts(contexts, true, true);
+ }
+
+ public void testMatchesWithSurroundingLatinCharsAndLeadingPunctuation() throws Exception {
+ // Contexts with trailing characters. Leading characters are okay here since the numbers we will
+ // insert start with punctuation, but trailing characters are still not allowed.
+ ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>();
+ possibleOnlyContexts.add(new NumberContext("abc", "def"));
+ possibleOnlyContexts.add(new NumberContext("", "def"));
+ possibleOnlyContexts.add(new NumberContext("", "\u00C9"));
+
+ // Numbers should not be considered valid, if they have trailing Latin characters, but should be
+ // considered possible.
+ String numberWithPlus = "+14156667777";
+ String numberWithBrackets = "(415)6667777";
+ findMatchesInContexts(possibleOnlyContexts, false, true, RegionCode.US, numberWithPlus);
+ findMatchesInContexts(possibleOnlyContexts, false, true, RegionCode.US, numberWithBrackets);
+
+ ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>();
+ validContexts.add(new NumberContext("abc", ""));
+ validContexts.add(new NumberContext("\u00C9", ""));
+ validContexts.add(new NumberContext("\u00C9", ".")); // Trailing punctuation.
+ validContexts.add(new NumberContext("\u00C9", " def")); // Trailing white-space.
+
+ // Numbers should be considered valid, since they start with punctuation.
+ findMatchesInContexts(validContexts, true, true, RegionCode.US, numberWithPlus);
+ findMatchesInContexts(validContexts, true, true, RegionCode.US, numberWithBrackets);
+ }
+
+ public void testMatchesWithSurroundingChineseChars() throws Exception {
+ ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>();
+ validContexts.add(new NumberContext("\u6211\u7684\u7535\u8BDD\u53F7\u7801\u662F", ""));
+ validContexts.add(new NumberContext("", "\u662F\u6211\u7684\u7535\u8BDD\u53F7\u7801"));
+ validContexts.add(new NumberContext("\u8BF7\u62E8\u6253", "\u6211\u5728\u660E\u5929"));
+
+ // Numbers should be considered valid, since they are surrounded by Chinese.
+ findMatchesInContexts(validContexts, true, true);
+ }
+
+ public void testMatchesWithSurroundingPunctuation() throws Exception {
+ ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>();
+ validContexts.add(new NumberContext("My number-", "")); // At end of text.
+ validContexts.add(new NumberContext("", ".Nice day.")); // At start of text.
+ validContexts.add(new NumberContext("Tel:", ".")); // Punctuation surrounds number.
+ validContexts.add(new NumberContext("Tel: ", " on Saturdays.")); // White-space is also fine.
+
+ // Numbers should be considered valid, since they are surrounded by punctuation.
+ findMatchesInContexts(validContexts, true, true);
+ }
+
+ public void testMatchesMultiplePhoneNumbersSeparatedByPhoneNumberPunctuation() throws Exception {
+ String text = "Call 650-253-4561 -- 455-234-3451";
+ String region = RegionCode.US;
+
+ PhoneNumber number1 = new PhoneNumber();
+ number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
+ number1.setNationalNumber(6502534561L);
+ PhoneNumberMatch match1 = new PhoneNumberMatch(5, "650-253-4561", number1);
+
+ PhoneNumber number2 = new PhoneNumber();
+ number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
+ number2.setNationalNumber(4552343451L);
+ PhoneNumberMatch match2 = new PhoneNumberMatch(21, "455-234-3451", number2);
+
+ Iterator<PhoneNumberMatch> matches = phoneUtil.findNumbers(text, region).iterator();
+ assertEquals(match1, matches.next());
+ assertEquals(match2, matches.next());
+ }
+
+ public void testDoesNotMatchMultiplePhoneNumbersSeparatedWithNoWhiteSpace() throws Exception {
+ // No white-space found between numbers - neither is found.
+ String text = "Call 650-253-4561--455-234-3451";
+ String region = RegionCode.US;
+
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(text, region)));
+ }
+
+ /**
+ * Strings with number-like things that shouldn't be found under any level.
+ */
+ private static final NumberTest[] IMPOSSIBLE_CASES = {
+ new NumberTest("12345", RegionCode.US),
+ new NumberTest("23456789", RegionCode.US),
+ new NumberTest("234567890112", RegionCode.US),
+ new NumberTest("650+253+1234", RegionCode.US),
+ new NumberTest("3/10/1984", RegionCode.CA),
+ new NumberTest("03/27/2011", RegionCode.US),
+ new NumberTest("31/8/2011", RegionCode.US),
+ new NumberTest("1/12/2011", RegionCode.US),
+ new NumberTest("10/12/82", RegionCode.DE),
+ };
+
+ /**
+ * Strings with number-like things that should only be found under "possible".
+ */
+ private static final NumberTest[] POSSIBLE_ONLY_CASES = {
+ new NumberTest("abc8002345678", RegionCode.US),
+ // US numbers cannot start with 7 in the test metadata to be valid.
+ new NumberTest("7121115678", RegionCode.US),
+ // 'X' should not be found in numbers at leniencies stricter than POSSIBLE, unless it represents
+ // a carrier code or extension.
+ new NumberTest("1650 x 253 - 1234", RegionCode.US),
+ new NumberTest("650 x 253 - 1234", RegionCode.US),
+ new NumberTest("650x2531234", RegionCode.US),
+ new NumberTest("(20) 3346 1234", RegionCode.GB), // Non-optional NP omitted
+ };
+
+ /**
+ * Strings with number-like things that should only be found up to and including the "valid"
+ * leniency level.
+ */
+ private static final NumberTest[] VALID_CASES = {
+ new NumberTest("65 02 53 00 00.", RegionCode.US),
+ new NumberTest("6502 538365", RegionCode.US),
+ new NumberTest("650//253-1234", RegionCode.US), // 2 slashes are illegal at higher levels
+ new NumberTest("650/253/1234", RegionCode.US),
+ new NumberTest("9002309. 158", RegionCode.US),
+ new NumberTest("21 7/8 - 14 12/34 - 5", RegionCode.US),
+ new NumberTest("12.1 - 23.71 - 23.45", RegionCode.US),
+ new NumberTest("1979-2011 100%", RegionCode.US),
+ new NumberTest("800 234 1 111x1111", RegionCode.US),
+ new NumberTest("+494949-4-94", RegionCode.DE), // National number in wrong format
+ new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17\uFF17",
+ RegionCode.US),
+ };
+
+ /**
+ * Strings with number-like things that should only be found up to and including the
+ * "strict_grouping" leniency level.
+ */
+ private static final NumberTest[] STRICT_GROUPING_CASES = {
+ new NumberTest("(415) 6667777", RegionCode.US),
+ new NumberTest("415-6667777", RegionCode.US),
+ // Should be found by strict grouping but not exact grouping, as the last two groups are
+ // formatted together as a block.
+ new NumberTest("0800-2491234", RegionCode.DE),
+ };
+
+ /**
+ * Strings with number-like things that should found at all levels.
+ */
+ private static final NumberTest[] EXACT_GROUPING_CASES = {
+ new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF17\uFF17\uFF17\uFF17", RegionCode.US),
+ new NumberTest("\uFF14\uFF11\uFF15-\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17\uFF17", RegionCode.US),
+ new NumberTest("4156667777", RegionCode.US),
+ new NumberTest("4156667777 x 123", RegionCode.US),
+ new NumberTest("415-666-7777", RegionCode.US),
+ new NumberTest("415/666-7777", RegionCode.US),
+ new NumberTest("415-666-7777 ext. 503", RegionCode.US),
+ new NumberTest("1 415 666 7777 x 123", RegionCode.US),
+ new NumberTest("+1 415-666-7777", RegionCode.US),
+ new NumberTest("+494949 49", RegionCode.DE),
+ new NumberTest("+49-49-34", RegionCode.DE),
+ new NumberTest("+49-4931-49", RegionCode.DE),
+ new NumberTest("04931-49", RegionCode.DE), // With National Prefix
+ new NumberTest("+49-494949", RegionCode.DE), // One group with country code
+ new NumberTest("+49-494949 ext. 49", RegionCode.DE),
+ new NumberTest("+49494949 ext. 49", RegionCode.DE),
+ new NumberTest("0494949", RegionCode.DE),
+ new NumberTest("0494949 ext. 49", RegionCode.DE),
+ new NumberTest("01 (33) 3461 2234", RegionCode.MX), // Optional NP present
+ new NumberTest("(33) 3461 2234", RegionCode.MX), // Optional NP omitted
+ };
+
+ public void testMatchesWithStrictGroupingLeniency() throws Exception {
+ List<NumberTest> testCases = new ArrayList<NumberTest>();
+ testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));
+ testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES));
+ doTestNumberMatchesForLeniency(testCases, Leniency.STRICT_GROUPING);
+ }
+
+ public void testNonMatchesWithStrictGroupLeniency() throws Exception {
+ List<NumberTest> testCases = new ArrayList<NumberTest>();
+ testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES));
+ testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES));
+ testCases.addAll(Arrays.asList(VALID_CASES));
+ doTestNumberNonMatchesForLeniency(testCases, Leniency.STRICT_GROUPING);
+ }
+
+ public void testMatchesWithExactGroupingLeniency() throws Exception {
+ List<NumberTest> testCases = new ArrayList<NumberTest>();
+ testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES));
+ doTestNumberMatchesForLeniency(testCases, Leniency.EXACT_GROUPING);
+ }
+
+ public void testNonMatchesExactGroupLeniency() throws Exception {
+ List<NumberTest> testCases = new ArrayList<NumberTest>();
+ testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES));
+ testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES));
+ testCases.addAll(Arrays.asList(VALID_CASES));
+ testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));
+ doTestNumberNonMatchesForLeniency(testCases, Leniency.EXACT_GROUPING);
+ }
+
+ private void doTestNumberMatchesForLeniency(List<NumberTest> testCases,
+ PhoneNumberUtil.Leniency leniency) {
+ int noMatchFoundCount = 0;
+ int wrongMatchFoundCount = 0;
+ for (NumberTest test : testCases) {
+ Iterator<PhoneNumberMatch> iterator =
+ findNumbersForLeniency(test.rawString, test.region, leniency);
+ PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
+ if (match == null) {
+ noMatchFoundCount++;
+ System.err.println("No match found in " + test.toString() + " for leniency: " + leniency);
+ } else {
+ if (!test.rawString.equals(match.rawString())) {
+ wrongMatchFoundCount++;
+ System.err.println("Found wrong match in test " + test.toString() +
+ ". Found " + match.rawString());
+ }
+ }
+ }
+ assertEquals(0, noMatchFoundCount);
+ assertEquals(0, wrongMatchFoundCount);
+ }
+
+ private void doTestNumberNonMatchesForLeniency(List<NumberTest> testCases,
+ PhoneNumberUtil.Leniency leniency) {
+ int matchFoundCount = 0;
+ for (NumberTest test : testCases) {
+ Iterator<PhoneNumberMatch> iterator =
+ findNumbersForLeniency(test.rawString, test.region, leniency);
+ PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
+ if (match != null) {
+ matchFoundCount++;
+ System.err.println("Match found in " + test.toString() + " for leniency: " + leniency);
+ }
+ }
+ assertEquals(0, matchFoundCount);
+ }
+
+ /**
+ * Helper method which tests the contexts provided and ensures that:
+ * -- if isValid is true, they all find a test number inserted in the middle when leniency of
+ * matching is set to VALID; else no test number should be extracted at that leniency level
+ * -- if isPossible is true, they all find a test number inserted in the middle when leniency of
+ * matching is set to POSSIBLE; else no test number should be extracted at that leniency level
+ */
+ private void findMatchesInContexts(List<NumberContext> contexts, boolean isValid,
+ boolean isPossible, String region, String number) {
+ if (isValid) {
+ doTestInContext(number, region, contexts, Leniency.VALID);
+ } else {
+ for (NumberContext context : contexts) {
+ String text = context.leadingText + number + context.trailingText;
+ assertTrue("Should not have found a number in " + text,
+ hasNoMatches(phoneUtil.findNumbers(text, region)));
+ }
+ }
+ if (isPossible) {
+ doTestInContext(number, region, contexts, Leniency.POSSIBLE);
+ } else {
+ for (NumberContext context : contexts) {
+ String text = context.leadingText + number + context.trailingText;
+ assertTrue("Should not have found a number in " + text,
+ hasNoMatches(phoneUtil.findNumbers(text, region, Leniency.POSSIBLE,
+ Long.MAX_VALUE)));
+ }
+ }
+ }
+
+ /**
+ * Variant of findMatchesInContexts that uses a default number and region.
+ */
+ private void findMatchesInContexts(List<NumberContext> contexts, boolean isValid,
+ boolean isPossible) {
+ String region = RegionCode.US;
+ String number = "415-666-7777";
+
+ findMatchesInContexts(contexts, isValid, isPossible, region, number);
+ }
+
+ public void testNonMatchingBracketsAreInvalid() throws Exception {
+ // The digits up to the ", " form a valid US number, but it shouldn't be matched as one since
+ // there was a non-matching bracket present.
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "80.585 [79.964, 81.191]", RegionCode.US)));
+
+ // The trailing "]" is thrown away before parsing, so the resultant number, while a valid US
+ // number, does not have matching brackets.
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "80.585 [79.964]", RegionCode.US)));
+
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "80.585 ((79.964)", RegionCode.US)));
+
+ // This case has too many sets of brackets to be valid.
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "(80).(585) (79).(9)64", RegionCode.US)));
+ }
+
+ public void testNoMatchIfRegionIsNull() throws Exception {
+ // Fail on non-international prefix if region code is null.
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "Random text body - number is 0331 6005, see you there", null)));
+ }
+
+ public void testNoMatchInEmptyString() throws Exception {
+ assertTrue(hasNoMatches(phoneUtil.findNumbers("", RegionCode.US)));
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(" ", RegionCode.US)));
+ }
+
+ public void testNoMatchIfNoNumber() throws Exception {
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(
+ "Random text body - number is foobar, see you there", RegionCode.US)));
+ }
+
+ public void testSequences() throws Exception {
+ // Test multiple occurrences.
+ String text = "Call 033316005 or 032316005!";
+ String region = RegionCode.NZ;
+
+ PhoneNumber number1 = new PhoneNumber();
+ number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
+ number1.setNationalNumber(33316005);
+ PhoneNumberMatch match1 = new PhoneNumberMatch(5, "033316005", number1);
+
+ PhoneNumber number2 = new PhoneNumber();
+ number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
+ number2.setNationalNumber(32316005);
+ PhoneNumberMatch match2 = new PhoneNumberMatch(19, "032316005", number2);
+
+ Iterator<PhoneNumberMatch> matches =
+ phoneUtil.findNumbers(text, region, Leniency.POSSIBLE, Long.MAX_VALUE).iterator();
+
+ assertEquals(match1, matches.next());
+ assertEquals(match2, matches.next());
+ }
+
+ public void testNullInput() throws Exception {
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(null, RegionCode.US)));
+ assertTrue(hasNoMatches(phoneUtil.findNumbers(null, null)));
+ }
+
+ public void testMaxMatches() throws Exception {
+ // Set up text with 100 valid phone numbers.
+ StringBuilder numbers = new StringBuilder();
+ for (int i = 0; i < 100; i++) {
+ numbers.append("My info: 415-666-7777,");
+ }
+
+ // Matches all 100. Max only applies to failed cases.
+ List<PhoneNumber> expected = new ArrayList<PhoneNumber>(100);
+ PhoneNumber number = phoneUtil.parse("+14156667777", null);
+ for (int i = 0; i < 100; i++) {
+ expected.add(number);
+ }
+
+ Iterable<PhoneNumberMatch> iterable =
+ phoneUtil.findNumbers(numbers.toString(), RegionCode.US, Leniency.VALID, 10);
+ List<PhoneNumber> actual = new ArrayList<PhoneNumber>(100);
+ for (PhoneNumberMatch match : iterable) {
+ actual.add(match.number());
+ }
+ assertEquals(expected, actual);
+ }
+
+ public void testMaxMatchesInvalid() throws Exception {
+ // Set up text with 10 invalid phone numbers followed by 100 valid.
+ StringBuilder numbers = new StringBuilder();
+ for (int i = 0; i < 10; i++) {
+ numbers.append("My address 949-8945-0");
+ }
+ for (int i = 0; i < 100; i++) {
+ numbers.append("My info: 415-666-7777,");
+ }
+
+ Iterable<PhoneNumberMatch> iterable =
+ phoneUtil.findNumbers(numbers.toString(), RegionCode.US, Leniency.VALID, 10);
+ assertFalse(iterable.iterator().hasNext());
+ }
+
+ public void testMaxMatchesMixed() throws Exception {
+ // Set up text with 100 valid numbers inside an invalid number.
+ StringBuilder numbers = new StringBuilder();
+ for (int i = 0; i < 100; i++) {
+ numbers.append("My info: 415-666-7777 123 fake street");
+ }
+
+ // Only matches the first 10 despite there being 100 numbers due to max matches.
+ List<PhoneNumber> expected = new ArrayList<PhoneNumber>(100);
+ PhoneNumber number = phoneUtil.parse("+14156667777", null);
+ for (int i = 0; i < 10; i++) {
+ expected.add(number);
+ }
+
+ Iterable<PhoneNumberMatch> iterable =
+ phoneUtil.findNumbers(numbers.toString(), RegionCode.US, Leniency.VALID, 10);
+ List<PhoneNumber> actual = new ArrayList<PhoneNumber>(100);
+ for (PhoneNumberMatch match : iterable) {
+ actual.add(match.number());
+ }
+ assertEquals(expected, actual);
+ }
+
+ public void testEmptyIteration() throws Exception {
+ Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("", RegionCode.ZZ);
+ Iterator<PhoneNumberMatch> iterator = iterable.iterator();
+
+ assertFalse(iterator.hasNext());
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ assertFalse(iterator.hasNext());
+ }
+
+ public void testSingleIteration() throws Exception {
+ Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("+14156667777", RegionCode.ZZ);
+
+ // With hasNext() -> next().
+ Iterator<PhoneNumberMatch> iterator = iterable.iterator();
+ // Double hasNext() to ensure it does not advance.
+ assertTrue(iterator.hasNext());
+ assertTrue(iterator.hasNext());
+ assertNotNull(iterator.next());
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ assertFalse(iterator.hasNext());
+
+ // With next() only.
+ iterator = iterable.iterator();
+ assertNotNull(iterator.next());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ }
+
+ public void testDoubleIteration() throws Exception {
+ Iterable<PhoneNumberMatch> iterable =
+ phoneUtil.findNumbers("+14156667777 foobar +14156667777 ", RegionCode.ZZ);
+
+ // With hasNext() -> next().
+ Iterator<PhoneNumberMatch> iterator = iterable.iterator();
+ // Double hasNext() to ensure it does not advance.
+ assertTrue(iterator.hasNext());
+ assertTrue(iterator.hasNext());
+ assertNotNull(iterator.next());
+ assertTrue(iterator.hasNext());
+ assertTrue(iterator.hasNext());
+ assertNotNull(iterator.next());
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ assertFalse(iterator.hasNext());
+
+ // With next() only.
+ iterator = iterable.iterator();
+ assertNotNull(iterator.next());
+ assertNotNull(iterator.next());
+ try {
+ iterator.next();
+ fail("Violation of the Iterator contract.");
+ } catch (NoSuchElementException e) { /* Success */ }
+ }
+
+ /**
+ * Ensures that {@link Iterator#remove()} is not supported and that calling it does not
+ * change iteration behavior.
+ */
+ public void testRemovalNotSupported() throws Exception {
+ Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("+14156667777", RegionCode.ZZ);
+
+ Iterator<PhoneNumberMatch> iterator = iterable.iterator();
+ try {
+ iterator.remove();
+ fail("Iterator must not support remove.");
+ } catch (UnsupportedOperationException e) { /* success */ }
+
+ assertTrue(iterator.hasNext());
+
+ try {
+ iterator.remove();
+ fail("Iterator must not support remove.");
+ } catch (UnsupportedOperationException e) { /* success */ }
+
+ assertNotNull(iterator.next());
+
+ try {
+ iterator.remove();
+ fail("Iterator must not support remove.");
+ } catch (UnsupportedOperationException e) { /* success */ }
+
+ assertFalse(iterator.hasNext());
+ }
+
+ /**
+ * Asserts that another number can be found in {@code text} starting at {@code index}, and that
+ * its corresponding range is {@code [start, end)}.
+ */
+ private void assertEqualRange(CharSequence text, int index, int start, int end) {
+ CharSequence sub = text.subSequence(index, text.length());
+ Iterator<PhoneNumberMatch> matches =
+ phoneUtil.findNumbers(sub, RegionCode.NZ, Leniency.POSSIBLE, Long.MAX_VALUE).iterator();
+ assertTrue(matches.hasNext());
+ PhoneNumberMatch match = matches.next();
+ assertEquals(start - index, match.start());
+ assertEquals(end - index, match.end());
+ assertEquals(sub.subSequence(match.start(), match.end()).toString(), match.rawString());
+ }
+
+ /**
+ * Tests numbers found by {@link PhoneNumberUtil#findNumbers(CharSequence, String)} in various
+ * textual contexts.
+ *
+ * @param number the number to test and the corresponding region code to use
+ */
+ private void doTestFindInContext(String number, String defaultCountry) throws Exception {
+ findPossibleInContext(number, defaultCountry);
+
+ PhoneNumber parsed = phoneUtil.parse(number, defaultCountry);
+ if (phoneUtil.isValidNumber(parsed)) {
+ findValidInContext(number, defaultCountry);
+ }
+ }
+
+ /**
+ * Tests valid numbers in contexts that should pass for {@link Leniency#POSSIBLE}.
+ */
+ private void findPossibleInContext(String number, String defaultCountry) {
+ ArrayList<NumberContext> contextPairs = new ArrayList<NumberContext>();
+ contextPairs.add(new NumberContext("", "")); // no context
+ contextPairs.add(new NumberContext(" ", "\t")); // whitespace only
+ contextPairs.add(new NumberContext("Hello ", "")); // no context at end
+ contextPairs.add(new NumberContext("", " to call me!")); // no context at start
+ contextPairs.add(new NumberContext("Hi there, call ", " to reach me!")); // no context at start
+ contextPairs.add(new NumberContext("Hi there, call ", ", or don't")); // with commas
+ // Three examples without whitespace around the number.
+ contextPairs.add(new NumberContext("Hi call", ""));
+ contextPairs.add(new NumberContext("", "forme"));
+ contextPairs.add(new NumberContext("Hi call", "forme"));
+ // With other small numbers.
+ contextPairs.add(new NumberContext("It's cheap! Call ", " before 6:30"));
+ // With a second number later.
+ contextPairs.add(new NumberContext("Call ", " or +1800-123-4567!"));
+ contextPairs.add(new NumberContext("Call me on June 21 at", "")); // with a Month-Day date
+ // With publication pages.
+ contextPairs.add(new NumberContext(
+ "As quoted by Alfonso 12-15 (2009), you may call me at ", ""));
+ contextPairs.add(new NumberContext(
+ "As quoted by Alfonso et al. 12-15 (2009), you may call me at ", ""));
+ // With dates, written in the American style.
+ contextPairs.add(new NumberContext(
+ "As I said on 03/10/2011, you may call me at ", ""));
+ // With trailing numbers after a comma. The 45 should not be considered an extension.
+ contextPairs.add(new NumberContext("", ", 45 days a year"));
+ // With a postfix stripped off as it looks like the start of another number.
+ contextPairs.add(new NumberContext("Call ", "/x12 more"));
+
+ doTestInContext(number, defaultCountry, contextPairs, Leniency.POSSIBLE);
+ }
+
+ /**
+ * Tests valid numbers in contexts that fail for {@link Leniency#POSSIBLE} but are valid for
+ * {@link Leniency#VALID}.
+ */
+ private void findValidInContext(String number, String defaultCountry) {
+ ArrayList<NumberContext> contextPairs = new ArrayList<NumberContext>();
+ // With other small numbers.
+ contextPairs.add(new NumberContext("It's only 9.99! Call ", " to buy"));
+ // With a number Day.Month.Year date.
+ contextPairs.add(new NumberContext("Call me on 21.6.1984 at ", ""));
+ // With a number Month/Day date.
+ contextPairs.add(new NumberContext("Call me on 06/21 at ", ""));
+ // With a number Day.Month date.
+ contextPairs.add(new NumberContext("Call me on 21.6. at ", ""));
+ // With a number Month/Day/Year date.
+ contextPairs.add(new NumberContext("Call me on 06/21/84 at ", ""));
+
+ doTestInContext(number, defaultCountry, contextPairs, Leniency.VALID);
+ }
+
+ private void doTestInContext(String number, String defaultCountry,
+ List<NumberContext> contextPairs, Leniency leniency) {
+ for (NumberContext context : contextPairs) {
+ String prefix = context.leadingText;
+ String text = prefix + number + context.trailingText;
+
+ int start = prefix.length();
+ int end = start + number.length();
+ Iterator<PhoneNumberMatch> iterator =
+ phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE).iterator();
+
+ PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
+ assertNotNull("Did not find a number in '" + text + "'; expected '" + number + "'", match);
+
+ CharSequence extracted = text.subSequence(match.start(), match.end());
+ assertTrue("Unexpected phone region in '" + text + "'; extracted '" + extracted + "'",
+ start == match.start() && end == match.end());
+ assertTrue(number.contentEquals(extracted));
+ assertTrue(match.rawString().contentEquals(extracted));
+
+ ensureTermination(text, defaultCountry, leniency);
+ }
+ }
+
+ /**
+ * Exhaustively searches for phone numbers from each index within {@code text} to test that
+ * finding matches always terminates.
+ */
+ private void ensureTermination(String text, String defaultCountry, Leniency leniency) {
+ for (int index = 0; index <= text.length(); index++) {
+ String sub = text.substring(index);
+ StringBuilder matches = new StringBuilder();
+ // Iterates over all matches.
+ for (PhoneNumberMatch match :
+ phoneUtil.findNumbers(sub, defaultCountry, leniency, Long.MAX_VALUE)) {
+ matches.append(", ").append(match.toString());
+ }
+ }
+ }
+
+ private Iterator<PhoneNumberMatch> findNumbersForLeniency(
+ String text, String defaultCountry, PhoneNumberUtil.Leniency leniency) {
+ return phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE).iterator();
+ }
+
+ private boolean hasNoMatches(Iterable<PhoneNumberMatch> iterable) {
+ return !iterable.iterator().hasNext();
+ }
+
+ /**
+ * Small class that holds the context of the number we are testing against. The test will
+ * insert the phone number to be found between leadingText and trailingText.
+ */
+ private static class NumberContext {
+ final String leadingText;
+ final String trailingText;
+
+ NumberContext(String leadingText, String trailingText) {
+ this.leadingText = leadingText;
+ this.trailingText = trailingText;
+ }
+ }
+
+ /**
+ * Small class that holds the number we want to test and the region for which it should be valid.
+ */
+ private static class NumberTest {
+ final String rawString;
+ final String region;
+
+ NumberTest(String rawString, String regionCode) {
+ this.rawString = rawString;
+ this.region = regionCode;
+ }
+
+ @Override
+ public String toString() {
+ return rawString + " (" + region.toString() + ")";
+ }
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
new file mode 100644
index 0000000..e7038c6
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
@@ -0,0 +1,1968 @@
+/*
+ * 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.PhoneNumberUtil.PhoneNumberFormat;
+import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit tests for PhoneNumberUtil.java
+ *
+ * Note that these tests use the metadata contained in the files with TEST_META_DATA_FILE_PREFIX,
+ * not the normal metadata files, so should not be used for regression test purposes - these tests
+ * are illustrative only and test functionality.
+ *
+ * @author Shaopeng Jia
+ * @author Lara Rennie
+ */
+public class PhoneNumberUtilTest extends TestCase {
+ private PhoneNumberUtil phoneUtil;
+ // This is used by BuildMetadataProtoFromXml.
+ static final String TEST_META_DATA_FILE_PREFIX =
+ "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting";
+
+ // Set up some test numbers to re-use.
+ private static final PhoneNumber ALPHA_NUMERIC_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(80074935247L);
+ private static final PhoneNumber AR_MOBILE =
+ new PhoneNumber().setCountryCode(54).setNationalNumber(91187654321L);
+ private static final PhoneNumber AR_NUMBER =
+ new PhoneNumber().setCountryCode(54).setNationalNumber(1187654321);
+ private static final PhoneNumber AU_NUMBER =
+ new PhoneNumber().setCountryCode(61).setNationalNumber(236618300L);
+ private static final PhoneNumber BS_MOBILE =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2423570000L);
+ private static final PhoneNumber BS_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L);
+ // Note that this is the same as the example number for DE in the metadata.
+ private static final PhoneNumber DE_NUMBER =
+ new PhoneNumber().setCountryCode(49).setNationalNumber(30123456L);
+ private static final PhoneNumber DE_SHORT_NUMBER =
+ new PhoneNumber().setCountryCode(49).setNationalNumber(1234L);
+ private static final PhoneNumber GB_MOBILE =
+ new PhoneNumber().setCountryCode(44).setNationalNumber(7912345678L);
+ private static final PhoneNumber GB_NUMBER =
+ new PhoneNumber().setCountryCode(44).setNationalNumber(2070313000L);
+ private static final PhoneNumber IT_MOBILE =
+ new PhoneNumber().setCountryCode(39).setNationalNumber(345678901L);
+ private static final PhoneNumber IT_NUMBER =
+ new PhoneNumber().setCountryCode(39).setNationalNumber(236618300L).
+ setItalianLeadingZero(true);
+ // Numbers to test the formatting rules from Mexico.
+ private static final PhoneNumber MX_MOBILE1 =
+ new PhoneNumber().setCountryCode(52).setNationalNumber(12345678900L);
+ private static final PhoneNumber MX_MOBILE2 =
+ new PhoneNumber().setCountryCode(52).setNationalNumber(15512345678L);
+ private static final PhoneNumber MX_NUMBER1 =
+ new PhoneNumber().setCountryCode(52).setNationalNumber(3312345678L);
+ private static final PhoneNumber MX_NUMBER2 =
+ new PhoneNumber().setCountryCode(52).setNationalNumber(8211234567L);
+ private static final PhoneNumber NZ_NUMBER =
+ new PhoneNumber().setCountryCode(64).setNationalNumber(33316005L);
+ private static final PhoneNumber SG_NUMBER =
+ new PhoneNumber().setCountryCode(65).setNationalNumber(65218000L);
+ // A too-long and hence invalid US number.
+ private static final PhoneNumber US_LONG_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(65025300001L);
+ private static final PhoneNumber US_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
+ private static final PhoneNumber US_PREMIUM =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(9002530000L);
+ // Too short, but still possible US numbers.
+ private static final PhoneNumber US_LOCAL_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2530000L);
+ private static final PhoneNumber US_SHORT_BY_ONE_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(650253000L);
+ private static final PhoneNumber US_TOLLFREE =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(8002530000L);
+ private static final PhoneNumber US_SPOOF =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(0L);
+ private static final PhoneNumber US_SPOOF_WITH_RAW_INPUT =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(0L)
+ .setRawInput("000-000-0000");
+
+ public PhoneNumberUtilTest() {
+ phoneUtil = initializePhoneUtilForTesting();
+ }
+
+ static PhoneNumberUtil initializePhoneUtilForTesting() {
+ PhoneNumberUtil.resetInstance();
+ return PhoneNumberUtil.getInstance(
+ TEST_META_DATA_FILE_PREFIX,
+ CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
+ }
+
+ public void testGetSupportedRegions() {
+ assertTrue(phoneUtil.getSupportedRegions().size() > 0);
+ }
+
+ public void testGetInstanceLoadUSMetadata() {
+ PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
+ assertEquals(RegionCode.US, metadata.getId());
+ assertEquals(1, metadata.getCountryCode());
+ assertEquals("011", metadata.getInternationalPrefix());
+ assertTrue(metadata.hasNationalPrefix());
+ assertEquals(2, metadata.numberFormatSize());
+ assertEquals("(\\d{3})(\\d{3})(\\d{4})",
+ metadata.getNumberFormat(1).getPattern());
+ assertEquals("$1 $2 $3", metadata.getNumberFormat(1).getFormat());
+ assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}",
+ metadata.getGeneralDesc().getNationalNumberPattern());
+ assertEquals("\\d{7}(?:\\d{3})?", metadata.getGeneralDesc().getPossibleNumberPattern());
+ assertTrue(metadata.getGeneralDesc().exactlySameAs(metadata.getFixedLine()));
+ assertEquals("\\d{10}", metadata.getTollFree().getPossibleNumberPattern());
+ assertEquals("900\\d{7}", metadata.getPremiumRate().getNationalNumberPattern());
+ // No shared-cost data is available, so it should be initialised to "NA".
+ assertEquals("NA", metadata.getSharedCost().getNationalNumberPattern());
+ assertEquals("NA", metadata.getSharedCost().getPossibleNumberPattern());
+ }
+
+ public void testGetInstanceLoadDEMetadata() {
+ PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.DE);
+ assertEquals(RegionCode.DE, metadata.getId());
+ assertEquals(49, metadata.getCountryCode());
+ assertEquals("00", metadata.getInternationalPrefix());
+ assertEquals("0", metadata.getNationalPrefix());
+ assertEquals(6, metadata.numberFormatSize());
+ assertEquals(1, metadata.getNumberFormat(5).leadingDigitsPatternSize());
+ assertEquals("900", metadata.getNumberFormat(5).getLeadingDigitsPattern(0));
+ assertEquals("(\\d{3})(\\d{3,4})(\\d{4})",
+ metadata.getNumberFormat(5).getPattern());
+ assertEquals("$1 $2 $3", metadata.getNumberFormat(5).getFormat());
+ assertEquals("(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:[1-9]\\d|0[2-9]))\\d{1,8}",
+ metadata.getFixedLine().getNationalNumberPattern());
+ assertEquals("\\d{2,14}", metadata.getFixedLine().getPossibleNumberPattern());
+ assertEquals("30123456", metadata.getFixedLine().getExampleNumber());
+ assertEquals("\\d{10}", metadata.getTollFree().getPossibleNumberPattern());
+ assertEquals("900([135]\\d{6}|9\\d{7})", metadata.getPremiumRate().getNationalNumberPattern());
+ }
+
+ public void testGetInstanceLoadARMetadata() {
+ PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.AR);
+ assertEquals(RegionCode.AR, metadata.getId());
+ assertEquals(54, metadata.getCountryCode());
+ assertEquals("00", metadata.getInternationalPrefix());
+ assertEquals("0", metadata.getNationalPrefix());
+ assertEquals("0(?:(11|343|3715)15)?", metadata.getNationalPrefixForParsing());
+ assertEquals("9$1", metadata.getNationalPrefixTransformRule());
+ assertEquals("$2 15 $3-$4", metadata.getNumberFormat(2).getFormat());
+ assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})",
+ metadata.getNumberFormat(3).getPattern());
+ assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})",
+ metadata.getIntlNumberFormat(3).getPattern());
+ assertEquals("$1 $2 $3 $4", metadata.getIntlNumberFormat(3).getFormat());
+ }
+
+ public void testIsLeadingZeroPossible() {
+ assertTrue(phoneUtil.isLeadingZeroPossible(39)); // Italy
+ assertFalse(phoneUtil.isLeadingZeroPossible(1)); // USA
+ assertFalse(phoneUtil.isLeadingZeroPossible(800)); // Not in metadata file, just default to
+ // false.
+ }
+
+ public void testGetLengthOfGeographicalAreaCode() {
+ // Google MTV, which has area code "650".
+ assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(US_NUMBER));
+
+ // A North America toll-free number, which has no area code.
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_TOLLFREE));
+
+ // Google London, which has area code "20".
+ assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(GB_NUMBER));
+
+ // A UK mobile phone, which has no area code.
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(GB_MOBILE));
+
+ // Google Buenos Aires, which has area code "11".
+ assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(AR_NUMBER));
+
+ // Google Sydney, which has area code "2".
+ assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(AU_NUMBER));
+
+ // Google Singapore. Singapore has no area code and no national prefix.
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(SG_NUMBER));
+
+ // An invalid US number (1 digit shorter), which has no area code.
+ assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_SHORT_BY_ONE_NUMBER));
+ }
+
+ public void testGetLengthOfNationalDestinationCode() {
+ // Google MTV, which has national destination code (NDC) "650".
+ assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_NUMBER));
+
+ // A North America toll-free number, which has NDC "800".
+ assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_TOLLFREE));
+
+ // Google London, which has NDC "20".
+ assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(GB_NUMBER));
+
+ // A UK mobile phone, which has NDC "7912".
+ assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(GB_MOBILE));
+
+ // Google Buenos Aires, which has NDC "11".
+ assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(AR_NUMBER));
+
+ // An Argentinian mobile which has NDC "911".
+ assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(AR_MOBILE));
+
+ // Google Sydney, which has NDC "2".
+ assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(AU_NUMBER));
+
+ // Google Singapore, which has NDC "6521".
+ assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(SG_NUMBER));
+
+ // An invalid US number (1 digit shorter), which has no NDC.
+ assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(US_SHORT_BY_ONE_NUMBER));
+
+ // A number containing an invalid country calling code, which shouldn't have any NDC.
+ PhoneNumber number = new PhoneNumber().setCountryCode(123).setNationalNumber(6502530000L);
+ assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
+ }
+
+ public void testGetNationalSignificantNumber() {
+ assertEquals("6502530000", phoneUtil.getNationalSignificantNumber(US_NUMBER));
+
+ // An Italian mobile number.
+ assertEquals("345678901", phoneUtil.getNationalSignificantNumber(IT_MOBILE));
+
+ // An Italian fixed line number.
+ assertEquals("0236618300", phoneUtil.getNationalSignificantNumber(IT_NUMBER));
+ }
+
+ public void testGetExampleNumber() {
+ assertEquals(DE_NUMBER, phoneUtil.getExampleNumber(RegionCode.DE));
+
+ assertEquals(DE_NUMBER,
+ phoneUtil.getExampleNumberForType(RegionCode.DE,
+ PhoneNumberUtil.PhoneNumberType.FIXED_LINE));
+ assertEquals(null,
+ phoneUtil.getExampleNumberForType(RegionCode.DE,
+ PhoneNumberUtil.PhoneNumberType.MOBILE));
+ // For the US, the example number is placed under general description, and hence should be used
+ // for both fixed line and mobile, so neither of these should return null.
+ assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US,
+ PhoneNumberUtil.PhoneNumberType.FIXED_LINE));
+ assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US,
+ PhoneNumberUtil.PhoneNumberType.MOBILE));
+ // CS is an invalid region, so we have no data for it.
+ assertNull(phoneUtil.getExampleNumberForType(RegionCode.CS,
+ PhoneNumberUtil.PhoneNumberType.MOBILE));
+ }
+
+ public void testConvertAlphaCharactersInNumber() {
+ String input = "1800-ABC-DEF";
+ // Alpha chars are converted to digits; everything else is left untouched.
+ String expectedOutput = "1800-222-333";
+ assertEquals(expectedOutput, PhoneNumberUtil.convertAlphaCharactersInNumber(input));
+ }
+
+ public void testNormaliseRemovePunctuation() {
+ String inputNumber = "034-56&+#234";
+ String expectedOutput = "03456234";
+ assertEquals("Conversion did not correctly remove punctuation",
+ expectedOutput,
+ PhoneNumberUtil.normalize(inputNumber));
+ }
+
+ public void testNormaliseReplaceAlphaCharacters() {
+ String inputNumber = "034-I-am-HUNGRY";
+ String expectedOutput = "034426486479";
+ assertEquals("Conversion did not correctly replace alpha characters",
+ expectedOutput,
+ PhoneNumberUtil.normalize(inputNumber));
+ }
+
+ public void testNormaliseOtherDigits() {
+ String inputNumber = "\uFF125\u0665";
+ String expectedOutput = "255";
+ assertEquals("Conversion did not correctly replace non-latin digits",
+ expectedOutput,
+ PhoneNumberUtil.normalize(inputNumber));
+ // Eastern-Arabic digits.
+ inputNumber = "\u06F52\u06F0";
+ expectedOutput = "520";
+ assertEquals("Conversion did not correctly replace non-latin digits",
+ expectedOutput,
+ PhoneNumberUtil.normalize(inputNumber));
+ }
+
+ public void testNormaliseStripAlphaCharacters() {
+ String inputNumber = "034-56&+a#234";
+ String expectedOutput = "03456234";
+ assertEquals("Conversion did not correctly remove alpha character",
+ expectedOutput,
+ PhoneNumberUtil.normalizeDigitsOnly(inputNumber));
+ }
+
+ public void testFormatUSNumber() {
+ assertEquals("650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+
+ assertEquals("800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.INTERNATIONAL));
+
+ assertEquals("900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+1-900-253-0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.RFC3966));
+ // Numbers with all zeros in the national number part will be formatted by using the raw_input
+ // if that is available no matter which format is specified.
+ assertEquals("000-000-0000",
+ phoneUtil.format(US_SPOOF_WITH_RAW_INPUT, PhoneNumberFormat.NATIONAL));
+ assertEquals("0", phoneUtil.format(US_SPOOF, PhoneNumberFormat.NATIONAL));
+ }
+
+ public void testFormatBSNumber() {
+ assertEquals("242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+1 242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ }
+
+ public void testFormatGBNumber() {
+ assertEquals("(020) 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+44 20 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+
+ assertEquals("(07912) 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+44 7912 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.INTERNATIONAL));
+ }
+
+ public void testFormatDENumber() {
+ PhoneNumber deNumber = new PhoneNumber();
+ deNumber.setCountryCode(49).setNationalNumber(301234L);
+ assertEquals("030/1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 30/1234", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+49-30-1234", phoneUtil.format(deNumber, PhoneNumberFormat.RFC3966));
+
+ deNumber.clear();
+ deNumber.setCountryCode(49).setNationalNumber(291123L);
+ assertEquals("0291 123", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 291 123", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+
+ deNumber.clear();
+ deNumber.setCountryCode(49).setNationalNumber(29112345678L);
+ assertEquals("0291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+
+ deNumber.clear();
+ deNumber.setCountryCode(49).setNationalNumber(912312345L);
+ assertEquals("09123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 9123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+ deNumber.clear();
+ deNumber.setCountryCode(49).setNationalNumber(80212345L);
+ assertEquals("08021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 8021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
+ // Note this number is correctly formatted without national prefix. Most of the numbers that
+ // are treated as invalid numbers by the library are short numbers, and they are usually not
+ // dialed with national prefix.
+ assertEquals("1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+49 1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+
+ deNumber.clear();
+ deNumber.setCountryCode(49).setNationalNumber(41341234);
+ assertEquals("04134 1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
+ }
+
+ public void testFormatITNumber() {
+ assertEquals("02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+39 02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+390236618300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.E164));
+
+ assertEquals("345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+39 345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+39345678901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.E164));
+ }
+
+ public void testFormatAUNumber() {
+ assertEquals("02 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+61 2 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+61236618300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.E164));
+
+ PhoneNumber auNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(1800123456L);
+ assertEquals("1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("+61 1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+611800123456", phoneUtil.format(auNumber, PhoneNumberFormat.E164));
+ }
+
+ public void testFormatARNumber() {
+ assertEquals("011 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.NATIONAL));
+ assertEquals("+54 11 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+541187654321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.E164));
+
+ assertEquals("011 15 8765-4321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.NATIONAL));
+ assertEquals("+54 9 11 8765 4321", phoneUtil.format(AR_MOBILE,
+ PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+5491187654321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.E164));
+ }
+
+ public void testFormatMXNumber() {
+ assertEquals("045 234 567 8900", phoneUtil.format(MX_MOBILE1, PhoneNumberFormat.NATIONAL));
+ assertEquals("+52 1 234 567 8900", phoneUtil.format(
+ MX_MOBILE1, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+5212345678900", phoneUtil.format(MX_MOBILE1, PhoneNumberFormat.E164));
+
+ assertEquals("045 55 1234 5678", phoneUtil.format(MX_MOBILE2, PhoneNumberFormat.NATIONAL));
+ assertEquals("+52 1 55 1234 5678", phoneUtil.format(
+ MX_MOBILE2, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+5215512345678", phoneUtil.format(MX_MOBILE2, PhoneNumberFormat.E164));
+
+ assertEquals("01 33 1234 5678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.NATIONAL));
+ assertEquals("+52 33 1234 5678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+523312345678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.E164));
+
+ assertEquals("01 821 123 4567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.NATIONAL));
+ assertEquals("+52 821 123 4567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+528211234567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.E164));
+ }
+
+ public void testFormatOutOfCountryCallingNumber() {
+ assertEquals("00 1 900 253 0000",
+ phoneUtil.formatOutOfCountryCallingNumber(US_PREMIUM, RegionCode.DE));
+
+ assertEquals("1 650 253 0000",
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.BS));
+
+ assertEquals("00 1 650 253 0000",
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.PL));
+
+ assertEquals("011 44 7912 345 678",
+ phoneUtil.formatOutOfCountryCallingNumber(GB_MOBILE, RegionCode.US));
+
+ assertEquals("00 49 1234",
+ phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.GB));
+ // Note this number is correctly formatted without national prefix. Most of the numbers that
+ // are treated as invalid numbers by the library are short numbers, and they are usually not
+ // dialed with national prefix.
+ assertEquals("1234", phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.DE));
+
+ assertEquals("011 39 02 3661 8300",
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.US));
+ assertEquals("02 3661 8300",
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.IT));
+ assertEquals("+39 02 3661 8300",
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.SG));
+
+ assertEquals("6521 8000",
+ phoneUtil.formatOutOfCountryCallingNumber(SG_NUMBER, RegionCode.SG));
+
+ assertEquals("011 54 9 11 8765 4321",
+ phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, RegionCode.US));
+
+ PhoneNumber arNumberWithExtn = new PhoneNumber().mergeFrom(AR_MOBILE).setExtension("1234");
+ assertEquals("011 54 9 11 8765 4321 ext. 1234",
+ phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.US));
+ assertEquals("0011 54 9 11 8765 4321 ext. 1234",
+ phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AU));
+ assertEquals("011 15 8765-4321 ext. 1234",
+ phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AR));
+ }
+
+ public void testFormatOutOfCountryWithInvalidRegion() {
+ // AQ/Antarctica isn't a valid region code for phone number formatting,
+ // so this falls back to intl formatting.
+ assertEquals("+1 650 253 0000",
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, "AQ"));
+ }
+
+ public void testFormatOutOfCountryWithPreferredIntlPrefix() {
+ // This should use 0011, since that is the preferred international prefix (both 0011 and 0012
+ // are accepted as possible international prefixes in our test metadta.)
+ assertEquals("0011 39 02 3661 8300",
+ phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.AU));
+ }
+
+ public void testFormatOutOfCountryKeepingAlphaChars() {
+ PhoneNumber alphaNumericNumber = new PhoneNumber();
+ alphaNumericNumber.setCountryCode(1).setNationalNumber(8007493524L)
+ .setRawInput("1800 six-flag");
+ assertEquals("0011 1 800 SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ alphaNumericNumber.setRawInput("1-800-SIX-flag");
+ assertEquals("0011 1 800-SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ alphaNumericNumber.setRawInput("Call us from UK: 00 1 800 SIX-flag");
+ assertEquals("0011 1 800 SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ alphaNumericNumber.setRawInput("800 SIX-flag");
+ assertEquals("0011 1 800 SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ // Formatting from within the NANPA region.
+ assertEquals("1 800 SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.US));
+
+ assertEquals("1 800 SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.BS));
+
+ // Testing that if the raw input doesn't exist, it is formatted using
+ // formatOutOfCountryCallingNumber.
+ alphaNumericNumber.clearRawInput();
+ assertEquals("00 1 800 749 3524",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
+
+ // Testing AU alpha number formatted from Australia.
+ alphaNumericNumber.setCountryCode(61).setNationalNumber(827493524L)
+ .setRawInput("+61 82749-FLAG");
+ // This number should have the national prefix fixed.
+ assertEquals("082749-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ alphaNumericNumber.setRawInput("082749-FLAG");
+ assertEquals("082749-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ alphaNumericNumber.setNationalNumber(18007493524L).setRawInput("1-800-SIX-flag");
+ // This number should not have the national prefix prefixed, in accordance with the override for
+ // this specific formatting rule.
+ assertEquals("1-800-SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
+
+ // The metadata should not be permanently changed, since we copied it before modifying patterns.
+ // Here we check this.
+ alphaNumericNumber.setNationalNumber(1800749352L);
+ assertEquals("1800 749 352",
+ phoneUtil.formatOutOfCountryCallingNumber(alphaNumericNumber, RegionCode.AU));
+
+ // Testing a region with multiple international prefixes.
+ assertEquals("+61 1-800-SIX-FLAG",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.SG));
+
+ // Testing the case with an invalid country calling code.
+ alphaNumericNumber.setCountryCode(0).setNationalNumber(18007493524L)
+ .setRawInput("1-800-SIX-flag");
+ // Uses the raw input only.
+ assertEquals("1-800-SIX-flag",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
+
+ // Testing the case of an invalid alpha number.
+ alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
+ // No country-code stripping can be done.
+ assertEquals("00 1 180-SIX",
+ phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
+ }
+
+ public void testFormatWithCarrierCode() {
+ // We only support this for AR in our test metadata, and only for mobile numbers starting with
+ // certain values.
+ PhoneNumber arMobile = new PhoneNumber().setCountryCode(54).setNationalNumber(92234654321L);
+ assertEquals("02234 65-4321", phoneUtil.format(arMobile, PhoneNumberFormat.NATIONAL));
+ // Here we force 14 as the carrier code.
+ assertEquals("02234 14 65-4321",
+ phoneUtil.formatNationalNumberWithCarrierCode(arMobile, "14"));
+ // Here we force the number to be shown with no carrier code.
+ assertEquals("02234 65-4321",
+ phoneUtil.formatNationalNumberWithCarrierCode(arMobile, ""));
+ // Here the international rule is used, so no carrier code should be present.
+ assertEquals("+5492234654321", phoneUtil.format(arMobile, PhoneNumberFormat.E164));
+ // We don't support this for the US so there should be no change.
+ assertEquals("650 253 0000", phoneUtil.formatNationalNumberWithCarrierCode(US_NUMBER, "15"));
+ }
+
+ public void testFormatWithPreferredCarrierCode() {
+ // We only support this for AR in our test metadata.
+ PhoneNumber arNumber = new PhoneNumber();
+ arNumber.setCountryCode(54).setNationalNumber(91234125678L);
+ // Test formatting with no preferred carrier code stored in the number itself.
+ assertEquals("01234 15 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
+ assertEquals("01234 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
+ // Test formatting with preferred carrier code present.
+ arNumber.setPreferredDomesticCarrierCode("19");
+ assertEquals("01234 12-5678", phoneUtil.format(arNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("01234 19 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
+ assertEquals("01234 19 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
+ // When the preferred_domestic_carrier_code is present (even when it contains an empty string),
+ // use it instead of the default carrier code passed in.
+ arNumber.setPreferredDomesticCarrierCode("");
+ assertEquals("01234 12-5678",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
+ // We don't support this for the US so there should be no change.
+ PhoneNumber usNumber = new PhoneNumber();
+ usNumber.setCountryCode(1).setNationalNumber(4241231234L).setPreferredDomesticCarrierCode("99");
+ assertEquals("424 123 1234", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals("424 123 1234",
+ phoneUtil.formatNationalNumberWithPreferredCarrierCode(usNumber, "15"));
+ }
+
+ public void testFormatNumberForMobileDialing() {
+ // US toll free numbers are marked as noInternationalDialling in the test metadata for testing
+ // purposes.
+ assertEquals("800 253 0000",
+ phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US, true));
+ assertEquals("", phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, true));
+ assertEquals("+1 650 253 0000",
+ phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, true));
+ PhoneNumber usNumberWithExtn = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("1234");
+ assertEquals("+1 650 253 0000",
+ phoneUtil.formatNumberForMobileDialing(usNumberWithExtn, RegionCode.US, true));
+
+ assertEquals("8002530000",
+ phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US, false));
+ assertEquals("", phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, false));
+ assertEquals("+16502530000",
+ phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, false));
+ assertEquals("+16502530000",
+ phoneUtil.formatNumberForMobileDialing(usNumberWithExtn, RegionCode.US, false));
+ }
+
+ public void testFormatByPattern() {
+ NumberFormat newNumFormat = new NumberFormat();
+ newNumFormat.setPattern("(\\d{3})(\\d{3})(\\d{4})");
+ newNumFormat.setFormat("($1) $2-$3");
+ List<NumberFormat> newNumberFormats = new ArrayList<NumberFormat>();
+ newNumberFormats.add(newNumFormat);
+
+ assertEquals("(650) 253-0000", phoneUtil.formatByPattern(US_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+ assertEquals("+1 (650) 253-0000", phoneUtil.formatByPattern(US_NUMBER,
+ PhoneNumberFormat.INTERNATIONAL,
+ newNumberFormats));
+
+ // $NP is set to '1' for the US. Here we check that for other NANPA countries the US rules are
+ // followed.
+ newNumFormat.setNationalPrefixFormattingRule("$NP ($FG)");
+ newNumFormat.setFormat("$1 $2-$3");
+ assertEquals("1 (242) 365-1234",
+ phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+ assertEquals("+1 242 365-1234",
+ phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL,
+ newNumberFormats));
+
+ newNumFormat.setPattern("(\\d{2})(\\d{5})(\\d{3})");
+ newNumFormat.setFormat("$1-$2 $3");
+ newNumberFormats.set(0, newNumFormat);
+
+ assertEquals("02-36618 300",
+ phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+ assertEquals("+39 02-36618 300",
+ phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL,
+ newNumberFormats));
+
+ newNumFormat.setNationalPrefixFormattingRule("$NP$FG");
+ newNumFormat.setPattern("(\\d{2})(\\d{4})(\\d{4})");
+ newNumFormat.setFormat("$1 $2 $3");
+ newNumberFormats.set(0, newNumFormat);
+ assertEquals("020 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+
+ newNumFormat.setNationalPrefixFormattingRule("($NP$FG)");
+ assertEquals("(020) 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+
+ newNumFormat.setNationalPrefixFormattingRule("");
+ assertEquals("20 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
+ newNumberFormats));
+
+ assertEquals("+44 20 7031 3000",
+ phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL,
+ newNumberFormats));
+ }
+
+ public void testFormatE164Number() {
+ assertEquals("+16502530000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.E164));
+ assertEquals("+4930123456", phoneUtil.format(DE_NUMBER, PhoneNumberFormat.E164));
+ }
+
+ public void testFormatNumberWithExtension() {
+ PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("1234");
+ // Uses default extension prefix:
+ assertEquals("03-331 6005 ext. 1234", phoneUtil.format(nzNumber, PhoneNumberFormat.NATIONAL));
+ // Uses RFC 3966 syntax.
+ assertEquals("+64-3-331-6005;ext=1234", phoneUtil.format(nzNumber, PhoneNumberFormat.RFC3966));
+ // Extension prefix overridden in the territory information for the US:
+ PhoneNumber usNumberWithExtension = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("4567");
+ assertEquals("650 253 0000 extn. 4567", phoneUtil.format(usNumberWithExtension,
+ PhoneNumberFormat.NATIONAL));
+ }
+
+ public void testFormatUsingOriginalNumberFormat() throws Exception {
+ PhoneNumber number1 = phoneUtil.parseAndKeepRawInput("+442087654321", RegionCode.GB);
+ assertEquals("+44 20 8765 4321", phoneUtil.formatInOriginalFormat(number1, RegionCode.GB));
+
+ PhoneNumber number2 = phoneUtil.parseAndKeepRawInput("02087654321", RegionCode.GB);
+ assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number2, RegionCode.GB));
+
+ PhoneNumber number3 = phoneUtil.parseAndKeepRawInput("011442087654321", RegionCode.US);
+ assertEquals("011 44 20 8765 4321", phoneUtil.formatInOriginalFormat(number3, RegionCode.US));
+
+ PhoneNumber number4 = phoneUtil.parseAndKeepRawInput("442087654321", RegionCode.GB);
+ assertEquals("44 20 8765 4321", phoneUtil.formatInOriginalFormat(number4, RegionCode.GB));
+
+ PhoneNumber number5 = phoneUtil.parse("+442087654321", RegionCode.GB);
+ assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number5, RegionCode.GB));
+
+ // Invalid numbers should be formatted using its raw input when that is available. Note area
+ // codes starting with 7 are intentionally excluded in the test metadata for testing purposes.
+ PhoneNumber number6 = phoneUtil.parseAndKeepRawInput("7345678901", RegionCode.US);
+ assertEquals("7345678901", phoneUtil.formatInOriginalFormat(number6, RegionCode.US));
+
+ // When the raw input is unavailable, format as usual.
+ PhoneNumber number7 = phoneUtil.parse("7345678901", RegionCode.US);
+ assertEquals("734 567 8901", phoneUtil.formatInOriginalFormat(number7, RegionCode.US));
+ }
+
+ public void testIsPremiumRate() {
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(US_PREMIUM));
+
+ PhoneNumber premiumRateNumber = new PhoneNumber();
+ premiumRateNumber.setCountryCode(39).setNationalNumber(892123L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
+ phoneUtil.getNumberType(premiumRateNumber));
+
+ premiumRateNumber.clear();
+ premiumRateNumber.setCountryCode(44).setNationalNumber(9187654321L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
+ phoneUtil.getNumberType(premiumRateNumber));
+
+ premiumRateNumber.clear();
+ premiumRateNumber.setCountryCode(49).setNationalNumber(9001654321L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
+ phoneUtil.getNumberType(premiumRateNumber));
+
+ premiumRateNumber.clear();
+ premiumRateNumber.setCountryCode(49).setNationalNumber(90091234567L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
+ phoneUtil.getNumberType(premiumRateNumber));
+ }
+
+ public void testIsTollFree() {
+ PhoneNumber tollFreeNumber = new PhoneNumber();
+
+ tollFreeNumber.setCountryCode(1).setNationalNumber(8881234567L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
+ phoneUtil.getNumberType(tollFreeNumber));
+
+ tollFreeNumber.clear();
+ tollFreeNumber.setCountryCode(39).setNationalNumber(803123L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
+ phoneUtil.getNumberType(tollFreeNumber));
+
+ tollFreeNumber.clear();
+ tollFreeNumber.setCountryCode(44).setNationalNumber(8012345678L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
+ phoneUtil.getNumberType(tollFreeNumber));
+
+ tollFreeNumber.clear();
+ tollFreeNumber.setCountryCode(49).setNationalNumber(8001234567L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
+ phoneUtil.getNumberType(tollFreeNumber));
+ }
+
+ public void testIsMobile() {
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(BS_MOBILE));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(GB_MOBILE));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(IT_MOBILE));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(AR_MOBILE));
+
+ PhoneNumber mobileNumber = new PhoneNumber();
+ mobileNumber.setCountryCode(49).setNationalNumber(15123456789L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(mobileNumber));
+ }
+
+ public void testIsFixedLine() {
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(BS_NUMBER));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(IT_NUMBER));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(GB_NUMBER));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(DE_NUMBER));
+ }
+
+ public void testIsFixedLineAndMobile() {
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE_OR_MOBILE,
+ phoneUtil.getNumberType(US_NUMBER));
+
+ PhoneNumber fixedLineAndMobileNumber = new PhoneNumber().
+ setCountryCode(54).setNationalNumber(1987654321L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE_OR_MOBILE,
+ phoneUtil.getNumberType(fixedLineAndMobileNumber));
+ }
+
+ public void testIsSharedCost() {
+ PhoneNumber gbNumber = new PhoneNumber();
+ gbNumber.setCountryCode(44).setNationalNumber(8431231234L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.SHARED_COST, phoneUtil.getNumberType(gbNumber));
+ }
+
+ public void testIsVoip() {
+ PhoneNumber gbNumber = new PhoneNumber();
+ gbNumber.setCountryCode(44).setNationalNumber(5631231234L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.VOIP, phoneUtil.getNumberType(gbNumber));
+ }
+
+ public void testIsPersonalNumber() {
+ PhoneNumber gbNumber = new PhoneNumber();
+ gbNumber.setCountryCode(44).setNationalNumber(7031231234L);
+ assertEquals(PhoneNumberUtil.PhoneNumberType.PERSONAL_NUMBER,
+ phoneUtil.getNumberType(gbNumber));
+ }
+
+ public void testIsUnknown() {
+ // Invalid numbers should be of type UNKNOWN.
+ assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(US_LOCAL_NUMBER));
+ }
+
+ public void testIsValidNumber() {
+ assertTrue(phoneUtil.isValidNumber(US_NUMBER));
+ assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
+ assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
+
+ PhoneNumber nzNumber = new PhoneNumber().setCountryCode(64).setNationalNumber(21387835L);
+ assertTrue(phoneUtil.isValidNumber(nzNumber));
+ }
+
+ public void testIsValidForRegion() {
+ // This number is valid for the Bahamas, but is not a valid US number.
+ assertTrue(phoneUtil.isValidNumber(BS_NUMBER));
+ assertTrue(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.BS));
+ assertFalse(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.US));
+ PhoneNumber bsInvalidNumber =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2421232345L);
+ // This number is no longer valid.
+ assertFalse(phoneUtil.isValidNumber(bsInvalidNumber));
+
+ // La Mayotte and Reunion use 'leadingDigits' to differentiate them.
+ PhoneNumber reNumber = new PhoneNumber();
+ reNumber.setCountryCode(262).setNationalNumber(262123456L);
+ assertTrue(phoneUtil.isValidNumber(reNumber));
+ assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
+ assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
+ // Now change the number to be a number for La Mayotte.
+ reNumber.setNationalNumber(269601234L);
+ assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
+ assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
+ // This number is no longer valid for La Reunion.
+ reNumber.setNationalNumber(269123456L);
+ assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
+ assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
+ assertFalse(phoneUtil.isValidNumber(reNumber));
+ // However, it should be recognised as from La Mayotte, since it is valid for this region.
+ assertEquals(RegionCode.YT, phoneUtil.getRegionCodeForNumber(reNumber));
+ // This number is valid in both places.
+ reNumber.setNationalNumber(800123456L);
+ assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
+ assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
+ }
+
+ public void testIsNotValidNumber() {
+ assertFalse(phoneUtil.isValidNumber(US_LOCAL_NUMBER));
+
+ PhoneNumber invalidNumber = new PhoneNumber();
+ invalidNumber.setCountryCode(39).setNationalNumber(23661830000L).setItalianLeadingZero(true);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
+
+ invalidNumber.clear();
+ invalidNumber.setCountryCode(44).setNationalNumber(791234567L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
+
+ invalidNumber.clear();
+ invalidNumber.setCountryCode(49).setNationalNumber(1234L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
+
+ invalidNumber.clear();
+ invalidNumber.setCountryCode(64).setNationalNumber(3316005L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
+ }
+
+ public void testGetRegionCodeForCountryCode() {
+ assertEquals(RegionCode.US, phoneUtil.getRegionCodeForCountryCode(1));
+ assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
+ assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));
+ }
+
+ public void testGetRegionCodeForNumber() {
+ assertEquals(RegionCode.BS, phoneUtil.getRegionCodeForNumber(BS_NUMBER));
+ assertEquals(RegionCode.US, phoneUtil.getRegionCodeForNumber(US_NUMBER));
+ assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForNumber(GB_MOBILE));
+ }
+
+ public void testGetCountryCodeForRegion() {
+ assertEquals(1, phoneUtil.getCountryCodeForRegion(RegionCode.US));
+ assertEquals(64, phoneUtil.getCountryCodeForRegion(RegionCode.NZ));
+ assertEquals(0, phoneUtil.getCountryCodeForRegion(null));
+ assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.ZZ));
+ // CS is already deprecated so the library doesn't support it.
+ assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.CS));
+ }
+
+ public void testGetNationalDiallingPrefixForRegion() {
+ assertEquals("1", phoneUtil.getNddPrefixForRegion(RegionCode.US, false));
+ // Test non-main country to see it gets the national dialling prefix for the main country with
+ // that country calling code.
+ assertEquals("1", phoneUtil.getNddPrefixForRegion(RegionCode.BS, false));
+ assertEquals("0", phoneUtil.getNddPrefixForRegion(RegionCode.NZ, false));
+ // Test case with non digit in the national prefix.
+ assertEquals("0~0", phoneUtil.getNddPrefixForRegion(RegionCode.AO, false));
+ assertEquals("00", phoneUtil.getNddPrefixForRegion(RegionCode.AO, true));
+ // Test cases with invalid regions.
+ assertEquals(null, phoneUtil.getNddPrefixForRegion(null, false));
+ assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.ZZ, false));
+ // CS is already deprecated so the library doesn't support it.
+ assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.CS, false));
+ }
+
+ public void testIsNANPACountry() {
+ assertTrue(phoneUtil.isNANPACountry(RegionCode.US));
+ assertTrue(phoneUtil.isNANPACountry(RegionCode.BS));
+ assertFalse(phoneUtil.isNANPACountry(RegionCode.DE));
+ assertFalse(phoneUtil.isNANPACountry(RegionCode.ZZ));
+ assertFalse(phoneUtil.isNANPACountry(null));
+ }
+
+ public void testIsPossibleNumber() {
+ assertTrue(phoneUtil.isPossibleNumber(US_NUMBER));
+ assertTrue(phoneUtil.isPossibleNumber(US_LOCAL_NUMBER));
+ assertTrue(phoneUtil.isPossibleNumber(GB_NUMBER));
+
+ assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.US));
+ assertTrue(phoneUtil.isPossibleNumber("+1 650 GOO OGLE", RegionCode.US));
+ assertTrue(phoneUtil.isPossibleNumber("(650) 253-0000", RegionCode.US));
+ assertTrue(phoneUtil.isPossibleNumber("253-0000", RegionCode.US));
+ assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.GB));
+ assertTrue(phoneUtil.isPossibleNumber("+44 20 7031 3000", RegionCode.GB));
+ assertTrue(phoneUtil.isPossibleNumber("(020) 7031 3000", RegionCode.GB));
+ assertTrue(phoneUtil.isPossibleNumber("7031 3000", RegionCode.GB));
+ assertTrue(phoneUtil.isPossibleNumber("3331 6005", RegionCode.NZ));
+ }
+
+ public void testIsPossibleNumberWithReason() {
+ // National numbers for country calling code +1 that are within 7 to 10 digits are possible.
+ assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
+ phoneUtil.isPossibleNumberWithReason(US_NUMBER));
+
+ assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
+ phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER));
+
+ assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
+ phoneUtil.isPossibleNumberWithReason(US_LONG_NUMBER));
+
+ PhoneNumber number = new PhoneNumber();
+ number.setCountryCode(0).setNationalNumber(2530000L);
+ assertEquals(PhoneNumberUtil.ValidationResult.INVALID_COUNTRY_CODE,
+ phoneUtil.isPossibleNumberWithReason(number));
+
+ number.clear();
+ number.setCountryCode(1).setNationalNumber(253000L);
+ assertEquals(PhoneNumberUtil.ValidationResult.TOO_SHORT,
+ phoneUtil.isPossibleNumberWithReason(number));
+
+ number.clear();
+ number.setCountryCode(65).setNationalNumber(1234567890L);
+ assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
+ phoneUtil.isPossibleNumberWithReason(number));
+
+ // Try with number that we don't have metadata for.
+ PhoneNumber adNumber = new PhoneNumber();
+ adNumber.setCountryCode(376).setNationalNumber(12345L);
+ assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
+ phoneUtil.isPossibleNumberWithReason(adNumber));
+ adNumber.setCountryCode(376).setNationalNumber(13L);
+ assertEquals(PhoneNumberUtil.ValidationResult.TOO_SHORT,
+ phoneUtil.isPossibleNumberWithReason(adNumber));
+ adNumber.setCountryCode(376).setNationalNumber(12345678901234567L);
+ assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
+ phoneUtil.isPossibleNumberWithReason(adNumber));
+ }
+
+ public void testIsNotPossibleNumber() {
+ assertFalse(phoneUtil.isPossibleNumber(US_LONG_NUMBER));
+
+ PhoneNumber number = new PhoneNumber();
+ number.setCountryCode(1).setNationalNumber(253000L);
+ assertFalse(phoneUtil.isPossibleNumber(number));
+
+ number.clear();
+ number.setCountryCode(44).setNationalNumber(300L);
+ assertFalse(phoneUtil.isPossibleNumber(number));
+
+ assertFalse(phoneUtil.isPossibleNumber("+1 650 253 00000", RegionCode.US));
+ assertFalse(phoneUtil.isPossibleNumber("(650) 253-00000", RegionCode.US));
+ assertFalse(phoneUtil.isPossibleNumber("I want a Pizza", RegionCode.US));
+ assertFalse(phoneUtil.isPossibleNumber("253-000", RegionCode.US));
+ assertFalse(phoneUtil.isPossibleNumber("1 3000", RegionCode.GB));
+ assertFalse(phoneUtil.isPossibleNumber("+44 300", RegionCode.GB));
+ }
+
+ public void testTruncateTooLongNumber() {
+ // US number 650-253-0000, but entered with one additional digit at the end.
+ assertTrue(phoneUtil.truncateTooLongNumber(US_LONG_NUMBER));
+ assertEquals(US_NUMBER, US_LONG_NUMBER);
+
+ // GB number 080 1234 5678, but entered with 4 extra digits at the end.
+ PhoneNumber tooLongNumber = new PhoneNumber();
+ tooLongNumber.setCountryCode(44).setNationalNumber(80123456780123L);
+ PhoneNumber validNumber = new PhoneNumber();
+ validNumber.setCountryCode(44).setNationalNumber(8012345678L);
+ assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
+ assertEquals(validNumber, tooLongNumber);
+
+ // IT number 022 3456 7890, but entered with 3 extra digits at the end.
+ tooLongNumber.clear();
+ tooLongNumber.setCountryCode(39).setNationalNumber(2234567890123L).setItalianLeadingZero(true);
+ validNumber.clear();
+ validNumber.setCountryCode(39).setNationalNumber(2234567890L).setItalianLeadingZero(true);
+ assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
+ assertEquals(validNumber, tooLongNumber);
+
+ // Tests what happens when a valid number is passed in.
+ PhoneNumber validNumberCopy = new PhoneNumber().mergeFrom(validNumber);
+ assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
+ // Tests the number is not modified.
+ assertEquals(validNumberCopy, validNumber);
+
+ // Tests what happens when a number with invalid prefix is passed in.
+ PhoneNumber numberWithInvalidPrefix = new PhoneNumber();
+ // The test metadata says US numbers cannot have prefix 240.
+ numberWithInvalidPrefix.setCountryCode(1).setNationalNumber(2401234567L);
+ PhoneNumber invalidNumberCopy = new PhoneNumber().mergeFrom(numberWithInvalidPrefix);
+ assertFalse(phoneUtil.truncateTooLongNumber(numberWithInvalidPrefix));
+ // Tests the number is not modified.
+ assertEquals(invalidNumberCopy, numberWithInvalidPrefix);
+
+ // Tests what happens when a too short number is passed in.
+ PhoneNumber tooShortNumber = new PhoneNumber().setCountryCode(1).setNationalNumber(1234L);
+ PhoneNumber tooShortNumberCopy = new PhoneNumber().mergeFrom(tooShortNumber);
+ assertFalse(phoneUtil.truncateTooLongNumber(tooShortNumber));
+ // Tests the number is not modified.
+ assertEquals(tooShortNumberCopy, tooShortNumber);
+ }
+
+ public void testIsViablePhoneNumber() {
+ // Only one or two digits before strange non-possible punctuation.
+ assertFalse(PhoneNumberUtil.isViablePhoneNumber("12. March"));
+ assertFalse(PhoneNumberUtil.isViablePhoneNumber("1+1+1"));
+ assertFalse(PhoneNumberUtil.isViablePhoneNumber("80+0"));
+ assertFalse(PhoneNumberUtil.isViablePhoneNumber("00"));
+ // Three digits is viable.
+ assertTrue(PhoneNumberUtil.isViablePhoneNumber("111"));
+ // Alpha numbers.
+ assertTrue(PhoneNumberUtil.isViablePhoneNumber("0800-4-pizza"));
+ assertTrue(PhoneNumberUtil.isViablePhoneNumber("0800-4-PIZZA"));
+ }
+
+ public void testIsViablePhoneNumberNonAscii() {
+ // Only one or two digits before possible punctuation followed by more digits.
+ assertTrue(PhoneNumberUtil.isViablePhoneNumber("1\u300034"));
+ assertFalse(PhoneNumberUtil.isViablePhoneNumber("1\u30003+4"));
+ // Unicode variants of possible starting character and other allowed punctuation/digits.
+ assertTrue(PhoneNumberUtil.isViablePhoneNumber("\uFF081\uFF09\u30003456789"));
+ // Testing a leading + is okay.
+ assertTrue(PhoneNumberUtil.isViablePhoneNumber("+1\uFF09\u30003456789"));
+ }
+
+ public void testExtractPossibleNumber() {
+ // Removes preceding funky punctuation and letters but leaves the rest untouched.
+ assertEquals("0800-345-600", PhoneNumberUtil.extractPossibleNumber("Tel:0800-345-600"));
+ assertEquals("0800 FOR PIZZA", PhoneNumberUtil.extractPossibleNumber("Tel:0800 FOR PIZZA"));
+ // Should not remove plus sign
+ assertEquals("+800-345-600", PhoneNumberUtil.extractPossibleNumber("Tel:+800-345-600"));
+ // Should recognise wide digits as possible start values.
+ assertEquals("\uFF10\uFF12\uFF13",
+ PhoneNumberUtil.extractPossibleNumber("\uFF10\uFF12\uFF13"));
+ // Dashes are not possible start values and should be removed.
+ assertEquals("\uFF11\uFF12\uFF13",
+ PhoneNumberUtil.extractPossibleNumber("Num-\uFF11\uFF12\uFF13"));
+ // If not possible number present, return empty string.
+ assertEquals("", PhoneNumberUtil.extractPossibleNumber("Num-...."));
+ // Leading brackets are stripped - these are not used when parsing.
+ assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000"));
+
+ // Trailing non-alpha-numeric characters should be removed.
+ assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000..- .."));
+ assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000."));
+ // This case has a trailing RTL char.
+ assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000\u200F"));
+ }
+
+ public void testMaybeStripNationalPrefix() {
+ PhoneMetadata metadata = new PhoneMetadata();
+ metadata.setNationalPrefixForParsing("34");
+ metadata.setGeneralDesc(new PhoneNumberDesc().setNationalNumberPattern("\\d{4,8}"));
+ StringBuilder numberToStrip = new StringBuilder("34356778");
+ String strippedNumber = "356778";
+ assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, null));
+ assertEquals("Should have had national prefix stripped.",
+ strippedNumber, numberToStrip.toString());
+ // Retry stripping - now the number should not start with the national prefix, so no more
+ // stripping should occur.
+ assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, null));
+ assertEquals("Should have had no change - no national prefix present.",
+ strippedNumber, numberToStrip.toString());
+ // Some countries have no national prefix. Repeat test with none specified.
+ metadata.setNationalPrefixForParsing("");
+ assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, null));
+ assertEquals("Should not strip anything with empty national prefix.",
+ strippedNumber, numberToStrip.toString());
+ // If the resultant number doesn't match the national rule, it shouldn't be stripped.
+ metadata.setNationalPrefixForParsing("3");
+ numberToStrip = new StringBuilder("3123");
+ strippedNumber = "3123";
+ assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, null));
+ assertEquals("Should have had no change - after stripping, it wouldn't have matched " +
+ "the national rule.",
+ strippedNumber, numberToStrip.toString());
+ // Test extracting carrier selection code.
+ metadata.setNationalPrefixForParsing("0(81)?");
+ numberToStrip = new StringBuilder("08122123456");
+ strippedNumber = "22123456";
+ StringBuilder carrierCode = new StringBuilder();
+ assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
+ numberToStrip, metadata, carrierCode));
+ assertEquals("81", carrierCode.toString());
+ assertEquals("Should have had national prefix and carrier code stripped.",
+ strippedNumber, numberToStrip.toString());
+ // If there was a transform rule, check it was applied.
+ metadata.setNationalPrefixTransformRule("5$15");
+ // Note that a capturing group is present here.
+ metadata.setNationalPrefixForParsing("0(\\d{2})");
+ numberToStrip = new StringBuilder("031123");
+ String transformedNumber = "5315123";
+ assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, null));
+ assertEquals("Should transform the 031 to a 5315.",
+ transformedNumber, numberToStrip.toString());
+ }
+
+ public void testMaybeStripInternationalPrefix() {
+ String internationalPrefix = "00[39]";
+ StringBuilder numberToStrip = new StringBuilder("0034567700-3898003");
+ // Note the dash is removed as part of the normalization.
+ StringBuilder strippedNumber = new StringBuilder("45677003898003");
+ assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+ assertEquals("The number supplied was not stripped of its international prefix.",
+ strippedNumber.toString(), numberToStrip.toString());
+ // Now the number no longer starts with an IDD prefix, so it should now report
+ // FROM_DEFAULT_COUNTRY.
+ assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+
+ numberToStrip = new StringBuilder("00945677003898003");
+ assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+ assertEquals("The number supplied was not stripped of its international prefix.",
+ strippedNumber.toString(), numberToStrip.toString());
+ // Test it works when the international prefix is broken up by spaces.
+ numberToStrip = new StringBuilder("00 9 45677003898003");
+ assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+ assertEquals("The number supplied was not stripped of its international prefix.",
+ strippedNumber.toString(), numberToStrip.toString());
+ // Now the number no longer starts with an IDD prefix, so it should now report
+ // FROM_DEFAULT_COUNTRY.
+ assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+
+ // Test the + symbol is also recognised and stripped.
+ numberToStrip = new StringBuilder("+45677003898003");
+ strippedNumber = new StringBuilder("45677003898003");
+ assertEquals(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+ assertEquals("The number supplied was not stripped of the plus symbol.",
+ strippedNumber.toString(), numberToStrip.toString());
+
+ // If the number afterwards is a zero, we should not strip this - no country calling code begins
+ // with 0.
+ numberToStrip = new StringBuilder("0090112-3123");
+ strippedNumber = new StringBuilder("00901123123");
+ assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+ assertEquals("The number supplied had a 0 after the match so shouldn't be stripped.",
+ strippedNumber.toString(), numberToStrip.toString());
+ // Here the 0 is separated by a space from the IDD.
+ numberToStrip = new StringBuilder("009 0-112-3123");
+ assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
+ phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
+ internationalPrefix));
+ }
+
+ public void testMaybeExtractCountryCode() {
+ PhoneNumber number = new PhoneNumber();
+ PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
+ // Note that for the US, the IDD is 011.
+ try {
+ String phoneNumber = "011112-3456789";
+ String strippedNumber = "123456789";
+ int countryCallingCode = 1;
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
+ countryCallingCode,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+ number));
+ assertEquals("Did not figure out CountryCodeSource correctly",
+ CountryCodeSource.FROM_NUMBER_WITH_IDD, number.getCountryCodeSource());
+ // Should strip and normalize national significant number.
+ assertEquals("Did not strip off the country calling code correctly.",
+ strippedNumber,
+ numberToFill.toString());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "+6423456789";
+ int countryCallingCode = 64;
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
+ countryCallingCode,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+ number));
+ assertEquals("Did not figure out CountryCodeSource correctly",
+ CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "2345-6789";
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals(
+ "Should not have extracted a country calling code - no international prefix present.",
+ 0,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number));
+ assertEquals("Did not figure out CountryCodeSource correctly",
+ CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "0119991123456789";
+ StringBuilder numberToFill = new StringBuilder();
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number);
+ fail("Should have thrown an exception, no valid country calling code present.");
+ } catch (NumberParseException e) {
+ // Expected.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "(1 610) 619 4466";
+ int countryCallingCode = 1;
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals("Should have extracted the country calling code of the region passed in",
+ countryCallingCode,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+ number));
+ assertEquals("Did not figure out CountryCodeSource correctly",
+ CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN,
+ number.getCountryCodeSource());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "(1 610) 619 4466";
+ int countryCallingCode = 1;
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals("Should have extracted the country calling code of the region passed in",
+ countryCallingCode,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
+ number));
+ assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "(1 610) 619 446";
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals("Should not have extracted a country calling code - invalid number after " +
+ "extraction of uncertain country calling code.",
+ 0,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
+ number));
+ assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ number.clear();
+ try {
+ String phoneNumber = "(1 610) 619";
+ StringBuilder numberToFill = new StringBuilder();
+ assertEquals("Should not have extracted a country calling code - too short number both " +
+ "before and after extraction of uncertain country calling code.",
+ 0,
+ phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
+ number));
+ assertEquals("Did not figure out CountryCodeSource correctly",
+ CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
+ } catch (NumberParseException e) {
+ fail("Should not have thrown an exception: " + e.toString());
+ }
+ }
+
+ public void testParseNationalNumber() throws Exception {
+ // National prefix attached.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("033316005", RegionCode.NZ));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("33316005", RegionCode.NZ));
+ // National prefix attached and some formatting present.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("03-331 6005", RegionCode.NZ));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("03 331 6005", RegionCode.NZ));
+
+ // Testing international prefixes.
+ // Should strip country calling code.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("0064 3 331 6005", RegionCode.NZ));
+ // Try again, but this time we have an international number with Region Code US. It should
+ // recognise the country calling code and parse accordingly.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("01164 3 331 6005", RegionCode.US));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.US));
+ // We should ignore the leading plus here, since it is not followed by a valid country code but
+ // instead is followed by the IDD for the US.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+01164 3 331 6005", RegionCode.US));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+0064 3 331 6005", RegionCode.NZ));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+ 00 64 3 331 6005", RegionCode.NZ));
+
+ PhoneNumber nzNumber = new PhoneNumber();
+ nzNumber.setCountryCode(64).setNationalNumber(64123456L);
+ assertEquals(nzNumber, phoneUtil.parse("64(0)64123456", RegionCode.NZ));
+ // Check that using a "/" is fine in a phone number.
+ assertEquals(DE_NUMBER, phoneUtil.parse("301/23456", RegionCode.DE));
+
+ PhoneNumber usNumber = new PhoneNumber();
+ // Check it doesn't use the '1' as a country calling code when parsing if the phone number was
+ // already possible.
+ usNumber.setCountryCode(1).setNationalNumber(1234567890L);
+ assertEquals(usNumber, phoneUtil.parse("123-456-7890", RegionCode.US));
+ }
+
+ public void testParseNumberWithAlphaCharacters() throws Exception {
+ // Test case with alpha characters.
+ PhoneNumber tollfreeNumber = new PhoneNumber();
+ tollfreeNumber.setCountryCode(64).setNationalNumber(800332005L);
+ assertEquals(tollfreeNumber, phoneUtil.parse("0800 DDA 005", RegionCode.NZ));
+ PhoneNumber premiumNumber = new PhoneNumber();
+ premiumNumber.setCountryCode(64).setNationalNumber(9003326005L);
+ assertEquals(premiumNumber, phoneUtil.parse("0900 DDA 6005", RegionCode.NZ));
+ // Not enough alpha characters for them to be considered intentional, so they are stripped.
+ assertEquals(premiumNumber, phoneUtil.parse("0900 332 6005a", RegionCode.NZ));
+ assertEquals(premiumNumber, phoneUtil.parse("0900 332 600a5", RegionCode.NZ));
+ assertEquals(premiumNumber, phoneUtil.parse("0900 332 600A5", RegionCode.NZ));
+ assertEquals(premiumNumber, phoneUtil.parse("0900 a332 600A5", RegionCode.NZ));
+ }
+
+ public void testParseWithInternationalPrefixes() throws Exception {
+ assertEquals(US_NUMBER, phoneUtil.parse("+1 (650) 253-0000", RegionCode.NZ));
+ assertEquals(US_NUMBER, phoneUtil.parse("1-650-253-0000", RegionCode.US));
+ // Calling the US number from Singapore by using different service providers
+ // 1st test: calling using SingTel IDD service (IDD is 001)
+ assertEquals(US_NUMBER, phoneUtil.parse("0011-650-253-0000", RegionCode.SG));
+ // 2nd test: calling using StarHub IDD service (IDD is 008)
+ assertEquals(US_NUMBER, phoneUtil.parse("0081-650-253-0000", RegionCode.SG));
+ // 3rd test: calling using SingTel V019 service (IDD is 019)
+ assertEquals(US_NUMBER, phoneUtil.parse("0191-650-253-0000", RegionCode.SG));
+ // Calling the US number from Poland
+ assertEquals(US_NUMBER, phoneUtil.parse("0~01-650-253-0000", RegionCode.PL));
+ // Using "++" at the start.
+ assertEquals(US_NUMBER, phoneUtil.parse("++1 (650) 253-0000", RegionCode.PL));
+ }
+
+ public void testParseNonAscii() throws Exception {
+ // Using a full-width plus sign.
+ assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B1 (650) 253-0000", RegionCode.SG));
+ // The whole number, including punctuation, is here represented in full-width form.
+ assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
+ "\u3000\uFF12\uFF15\uFF13\uFF0D\uFF10\uFF10\uFF10" +
+ "\uFF10",
+ RegionCode.SG));
+ // Using U+30FC dash instead.
+ assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
+ "\u3000\uFF12\uFF15\uFF13\u30FC\uFF10\uFF10\uFF10" +
+ "\uFF10",
+ RegionCode.SG));
+
+ // Using a very strange decimal digit range (Mongolian digits).
+ assertEquals(US_NUMBER, phoneUtil.parse("\u1811 \u1816\u1815\u1810 " +
+ "\u1812\u1815\u1813 \u1810\u1810\u1810\u1810",
+ RegionCode.US));
+ }
+
+ public void testParseWithLeadingZero() throws Exception {
+ assertEquals(IT_NUMBER, phoneUtil.parse("+39 02-36618 300", RegionCode.NZ));
+ assertEquals(IT_NUMBER, phoneUtil.parse("02-36618 300", RegionCode.IT));
+
+ assertEquals(IT_MOBILE, phoneUtil.parse("345 678 901", RegionCode.IT));
+ }
+
+ public void testParseNationalNumberArgentina() throws Exception {
+ // Test parsing mobile numbers of Argentina.
+ PhoneNumber arNumber = new PhoneNumber();
+ arNumber.setCountryCode(54).setNationalNumber(93435551212L);
+ assertEquals(arNumber, phoneUtil.parse("+54 9 343 555 1212", RegionCode.AR));
+ assertEquals(arNumber, phoneUtil.parse("0343 15 555 1212", RegionCode.AR));
+
+ arNumber.clear();
+ arNumber.setCountryCode(54).setNationalNumber(93715654320L);
+ assertEquals(arNumber, phoneUtil.parse("+54 9 3715 65 4320", RegionCode.AR));
+ assertEquals(arNumber, phoneUtil.parse("03715 15 65 4320", RegionCode.AR));
+ assertEquals(AR_MOBILE, phoneUtil.parse("911 876 54321", RegionCode.AR));
+
+ // Test parsing fixed-line numbers of Argentina.
+ assertEquals(AR_NUMBER, phoneUtil.parse("+54 11 8765 4321", RegionCode.AR));
+ assertEquals(AR_NUMBER, phoneUtil.parse("011 8765 4321", RegionCode.AR));
+
+ arNumber.clear();
+ arNumber.setCountryCode(54).setNationalNumber(3715654321L);
+ assertEquals(arNumber, phoneUtil.parse("+54 3715 65 4321", RegionCode.AR));
+ assertEquals(arNumber, phoneUtil.parse("03715 65 4321", RegionCode.AR));
+
+ arNumber.clear();
+ arNumber.setCountryCode(54).setNationalNumber(2312340000L);
+ assertEquals(arNumber, phoneUtil.parse("+54 23 1234 0000", RegionCode.AR));
+ assertEquals(arNumber, phoneUtil.parse("023 1234 0000", RegionCode.AR));
+ }
+
+ public void testParseWithXInNumber() throws Exception {
+ // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
+ assertEquals(AR_NUMBER, phoneUtil.parse("01187654321", RegionCode.AR));
+ assertEquals(AR_NUMBER, phoneUtil.parse("(0) 1187654321", RegionCode.AR));
+ assertEquals(AR_NUMBER, phoneUtil.parse("0 1187654321", RegionCode.AR));
+ assertEquals(AR_NUMBER, phoneUtil.parse("(0xx) 1187654321", RegionCode.AR));
+ PhoneNumber arFromUs = new PhoneNumber();
+ arFromUs.setCountryCode(54).setNationalNumber(81429712L);
+ // This test is intentionally constructed such that the number of digit after xx is larger than
+ // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
+ // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
+ // code is written in the form of xx have a national significant number of length larger than 7.
+ assertEquals(arFromUs, phoneUtil.parse("011xx5481429712", RegionCode.US));
+ }
+
+ public void testParseNumbersMexico() throws Exception {
+ // Test parsing fixed-line numbers of Mexico.
+ PhoneNumber mxNumber = new PhoneNumber();
+ mxNumber.setCountryCode(52).setNationalNumber(4499780001L);
+ assertEquals(mxNumber, phoneUtil.parse("+52 (449)978-0001", RegionCode.MX));
+ assertEquals(mxNumber, phoneUtil.parse("01 (449)978-0001", RegionCode.MX));
+ assertEquals(mxNumber, phoneUtil.parse("(449)978-0001", RegionCode.MX));
+
+ // Test parsing mobile numbers of Mexico.
+ mxNumber.clear();
+ mxNumber.setCountryCode(52).setNationalNumber(13312345678L);
+ assertEquals(mxNumber, phoneUtil.parse("+52 1 33 1234-5678", RegionCode.MX));
+ assertEquals(mxNumber, phoneUtil.parse("044 (33) 1234-5678", RegionCode.MX));
+ assertEquals(mxNumber, phoneUtil.parse("045 33 1234-5678", RegionCode.MX));
+ }
+
+ public void testFailedParseOnInvalidNumbers() {
+ try {
+ String sentencePhoneNumber = "This is not a phone number";
+ phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
+ fail("This should not parse without throwing an exception " + sentencePhoneNumber);
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.NOT_A_NUMBER,
+ e.getErrorType());
+ }
+ try {
+ String tooLongPhoneNumber = "01495 72553301873 810104";
+ phoneUtil.parse(tooLongPhoneNumber, RegionCode.GB);
+ fail("This should not parse without throwing an exception " + tooLongPhoneNumber);
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.TOO_LONG,
+ e.getErrorType());
+ }
+ try {
+ String plusMinusPhoneNumber = "+---";
+ phoneUtil.parse(plusMinusPhoneNumber, RegionCode.DE);
+ fail("This should not parse without throwing an exception " + plusMinusPhoneNumber);
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.NOT_A_NUMBER,
+ e.getErrorType());
+ }
+ try {
+ String tooShortPhoneNumber = "+49 0";
+ phoneUtil.parse(tooShortPhoneNumber, RegionCode.DE);
+ fail("This should not parse without throwing an exception " + tooShortPhoneNumber);
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.TOO_SHORT_NSN,
+ e.getErrorType());
+ }
+ try {
+ String invalidCountryCode = "+210 3456 56789";
+ phoneUtil.parse(invalidCountryCode, RegionCode.NZ);
+ fail("This is not a recognised region code: should fail: " + invalidCountryCode);
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+ try {
+ String plusAndIddAndInvalidCountryCode = "+ 00 210 3 331 6005";
+ phoneUtil.parse(plusAndIddAndInvalidCountryCode, RegionCode.NZ);
+ fail("This should not parse without throwing an exception.");
+ } catch (NumberParseException e) {
+ // Expected this exception. 00 is a correct IDD, but 210 is not a valid country code.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "123 456 7890";
+ phoneUtil.parse(someNumber, RegionCode.ZZ);
+ fail("'Unknown' region code not allowed: should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "123 456 7890";
+ phoneUtil.parse(someNumber, RegionCode.CS);
+ fail("Deprecated region code not allowed: should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "123 456 7890";
+ phoneUtil.parse(someNumber, null);
+ fail("Null region code not allowed: should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "0044------";
+ phoneUtil.parse(someNumber, RegionCode.GB);
+ fail("No number provided, only region code: should fail");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "0044";
+ phoneUtil.parse(someNumber, RegionCode.GB);
+ fail("No number provided, only region code: should fail");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "011";
+ phoneUtil.parse(someNumber, RegionCode.US);
+ fail("Only IDD provided - should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
+ e.getErrorType());
+ }
+ try {
+ String someNumber = "0119";
+ phoneUtil.parse(someNumber, RegionCode.US);
+ fail("Only IDD provided and then 9 - should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
+ e.getErrorType());
+ }
+ try {
+ String emptyNumber = "";
+ // Invalid region.
+ phoneUtil.parse(emptyNumber, RegionCode.ZZ);
+ fail("Empty string - should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.NOT_A_NUMBER,
+ e.getErrorType());
+ }
+ try {
+ String nullNumber = null;
+ // Invalid region.
+ phoneUtil.parse(nullNumber, RegionCode.ZZ);
+ fail("Null string - should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.NOT_A_NUMBER,
+ e.getErrorType());
+ } catch (NullPointerException e) {
+ fail("Null string - but should not throw a null pointer exception.");
+ }
+ try {
+ String nullNumber = null;
+ phoneUtil.parse(nullNumber, RegionCode.US);
+ fail("Null string - should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.NOT_A_NUMBER,
+ e.getErrorType());
+ } catch (NullPointerException e) {
+ fail("Null string - but should not throw a null pointer exception.");
+ }
+ }
+
+ public void testParseNumbersWithPlusWithNoRegion() throws Exception {
+ // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country calling code
+ // can be calculated.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.ZZ));
+ // Test with full-width plus.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("\uFF0B64 3 331 6005", RegionCode.ZZ));
+ // Test with normal plus but leading characters that need to be stripped.
+ assertEquals(NZ_NUMBER, phoneUtil.parse("Tel: +64 3 331 6005", RegionCode.ZZ));
+ assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", null));
+
+ // It is important that we set the carrier code to an empty string, since we used
+ // ParseAndKeepRawInput and no carrier code was found.
+ PhoneNumber nzNumberWithRawInput = new PhoneNumber().mergeFrom(NZ_NUMBER).
+ setRawInput("+64 3 331 6005").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).
+ setPreferredDomesticCarrierCode("");
+ assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005",
+ RegionCode.ZZ));
+ // Null is also allowed for the region code in these cases.
+ assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", null));
+ }
+
+ public void testParseExtensions() throws Exception {
+ PhoneNumber nzNumber = new PhoneNumber();
+ nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("3456");
+ assertEquals(nzNumber, phoneUtil.parse("03 331 6005 ext 3456", RegionCode.NZ));
+ assertEquals(nzNumber, phoneUtil.parse("03-3316005x3456", RegionCode.NZ));
+ assertEquals(nzNumber, phoneUtil.parse("03-3316005 int.3456", RegionCode.NZ));
+ assertEquals(nzNumber, phoneUtil.parse("03 3316005 #3456", RegionCode.NZ));
+ // Test the following do not extract extensions:
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 six-flags", RegionCode.US));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 SIX FLAGS", RegionCode.US));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("0~0 1800 7493 5247", RegionCode.PL));
+ assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("(1800) 7493.5247", RegionCode.US));
+ // Check that the last instance of an extension token is matched.
+ PhoneNumber extnNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).setExtension("1234");
+ assertEquals(extnNumber, phoneUtil.parse("0~0 1800 7493 5247 ~1234", RegionCode.PL));
+ // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
+ // extracting the extension. Also verifying a few different cases of extensions.
+ PhoneNumber ukNumber = new PhoneNumber();
+ ukNumber.setCountryCode(44).setNationalNumber(2034567890L).setExtension("456");
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.NZ));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x456", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X456", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X 456", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X 456", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x 456 ", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X 456", RegionCode.GB));
+ assertEquals(ukNumber, phoneUtil.parse("+44-2034567890;ext=456", RegionCode.GB));
+
+ PhoneNumber usWithExtension = new PhoneNumber();
+ usWithExtension.setCountryCode(1).setNationalNumber(8009013355L).setExtension("7246433");
+ assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 x 7246433", RegionCode.US));
+ assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , ext 7246433", RegionCode.US));
+ assertEquals(usWithExtension,
+ phoneUtil.parse("(800) 901-3355 ,extension 7246433", RegionCode.US));
+ assertEquals(usWithExtension,
+ phoneUtil.parse("(800) 901-3355 ,extensi\u00F3n 7246433", RegionCode.US));
+ // Repeat with the small letter o with acute accent created by combining characters.
+ assertEquals(usWithExtension,
+ phoneUtil.parse("(800) 901-3355 ,extensio\u0301n 7246433", RegionCode.US));
+ assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , 7246433", RegionCode.US));
+ assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ext: 7246433", RegionCode.US));
+
+ // Test that if a number has two extensions specified, we ignore the second.
+ PhoneNumber usWithTwoExtensionsNumber = new PhoneNumber();
+ usWithTwoExtensionsNumber.setCountryCode(1).setNationalNumber(2121231234L).setExtension("508");
+ assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/x1234",
+ RegionCode.US));
+ assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/ x1234",
+ RegionCode.US));
+ assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508\\x1234",
+ RegionCode.US));
+
+ // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
+ // the # are an extension.
+ usWithExtension.clear();
+ usWithExtension.setCountryCode(1).setNationalNumber(6451231234L).setExtension("910");
+ assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234-910#", RegionCode.US));
+ // Retry with the same number in a slightly different format.
+ assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234 ext. 910#", RegionCode.US));
+ }
+
+ public void testParseAndKeepRaw() throws Exception {
+ PhoneNumber alphaNumericNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).
+ setRawInput("800 six-flags").
+ setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
+ setPreferredDomesticCarrierCode("");
+ assertEquals(alphaNumericNumber,
+ phoneUtil.parseAndKeepRawInput("800 six-flags", RegionCode.US));
+
+ PhoneNumber shorterAlphaNumber = new PhoneNumber().
+ setCountryCode(1).setNationalNumber(8007493524L).
+ setRawInput("1800 six-flag").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN).
+ setPreferredDomesticCarrierCode("");
+ assertEquals(shorterAlphaNumber,
+ phoneUtil.parseAndKeepRawInput("1800 six-flag", RegionCode.US));
+
+ shorterAlphaNumber.setRawInput("+1800 six-flag").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
+ assertEquals(shorterAlphaNumber,
+ phoneUtil.parseAndKeepRawInput("+1800 six-flag", RegionCode.NZ));
+
+ shorterAlphaNumber.setRawInput("001800 six-flag").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_IDD);
+ assertEquals(shorterAlphaNumber,
+ phoneUtil.parseAndKeepRawInput("001800 six-flag", RegionCode.NZ));
+
+ // Invalid region code supplied.
+ try {
+ phoneUtil.parseAndKeepRawInput("123 456 7890", RegionCode.CS);
+ fail("Deprecated region code not allowed: should fail.");
+ } catch (NumberParseException e) {
+ // Expected this exception.
+ assertEquals("Wrong error type stored in exception.",
+ NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
+ e.getErrorType());
+ }
+
+ PhoneNumber koreanNumber = new PhoneNumber();
+ koreanNumber.setCountryCode(82).setNationalNumber(22123456).setRawInput("08122123456").
+ setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
+ setPreferredDomesticCarrierCode("81");
+ assertEquals(koreanNumber, phoneUtil.parseAndKeepRawInput("08122123456", RegionCode.KR));
+ }
+
+ public void testCountryWithNoNumberDesc() {
+ // Andorra is a country where we don't have PhoneNumberDesc info in the metadata.
+ PhoneNumber adNumber = new PhoneNumber();
+ adNumber.setCountryCode(376).setNationalNumber(12345L);
+ assertEquals("+376 12345", phoneUtil.format(adNumber, PhoneNumberFormat.INTERNATIONAL));
+ assertEquals("+37612345", phoneUtil.format(adNumber, PhoneNumberFormat.E164));
+ assertEquals("12345", phoneUtil.format(adNumber, PhoneNumberFormat.NATIONAL));
+ assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(adNumber));
+ assertTrue(phoneUtil.isValidNumber(adNumber));
+
+ // Test dialing a US number from within Andorra.
+ assertEquals("00 1 650 253 0000",
+ phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.AD));
+ }
+
+ public void testUnknownCountryCallingCodeForValidation() {
+ PhoneNumber invalidNumber = new PhoneNumber();
+ invalidNumber.setCountryCode(0).setNationalNumber(1234L);
+ assertFalse(phoneUtil.isValidNumber(invalidNumber));
+ }
+
+ public void testIsNumberMatchMatches() throws Exception {
+ // Test simple matches where formatting is different, or leading zeroes, or country calling code
+ // has been specified.
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331 6005", "+64 03 331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+64 03 331-6005", "+64 03331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+643 331-6005", "+64033316005"));
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+643 331-6005", "+6433316005"));
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005", "+6433316005"));
+ // Test alpha numbers.
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+1800 siX-Flags", "+1 800 7493 5247"));
+ // Test numbers with extensions.
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "+6433316005#1234"));
+ // Test proto buffers.
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch(NZ_NUMBER, "+6403 331 6005"));
+
+ PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("3456");
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch(nzNumber, "+643 331 6005 ext 3456"));
+ // Check empty extensions are ignored.
+ nzNumber.setExtension("");
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch(nzNumber, "+6403 331 6005"));
+ // Check variant with two proto buffers.
+ assertEquals("Number " + nzNumber.toString() + " did not match " + NZ_NUMBER.toString(),
+ PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch(nzNumber, NZ_NUMBER));
+
+ // Check raw_input, country_code_source and preferred_domestic_carrier_code are ignored.
+ PhoneNumber brNumberOne = new PhoneNumber();
+ PhoneNumber brNumberTwo = new PhoneNumber();
+ brNumberOne.setCountryCode(55).setNationalNumber(3121286979L)
+ .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)
+ .setPreferredDomesticCarrierCode("12").setRawInput("012 3121286979");
+ brNumberTwo.setCountryCode(55).setNationalNumber(3121286979L)
+ .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY)
+ .setPreferredDomesticCarrierCode("14").setRawInput("143121286979");
+ assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
+ phoneUtil.isNumberMatch(brNumberOne, brNumberTwo));
+ }
+
+ public void testIsNumberMatchNonMatches() throws Exception {
+ // Non-matches.
+ assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
+ phoneUtil.isNumberMatch("03 331 6005", "03 331 6006"));
+ // Different country calling code, partial number match.
+ assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005", "+16433316005"));
+ // Different country calling code, same number.
+ assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005", "+6133316005"));
+ // Extension different, all else the same.
+ assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "0116433316005#1235"));
+ // NSN matches, but extension is different - not the same number.
+ assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005 ext.1235", "3 331 6005#1234"));
+
+ // Invalid numbers that can't be parsed.
+ assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
+ phoneUtil.isNumberMatch("43", "3 331 6043"));
+ assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
+ phoneUtil.isNumberMatch("+43", "+64 3 331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
+ phoneUtil.isNumberMatch("+43", "64 3 331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
+ phoneUtil.isNumberMatch("Dog", "64 3 331 6005"));
+ }
+
+ public void testIsNumberMatchNsnMatches() throws Exception {
+ // NSN matches.
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005", "03 331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch(NZ_NUMBER, "03 331 6005"));
+ // Here the second number possibly starts with the country calling code for New Zealand,
+ // although we are unsure.
+ PhoneNumber unchangedNzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER);
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch(unchangedNzNumber, "(64-3) 331 6005"));
+ // Check the phone number proto was not edited during the method call.
+ assertEquals(NZ_NUMBER, unchangedNzNumber);
+
+ // Here, the 1 might be a national prefix, if we compare it to the US number, so the resultant
+ // match is an NSN match.
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch(US_NUMBER, "1-650-253-0000"));
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch(US_NUMBER, "6502530000"));
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch("+1 650-253 0000", "1 650 253 0000"));
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch("1 650-253 0000", "1 650 253 0000"));
+ assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
+ phoneUtil.isNumberMatch("1 650-253 0000", "+1 650 253 0000"));
+ // For this case, the match will be a short NSN match, because we cannot assume that the 1 might
+ // be a national prefix, so don't remove it when parsing.
+ PhoneNumber randomNumber = new PhoneNumber();
+ randomNumber.setCountryCode(41).setNationalNumber(6502530000L);
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch(randomNumber, "1-650-253-0000"));
+ }
+
+ public void testIsNumberMatchShortNsnMatches() throws Exception {
+ // Short NSN matches with the country not specified for either one or both numbers.
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005", "331 6005"));
+ // We did not know that the "0" was a national prefix since neither number has a country code,
+ // so this is considered a SHORT_NSN_MATCH.
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("3 331-6005", "03 331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("3 331-6005", "331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("3 331-6005", "+64 331 6005"));
+ // Short NSN match with the country specified.
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("03 331-6005", "331 6005"));
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("1 234 345 6789", "345 6789"));
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("+1 (234) 345 6789", "345 6789"));
+ // NSN matches, country calling code omitted for one number, extension missing for one.
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch("+64 3 331-6005", "3 331 6005#1234"));
+ // One has Italian leading zero, one does not.
+ PhoneNumber italianNumberOne = new PhoneNumber();
+ italianNumberOne.setCountryCode(39).setNationalNumber(1234L).setItalianLeadingZero(true);
+ PhoneNumber italianNumberTwo = new PhoneNumber();
+ italianNumberTwo.setCountryCode(39).setNationalNumber(1234L);
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
+ // One has an extension, the other has an extension of "".
+ italianNumberOne.setExtension("1234").clearItalianLeadingZero();
+ italianNumberTwo.setExtension("");
+ assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
+ phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
+ }
+
+ public void testCanBeInternationallyDialled() throws Exception {
+ // We have no-international-dialling rules for the US in our test metadata that say that
+ // toll-free numbers cannot be dialled internationally.
+ assertFalse(phoneUtil.canBeInternationallyDialled(US_TOLLFREE));
+
+ // Normal US numbers can be internationally dialled.
+ assertTrue(phoneUtil.canBeInternationallyDialled(US_NUMBER));
+
+ // Invalid number.
+ assertTrue(phoneUtil.canBeInternationallyDialled(US_LOCAL_NUMBER));
+
+ // We have no data for NZ - should return true.
+ assertTrue(phoneUtil.canBeInternationallyDialled(NZ_NUMBER));
+ }
+
+ public void testIsAlphaNumber() throws Exception {
+ assertTrue(phoneUtil.isAlphaNumber("1800 six-flags"));
+ assertTrue(phoneUtil.isAlphaNumber("1800 six-flags ext. 1234"));
+ assertFalse(phoneUtil.isAlphaNumber("1800 123-1234"));
+ assertFalse(phoneUtil.isAlphaNumber("1800 123-1234 extension: 1234"));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhonenumberTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhonenumberTest.java
new file mode 100644
index 0000000..466a0e3
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhonenumberTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.Phonenumber.PhoneNumber;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for the Phonenumber.PhoneNumber object itself.
+ *
+ * @author Lara Rennie
+ */
+public class PhonenumberTest extends TestCase {
+
+ public void testEqualSimpleNumber() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L);
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L);
+
+ assertEquals(numberA, numberB);
+ assertEquals(numberA.hashCode(), numberB.hashCode());
+ }
+
+ public void testEqualWithItalianLeadingZeroSetToDefault() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(false);
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L);
+
+ // These should still be equal, since the default value for this field is false.
+ assertEquals(numberA, numberB);
+ assertEquals(numberA.hashCode(), numberB.hashCode());
+ }
+
+ public void testEqualWithCountryCodeSourceSet() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setRawInput("+1 650 253 00 00").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setRawInput("+1 650 253 00 00").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
+ assertEquals(numberA, numberB);
+ assertEquals(numberA.hashCode(), numberB.hashCode());
+ }
+
+ public void testNonEqualWithItalianLeadingZeroSetToTrue() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(true);
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L);
+
+ assertFalse(numberA.equals(numberB));
+ assertFalse(numberA.hashCode() == numberB.hashCode());
+ }
+
+ public void testNonEqualWithDifferingRawInput() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1 650 253 00 00").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
+
+ PhoneNumber numberB = new PhoneNumber();
+ // Although these numbers would pass an isNumberMatch test, they are not considered "equal" as
+ // objects, since their raw input is different.
+ numberB.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1-650-253-00-00").
+ setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
+
+ assertFalse(numberA.equals(numberB));
+ assertFalse(numberA.hashCode() == numberB.hashCode());
+ }
+
+ public void testNonEqualWithPreferredDomesticCarrierCodeSetToDefault() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L);
+
+ assertFalse(numberA.equals(numberB));
+ assertFalse(numberA.hashCode() == numberB.hashCode());
+ }
+
+ public void testEqualWithPreferredDomesticCarrierCodeSetToDefault() throws Exception {
+ PhoneNumber numberA = new PhoneNumber();
+ numberA.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");
+
+ PhoneNumber numberB = new PhoneNumber();
+ numberB.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");
+
+ assertEquals(numberA, numberB);
+ assertEquals(numberA.hashCode(), numberB.hashCode());
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/RegexCacheTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/RegexCacheTest.java
new file mode 100644
index 0000000..a2839d3
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/RegexCacheTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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 junit.framework.TestCase;
+
+/**
+ * Unittests for LRU Cache for compiled regular expressions used by the libphonenumbers libary.
+ *
+ * @author Shaopeng Jia
+ */
+
+public class RegexCacheTest extends TestCase {
+ private RegexCache regexCache;
+
+ public RegexCacheTest() {
+ regexCache = new RegexCache(2);
+ }
+
+ public void testRegexInsertion() {
+ final String regex1 = "[1-5]";
+ final String regex2 = "(?:12|34)";
+ final String regex3 = "[1-3][58]";
+
+ regexCache.getPatternForRegex(regex1);
+ assertTrue(regexCache.containsRegex(regex1));
+
+ regexCache.getPatternForRegex(regex2);
+ assertTrue(regexCache.containsRegex(regex2));
+ assertTrue(regexCache.containsRegex(regex1));
+
+ regexCache.getPatternForRegex(regex1);
+ assertTrue(regexCache.containsRegex(regex1));
+
+ regexCache.getPatternForRegex(regex3);
+ assertTrue(regexCache.containsRegex(regex3));
+
+ assertFalse(regexCache.containsRegex(regex2));
+ assertTrue(regexCache.containsRegex(regex1));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java
new file mode 100644
index 0000000..36e44e5
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+/**
+ * Class containing string constants of region codes for easier testing.
+ */
+final class RegionCode {
+ static final String AD = "AD";
+ static final String AO = "AO";
+ static final String AR = "AR";
+ static final String AU = "AU";
+ static final String BR = "BR";
+ static final String BS = "BS";
+ static final String CA = "CA";
+ static final String CN = "CN";
+ static final String CS = "CS";
+ static final String DE = "DE";
+ static final String GB = "GB";
+ static final String IT = "IT";
+ static final String JP = "JP";
+ static final String KR = "KR";
+ static final String MX = "MX";
+ static final String NZ = "NZ";
+ static final String PL = "PL";
+ static final String RE = "RE";
+ static final String SG = "SG";
+ static final String US = "US";
+ static final String YT = "YT";
+ static final String ZW = "ZW";
+ // Official code for the unknown region.
+ static final String ZZ = "ZZ";
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java
new file mode 100644
index 0000000..20644d2
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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 junit.framework.TestCase;
+
+import java.io.InputStream;
+
+/**
+ * Unit tests for ShortNumberUtil.java
+ *
+ * @author Shaopeng Jia
+ */
+public class ShortNumberUtilTest extends TestCase {
+ private ShortNumberUtil shortUtil;
+ static final String TEST_META_DATA_FILE_PREFIX =
+ "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting";
+
+ public ShortNumberUtilTest() {
+ PhoneNumberUtil.resetInstance();
+ PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(
+ TEST_META_DATA_FILE_PREFIX,
+ CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
+ shortUtil = new ShortNumberUtil(phoneUtil);
+ }
+
+ public void testConnectsToEmergencyNumber_US() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("911", RegionCode.US));
+ assertTrue(shortUtil.connectsToEmergencyNumber("119", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("999", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumberLongNumber_US() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("9116666666", RegionCode.US));
+ assertTrue(shortUtil.connectsToEmergencyNumber("1196666666", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("9996666666", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumberWithFormatting_US() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("9-1-1", RegionCode.US));
+ assertTrue(shortUtil.connectsToEmergencyNumber("1-1-9", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("9-9-9", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumberWithPlusSign_US() {
+ assertFalse(shortUtil.connectsToEmergencyNumber("+911", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("\uFF0B911", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber(" +911", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("+119", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("+999", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumber_BR() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("911", RegionCode.BR));
+ assertTrue(shortUtil.connectsToEmergencyNumber("190", RegionCode.BR));
+ assertFalse(shortUtil.connectsToEmergencyNumber("999", RegionCode.BR));
+ }
+
+ public void testConnectsToEmergencyNumberLongNumber_BR() {
+ // Brazilian emergency numbers don't work when additional digits are appended.
+ assertFalse(shortUtil.connectsToEmergencyNumber("9111", RegionCode.BR));
+ assertFalse(shortUtil.connectsToEmergencyNumber("1900", RegionCode.BR));
+ assertFalse(shortUtil.connectsToEmergencyNumber("9996", RegionCode.BR));
+ }
+
+ public void testConnectsToEmergencyNumber_AO() {
+ // Angola doesn't have any metadata for emergency numbers in the test metadata.
+ assertFalse(shortUtil.connectsToEmergencyNumber("911", RegionCode.AO));
+ assertFalse(shortUtil.connectsToEmergencyNumber("222123456", RegionCode.AO));
+ assertFalse(shortUtil.connectsToEmergencyNumber("923123456", RegionCode.AO));
+ }
+
+ public void testConnectsToEmergencyNumber_ZW() {
+ // Zimbabwe doesn't have any metadata in the test metadata.
+ assertFalse(shortUtil.connectsToEmergencyNumber("911", RegionCode.ZW));
+ assertFalse(shortUtil.connectsToEmergencyNumber("01312345", RegionCode.ZW));
+ assertFalse(shortUtil.connectsToEmergencyNumber("0711234567", RegionCode.ZW));
+ }
+
+ public void testIsEmergencyNumber_US() {
+ assertTrue(shortUtil.isEmergencyNumber("911", RegionCode.US));
+ assertTrue(shortUtil.isEmergencyNumber("119", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("999", RegionCode.US));
+ }
+
+ public void testIsEmergencyNumberLongNumber_US() {
+ assertFalse(shortUtil.isEmergencyNumber("9116666666", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("1196666666", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("9996666666", RegionCode.US));
+ }
+
+ public void testIsEmergencyNumberWithFormatting_US() {
+ assertTrue(shortUtil.isEmergencyNumber("9-1-1", RegionCode.US));
+ assertTrue(shortUtil.isEmergencyNumber("*911", RegionCode.US));
+ assertTrue(shortUtil.isEmergencyNumber("1-1-9", RegionCode.US));
+ assertTrue(shortUtil.isEmergencyNumber("*119", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("9-9-9", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("*999", RegionCode.US));
+ }
+
+ public void testIsEmergencyNumberWithPlusSign_US() {
+ assertFalse(shortUtil.isEmergencyNumber("+911", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("\uFF0B911", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber(" +911", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("+119", RegionCode.US));
+ assertFalse(shortUtil.isEmergencyNumber("+999", RegionCode.US));
+ }
+
+ public void testIsEmergencyNumber_BR() {
+ assertTrue(shortUtil.isEmergencyNumber("911", RegionCode.BR));
+ assertTrue(shortUtil.isEmergencyNumber("190", RegionCode.BR));
+ assertFalse(shortUtil.isEmergencyNumber("999", RegionCode.BR));
+ }
+
+ public void testIsEmergencyNumberLongNumber_BR() {
+ assertFalse(shortUtil.isEmergencyNumber("9111", RegionCode.BR));
+ assertFalse(shortUtil.isEmergencyNumber("1900", RegionCode.BR));
+ assertFalse(shortUtil.isEmergencyNumber("9996", RegionCode.BR));
+ }
+
+ public void testIsEmergencyNumber_AO() {
+ // Angola doesn't have any metadata for emergency numbers in the test metadata.
+ assertFalse(shortUtil.isEmergencyNumber("911", RegionCode.AO));
+ assertFalse(shortUtil.isEmergencyNumber("222123456", RegionCode.AO));
+ assertFalse(shortUtil.isEmergencyNumber("923123456", RegionCode.AO));
+ }
+
+ public void testIsEmergencyNumber_ZW() {
+ // Zimbabwe doesn't have any metadata in the test metadata.
+ assertFalse(shortUtil.isEmergencyNumber("911", RegionCode.ZW));
+ assertFalse(shortUtil.isEmergencyNumber("01312345", RegionCode.ZW));
+ assertFalse(shortUtil.isEmergencyNumber("0711234567", RegionCode.ZW));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java.orig b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java.orig
new file mode 100644
index 0000000..b1ae29b
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberUtilTest.java.orig
@@ -0,0 +1,76 @@
+/*
+ * 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 junit.framework.TestCase;
+
+import java.io.InputStream;
+
+/**
+ * @author Shaopeng Jia
+ */
+public class ShortNumberUtilTest extends TestCase {
+ private ShortNumberUtil shortUtil;
+ static final String TEST_META_DATA_FILE_PREFIX =
+ "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting";
+
+ public ShortNumberUtilTest() {
+ PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(
+ TEST_META_DATA_FILE_PREFIX,
+ CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
+ shortUtil = new ShortNumberUtil(phoneUtil);
+ }
+
+ public void testConnectsToEmergencyNumber_US() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("911", RegionCode.US));
+ assertTrue(shortUtil.connectsToEmergencyNumber("119", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("999", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumberLongNumber_US() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("9116666666", RegionCode.US));
+ assertTrue(shortUtil.connectsToEmergencyNumber("1196666666", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("9996666666", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumberWithFormatting_US() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("9-1-1", RegionCode.US));
+ assertTrue(shortUtil.connectsToEmergencyNumber("1-1-9", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("9-9-9", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumberWithPlusSign_US() {
+ assertFalse(shortUtil.connectsToEmergencyNumber("+911", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("\uFF0B911", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber(" +911", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("+119", RegionCode.US));
+ assertFalse(shortUtil.connectsToEmergencyNumber("+999", RegionCode.US));
+ }
+
+ public void testConnectsToEmergencyNumber_BR() {
+ assertTrue(shortUtil.connectsToEmergencyNumber("911", RegionCode.BR));
+ assertTrue(shortUtil.connectsToEmergencyNumber("190", RegionCode.BR));
+ assertFalse(shortUtil.connectsToEmergencyNumber("999", RegionCode.BR));
+ }
+
+ public void testConnectsToEmergencyNumberLongNumber_BR() {
+ // Brazilian emergency numbers don't work when additional digits are appended.
+ assertFalse(shortUtil.connectsToEmergencyNumber("9111", RegionCode.BR));
+ assertFalse(shortUtil.connectsToEmergencyNumber("1900", RegionCode.BR));
+ assertFalse(shortUtil.connectsToEmergencyNumber("9996", RegionCode.BR));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AD b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AD
new file mode 100644
index 0000000..8dba7fa
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AD
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AO b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AO
new file mode 100644
index 0000000..44b042e
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AO
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
new file mode 100644
index 0000000..549bc8b
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AU b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AU
new file mode 100644
index 0000000..b3ee483
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AU
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BR b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BR
new file mode 100644
index 0000000..fc33520
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BR
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BS b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BS
new file mode 100644
index 0000000..7ec5aa3
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BS
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE
new file mode 100644
index 0000000..42d58fe
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_DE
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB
new file mode 100644
index 0000000..171bbc0
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_IT b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_IT
new file mode 100644
index 0000000..be4d9c1
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_IT
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_JP b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_JP
new file mode 100644
index 0000000..1dbb2b1
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_JP
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR
new file mode 100644
index 0000000..21c764e
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_KR
Binary files 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
new file mode 100644
index 0000000..854f020
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_NZ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_NZ
new file mode 100644
index 0000000..d3b27a6
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_NZ
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_PL b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_PL
new file mode 100644
index 0000000..9b082df
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_PL
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_RE b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_RE
new file mode 100644
index 0000000..02b38fa
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_RE
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_SG b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_SG
new file mode 100644
index 0000000..c5df8dc
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_SG
Binary files 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
new file mode 100644
index 0000000..cf65f6a
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_YT b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_YT
new file mode 100644
index 0000000..ecee4a4
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_YT
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java
new file mode 100644
index 0000000..84ec90d
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.geocoding;
+
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Unittests for AreaCodeMap.java
+ *
+ * @author Shaopeng Jia
+ */
+public class AreaCodeMapTest extends TestCase {
+ private final AreaCodeMap areaCodeMapForUS = new AreaCodeMap();
+ private final AreaCodeMap areaCodeMapForIT = new AreaCodeMap();
+ private PhoneNumber number = new PhoneNumber();
+
+ public AreaCodeMapTest() {
+ SortedMap<Integer, String> sortedMapForUS = new TreeMap<Integer, String>();
+ sortedMapForUS.put(1212, "New York");
+ sortedMapForUS.put(1480, "Arizona");
+ sortedMapForUS.put(1650, "California");
+ sortedMapForUS.put(1907, "Alaska");
+ sortedMapForUS.put(1201664, "Westwood, NJ");
+ sortedMapForUS.put(1480893, "Phoenix, AZ");
+ sortedMapForUS.put(1501372, "Little Rock, AR");
+ sortedMapForUS.put(1626308, "Alhambra, CA");
+ sortedMapForUS.put(1650345, "San Mateo, CA");
+ sortedMapForUS.put(1867993, "Dawson, YT");
+ sortedMapForUS.put(1972480, "Richardson, TX");
+
+ areaCodeMapForUS.readAreaCodeMap(sortedMapForUS);
+
+ SortedMap<Integer, String> sortedMapForIT = new TreeMap<Integer, String>();
+ sortedMapForIT.put(3902, "Milan");
+ sortedMapForIT.put(3906, "Rome");
+ sortedMapForIT.put(39010, "Genoa");
+ sortedMapForIT.put(390131, "Alessandria");
+ sortedMapForIT.put(390321, "Novara");
+ sortedMapForIT.put(390975, "Potenza");
+
+ areaCodeMapForIT.readAreaCodeMap(sortedMapForIT);
+ }
+
+ private static SortedMap<Integer, String> createDefaultStorageMapCandidate() {
+ SortedMap<Integer, String> sortedMap = new TreeMap<Integer, String>();
+ // Make the area codes bigger to store them using integer.
+ sortedMap.put(121212345, "New York");
+ sortedMap.put(148034434, "Arizona");
+ return sortedMap;
+ }
+
+ private static SortedMap<Integer, String> createFlyweightStorageMapCandidate() {
+ SortedMap<Integer, String> sortedMap = new TreeMap<Integer, String>();
+ sortedMap.put(1212, "New York");
+ sortedMap.put(1213, "New York");
+ sortedMap.put(1214, "New York");
+ sortedMap.put(1480, "Arizona");
+ return sortedMap;
+ }
+
+ public void testGetSmallerMapStorageChoosesDefaultImpl() {
+ AreaCodeMapStorageStrategy mapStorage =
+ new AreaCodeMap().getSmallerMapStorage(createDefaultStorageMapCandidate());
+ assertFalse(mapStorage instanceof FlyweightMapStorage);
+ }
+
+ public void testGetSmallerMapStorageChoosesFlyweightImpl() {
+ AreaCodeMapStorageStrategy mapStorage =
+ new AreaCodeMap().getSmallerMapStorage(createFlyweightStorageMapCandidate());
+ assertTrue(mapStorage instanceof FlyweightMapStorage);
+ }
+
+ public void testLookupInvalidNumber_US() {
+ // central office code cannot start with 1.
+ number.setCountryCode(1).setNationalNumber(2121234567L);
+ assertEquals("New York", areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumber_NJ() {
+ number.setCountryCode(1).setNationalNumber(2016641234L);
+ assertEquals("Westwood, NJ", areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumber_NY() {
+ number.setCountryCode(1).setNationalNumber(2126641234L);
+ assertEquals("New York", areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumber_CA_1() {
+ number.setCountryCode(1).setNationalNumber(6503451234L);
+ assertEquals("San Mateo, CA", areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumber_CA_2() {
+ number.setCountryCode(1).setNationalNumber(6502531234L);
+ assertEquals("California", areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumberFound_TX() {
+ number.setCountryCode(1).setNationalNumber(9724801234L);
+ assertEquals("Richardson, TX", areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumberNotFound_TX() {
+ number.setCountryCode(1).setNationalNumber(9724811234L);
+ assertNull(areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumber_CH() {
+ number.setCountryCode(41).setNationalNumber(446681300L);
+ assertNull(areaCodeMapForUS.lookup(number));
+ }
+
+ public void testLookupNumber_IT() {
+ number.setCountryCode(39).setNationalNumber(212345678L).setItalianLeadingZero(true);
+ assertEquals("Milan", areaCodeMapForIT.lookup(number));
+
+ number.setNationalNumber(612345678L);
+ assertEquals("Rome", areaCodeMapForIT.lookup(number));
+
+ number.setNationalNumber(3211234L);
+ assertEquals("Novara", areaCodeMapForIT.lookup(number));
+
+ // A mobile number
+ number.setNationalNumber(321123456L).setItalianLeadingZero(false);
+ assertNull(areaCodeMapForIT.lookup(number));
+
+ // An invalid number (too short)
+ number.setNationalNumber(321123L).setItalianLeadingZero(true);
+ assertEquals("Novara", areaCodeMapForIT.lookup(number));
+ }
+
+ /**
+ * Creates a new area code map serializing the provided area code map to a stream and then reading
+ * this stream. The resulting area code map is expected to be strictly equal to the provided one
+ * from which it was generated.
+ */
+ private static AreaCodeMap createNewAreaCodeMap(AreaCodeMap areaCodeMap) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ areaCodeMap.writeExternal(objectOutputStream);
+ objectOutputStream.flush();
+
+ AreaCodeMap newAreaCodeMap = new AreaCodeMap();
+ newAreaCodeMap.readExternal(
+ new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
+ return newAreaCodeMap;
+ }
+
+ public void testReadWriteExternalWithDefaultStrategy() throws IOException {
+ AreaCodeMap localAreaCodeMap = new AreaCodeMap();
+ localAreaCodeMap.readAreaCodeMap(createDefaultStorageMapCandidate());
+ assertFalse(localAreaCodeMap.getAreaCodeMapStorage() instanceof FlyweightMapStorage);
+
+ AreaCodeMap newAreaCodeMap;
+ newAreaCodeMap = createNewAreaCodeMap(localAreaCodeMap);
+ assertEquals(localAreaCodeMap.toString(), newAreaCodeMap.toString());
+ }
+
+ public void testReadWriteExternalWithFlyweightStrategy() throws IOException {
+ AreaCodeMap localAreaCodeMap = new AreaCodeMap();
+ localAreaCodeMap.readAreaCodeMap(createFlyweightStorageMapCandidate());
+ assertTrue(localAreaCodeMap.getAreaCodeMapStorage() instanceof FlyweightMapStorage);
+
+ AreaCodeMap newAreaCodeMap;
+ newAreaCodeMap = createNewAreaCodeMap(localAreaCodeMap);
+ assertEquals(localAreaCodeMap.toString(), newAreaCodeMap.toString());
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorageTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorageTest.java
new file mode 100644
index 0000000..3db1264
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorageTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.geocoding;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Unittests for FlyweightMapStorage.java
+ *
+ * @author Philippe Liard
+ */
+public class FlyweightMapStorageTest extends TestCase {
+ private static final SortedMap<Integer, String> areaCodeMap;
+ static {
+ SortedMap<Integer, String> tmpMap = new TreeMap<Integer, String>();
+ tmpMap.put(331402, "Paris");
+ tmpMap.put(331434, "Paris");
+ tmpMap.put(334910, "Marseille");
+ tmpMap.put(334911, "Marseille");
+ tmpMap.put(334912, "");
+ tmpMap.put(334913, "");
+ areaCodeMap = Collections.unmodifiableSortedMap(tmpMap);
+ }
+
+ private FlyweightMapStorage mapStorage;
+
+ @Override
+ protected void setUp() throws Exception {
+ mapStorage = new FlyweightMapStorage();
+ mapStorage.readFromSortedMap(areaCodeMap);
+ }
+
+ public void testReadFromSortedMap() {
+ assertEquals(331402, mapStorage.getPrefix(0));
+ assertEquals(331434, mapStorage.getPrefix(1));
+ assertEquals(334910, mapStorage.getPrefix(2));
+ assertEquals(334911, mapStorage.getPrefix(3));
+
+ assertEquals("Paris", mapStorage.getDescription(0));
+ assertSame(mapStorage.getDescription(0), mapStorage.getDescription(1));
+
+ assertEquals("Marseille", mapStorage.getDescription(2));
+ assertSame(mapStorage.getDescription(2), mapStorage.getDescription(3));
+ }
+
+ public void testReadFromSortedMapSupportsEmptyDescription() {
+ assertEquals(334912, mapStorage.getPrefix(4));
+ assertEquals(334913, mapStorage.getPrefix(5));
+
+ assertEquals("", mapStorage.getDescription(4));
+ assertSame(mapStorage.getDescription(4), mapStorage.getDescription(5));
+ }
+
+ public void testWriteAndReadExternal() throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ mapStorage.writeExternal(objectOutputStream);
+ objectOutputStream.flush();
+
+ FlyweightMapStorage newMapStorage = new FlyweightMapStorage();
+ ObjectInputStream objectInputStream =
+ new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
+ newMapStorage.readExternal(objectInputStream);
+
+ String expected = mapStorage.toString();
+ assertEquals(expected, newMapStorage.toString());
+ }
+
+ public void testReadExternalThrowsIOExceptionWithMalformedData() throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ objectOutputStream.writeUTF("hello");
+ objectOutputStream.flush();
+ ObjectInputStream objectInputStream =
+ new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
+ FlyweightMapStorage newMapStorage = new FlyweightMapStorage();
+ try {
+ newMapStorage.readExternal(objectInputStream);
+ fail();
+ } catch (IOException e) {
+ // Exception expected.
+ }
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/MappingFileProviderTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/MappingFileProviderTest.java
new file mode 100644
index 0000000..c426189
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/MappingFileProviderTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.geocoding;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Unittests for MappingFileProvider.java
+ *
+ * @author Shaopeng Jia
+ */
+public class MappingFileProviderTest extends TestCase {
+ private final MappingFileProvider mappingProvider = new MappingFileProvider();
+ private static final Logger LOGGER = Logger.getLogger(MappingFileProviderTest.class.getName());
+
+ public MappingFileProviderTest() {
+ SortedMap<Integer, Set<String>> mapping = new TreeMap<Integer, Set<String>>();
+ mapping.put(1, newHashSet("en"));
+ mapping.put(86, newHashSet("zh", "en", "zh_Hant"));
+ mapping.put(41, newHashSet("de", "fr", "it", "rm"));
+ mapping.put(65, newHashSet("en", "zh_Hans", "ms", "ta"));
+
+ mappingProvider.readFileConfigs(mapping);
+ }
+
+ private static HashSet<String> newHashSet(String... strings) {
+ HashSet<String> set = new HashSet<String>();
+ set.addAll(Arrays.asList(strings));
+ return set;
+ }
+
+ public void testReadWriteExternal() {
+ try {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ mappingProvider.writeExternal(objectOutputStream);
+ objectOutputStream.flush();
+
+ MappingFileProvider newMappingProvider = new MappingFileProvider();
+ newMappingProvider.readExternal(
+ new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
+ assertEquals(mappingProvider.toString(), newMappingProvider.toString());
+ } catch (IOException e) {
+ LOGGER.log(Level.SEVERE, e.getMessage());
+ fail();
+ }
+ }
+
+ public void testGetFileName() {
+ assertEquals("1_en", mappingProvider.getFileName(1, "en", "", ""));
+ assertEquals("1_en", mappingProvider.getFileName(1, "en", "", "US"));
+ assertEquals("1_en", mappingProvider.getFileName(1, "en", "", "GB"));
+ assertEquals("41_de", mappingProvider.getFileName(41, "de", "", "CH"));
+ assertEquals("", mappingProvider.getFileName(44, "en", "", "GB"));
+ assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "", ""));
+ assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "Hans", ""));
+ assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "", "CN"));
+ assertEquals("", mappingProvider.getFileName(86, "", "", "CN"));
+ assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "Hans", "CN"));
+ assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "Hans", "SG"));
+ assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "", "SG"));
+ assertEquals("86_zh_Hant", mappingProvider.getFileName(86, "zh", "", "TW"));
+ assertEquals("86_zh_Hant", mappingProvider.getFileName(86, "zh", "", "HK"));
+ assertEquals("86_zh_Hant", mappingProvider.getFileName(86, "zh", "Hant", "TW"));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java
new file mode 100644
index 0000000..e8488e4
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.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.geocoding;
+
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import junit.framework.TestCase;
+
+import java.util.Locale;
+
+/**
+ * Unit tests for PhoneNumberOfflineGeocoder.java
+ *
+ * @author Shaopeng Jia
+ */
+public class PhoneNumberOfflineGeocoderTest extends TestCase {
+ private final PhoneNumberOfflineGeocoder geocoder =
+ new PhoneNumberOfflineGeocoder(TEST_MAPPING_DATA_DIRECTORY);
+ private static final String TEST_MAPPING_DATA_DIRECTORY =
+ "/com/google/i18n/phonenumbers/geocoding/testing_data/";
+
+ // Set up some test numbers to re-use.
+ private static final PhoneNumber KO_NUMBER1 =
+ new PhoneNumber().setCountryCode(82).setNationalNumber(22123456L);
+ private static final PhoneNumber KO_NUMBER2 =
+ new PhoneNumber().setCountryCode(82).setNationalNumber(322123456L);
+ private static final PhoneNumber KO_NUMBER3 =
+ new PhoneNumber().setCountryCode(82).setNationalNumber(6421234567L);
+ private static final PhoneNumber KO_INVALID_NUMBER =
+ new PhoneNumber().setCountryCode(82).setNationalNumber(1234L);
+ private static final PhoneNumber US_NUMBER1 =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
+ private static final PhoneNumber US_NUMBER2 =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(6509600000L);
+ private static final PhoneNumber US_NUMBER3 =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2128120000L);
+ private static final PhoneNumber US_NUMBER4 =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(6174240000L);
+ private static final PhoneNumber US_INVALID_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(123456789L);
+ private static final PhoneNumber BS_NUMBER1 =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L);
+ private static final PhoneNumber AU_NUMBER =
+ new PhoneNumber().setCountryCode(61).setNationalNumber(236618300L);
+ private static final PhoneNumber NUMBER_WITH_INVALID_COUNTRY_CODE =
+ new PhoneNumber().setCountryCode(999).setNationalNumber(2423651234L);
+
+ public void testGetDescriptionForNumberWithNoDataFile() {
+ // No data file containing mappings for US numbers is available in Chinese for the unittests. As
+ // a result, the country name of United States in simplified Chinese is returned.
+ assertEquals("\u7F8E\u56FD",
+ geocoder.getDescriptionForNumber(US_NUMBER1, Locale.SIMPLIFIED_CHINESE));
+ assertEquals("Bahamas",
+ geocoder.getDescriptionForNumber(BS_NUMBER1, new Locale("en", "US")));
+ assertEquals("Australia",
+ geocoder.getDescriptionForNumber(AU_NUMBER, new Locale("en", "US")));
+ assertEquals("", geocoder.getDescriptionForNumber(NUMBER_WITH_INVALID_COUNTRY_CODE,
+ new Locale("en", "US")));
+ }
+
+ public void testGetDescriptionForNumberWithMissingPrefix() {
+ // Test that the name of the country is returned when the number passed in is valid but not
+ // covered by the geocoding data file.
+ assertEquals("United States",
+ geocoder.getDescriptionForNumber(US_NUMBER4, new Locale("en", "US")));
+ }
+
+ public void testGetDescriptionForNumber_en_US() {
+ assertEquals("CA",
+ geocoder.getDescriptionForNumber(US_NUMBER1, new Locale("en", "US")));
+ assertEquals("Mountain View, CA",
+ geocoder.getDescriptionForNumber(US_NUMBER2, new Locale("en", "US")));
+ assertEquals("New York, NY",
+ geocoder.getDescriptionForNumber(US_NUMBER3, new Locale("en", "US")));
+ }
+
+ public void testGetDescriptionForKoreanNumber() {
+ assertEquals("Seoul",
+ geocoder.getDescriptionForNumber(KO_NUMBER1, Locale.ENGLISH));
+ assertEquals("Incheon",
+ geocoder.getDescriptionForNumber(KO_NUMBER2, Locale.ENGLISH));
+ assertEquals("Jeju",
+ geocoder.getDescriptionForNumber(KO_NUMBER3, Locale.ENGLISH));
+ assertEquals("\uC11C\uC6B8",
+ geocoder.getDescriptionForNumber(KO_NUMBER1, Locale.KOREAN));
+ assertEquals("\uC778\uCC9C",
+ geocoder.getDescriptionForNumber(KO_NUMBER2, Locale.KOREAN));
+ }
+
+ public void testGetDescriptionForFallBack() {
+ // No fallback, as the location name for the given phone number is available in the requested
+ // language.
+ assertEquals("Kalifornien",
+ geocoder.getDescriptionForNumber(US_NUMBER1, Locale.GERMAN));
+ // German falls back to English.
+ assertEquals("New York, NY",
+ geocoder.getDescriptionForNumber(US_NUMBER3, Locale.GERMAN));
+ // Italian falls back to English.
+ assertEquals("CA",
+ geocoder.getDescriptionForNumber(US_NUMBER1, Locale.ITALIAN));
+ // Korean doesn't fall back to English.
+ assertEquals("\uB300\uD55C\uBBFC\uAD6D",
+ geocoder.getDescriptionForNumber(KO_NUMBER3, Locale.KOREAN));
+ }
+
+ public void testGetDescriptionForInvalidNumber() {
+ assertEquals("", geocoder.getDescriptionForNumber(KO_INVALID_NUMBER, Locale.ENGLISH));
+ assertEquals("", geocoder.getDescriptionForNumber(US_INVALID_NUMBER, Locale.ENGLISH));
+ }
+}
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_de b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_de
new file mode 100644
index 0000000..2a516e0
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_de
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_en b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_en
new file mode 100644
index 0000000..9af68fa
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1201_en
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1212_en b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1212_en
new file mode 100644
index 0000000..0c3d5d8
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1212_en
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1617_en b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1617_en
new file mode 100644
index 0000000..b4f7c1d
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1617_en
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_de b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_de
new file mode 100644
index 0000000..1fa2f0f
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_de
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_en b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_en
new file mode 100644
index 0000000..a95364e
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1650_en
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1989_en b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1989_en
new file mode 100644
index 0000000..40d8716
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/1989_en
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en
new file mode 100644
index 0000000..cd18ecb
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko
new file mode 100644
index 0000000..dfa91c3
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko
Binary files differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/config b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/config
new file mode 100644
index 0000000..aab8c13
--- /dev/null
+++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/geocoding/testing_data/config
Binary files differ