maybeExtractCountryCode method

int maybeExtractCountryCode(
  1. String number,
  2. PhoneMetadata? defaultRegionMetadata,
  3. StringBuffer nationalNumber,
  4. bool keepRawInput,
  5. PhoneNumber phoneNumber,
)

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:

  • 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
  • by stripping the '+' sign if present and then looking at the next digits
  • 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.

It will throw a Error if the number starts with a '+' but the country calling code supplied after this does not match that of any known region.

number non-normalized telephone number that we wish to extract a country calling code from - may begin with '+'. defaultRegionMetadata metadata about the region this number may be from. 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. keepRawInput true if the country_code_source and preferredCarrierCode fields of phoneNumber should be populated. 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. maybeExtractCountryCode returns the country calling code extracted or 0 if none could be extracted. Throws NumberParseException.

Implementation

int maybeExtractCountryCode(
  String number,
  PhoneMetadata? defaultRegionMetadata,
  StringBuffer nationalNumber,
  bool keepRawInput,
  PhoneNumber phoneNumber,
) {
  if (number.isEmpty) return 0;

  StringBuffer fullNumber = StringBuffer(number);

  // Set the default prefix to be something that will never match.
  String possibleCountryIddPrefix = 'NonMatch';
  if (defaultRegionMetadata != null) {
    possibleCountryIddPrefix = defaultRegionMetadata.internationalPrefix;
  }

  PhoneNumber_CountryCodeSource countryCodeSource =
      maybeStripInternationalPrefixAndNormalize(
          fullNumber, possibleCountryIddPrefix);

  if (keepRawInput) {
    phoneNumber.countryCodeSource = countryCodeSource;
  }
  if (countryCodeSource !=
      PhoneNumber_CountryCodeSource.FROM_DEFAULT_COUNTRY) {
    if (fullNumber.length <= _minLengthForNsn) {
      throw NumberParseException(ErrorType.tooShortAfterIdd);
    }

    int potentialCountryCode = extractCountryCode(fullNumber, nationalNumber);
    if (potentialCountryCode != 0) {
      phoneNumber.countryCode = 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 NumberParseException(ErrorType.invalidCountryCode);
  } 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.countryCode;

    String defaultCountryCodeString = '$defaultCountryCode';
    String normalizedNumber = fullNumber.toString();

    if (normalizedNumber.startsWith(defaultCountryCodeString)) {
      StringBuffer potentialNationalNumber = StringBuffer(
        normalizedNumber.substring(defaultCountryCodeString.length),
      );

      PhoneNumberDesc generalDesc = defaultRegionMetadata.generalDesc;

      // Passing null since we don't need the carrier code.
      maybeStripNationalPrefixAndCarrierCode(
        potentialNationalNumber,
        defaultRegionMetadata,
        null,
      );

      // 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 ((!matchNationalNumber(fullNumber.toString(), generalDesc, false) &&
              matchNationalNumber(
                  potentialNationalNumber.toString(), generalDesc, false)) ||
          _testNumberLength(fullNumber.toString(), defaultRegionMetadata) ==
              ValidationResult.tooLong) {
        nationalNumber.write(potentialNationalNumber);
        if (keepRawInput) {
          phoneNumber.countryCodeSource =
              (PhoneNumber_CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
        }
        phoneNumber.countryCode = defaultCountryCode;
        return defaultCountryCode;
      }
    }
  }
  // No country calling code present.
  phoneNumber.countryCode = 0;
  return 0;
}