cpp/src/phonenumbers/phonenumberutil.cc
// Note if any new field is added to this method that should always be filled
// in, even when keepRawInput is false, it should also be handled in the
// CopyCoreFieldsOnly() method.
Note if any new field is added to this method that should always be filled
in, even when keepRawInput is false, it should also be handled in the
CopyCoreFieldsOnly() method.
Note if any new field is added to this method that should always be filled in even when keepRawInput is false it should also be handled in the CopyCoreFieldsOnly () method .
PhoneNumberUtil::ErrorType PhoneNumberUtil::ParseHelper(
    const string& number_to_parse,
    const string& default_region,
    bool keep_raw_input,
    bool check_region,
    PhoneNumber* phone_number) const {
  DCHECK(phone_number);
  string national_number;
  BuildNationalNumberForParsing(number_to_parse, &national_number);
  if (!IsViablePhoneNumber(national_number)) {
    VLOG(2) << "The string supplied did not seem to be a phone number.";
    return NOT_A_NUMBER;
  }
  if (check_region &&
      !CheckRegionForParsing(national_number, default_region)) {
    VLOG(1) << "Missing or invalid default country.";
    return INVALID_COUNTRY_CODE_ERROR;
  }
  PhoneNumber temp_number;
  if (keep_raw_input) {
    temp_number.set_raw_input(number_to_parse);
  }
  string extension;
  MaybeStripExtension(&national_number, &extension);
  if (!extension.empty()) {
    temp_number.set_extension(extension);
  }
  const PhoneMetadata* country_metadata = GetMetadataForRegion(default_region);
  string normalized_national_number(national_number);
  ErrorType country_code_error =
      MaybeExtractCountryCode(country_metadata, keep_raw_input,
                              &normalized_national_number, &temp_number);
  if (country_code_error != NO_PARSING_ERROR) {
    const scoped_ptr<RegExpInput> number_string_piece(
        reg_exps_->regexp_factory_->CreateInput(national_number));
    if ((country_code_error == INVALID_COUNTRY_CODE_ERROR) &&
        (reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get()))) {
      normalized_national_number.assign(number_string_piece->ToString());
      MaybeExtractCountryCode(country_metadata,
                              keep_raw_input,
                              &normalized_national_number,
                              &temp_number);
      if (temp_number.country_code() == 0) {
        return INVALID_COUNTRY_CODE_ERROR;
      }
    } else {
      return country_code_error;
    }
  }
  int country_code = temp_number.country_code();
  if (country_code != 0) {
    string phone_number_region;
    GetRegionCodeForCountryCode(country_code, &phone_number_region);
    if (phone_number_region != default_region) {
      country_metadata =
          GetMetadataForRegionOrCallingCode(country_code, phone_number_region);
    }
  } else if (country_metadata) {
    country_code = country_metadata->country_code();
  }
  if (normalized_national_number.length() < kMinLengthForNsn) {
    VLOG(2) << "The string supplied is too short to be a phone number.";
    return TOO_SHORT_NSN;
  }
  if (country_metadata) {
    string carrier_code;
    string potential_national_number(normalized_national_number);
    MaybeStripNationalPrefixAndCarrierCode(*country_metadata,
                                           &potential_national_number,
                                           &carrier_code);
    ValidationResult validation_result =
        TestNumberLength(potential_national_number, *country_metadata);
    if (validation_result != TOO_SHORT &&
        validation_result != IS_POSSIBLE_LOCAL_ONLY &&
        validation_result != INVALID_LENGTH) {
      normalized_national_number.assign(potential_national_number);
      if (keep_raw_input && !carrier_code.empty()) {
        temp_number.set_preferred_domestic_carrier_code(carrier_code);
      }
    }
  }
  size_t normalized_national_number_length =
      normalized_national_number.length();
  if (normalized_national_number_length < kMinLengthForNsn) {
    VLOG(2) << "The string supplied is too short to be a phone number.";
    return TOO_SHORT_NSN;
  }
  if (normalized_national_number_length > kMaxLengthForNsn) {
    VLOG(2) << "The string supplied is too long to be a phone number.";
    return TOO_LONG_NSN;
  }
  temp_number.set_country_code(country_code);
  SetItalianLeadingZerosForPhoneNumber(normalized_national_number,
      &temp_number);
  uint64 number_as_int;
  safe_strtou64(normalized_national_number, &number_as_int);
  temp_number.set_national_number(number_as_int);
  phone_number->Swap(&temp_number);
  return NO_PARSING_ERROR;
}
PhoneNumberUtil :: ErrorType PhoneNumberUtil :: ParseHelper ( const string & number_to_parse , const string & default_region , bool keep_raw_input , bool check_region , PhoneNumber * phone_number ) const { DCHECK ( phone_number ) ; string national_number ; BuildNationalNumberForParsing ( number_to_parse , & national_number ) ; if ( ! IsViablePhoneNumber ( national_number ) ) { VLOG ( 2 ) << " " ; return NOT_A_NUMBER ; } if ( check_region && ! CheckRegionForParsing ( national_number , default_region ) ) { VLOG ( 1 ) << " " ; return INVALID_COUNTRY_CODE_ERROR ; } PhoneNumber temp_number ; if ( keep_raw_input ) { temp_number . set_raw_input ( number_to_parse ) ; } string extension ; MaybeStripExtension ( & national_number , & extension ) ; if ( ! extension . empty ( ) ) { temp_number . set_extension ( extension ) ; } const PhoneMetadata * country_metadata = GetMetadataForRegion ( default_region ) ; string normalized_national_number ( national_number ) ; ErrorType country_code_error = MaybeExtractCountryCode ( country_metadata , keep_raw_input , & normalized_national_number , & temp_number ) ; if ( country_code_error != NO_PARSING_ERROR ) { const scoped_ptr < RegExpInput > number_string_piece ( reg_exps_ -> regexp_factory_ -> CreateInput ( national_number ) ) ; if ( ( country_code_error == INVALID_COUNTRY_CODE_ERROR ) && ( reg_exps_ -> plus_chars_pattern_ -> Consume ( number_string_piece . get ( ) ) ) ) { normalized_national_number . assign ( number_string_piece -> ToString ( ) ) ; MaybeExtractCountryCode ( country_metadata , keep_raw_input , & normalized_national_number , & temp_number ) ; if ( temp_number . country_code ( ) == 0 ) { return INVALID_COUNTRY_CODE_ERROR ; } } else { return country_code_error ; } } int country_code = temp_number . country_code ( ) ; if ( country_code != 0 ) { string phone_number_region ; GetRegionCodeForCountryCode ( country_code , & phone_number_region ) ; if ( phone_number_region != default_region ) { country_metadata = GetMetadataForRegionOrCallingCode ( country_code , phone_number_region ) ; } } else if ( country_metadata ) { country_code = country_metadata -> country_code ( ) ; } if ( normalized_national_number . length ( ) < kMinLengthForNsn ) { VLOG ( 2 ) << " " ; return TOO_SHORT_NSN ; } if ( country_metadata ) { string carrier_code ; string potential_national_number ( normalized_national_number ) ; MaybeStripNationalPrefixAndCarrierCode ( * country_metadata , & potential_national_number , & carrier_code ) ; ValidationResult validation_result = TestNumberLength ( potential_national_number , * country_metadata ) ; if ( validation_result != TOO_SHORT && validation_result != IS_POSSIBLE_LOCAL_ONLY && validation_result != INVALID_LENGTH ) { normalized_national_number . assign ( potential_national_number ) ; if ( keep_raw_input && ! carrier_code . empty ( ) ) { temp_number . set_preferred_domestic_carrier_code ( carrier_code ) ; } } } size_t normalized_national_number_length = normalized_national_number . length ( ) ; if ( normalized_national_number_length < kMinLengthForNsn ) { VLOG ( 2 ) << " " ; return TOO_SHORT_NSN ; } if ( normalized_national_number_length > kMaxLengthForNsn ) { VLOG ( 2 ) << " " ; return TOO_LONG_NSN ; } temp_number . set_country_code ( country_code ) ; SetItalianLeadingZerosForPhoneNumber ( normalized_national_number , & temp_number ) ; uint64 number_as_int ; safe_strtou64 ( normalized_national_number , & number_as_int ) ; temp_number . set_national_number ( number_as_int ) ; phone_number -> Swap ( & temp_number ) ; return NO_PARSING_ERROR ; }
Note if any new field is added to this method that should always be filled
in, even when keepRawInput is false, it should also be handled in the
CopyCoreFieldsOnly() method.
Note if any new field is added to this method that should always be filled in even when keepRawInput is false it should also be handled in the CopyCoreFieldsOnly () method .
// Attempt to parse extension first, since it doesn't require country-specific // data and we want to have the non-normalised number here. // Check to see if the number is given in international format so we know // whether this number is from the default country or not. // Strip the plus-char, and try again. // If no extracted country calling code, use the region supplied instead. // Note that the national number was already normalized by // MaybeExtractCountryCode. // We require that the NSN remaining after stripping the national prefix // and carrier code be long enough to be a possible length for the region. // Otherwise, we don't do the stripping, since the original number could be // a valid short number.