in phonenumbers.go [2905:3025]
func parseHelper(
numberToParse, defaultRegion string,
keepRawInput, checkRegion bool,
phoneNumber *PhoneNumber) error {
if len(numberToParse) == 0 {
return ErrNotANumber
} else if len(numberToParse) > MAX_INPUT_STRING_LENGTH {
return ErrNumTooLong
}
nationalNumber := NewBuilder(nil)
err := buildNationalNumberForParsing(numberToParse, nationalNumber)
if err != nil {
return err
}
if !isViablePhoneNumber(nationalNumber.String()) {
return ErrNotANumber
}
// Check the region supplied is valid, or that the extracted number
// starts with some sort of + sign so the number's region can be determined.
if checkRegion &&
!checkRegionForParsing(nationalNumber.String(), defaultRegion) {
return ErrInvalidCountryCode
}
if keepRawInput {
phoneNumber.RawInput = proto.String(numberToParse)
}
// Attempt to parse extension first, since it doesn't require
// region-specific data and we want to have the non-normalised
// number here.
extension := maybeStripExtension(nationalNumber)
if len(extension) > 0 {
phoneNumber.Extension = proto.String(extension)
}
var regionMetadata *PhoneMetadata = getMetadataForRegion(defaultRegion)
// Check to see if the number is given in international format so we
// know whether this number is from the default region or not.
normalizedNationalNumber := NewBuilder(nil)
// TODO: This method should really just take in the string buffer that
// has already been created, and just remove the prefix, rather than
// taking in a string and then outputting a string buffer.
countryCode, err := maybeExtractCountryCode(
nationalNumber.String(), regionMetadata,
normalizedNationalNumber, keepRawInput, phoneNumber)
if err != nil {
// There might be a plus at the beginning
inds := PLUS_CHARS_PATTERN.FindStringIndex(nationalNumber.String())
if err == ErrInvalidCountryCode && len(inds) > 0 {
// Strip the plus-char, and try again.
countryCode, err = maybeExtractCountryCode(
nationalNumber.String()[inds[1]:], regionMetadata,
normalizedNationalNumber, keepRawInput, phoneNumber)
if err != nil {
return err
} else if countryCode == 0 {
return ErrInvalidCountryCode
}
} else {
return err
}
}
if countryCode != 0 {
phoneNumberRegion := GetRegionCodeForCountryCode(countryCode)
if phoneNumberRegion != defaultRegion {
// Metadata cannot be null because the country calling
// code is valid.
regionMetadata = getMetadataForRegionOrCallingCode(
countryCode, phoneNumberRegion)
}
} else {
// If no extracted country calling code, use the region supplied
// instead. The national number is just the normalized version of
// the number we were given to parse.
normalizedNationalNumber.WriteString(normalize(nationalNumber.String()))
if len(defaultRegion) != 0 {
countryCode = int(regionMetadata.GetCountryCode())
phoneNumber.CountryCode = proto.Int32(int32(countryCode))
} else if keepRawInput {
phoneNumber.CountryCodeSource = nil
}
}
if len(normalizedNationalNumber.String()) < MIN_LENGTH_FOR_NSN {
return ErrTooShortNSN
}
if regionMetadata != nil {
carrierCode := NewBuilder(nil)
bufferCopy := make([]byte, normalizedNationalNumber.Len())
copy(bufferCopy, normalizedNationalNumber.Bytes())
potentialNationalNumber := NewBuilder(bufferCopy)
maybeStripNationalPrefixAndCarrierCode(
potentialNationalNumber, regionMetadata, carrierCode)
// We require that the NSN remaining after stripping the national
// prefix and carrier code be of a possible length for the region.
// Otherwise, we don't do the stripping, since the original number
// could be a valid short number.
validationResult := testNumberLength(potentialNationalNumber.String(), regionMetadata, UNKNOWN)
if validationResult != TOO_SHORT && validationResult != IS_POSSIBLE_LOCAL_ONLY && validationResult != INVALID_LENGTH {
normalizedNationalNumber = potentialNationalNumber
if keepRawInput {
phoneNumber.PreferredDomesticCarrierCode =
proto.String(carrierCode.String())
}
}
}
lengthOfNationalNumber := len(normalizedNationalNumber.String())
if lengthOfNationalNumber < MIN_LENGTH_FOR_NSN {
return ErrTooShortNSN
}
if lengthOfNationalNumber > MAX_LENGTH_FOR_NSN {
return ErrNumTooLong
}
setItalianLeadingZerosForPhoneNumber(
normalizedNationalNumber.String(), phoneNumber)
val, _ := strconv.ParseUint(normalizedNationalNumber.String(), 10, 64)
phoneNumber.NationalNumber = proto.Uint64(val)
return nil
}