func parseHelper()

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
}