in phonenumbers.go [2545:2623]
func maybeExtractCountryCode(
number string,
defaultRegionMetadata *PhoneMetadata,
nationalNumber *Builder,
keepRawInput bool,
phoneNumber *PhoneNumber) (int, error) {
if len(number) == 0 {
return 0, nil
}
fullNumber := NewBuilderString(number)
// Set the default prefix to be something that will never match.
possibleCountryIddPrefix := "NonMatch"
if defaultRegionMetadata != nil {
possibleCountryIddPrefix = defaultRegionMetadata.GetInternationalPrefix()
}
countryCodeSource :=
maybeStripInternationalPrefixAndNormalize(fullNumber, possibleCountryIddPrefix)
if keepRawInput {
phoneNumber.CountryCodeSource = &countryCodeSource
}
if countryCodeSource != PhoneNumber_FROM_DEFAULT_COUNTRY {
if len(fullNumber.String()) <= MIN_LENGTH_FOR_NSN {
return 0, ErrTooShortAfterIDD
}
potentialCountryCode := extractCountryCode(fullNumber, nationalNumber)
if potentialCountryCode != 0 {
phoneNumber.CountryCode = proto.Int32(int32(potentialCountryCode))
return potentialCountryCode, nil
}
// If this fails, they must be using a strange country calling code
// that we don't recognize, or that doesn't exist.
return 0, ErrInvalidCountryCode
} else if defaultRegionMetadata != nil {
// 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.
defaultCountryCode := int(defaultRegionMetadata.GetCountryCode())
defaultCountryCodeString := strconv.Itoa(defaultCountryCode)
normalizedNumber := fullNumber.String()
if strings.HasPrefix(normalizedNumber, defaultCountryCodeString) {
var (
potentialNationalNumber = NewBuilderString(
normalizedNumber[len(defaultCountryCodeString):])
generalDesc = defaultRegionMetadata.GetGeneralDesc()
patP = `^(?:` + generalDesc.GetNationalNumberPattern() + `)$` // Strictly match
validNumberPattern = regexFor(patP)
)
maybeStripNationalPrefixAndCarrierCode(
potentialNationalNumber,
defaultRegionMetadata,
NewBuilder(nil) /* Don't need the carrier code */)
// 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.
fullValid := validNumberPattern.MatchString(fullNumber.String())
nationalValid := validNumberPattern.MatchString(potentialNationalNumber.String())
lengthValid := testNumberLength(fullNumber.String(), defaultRegionMetadata, UNKNOWN)
if (!fullValid && nationalValid) || lengthValid == TOO_LONG {
nationalNumber.Write(potentialNationalNumber.Bytes())
if keepRawInput {
val := PhoneNumber_FROM_NUMBER_WITHOUT_PLUS_SIGN
phoneNumber.CountryCodeSource = &val
}
phoneNumber.CountryCode = proto.Int32(int32(defaultCountryCode))
return defaultCountryCode, nil
}
}
}
// No country calling code present.
phoneNumber.CountryCode = proto.Int32(0)
return 0, nil
}