public static function setPossibleLengthsGeneralDesc(PhoneNumberDesc $generalDesc, $metadataId, \DOMElement $data, $isShortNumberMetadata)
    {
        $lengths = array();
        $localOnlyLengths = array();
        // The general description node should *always* be present if metadata for other types is
        // present, aside from in some unit tests.
        // (However, for e.g. formatting metadata in PhoneNumberAlternateFormats, no PhoneNumberDesc
        // elements are present).
        $generalDescNodes = $data->getElementsByTagName(self::GENERAL_DESC);
        if ($generalDescNodes->length > 0) {
            $generalDescNode = $generalDescNodes->item(0);
            self::populatePossibleLengthSets($generalDescNode, $lengths, $localOnlyLengths);
            if (count($lengths) > 0 || count($localOnlyLengths) > 0) {
                // We shouldn't have anything specified at the "general desc" level: we are going to
                // calculate this ourselves from child elements.
                throw new \RuntimeException("Found possible lengths specified at general desc: this should be derived from child elements. Affected country: {$metadataId}");
            }
        }
        if (!$isShortNumberMetadata) {
            // Make a copy here since we want to remove some nodes, but we don't want to do that on our
            // actual data.
            /** @var \DOMElement $allDescData */
            $allDescData = $data->cloneNode(true);
            foreach (self::$phoneNumberDescsWithoutMatchingTypes as $tag) {
                $nodesToRemove = $allDescData->getElementsByTagName($tag);
                if ($nodesToRemove->length > 0) {
                    // We check when we process phone number descriptions that there are only one of each
                    // type, so this is safe to do.
                    $allDescData->removeChild($nodesToRemove->item(0));
                }
            }
            self::populatePossibleLengthSets($allDescData, $lengths, $localOnlyLengths);
        } else {
            // For short number metadata, we want to copy the lengths from the "short code" section only.
            // This is because it's the more detailed validation pattern, it's not a sub-type of short
            // codes. The other lengths will be checked later to see that they are a sub-set of these
            // possible lengths.
            $shortCodeDescList = $data->getElementsByTagName(self::SHORT_CODE);
            if (count($shortCodeDescList) > 0) {
                $shortCodeDesc = $shortCodeDescList->item(0);
                self::populatePossibleLengthSets($shortCodeDesc, $lengths, $localOnlyLengths);
            }
            if (count($localOnlyLengths) > 0) {
                throw new \RuntimeException('Found local-only lengths in short-number metadata');
            }
        }
        self::setPossibleLengths($lengths, $localOnlyLengths, null, $generalDesc);
    }