in phonenumbers.go [2341:2413]
func testNumberLength(number string, metadata *PhoneMetadata, numberType PhoneNumberType) ValidationResult {
desc := getNumberDescByType(metadata, numberType)
// There should always be "possibleLengths" set for every element. This is declared in the XML
// schema which is verified by PhoneNumberMetadataSchemaTest.
// For size efficiency, where a sub-description (e.g. fixed-line) has the same possibleLengths
// as the parent, this is missing, so we fall back to the general desc (where no numbers of the
// type exist at all, there is one possible length (-1) which is guaranteed not to match the
// length of any real phone number).
possibleLengths := desc.PossibleLength
if len(possibleLengths) == 0 {
possibleLengths = metadata.GeneralDesc.PossibleLength
}
localLengths := desc.PossibleLengthLocalOnly
if numberType == FIXED_LINE_OR_MOBILE {
if !descHasPossibleNumberData(getNumberDescByType(metadata, FIXED_LINE)) {
// The rare case has been encountered where no fixedLine data is available (true for some
// non-geographical entities), so we just check mobile.
return testNumberLength(number, metadata, MOBILE)
} else {
mobileDesc := getNumberDescByType(metadata, MOBILE)
if descHasPossibleNumberData(mobileDesc) {
// Note that when adding the possible lengths from mobile, we have to again check they
// aren't empty since if they are this indicates they are the same as the general desc and
// should be obtained from there.
mobileLengths := mobileDesc.PossibleLength
if len(mobileLengths) == 0 {
mobileLengths = metadata.GeneralDesc.PossibleLength
}
possibleLengths = mergeLengths(possibleLengths, mobileLengths)
if len(localLengths) == 0 {
localLengths = mobileDesc.PossibleLengthLocalOnly
} else {
localLengths = mergeLengths(localLengths, mobileDesc.PossibleLengthLocalOnly)
}
}
}
}
// If the type is not supported at all (indicated by the possible lengths containing -1 at this
// point) we return invalid length.
if possibleLengths[0] == -1 {
return INVALID_LENGTH
}
actualLength := int32(len(number))
// This is safe because there is never an overlap beween the possible lengths and the local-only
// lengths; this is checked at build time.
for _, l := range localLengths {
if l == actualLength {
return IS_POSSIBLE_LOCAL_ONLY
}
}
minimumLength := possibleLengths[0]
if minimumLength == actualLength {
return IS_POSSIBLE
} else if minimumLength > actualLength {
return TOO_SHORT
} else if possibleLengths[len(possibleLengths)-1] < actualLength {
return TOO_LONG
}
// We skip the first element; we've already checked it.
for _, l := range possibleLengths[1:] {
if l == actualLength {
return IS_POSSIBLE
}
}
return INVALID_LENGTH
}