summaryrefslogtreecommitdiff
path: root/phonenumberutil.h
diff options
context:
space:
mode:
Diffstat (limited to 'phonenumberutil.h')
-rw-r--r--phonenumberutil.h762
1 files changed, 762 insertions, 0 deletions
diff --git a/phonenumberutil.h b/phonenumberutil.h
new file mode 100644
index 0000000..d21542a
--- /dev/null
+++ b/phonenumberutil.h
@@ -0,0 +1,762 @@
+// 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.
+
+// Utility for international phone numbers.
+//
+// Author: Shaopeng Jia
+// Open-sourced by: Philippe Liard
+
+#ifndef I18N_PHONENUMBERS_PHONENUMBERUTIL_H_
+#define I18N_PHONENUMBERS_PHONENUMBERUTIL_H_
+
+#include <stddef.h>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+#include "phonenumbers/phonenumber.pb.h"
+
+class TelephoneNumber;
+
+namespace i18n {
+namespace phonenumbers {
+
+using std::list;
+using std::map;
+using std::pair;
+using std::set;
+using std::string;
+using std::vector;
+
+using google::protobuf::RepeatedPtrField;
+
+class AsYouTypeFormatter;
+class Logger;
+class NumberFormat;
+class PhoneMetadata;
+class PhoneNumberMatcherRegExps;
+class PhoneNumberRegExpsAndMappings;
+class RegExp;
+
+// 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. The list of the
+// codes can be found here:
+// http://www.iso.org/iso/english_country_names_and_code_elements
+
+#ifdef USE_GOOGLE_BASE
+class PhoneNumberUtil {
+ friend struct DefaultSingletonTraits<PhoneNumberUtil>;
+#else
+class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
+ friend class Singleton<PhoneNumberUtil>;
+#endif
+ friend class AsYouTypeFormatter;
+ friend class PhoneNumberMatcher;
+ friend class PhoneNumberMatcherRegExps;
+ friend class PhoneNumberMatcherTest;
+ friend class PhoneNumberRegExpsAndMappings;
+ friend class PhoneNumberUtilTest;
+ public:
+ ~PhoneNumberUtil();
+ static const char kRegionCodeForNonGeoEntity[];
+
+ // INTERNATIONAL and NATIONAL formats are consistent with the definition
+ // in ITU-T Recommendation E. 123. For example, the number of the Google
+ // Zürich 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=".
+ enum PhoneNumberFormat {
+ E164,
+ INTERNATIONAL,
+ NATIONAL,
+ RFC3966
+ };
+
+ // Type of phone numbers.
+ enum PhoneNumberType {
+ FIXED_LINE,
+ MOBILE,
+ // In some regions (e.g. the USA), it is impossible to distinguish between
+ // fixed-line and mobile numbers by looking at the phone number itself.
+ FIXED_LINE_OR_MOBILE,
+ // Freephone lines
+ TOLL_FREE,
+ PREMIUM_RATE,
+ // The cost of this call is shared between the caller and the recipient, and
+ // is hence typically less than PREMIUM_RATE calls. See
+ // http://en.wikipedia.org/wiki/Shared_Cost_Service for more information.
+ SHARED_COST,
+ // Voice over IP numbers. This includes TSoIP (Telephony Service over IP).
+ VOIP,
+ // A personal number is associated with a particular person, and may be
+ // routed to either a MOBILE or FIXED_LINE number. Some more information can
+ // be found here: http://en.wikipedia.org/wiki/Personal_Numbers
+ PERSONAL_NUMBER,
+ PAGER,
+ // Used for "Universal Access Numbers" or "Company Numbers". They may be
+ // further routed to specific offices, but allow one number to be used for a
+ // company.
+ UAN,
+ // Used for "Voice Mail Access Numbers".
+ VOICEMAIL,
+ // A phone number is of type UNKNOWN when it does not fit any of the known
+ // patterns for a specific region.
+ UNKNOWN
+ };
+
+ // Types of phone number matches. See detailed description beside the
+ // IsNumberMatch() method.
+ enum MatchType {
+ INVALID_NUMBER, // NOT_A_NUMBER in the java version.
+ NO_MATCH,
+ SHORT_NSN_MATCH,
+ NSN_MATCH,
+ EXACT_MATCH,
+ };
+
+ enum ErrorType {
+ NO_PARSING_ERROR,
+ INVALID_COUNTRY_CODE_ERROR, // INVALID_COUNTRY_CODE in the java version.
+ NOT_A_NUMBER,
+ TOO_SHORT_AFTER_IDD,
+ TOO_SHORT_NSN,
+ TOO_LONG_NSN, // TOO_LONG in the java version.
+ };
+
+ // Possible outcomes when testing if a PhoneNumber is possible.
+ enum ValidationResult {
+ IS_POSSIBLE,
+ INVALID_COUNTRY_CODE,
+ TOO_SHORT,
+ TOO_LONG,
+ };
+
+ // Convenience method to get a list of what regions the library has metadata
+ // for.
+ void GetSupportedRegions(set<string>* regions) const;
+
+ // Gets a 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, as specified by
+ // DEFAULT_REGIONS_.
+ //
+ // The PhoneNumberUtil is implemented as a singleton. Therefore, calling
+ // getInstance multiple times will only result in one instance being created.
+#ifdef USE_GOOGLE_BASE
+ static PhoneNumberUtil* GetInstance();
+#endif
+
+ // Returns true 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 IsPossibleNumberWithReason or
+ // IsValidNumber should be used.
+ bool IsAlphaNumber(const string& number) const;
+
+ // Converts all alpha characters in a number to their respective digits on
+ // a keypad, but retains existing formatting.
+ void ConvertAlphaCharactersInNumber(string* number) const;
+
+ // 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.
+ void NormalizeDigitsOnly(string* number) const;
+
+ // Gets the national significant number of a phone number. Note a national
+ // significant number doesn't contain a national prefix or any formatting.
+ void GetNationalSignificantNumber(const PhoneNumber& number,
+ string* national_significant_num) const;
+
+ // Gets the length of the geographical area code from the PhoneNumber object
+ // passed in, so that clients could use it to split a national significant
+ // number into geographical area code and subscriber number. It works in such
+ // a way that the resultant subscriber number should be diallable, at least on
+ // some devices. An example of how this could be used:
+ //
+ // const PhoneNumberUtil& phone_util(PhoneNumberUtil::GetInstance());
+ // PhoneNumber number;
+ // phone_util.Parse("16502530000", "US", &number);
+ // string national_significant_number;
+ // phone_util.GetNationalSignificantNumber(number,
+ // &national_significant_number);
+ // string area_code;
+ // string subscriber_number;
+ //
+ // int area_code_length = phone_util.GetLengthOfGeographicalAreaCode(number);
+ // if (area_code_length > 0) {
+ // area_code = national_significant_number.substr(0, area_code_length);
+ // subscriber_number = national_significant_number.substr(
+ // area_code_length, string::npos);
+ // else {
+ // area_code = "";
+ // subscriber_number = national_significant_number;
+ // }
+ //
+ // 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 national_number instead. Read the following carefully before
+ // deciding to use this method:
+ //
+ // - geographical area codes change over time, and this method honors those
+ // changes; therefore, it doesn't guarantee the stability of the result it
+ // produces.
+ // - 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).
+ // - most non-geographical numbers have no area codes, including numbers
+ // from non-geographical entities.
+ // - some geographical numbers have no area codes.
+ int GetLengthOfGeographicalAreaCode(const PhoneNumber& number) const;
+
+ // 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:
+ //
+ // const PhoneNumberUtil& phone_util(PhoneNumberUtil::GetInstance());
+ // PhoneNumber number;
+ // phone_util.Parse("16502530000", "US", &number);
+ // string national_significant_number;
+ // phone_util.GetNationalSignificantNumber(number,
+ // &national_significant_number);
+ // string national_destination_code;
+ // string subscriber_number;
+ //
+ // int national_destination_code_length =
+ // phone_util.GetLengthOfGeographicalAreaCode(number);
+ // if (national_destination_code_length > 0) {
+ // national_destination_code = national_significant_number.substr(
+ // 0, national_destination_code_length);
+ // subscriber_number = national_significant_number.substr(
+ // national_destination_code_length, string::npos);
+ // else {
+ // national_destination_code = "";
+ // subscriber_number = national_significant_number;
+ // }
+ //
+ // Refer to the unittests to see the difference between this function and
+ // GetLengthOfGeographicalAreaCode().
+ int GetLengthOfNationalDestinationCode(const PhoneNumber& number) const;
+
+ // 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.
+ void Format(const PhoneNumber& number,
+ PhoneNumberFormat number_format,
+ string* formatted_number) const;
+
+ // Formats a phone number in the specified format using client-defined
+ // formatting rules.
+ void FormatByPattern(
+ const PhoneNumber& number,
+ PhoneNumberFormat number_format,
+ const RepeatedPtrField<NumberFormat>& user_defined_formats,
+ string* formatted_number) const;
+
+ // Formats a phone number in national format for dialing using the carrier as
+ // specified in the carrier_code. The carrier_code will always be used
+ // regardless of whether the phone number already has a preferred domestic
+ // carrier code stored. If carrier_code contains an empty string, return the
+ // number in national format without any carrier code.
+ void FormatNationalNumberWithCarrierCode(const PhoneNumber& number,
+ const string& carrier_code,
+ string* formatted_number) const;
+
+ // Formats a phone number in national format for dialing using the carrier as
+ // specified in the preferred_domestic_carrier_code field of the PhoneNumber
+ // object passed in. If that is missing, use the fallback_carrier_code passed
+ // in instead. If there is no preferred_domestic_carrier_code, and the
+ // fallback_carrier_code contains an empty string, return the number in
+ // national format without any carrier code.
+ //
+ // Use FormatNationalNumberWithCarrierCode instead if the carrier code passed
+ // in should take precedence over the number's preferred_domestic_carrier_code
+ // when formatting.
+ void FormatNationalNumberWithPreferredCarrierCode(
+ const PhoneNumber& number,
+ const string& fallback_carrier_code,
+ string* formatted_number) const;
+
+ // 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.
+ void FormatNumberForMobileDialing(
+ const PhoneNumber& number,
+ const string& region_calling_from,
+ bool with_formatting,
+ string* formatted_number) const;
+
+ // Formats a phone number for out-of-country dialing purposes.
+ //
+ // 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.
+ void FormatOutOfCountryCallingNumber(
+ const PhoneNumber& number,
+ const string& calling_from,
+ string* formatted_number) const;
+
+ // 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.
+ void FormatInOriginalFormat(const PhoneNumber& number,
+ const string& region_calling_from,
+ string* formatted_number) const;
+
+ // 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.
+ //
+ // Caveats:
+ // 1) 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.
+ // 2) 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.
+ void FormatOutOfCountryKeepingAlphaChars(
+ const PhoneNumber& number,
+ const string& calling_from,
+ string* formatted_number) const;
+
+ // 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. It returns true if a valid phone number can
+ // be successfully extracted.
+ bool TruncateTooLongNumber(PhoneNumber* number) const;
+
+ // Gets the type of a phone number.
+ PhoneNumberType GetNumberType(const PhoneNumber& number) const;
+
+ // 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.
+ bool IsValidNumber(const PhoneNumber& number) const;
+
+ // 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.
+ bool IsValidNumberForRegion(
+ const PhoneNumber& number,
+ const string& region_code) const;
+
+ // Returns the region where a phone number is from. This could be used for
+ // geo-coding at the region level.
+ void GetRegionCodeForNumber(const PhoneNumber& number,
+ string* region_code) const;
+
+ // Returns the country calling code for a specific region. For example,
+ // this would be 1 for the United States, and 64 for New Zealand.
+ int GetCountryCodeForRegion(const string& region_code) const;
+
+ // Returns the region code that matches the specific country code. Note that
+ // it is possible that several regions share the same country calling code
+ // (e.g. US and Canada), and in that case, only one of the regions (normally
+ // the one with the largest population) is returned.
+ void GetRegionCodeForCountryCode(int country_code, string* region_code) const;
+
+ // Checks if this is a region under the North American Numbering Plan
+ // Administration (NANPA).
+ bool IsNANPACountry(const string& region_code) const;
+
+ // 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
+ // strip_non_digits 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 an empty string.
+ void GetNddPrefixForRegion(const string& region_code,
+ bool strip_non_digits,
+ string* national_prefix) const;
+
+ // Checks whether a phone number is a possible number. It provides a more
+ // lenient check than IsValidNumber() in the following sense:
+ // 1. It only checks the length of phone numbers. In particular, it doesn't
+ // check starting digits of the number.
+ // 2. 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().
+ // 3. 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.
+ ValidationResult IsPossibleNumberWithReason(const PhoneNumber& number) const;
+
+ // Convenience wrapper around IsPossibleNumberWithReason. Instead of returning
+ // the reason for failure, this method returns a boolean value.
+ bool IsPossibleNumber(const PhoneNumber& number) const;
+
+ // Checks whether a phone number is a possible number given a number in the
+ // form of a string, and the country where the number could be dialed from.
+ // It provides a more lenient check than IsValidNumber(). See
+ // IsPossibleNumber(const PhoneNumber& number) for details.
+ //
+ // This method first parses the number, then invokes
+ // IsPossibleNumber(const PhoneNumber& number) with the resultant PhoneNumber
+ // object.
+ //
+ // region_dialing_from represents 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 could be dialed from any region. When
+ // it is written as 00 1 650 253 0000, it could be dialed from any region
+ // which uses an international dialling prefix of 00. When it is written as
+ // 650 253 0000, it could only be dialed from within the US, and when written
+ // as 253 0000, it could only be dialed from within a smaller area in the US
+ // (Mountain View, CA, to be more specific).
+ bool IsPossibleNumberForString(
+ const string& number,
+ const string& region_dialing_from) const;
+
+ // Gets a valid fixed-line number for the specified region. Returns false if
+ // the region was unknown, or the region 001 is passed in. For 001
+ // (representing non-geographical numbers), call
+ // GetExampleNumberForNonGeoEntity instead.
+ bool GetExampleNumber(const string& region_code,
+ PhoneNumber* number) const;
+
+ // Gets a valid number of the specified type for the specified region.
+ // Returns false if the region was unknown or 001, or if no example number of
+ // that type could be found. For 001 (representing non-geographical numbers),
+ // call GetExampleNumberForNonGeoEntity instead.
+ bool GetExampleNumberForType(const string& region_code,
+ PhoneNumberType type,
+ PhoneNumber* number) const;
+
+ // Gets a valid number for the specified country calling code for a
+ // non-geographical entity. Returns false if the metadata does not contain
+ // such information, or the country calling code passed in does not belong to
+ // a non-geographical entity.
+ bool GetExampleNumberForNonGeoEntity(
+ int country_calling_code, PhoneNumber* number) const;
+
+ // Parses a string and returns it in proto buffer format. This method will
+ // return an error like INVALID_COUNTRY_CODE if the number is not considered
+ // to be a possible number, and NO_PARSING_ERROR if it parsed correctly. 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
+ // IsValidNumber().
+ //
+ // default_region represents the country 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 country supplied. If the number is guaranteed
+ // to start with a '+' followed by the country calling code, then
+ // "ZZ" can be supplied.
+ ErrorType Parse(const string& number_to_parse,
+ const string& default_region,
+ PhoneNumber* number) const;
+ // Parses a string and returns it in proto buffer format. This method differs
+ // from Parse() in that it always populates the raw_input field of the
+ // protocol buffer with number_to_parse as well as the country_code_source
+ // field.
+ ErrorType ParseAndKeepRawInput(const string& number_to_parse,
+ const string& default_region,
+ PhoneNumber* number) const;
+
+ // Takes two phone numbers and compares them for equality.
+ //
+ // Returns EXACT_MATCH if the country calling 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 country calling code specified,
+ // and the NSNs and extensions are the same.
+ // Returns SHORT_NSN_MATCH if either or both has no country calling code
+ // specified, or the country calling code 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.
+ MatchType IsNumberMatch(const PhoneNumber& first_number,
+ const PhoneNumber& second_number) const;
+
+ // Takes two phone numbers as strings and compares them for equality. This
+ // is a convenience wrapper for IsNumberMatch(PhoneNumber firstNumber,
+ // PhoneNumber secondNumber). No default region is known.
+ // Returns INVALID_NUMBER if either number cannot be parsed into a phone
+ // number.
+ MatchType IsNumberMatchWithTwoStrings(const string& first_number,
+ const string& second_number) const;
+
+ // Takes two phone numbers and compares them for equality. This is a
+ // convenience wrapper for IsNumberMatch(PhoneNumber firstNumber,
+ // PhoneNumber secondNumber). No default region is known.
+ // Returns INVALID_NUMBER if second_number cannot be parsed into a phone
+ // number.
+ MatchType IsNumberMatchWithOneString(const PhoneNumber& first_number,
+ const string& second_number) const;
+
+ // Overrides the default logging system. The provided logger destruction is
+ // handled by this class (i.e don't delete it).
+ static void SetLogger(Logger* logger);
+
+ // Gets an AsYouTypeFormatter for the specific region.
+ // Returns an AsYouTypeFormatter object, which could be used to format phone
+ // numbers in the specific region "as you type".
+ // The deletion of the returned instance is under the responsibility of the
+ // caller.
+ AsYouTypeFormatter* GetAsYouTypeFormatter(const string& region_code) const;
+
+ friend bool ConvertFromTelephoneNumberProto(
+ const TelephoneNumber& proto_to_convert,
+ PhoneNumber* new_proto);
+ friend bool ConvertToTelephoneNumberProto(const PhoneNumber& proto_to_convert,
+ TelephoneNumber* resulting_proto);
+
+ protected:
+ // Check whether the country_calling_code is from a country whose national
+ // significant number could contain a leading zero. An example of such a
+ // country is Italy.
+ bool IsLeadingZeroPossible(int country_calling_code) const;
+
+ private:
+ scoped_ptr<Logger> logger_;
+
+ typedef pair<int, list<string>*> IntRegionsPair;
+
+ // The minimum and maximum length of the national significant number.
+ static const size_t kMinLengthForNsn = 3;
+ // The ITU says the maximum length should be 15, but we have found longer
+ // numbers in Germany.
+ static const size_t kMaxLengthForNsn = 16;
+ // The maximum length of the country calling code.
+ static const size_t kMaxLengthCountryCode = 3;
+
+ static const char kPlusChars[];
+ // 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 const char kValidPunctuation[];
+
+ // 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. The
+ // string preceding this is captured.
+ // This corresponds to SECOND_NUMBER_START in the java version.
+ static const char kCaptureUpToSecondNumberStart[];
+
+ // Helper class holding useful regular expressions and character mappings.
+ scoped_ptr<PhoneNumberRegExpsAndMappings> reg_exps_;
+
+ // A mapping from a country calling code to a RegionCode object which denotes
+ // the region represented by that country calling code. Note regions under
+ // NANPA share the country calling code 1 and Russia and Kazakhstan share the
+ // country calling code 7. Under this map, 1 is mapped to region code "US" and
+ // 7 is mapped to region code "RU". This is implemented as a sorted vector to
+ // achieve better performance.
+ scoped_ptr<vector<IntRegionsPair> > country_calling_code_to_region_code_map_;
+
+ // The set of regions that share country calling code 1.
+ scoped_ptr<set<string> > nanpa_regions_;
+ static const int kNanpaCountryCode = 1;
+
+ // A mapping from a region code to a PhoneMetadata for that region.
+ scoped_ptr<map<string, PhoneMetadata> > region_to_metadata_map_;
+
+ // A mapping from a country calling code for a non-geographical entity to the
+ // PhoneMetadata for that country calling code. Examples of the country
+ // calling codes include 800 (International Toll Free Service) and 808
+ // (International Shared Cost Service).
+ scoped_ptr<map<int, PhoneMetadata> >
+ country_code_to_non_geographical_metadata_map_;
+
+ PhoneNumberUtil();
+
+ // Returns a regular expression for the possible extensions that may be found
+ // in a number, for use when matching.
+ const string& GetExtnPatternsForMatching() const;
+
+ // Checks whether a string contains only valid digits.
+ bool ContainsOnlyValidDigits(const string& s) const;
+
+ // Checks if a format is eligible to be used by the AsYouTypeFormatter.
+ bool IsFormatEligibleForAsYouTypeFormatter(const string& format) const;
+
+ // Trims unwanted end characters from a phone number string.
+ void TrimUnwantedEndChars(string* number) const;
+
+ // Helper function to check region code is not unknown or null.
+ bool IsValidRegionCode(const string& region_code) const;
+
+ // Helper function to check the country calling code is valid.
+ bool HasValidCountryCallingCode(int country_calling_code) const;
+
+ const i18n::phonenumbers::PhoneMetadata* GetMetadataForRegion(
+ const string& region_code) const;
+
+ const i18n::phonenumbers::PhoneMetadata* GetMetadataForNonGeographicalRegion(
+ int country_calling_code) const;
+
+ const i18n::phonenumbers::PhoneMetadata* GetMetadataForRegionOrCallingCode(
+ int country_calling_code,
+ const string& region_code) const;
+
+ // As per GetCountryCodeForRegion, but assumes the validity of the region_code
+ // has already been checked.
+ int GetCountryCodeForValidRegion(const string& region_code) const;
+
+ void GetRegionCodesForCountryCallingCode(
+ int country_calling_code,
+ list<string>* region_codes) const;
+
+ const NumberFormat* ChooseFormattingPatternForNumber(
+ const RepeatedPtrField<NumberFormat>& available_formats,
+ const string& national_number) const;
+
+ void FormatNsnUsingPatternWithCarrier(
+ const string& national_number,
+ const NumberFormat& formatting_pattern,
+ PhoneNumberUtil::PhoneNumberFormat number_format,
+ const string& carrier_code,
+ string* formatted_number) const;
+
+ void FormatNsnUsingPattern(
+ const string& national_number,
+ const NumberFormat& formatting_pattern,
+ PhoneNumberUtil::PhoneNumberFormat number_format,
+ string* formatted_number) const;
+
+ // Check if raw_input, which is assumed to be in the national format, has a
+ // national prefix. The national prefix is assumed to be in digits-only form.
+ bool RawInputContainsNationalPrefix(
+ const string& raw_input,
+ const string& national_prefix,
+ const string& region_code) const;
+
+ // Returns true if a number is from a region whose national significant number
+ // couldn't contain a leading zero, but has the italian_leading_zero field set
+ // to true.
+ bool HasUnexpectedItalianLeadingZero(const PhoneNumber& number) const;
+
+ bool HasFormattingPatternForNumber(const PhoneNumber& number) const;
+
+ // Simple wrapper of FormatNsnWithCarrier for the common case of
+ // no carrier code.
+ void FormatNsn(const string& number,
+ const PhoneMetadata& metadata,
+ PhoneNumberFormat number_format,
+ string* formatted_number) const;
+
+ void FormatNsnWithCarrier(const string& number,
+ const PhoneMetadata& metadata,
+ PhoneNumberFormat number_format,
+ const string& carrier_code,
+ string* formatted_number) const;
+
+ void MaybeAppendFormattedExtension(
+ const PhoneNumber& number,
+ const PhoneMetadata& metadata,
+ PhoneNumberFormat number_format,
+ string* extension) const;
+
+ void GetRegionCodeForNumberFromRegionList(
+ const PhoneNumber& number,
+ const list<string>& region_codes,
+ string* region_code) const;
+
+ // Strips the IDD from the start of the number if present. Helper function
+ // used by MaybeStripInternationalPrefixAndNormalize.
+ bool ParsePrefixAsIdd(const RegExp& idd_pattern, string* number) const;
+
+ void Normalize(string* number) const;
+ PhoneNumber::CountryCodeSource MaybeStripInternationalPrefixAndNormalize(
+ const string& possible_idd_prefix,
+ string* number) const;
+
+ bool MaybeStripNationalPrefixAndCarrierCode(
+ const PhoneMetadata& metadata,
+ string* number,
+ string* carrier_code) const;
+
+ void ExtractPossibleNumber(const string& number,
+ string* extracted_number) const;
+
+ bool IsViablePhoneNumber(const string& number) const;
+
+ bool MaybeStripExtension(string* number, string* extension) const;
+
+ int ExtractCountryCode(string* national_number) const;
+ ErrorType MaybeExtractCountryCode(
+ const PhoneMetadata* default_region_metadata,
+ bool keepRawInput,
+ string* national_number,
+ PhoneNumber* phone_number) const;
+
+ bool CheckRegionForParsing(
+ const string& number_to_parse,
+ const string& default_region) const;
+
+ ErrorType ParseHelper(const string& number_to_parse,
+ const string& default_region,
+ bool keep_raw_input,
+ bool check_region,
+ PhoneNumber* phone_number) const;
+
+ // Returns true if the number can be dialled from outside the region, or
+ // unknown. If the number can only be dialled from within the region, returns
+ // false. Does not check the number is a valid number.
+ bool CanBeInternationallyDialled(const PhoneNumber& number) const;
+
+ DISALLOW_COPY_AND_ASSIGN(PhoneNumberUtil);
+};
+
+} // namespace phonenumbers
+} // namespace i18n
+
+#endif // I18N_PHONENUMBERS_PHONENUMBERUTIL_H_