Home | History | Annotate | Download | only in phonenumbers
      1 // Copyright (C) 2011 The Libphonenumber Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 // http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "phonenumbers/asyoutypeformatter.h"
     16 
     17 #include <cctype>
     18 #include <list>
     19 #include <string>
     20 
     21 #include <google/protobuf/message_lite.h>
     22 
     23 #include "phonenumbers/base/logging.h"
     24 #include "phonenumbers/base/memory/scoped_ptr.h"
     25 #include "phonenumbers/phonemetadata.pb.h"
     26 #include "phonenumbers/phonenumberutil.h"
     27 #include "phonenumbers/regexp_cache.h"
     28 #include "phonenumbers/regexp_factory.h"
     29 #include "phonenumbers/stringutil.h"
     30 #include "phonenumbers/unicodestring.h"
     31 
     32 namespace i18n {
     33 namespace phonenumbers {
     34 
     35 using google::protobuf::RepeatedPtrField;
     36 
     37 namespace {
     38 
     39 const char kPlusSign = '+';
     40 
     41 // A pattern that is used to match character classes in regular expressions.
     42 // An example of a character class is [1-4].
     43 const char kCharacterClassPattern[] = "\\[([^\\[\\]])*\\]";
     44 
     45 // This is the minimum length of national number accrued that is required to
     46 // trigger the formatter. The first element of the leading_digits_pattern of
     47 // each number_format contains a regular expression that matches up to this
     48 // number of digits.
     49 const size_t kMinLeadingDigitsLength = 3;
     50 
     51 // The digits that have not been entered yet will be represented by a \u2008,
     52 // the punctuation space.
     53 const char kDigitPlaceholder[] = "\xE2\x80\x88"; /* "" */
     54 
     55 // Character used when appropriate to separate a prefix, such as a long NDD or a
     56 // country calling code, from the national number.
     57 const char kSeparatorBeforeNationalNumber = ' ';
     58 
     59 // A set of characters that, if found in a national prefix formatting rules, are
     60 // an indicator to us that we should separate the national prefix from the
     61 // number when formatting.
     62 const char kNationalPrefixSeparatorsPattern[] = "[- ]";
     63 
     64 // Replaces any standalone digit in the pattern (not any inside a {} grouping)
     65 // with \d. This function replaces the standalone digit regex used in the Java
     66 // version which is currently not supported by RE2 because it uses a special
     67 // construct (?=).
     68 void ReplacePatternDigits(string* pattern) {
     69   DCHECK(pattern);
     70   string new_pattern;
     71 
     72   for (string::const_iterator it = pattern->begin(); it != pattern->end();
     73        ++it) {
     74     const char current_char = *it;
     75 
     76     if (isdigit(current_char)) {
     77       if (it + 1 != pattern->end()) {
     78         const char next_char = it[1];
     79 
     80         if (next_char != ',' && next_char != '}') {
     81           new_pattern += "\\d";
     82         } else {
     83           new_pattern += current_char;
     84         }
     85       } else {
     86         new_pattern += "\\d";
     87       }
     88     } else {
     89       new_pattern += current_char;
     90     }
     91   }
     92   pattern->assign(new_pattern);
     93 }
     94 
     95 // Matches all the groups contained in 'input' against 'pattern'.
     96 void MatchAllGroups(const string& pattern,
     97                     const string& input,
     98                     const AbstractRegExpFactory& regexp_factory,
     99                     RegExpCache* cache,
    100                     string* group) {
    101   DCHECK(cache);
    102   DCHECK(group);
    103   string new_pattern(pattern);
    104 
    105   // Transforms pattern "(...)(...)(...)" to "(.........)".
    106   strrmm(&new_pattern, "()");
    107   new_pattern = StrCat("(", new_pattern, ")");
    108 
    109   const scoped_ptr<RegExpInput> consume_input(
    110       regexp_factory.CreateInput(input));
    111   bool status =
    112       cache->GetRegExp(new_pattern).Consume(consume_input.get(), group);
    113   DCHECK(status);
    114 }
    115 
    116 PhoneMetadata CreateEmptyMetadata() {
    117   PhoneMetadata metadata;
    118   metadata.set_international_prefix("NA");
    119   return metadata;
    120 }
    121 
    122 }  // namespace
    123 
    124 AsYouTypeFormatter::AsYouTypeFormatter(const string& region_code)
    125     : regexp_factory_(new RegExpFactory()),
    126       regexp_cache_(*regexp_factory_.get(), 64),
    127       current_output_(),
    128       formatting_template_(),
    129       current_formatting_pattern_(),
    130       accrued_input_(),
    131       accrued_input_without_formatting_(),
    132       able_to_format_(true),
    133       input_has_formatting_(false),
    134       is_complete_number_(false),
    135       is_expecting_country_code_(false),
    136       phone_util_(*PhoneNumberUtil::GetInstance()),
    137       default_country_(region_code),
    138       empty_metadata_(CreateEmptyMetadata()),
    139       default_metadata_(GetMetadataForRegion(region_code)),
    140       current_metadata_(default_metadata_),
    141       last_match_position_(0),
    142       original_position_(0),
    143       position_to_remember_(0),
    144       prefix_before_national_number_(),
    145       should_add_space_after_national_prefix_(false),
    146       national_prefix_extracted_(),
    147       national_number_(),
    148       possible_formats_() {
    149 }
    150 
    151 // The metadata needed by this class is the same for all regions sharing the
    152 // same country calling code. Therefore, we return the metadata for "main"
    153 // region for this country calling code.
    154 const PhoneMetadata* AsYouTypeFormatter::GetMetadataForRegion(
    155     const string& region_code) const {
    156   int country_calling_code = phone_util_.GetCountryCodeForRegion(region_code);
    157   string main_country;
    158   phone_util_.GetRegionCodeForCountryCode(country_calling_code, &main_country);
    159   const PhoneMetadata* const metadata =
    160       phone_util_.GetMetadataForRegion(main_country);
    161   if (metadata) {
    162     return metadata;
    163   }
    164   // Set to a default instance of the metadata. This allows us to function with
    165   // an incorrect region code, even if formatting only works for numbers
    166   // specified with "+".
    167   return &empty_metadata_;
    168 }
    169 
    170 bool AsYouTypeFormatter::MaybeCreateNewTemplate() {
    171   // When there are multiple available formats, the formatter uses the first
    172   // format where a formatting template could be created.
    173   for (list<const NumberFormat*>::const_iterator it = possible_formats_.begin();
    174        it != possible_formats_.end(); ++it) {
    175     DCHECK(*it);
    176     const NumberFormat& number_format = **it;
    177     const string& pattern = number_format.pattern();
    178     if (current_formatting_pattern_ == pattern) {
    179       return false;
    180     }
    181     if (CreateFormattingTemplate(number_format)) {
    182       current_formatting_pattern_ = pattern;
    183       SetShouldAddSpaceAfterNationalPrefix(number_format);
    184       // With a new formatting template, the matched position using the old
    185       // template needs to be reset.
    186       last_match_position_ = 0;
    187       return true;
    188     }
    189   }
    190   able_to_format_ = false;
    191   return false;
    192 }
    193 
    194 void AsYouTypeFormatter::GetAvailableFormats(
    195     const string& leading_three_digits) {
    196   const RepeatedPtrField<NumberFormat>& format_list =
    197       (is_complete_number_ &&
    198        current_metadata_->intl_number_format().size() > 0)
    199           ? current_metadata_->intl_number_format()
    200           : current_metadata_->number_format();
    201   bool national_prefix_used_by_country =
    202       current_metadata_->has_national_prefix();
    203   for (RepeatedPtrField<NumberFormat>::const_iterator it = format_list.begin();
    204        it != format_list.end(); ++it) {
    205     if (!national_prefix_used_by_country || is_complete_number_ ||
    206         it->national_prefix_optional_when_formatting() ||
    207         phone_util_.FormattingRuleHasFirstGroupOnly(
    208             it->national_prefix_formatting_rule())) {
    209       if (phone_util_.IsFormatEligibleForAsYouTypeFormatter(it->format())) {
    210         possible_formats_.push_back(&*it);
    211       }
    212     }
    213   }
    214   NarrowDownPossibleFormats(leading_three_digits);
    215 }
    216 
    217 void AsYouTypeFormatter::NarrowDownPossibleFormats(
    218     const string& leading_digits) {
    219   const int index_of_leading_digits_pattern =
    220       leading_digits.length() - kMinLeadingDigitsLength;
    221 
    222   for (list<const NumberFormat*>::iterator it = possible_formats_.begin();
    223        it != possible_formats_.end(); ) {
    224     DCHECK(*it);
    225     const NumberFormat& format = **it;
    226 
    227     if (format.leading_digits_pattern_size() >
    228         index_of_leading_digits_pattern) {
    229       const scoped_ptr<RegExpInput> input(
    230           regexp_factory_->CreateInput(leading_digits));
    231       if (!regexp_cache_.GetRegExp(format.leading_digits_pattern().Get(
    232               index_of_leading_digits_pattern)).Consume(input.get())) {
    233         it = possible_formats_.erase(it);
    234         continue;
    235       }
    236     }  // else the particular format has no more specific leadingDigitsPattern,
    237        // and it should be retained.
    238     ++it;
    239   }
    240 }
    241 
    242 void AsYouTypeFormatter::SetShouldAddSpaceAfterNationalPrefix(
    243     const NumberFormat& format) {
    244   static const scoped_ptr<const RegExp> national_prefix_separators_pattern(
    245       regexp_factory_->CreateRegExp(kNationalPrefixSeparatorsPattern));
    246   should_add_space_after_national_prefix_ =
    247       national_prefix_separators_pattern->PartialMatch(
    248           format.national_prefix_formatting_rule());
    249 }
    250 
    251 bool AsYouTypeFormatter::CreateFormattingTemplate(const NumberFormat& format) {
    252   string number_pattern = format.pattern();
    253 
    254   // The formatter doesn't format numbers when numberPattern contains "|", e.g.
    255   // (20|3)\d{4}. In those cases we quickly return.
    256   if (number_pattern.find('|') != string::npos) {
    257     return false;
    258   }
    259   // Replace anything in the form of [..] with \d.
    260   static const scoped_ptr<const RegExp> character_class_pattern(
    261       regexp_factory_->CreateRegExp(kCharacterClassPattern));
    262   character_class_pattern->GlobalReplace(&number_pattern, "\\\\d");
    263 
    264   // Replace any standalone digit (not the one in d{}) with \d.
    265   ReplacePatternDigits(&number_pattern);
    266 
    267   string number_format = format.format();
    268   formatting_template_.remove();
    269   UnicodeString temp_template;
    270   GetFormattingTemplate(number_pattern, number_format, &temp_template);
    271 
    272   if (temp_template.length() > 0) {
    273     formatting_template_.append(temp_template);
    274     return true;
    275   }
    276   return false;
    277 }
    278 
    279 void AsYouTypeFormatter::GetFormattingTemplate(
    280     const string& number_pattern,
    281     const string& number_format,
    282     UnicodeString* formatting_template) {
    283   DCHECK(formatting_template);
    284 
    285   // Creates a phone number consisting only of the digit 9 that matches the
    286   // number_pattern by applying the pattern to the longest_phone_number string.
    287   static const char longest_phone_number[] = "999999999999999";
    288   string a_phone_number;
    289 
    290   MatchAllGroups(number_pattern, longest_phone_number, *regexp_factory_,
    291                  &regexp_cache_, &a_phone_number);
    292   // No formatting template can be created if the number of digits entered so
    293   // far is longer than the maximum the current formatting rule can accommodate.
    294   if (a_phone_number.length() < national_number_.length()) {
    295     formatting_template->remove();
    296     return;
    297   }
    298   // Formats the number according to number_format.
    299   regexp_cache_.GetRegExp(number_pattern).GlobalReplace(
    300       &a_phone_number, number_format);
    301   // Replaces each digit with character kDigitPlaceholder.
    302   GlobalReplaceSubstring("9", kDigitPlaceholder, &a_phone_number);
    303   formatting_template->setTo(a_phone_number.c_str(), a_phone_number.size());
    304 }
    305 
    306 void AsYouTypeFormatter::Clear() {
    307   current_output_.clear();
    308   accrued_input_.remove();
    309   accrued_input_without_formatting_.remove();
    310   formatting_template_.remove();
    311   last_match_position_ = 0;
    312   current_formatting_pattern_.clear();
    313   prefix_before_national_number_.clear();
    314   national_prefix_extracted_.clear();
    315   national_number_.clear();
    316   able_to_format_ = true;
    317   input_has_formatting_ = false;
    318   position_to_remember_ = 0;
    319   original_position_ = 0;
    320   is_complete_number_ = false;
    321   is_expecting_country_code_ = false;
    322   possible_formats_.clear();
    323   should_add_space_after_national_prefix_ = false;
    324 
    325   if (current_metadata_ != default_metadata_) {
    326     current_metadata_ = GetMetadataForRegion(default_country_);
    327   }
    328 }
    329 
    330 const string& AsYouTypeFormatter::InputDigit(char32 next_char, string* result) {
    331   DCHECK(result);
    332 
    333   InputDigitWithOptionToRememberPosition(next_char, false, &current_output_);
    334   result->assign(current_output_);
    335   return *result;
    336 }
    337 
    338 const string& AsYouTypeFormatter::InputDigitAndRememberPosition(
    339     char32 next_char,
    340     string* result) {
    341   DCHECK(result);
    342 
    343   InputDigitWithOptionToRememberPosition(next_char, true, &current_output_);
    344   result->assign(current_output_);
    345   return *result;
    346 }
    347 
    348 void AsYouTypeFormatter::InputDigitWithOptionToRememberPosition(
    349     char32 next_char,
    350     bool remember_position,
    351     string* phone_number) {
    352   DCHECK(phone_number);
    353 
    354   accrued_input_.append(next_char);
    355   if (remember_position) {
    356     original_position_ = accrued_input_.length();
    357   }
    358   // We do formatting on-the-fly only when each character entered is either a
    359   // plus sign (accepted at the start of the number only).
    360   string next_char_string;
    361   UnicodeString(next_char).toUTF8String(next_char_string);
    362 
    363   char normalized_next_char = '\0';
    364   if (!(phone_util_.ContainsOnlyValidDigits(next_char_string) ||
    365       (accrued_input_.length() == 1 && next_char == kPlusSign))) {
    366     able_to_format_ = false;
    367     input_has_formatting_ = true;
    368   } else {
    369     normalized_next_char =
    370         NormalizeAndAccrueDigitsAndPlusSign(next_char, remember_position);
    371   }
    372   if (!able_to_format_) {
    373     // When we are unable to format because of reasons other than that
    374     // formatting chars have been entered, it can be due to really long IDDs or
    375     // NDDs. If that is the case, we might be able to do formatting again after
    376     // extracting them.
    377     if (input_has_formatting_) {
    378       phone_number->clear();
    379       accrued_input_.toUTF8String(*phone_number);
    380     } else if (AttemptToExtractIdd()) {
    381       if (AttemptToExtractCountryCode()) {
    382         AttemptToChoosePatternWithPrefixExtracted(phone_number);
    383         return;
    384       }
    385     } else if (AbleToExtractLongerNdd()) {
    386       // Add an additional space to separate long NDD and national significant
    387       // number for readability. We don't set
    388       // should_add_space_after_national_prefix_ to true, since we don't want
    389       // this to change later when we choose formatting templates.
    390       prefix_before_national_number_.push_back(kSeparatorBeforeNationalNumber);
    391       AttemptToChoosePatternWithPrefixExtracted(phone_number);
    392       return;
    393     }
    394     phone_number->clear();
    395     accrued_input_.toUTF8String(*phone_number);
    396     return;
    397   }
    398 
    399   // We start to attempt to format only when at least kMinLeadingDigitsLength
    400   // digits (the plus sign is counted as a digit as well for this purpose) have
    401   // been entered.
    402   switch (accrued_input_without_formatting_.length()) {
    403     case 0:
    404     case 1:
    405     case 2:
    406       phone_number->clear();
    407       accrued_input_.toUTF8String(*phone_number);
    408       return;
    409     case 3:
    410       if (AttemptToExtractIdd()) {
    411         is_expecting_country_code_ = true;
    412       } else {
    413         // No IDD or plus sign is found, might be entering in national format.
    414         RemoveNationalPrefixFromNationalNumber(&national_prefix_extracted_);
    415         AttemptToChooseFormattingPattern(phone_number);
    416         return;
    417       }
    418     default:
    419       if (is_expecting_country_code_) {
    420         if (AttemptToExtractCountryCode()) {
    421           is_expecting_country_code_ = false;
    422         }
    423         phone_number->assign(prefix_before_national_number_);
    424         phone_number->append(national_number_);
    425         return;
    426       }
    427       if (possible_formats_.size() > 0) {
    428         // The formatting pattern is already chosen.
    429         string temp_national_number;
    430         InputDigitHelper(normalized_next_char, &temp_national_number);
    431         // See if accrued digits can be formatted properly already. If not, use
    432         // the results from InputDigitHelper, which does formatting based on the
    433         // formatting pattern chosen.
    434         string formatted_number;
    435         AttemptToFormatAccruedDigits(&formatted_number);
    436         if (formatted_number.length() > 0) {
    437           phone_number->assign(formatted_number);
    438           return;
    439         }
    440         NarrowDownPossibleFormats(national_number_);
    441         if (MaybeCreateNewTemplate()) {
    442           InputAccruedNationalNumber(phone_number);
    443           return;
    444         }
    445         if (able_to_format_) {
    446           AppendNationalNumber(temp_national_number, phone_number);
    447         } else {
    448           phone_number->clear();
    449           accrued_input_.toUTF8String(*phone_number);
    450         }
    451         return;
    452       } else {
    453         AttemptToChooseFormattingPattern(phone_number);
    454       }
    455   }
    456 }
    457 
    458 void AsYouTypeFormatter::AttemptToChoosePatternWithPrefixExtracted(
    459     string* formatted_number) {
    460   able_to_format_ = true;
    461   is_expecting_country_code_ = false;
    462   possible_formats_.clear();
    463   AttemptToChooseFormattingPattern(formatted_number);
    464 }
    465 
    466 bool AsYouTypeFormatter::AbleToExtractLongerNdd() {
    467   if (national_prefix_extracted_.length() > 0) {
    468     // Put the extracted NDD back to the national number before attempting to
    469     // extract a new NDD.
    470     national_number_.insert(0, national_prefix_extracted_);
    471     // Remove the previously extracted NDD from prefixBeforeNationalNumber. We
    472     // cannot simply set it to empty string because people sometimes incorrectly
    473     // enter national prefix after the country code, e.g. +44 (0)20-1234-5678.
    474     int index_of_previous_ndd =
    475         prefix_before_national_number_.find_last_of(national_prefix_extracted_);
    476     prefix_before_national_number_.resize(index_of_previous_ndd);
    477   }
    478   string new_national_prefix;
    479   RemoveNationalPrefixFromNationalNumber(&new_national_prefix);
    480   return national_prefix_extracted_ != new_national_prefix;
    481 }
    482 
    483 void AsYouTypeFormatter::AttemptToFormatAccruedDigits(
    484     string* formatted_result) {
    485   DCHECK(formatted_result);
    486 
    487   for (list<const NumberFormat*>::const_iterator it = possible_formats_.begin();
    488        it != possible_formats_.end(); ++it) {
    489     DCHECK(*it);
    490     const NumberFormat& number_format = **it;
    491     const string& pattern = number_format.pattern();
    492 
    493     if (regexp_cache_.GetRegExp(pattern).FullMatch(national_number_)) {
    494       SetShouldAddSpaceAfterNationalPrefix(number_format);
    495 
    496       string formatted_number(national_number_);
    497       bool status = regexp_cache_.GetRegExp(pattern).GlobalReplace(
    498           &formatted_number, number_format.format());
    499       DCHECK(status);
    500 
    501       AppendNationalNumber(formatted_number, formatted_result);
    502       return;
    503     }
    504   }
    505 }
    506 
    507 int AsYouTypeFormatter::GetRememberedPosition() const {
    508   UnicodeString current_output(current_output_.c_str());
    509   if (!able_to_format_) {
    510     return ConvertUnicodeStringPosition(current_output, original_position_);
    511   }
    512   int accrued_input_index = 0;
    513   int current_output_index = 0;
    514 
    515   while (accrued_input_index < position_to_remember_ &&
    516          current_output_index < current_output.length()) {
    517     if (accrued_input_without_formatting_[accrued_input_index] ==
    518         current_output[current_output_index]) {
    519       ++accrued_input_index;
    520     }
    521     ++current_output_index;
    522   }
    523   return ConvertUnicodeStringPosition(current_output, current_output_index);
    524 }
    525 
    526 void AsYouTypeFormatter::AppendNationalNumber(const string& national_number,
    527                                               string* phone_number) const {
    528   int prefix_before_national_number_length =
    529       prefix_before_national_number_.size();
    530   if (should_add_space_after_national_prefix_ &&
    531       prefix_before_national_number_length > 0 &&
    532       prefix_before_national_number_.at(
    533           prefix_before_national_number_length - 1) !=
    534       kSeparatorBeforeNationalNumber) {
    535     // We want to add a space after the national prefix if the national prefix
    536     // formatting rule indicates that this would normally be done, with the
    537     // exception of the case where we already appended a space because the NDD
    538     // was surprisingly long.
    539     phone_number->assign(prefix_before_national_number_);
    540     phone_number->push_back(kSeparatorBeforeNationalNumber);
    541     StrAppend(phone_number, national_number);
    542   } else {
    543     phone_number->assign(
    544         StrCat(prefix_before_national_number_, national_number));
    545   }
    546 }
    547 
    548 void AsYouTypeFormatter::AttemptToChooseFormattingPattern(
    549     string* formatted_number) {
    550   DCHECK(formatted_number);
    551 
    552   if (national_number_.length() >= kMinLeadingDigitsLength) {
    553     const string leading_digits =
    554         national_number_.substr(0, kMinLeadingDigitsLength);
    555 
    556     GetAvailableFormats(leading_digits);
    557     if (MaybeCreateNewTemplate()) {
    558       InputAccruedNationalNumber(formatted_number);
    559     } else {
    560       formatted_number->clear();
    561       accrued_input_.toUTF8String(*formatted_number);
    562     }
    563     return;
    564   } else {
    565     AppendNationalNumber(national_number_, formatted_number);
    566   }
    567 }
    568 
    569 void AsYouTypeFormatter::InputAccruedNationalNumber(string* number) {
    570   DCHECK(number);
    571   int length_of_national_number = national_number_.length();
    572 
    573   if (length_of_national_number > 0) {
    574     string temp_national_number;
    575 
    576     for (int i = 0; i < length_of_national_number; ++i) {
    577       temp_national_number.clear();
    578       InputDigitHelper(national_number_[i], &temp_national_number);
    579     }
    580     if (able_to_format_) {
    581       AppendNationalNumber(temp_national_number, number);
    582     } else {
    583       number->clear();
    584       accrued_input_.toUTF8String(*number);
    585     }
    586     return;
    587   } else {
    588     number->assign(prefix_before_national_number_);
    589   }
    590 }
    591 
    592 bool AsYouTypeFormatter::IsNanpaNumberWithNationalPrefix() const {
    593   // For NANPA numbers beginning with 1[2-9], treat the 1 as the national
    594   // prefix. The reason is that national significant numbers in NANPA always
    595   // start with [2-9] after the national prefix.  Numbers beginning with 1[01]
    596   // can only be short/emergency numbers, which don't need the national
    597   // prefix.
    598   return (current_metadata_->country_code() == 1) &&
    599          (national_number_[0] == '1') && (national_number_[1] != '0') &&
    600          (national_number_[1] != '1');
    601 }
    602 
    603 void AsYouTypeFormatter::RemoveNationalPrefixFromNationalNumber(
    604     string* national_prefix) {
    605   int start_of_national_number = 0;
    606 
    607   if (IsNanpaNumberWithNationalPrefix()) {
    608     start_of_national_number = 1;
    609     prefix_before_national_number_.append("1");
    610     prefix_before_national_number_.push_back(kSeparatorBeforeNationalNumber);
    611     is_complete_number_ = true;
    612   } else if (current_metadata_->has_national_prefix_for_parsing()) {
    613     const scoped_ptr<RegExpInput> consumed_input(
    614         regexp_factory_->CreateInput(national_number_));
    615     const RegExp& pattern = regexp_cache_.GetRegExp(
    616         current_metadata_->national_prefix_for_parsing());
    617 
    618     if (pattern.Consume(consumed_input.get())) {
    619       // When the national prefix is detected, we use international formatting
    620       // rules instead of national ones, because national formatting rules could
    621       // countain local formatting rules for numbers entered without area code.
    622       is_complete_number_ = true;
    623       start_of_national_number =
    624           national_number_.length() - consumed_input->ToString().length();
    625       prefix_before_national_number_.append(
    626           national_number_.substr(0, start_of_national_number));
    627     }
    628   }
    629   national_prefix->assign(national_number_, 0, start_of_national_number);
    630   national_number_.erase(0, start_of_national_number);
    631 }
    632 
    633 bool AsYouTypeFormatter::AttemptToExtractIdd() {
    634   string accrued_input_without_formatting_stdstring;
    635   accrued_input_without_formatting_
    636       .toUTF8String(accrued_input_without_formatting_stdstring);
    637   const scoped_ptr<RegExpInput> consumed_input(
    638       regexp_factory_->CreateInput(accrued_input_without_formatting_stdstring));
    639   const RegExp& international_prefix = regexp_cache_.GetRegExp(
    640       StrCat("\\", string(&kPlusSign, 1), "|",
    641              current_metadata_->international_prefix()));
    642 
    643   if (international_prefix.Consume(consumed_input.get())) {
    644     is_complete_number_ = true;
    645     const int start_of_country_code =
    646         accrued_input_without_formatting_.length() -
    647         consumed_input->ToString().length();
    648 
    649     national_number_.clear();
    650     accrued_input_without_formatting_.tempSubString(start_of_country_code)
    651         .toUTF8String(national_number_);
    652 
    653     string before_country_code;
    654     accrued_input_without_formatting_.tempSubString(0, start_of_country_code)
    655         .toUTF8String(before_country_code);
    656     prefix_before_national_number_.clear();
    657     prefix_before_national_number_.append(before_country_code);
    658 
    659     if (accrued_input_without_formatting_[0] != kPlusSign) {
    660       prefix_before_national_number_.push_back(kSeparatorBeforeNationalNumber);
    661     }
    662     return true;
    663   }
    664   return false;
    665 }
    666 
    667 bool AsYouTypeFormatter::AttemptToExtractCountryCode() {
    668   if (national_number_.length() == 0) {
    669     return false;
    670   }
    671   string number_without_country_code(national_number_);
    672   int country_code =
    673     phone_util_.ExtractCountryCode(&number_without_country_code);
    674   if (country_code == 0) {
    675     return false;
    676   }
    677   national_number_.assign(number_without_country_code);
    678   string new_region_code;
    679   phone_util_.GetRegionCodeForCountryCode(country_code, &new_region_code);
    680   if (PhoneNumberUtil::kRegionCodeForNonGeoEntity == new_region_code) {
    681     current_metadata_ =
    682         phone_util_.GetMetadataForNonGeographicalRegion(country_code);
    683   } else if (new_region_code != default_country_) {
    684     current_metadata_ = GetMetadataForRegion(new_region_code);
    685   }
    686   StrAppend(&prefix_before_national_number_, country_code);
    687   prefix_before_national_number_.push_back(kSeparatorBeforeNationalNumber);
    688 
    689   return true;
    690 }
    691 
    692 char AsYouTypeFormatter::NormalizeAndAccrueDigitsAndPlusSign(
    693     char32 next_char,
    694     bool remember_position) {
    695   char normalized_char = next_char;
    696 
    697   if (next_char == kPlusSign) {
    698     accrued_input_without_formatting_.append(next_char);
    699   } else {
    700     string number;
    701     UnicodeString(next_char).toUTF8String(number);
    702     phone_util_.NormalizeDigitsOnly(&number);
    703     accrued_input_without_formatting_.append(next_char);
    704     national_number_.append(number);
    705     normalized_char = number[0];
    706   }
    707   if (remember_position) {
    708     position_to_remember_ = accrued_input_without_formatting_.length();
    709   }
    710   return normalized_char;
    711 }
    712 
    713 void AsYouTypeFormatter::InputDigitHelper(char next_char, string* number) {
    714   DCHECK(number);
    715   number->clear();
    716   const char32 placeholder_codepoint = UnicodeString(kDigitPlaceholder)[0];
    717   int placeholder_pos = formatting_template_
    718       .tempSubString(last_match_position_).indexOf(placeholder_codepoint);
    719   if (placeholder_pos != -1) {
    720     UnicodeString temp_template = formatting_template_;
    721     placeholder_pos = temp_template.indexOf(placeholder_codepoint);
    722     temp_template.setCharAt(placeholder_pos, UnicodeString(next_char)[0]);
    723     last_match_position_ = placeholder_pos;
    724     formatting_template_.replace(0, temp_template.length(), temp_template);
    725     formatting_template_.tempSubString(0, last_match_position_ + 1)
    726         .toUTF8String(*number);
    727   } else {
    728     if (possible_formats_.size() == 1) {
    729       // More digits are entered than we could handle, and there are no other
    730       // valid patterns to try.
    731       able_to_format_ = false;
    732     }  // else, we just reset the formatting pattern.
    733     current_formatting_pattern_.clear();
    734     accrued_input_.toUTF8String(*number);
    735   }
    736 }
    737 
    738 // Returns the number of bytes contained in the given UnicodeString up to the
    739 // specified position.
    740 // static
    741 int AsYouTypeFormatter::ConvertUnicodeStringPosition(const UnicodeString& s,
    742                                                      int pos) {
    743   if (pos > s.length()) {
    744     return -1;
    745   }
    746   string substring;
    747   s.tempSubString(0, pos).toUTF8String(substring);
    748   return substring.length();
    749 }
    750 
    751 }  // namespace phonenumbers
    752 }  // namespace i18n
    753