#ifdef DEBUG
#define assertIsValidAndCanonicalLanguageTag(locale, desc) \
do { \
let localeObj = parseLanguageTag(locale); \
assert(localeObj !== null, \
`${desc} is a structurally valid language tag`); \
assert(CanonicalizeLanguageTagFromObject(localeObj) === locale, \
`${desc} is a canonicalized language tag`); \
} while (false)
#else
#define assertIsValidAndCanonicalLanguageTag(locale, desc) ; #endif
function startOfUnicodeExtensions(locale) {
assert(typeof locale === "string", "locale is a string");
#define HYPHEN 0x2D
assert(std_String_fromCharCode(HYPHEN) === "-",
"code unit constant should match the expected character");
if (callFunction(std_String_charCodeAt, locale, 1) === HYPHEN) {
assert(locale[0] === "x" || locale[0] === "i",
"locale[1] === '-' implies a privateuse-only or grandfathered locale");
return -1;
}
#undef HYPHEN
var start = callFunction(std_String_indexOf, locale, "-u-");
if (start < 0)
return -1;
var privateExt = callFunction(std_String_indexOf, locale, "-x-");
if (privateExt >= 0 && privateExt < start)
return -1;
return start;
}
function endOfUnicodeExtensions(locale, start) {
assert(typeof locale === "string", "locale is a string");
assert(0 <= start && start < locale.length, "start is an index into locale");
assert(Substring(locale, start, 3) === "-u-", "start points to Unicode extension sequence");
#define HYPHEN 0x2D
assert(std_String_fromCharCode(HYPHEN) === "-",
"code unit constant should match the expected character");
for (var i = start + 5, end = locale.length - 4; i <= end; i++) {
if (callFunction(std_String_charCodeAt, locale, i) !== HYPHEN)
continue;
if (callFunction(std_String_charCodeAt, locale, i + 2) === HYPHEN)
return i;
i += 2;
}
#undef HYPHEN
return locale.length;
}
function removeUnicodeExtensions(locale) {
assertIsValidAndCanonicalLanguageTag(locale, "locale with possible Unicode extension");
var start = startOfUnicodeExtensions(locale);
if (start < 0)
return locale;
var end = endOfUnicodeExtensions(locale, start);
var left = Substring(locale, 0, start);
var right = Substring(locale, end, locale.length - end);
var combined = left + right;
assertIsValidAndCanonicalLanguageTag(combined, "the recombined locale");
assert(startOfUnicodeExtensions(combined) < 0,
"recombination failed to remove all Unicode locale extension sequences");
return combined;
}
function getUnicodeExtensions(locale) {
assertIsValidAndCanonicalLanguageTag(locale, "locale with Unicode extension");
var start = startOfUnicodeExtensions(locale);
assert(start >= 0, "start of Unicode extension sequence not found");
var end = endOfUnicodeExtensions(locale, start);
return Substring(locale, start, end - start);
}
function parseLanguageTag(locale) {
assert(typeof locale === "string", "locale is a string");
var index = 0;
#define NONE 0b00
#define ALPHA 0b01
#define DIGIT 0b10
var token = 0;
var tokenStart = 0;
var tokenLength = 0;
#define HYPHEN 0x2D
#define DIGIT_ZERO 0x30
#define DIGIT_NINE 0x39
#define UPPER_A 0x41
#define UPPER_Z 0x5A
#define LOWER_A 0x61
#define LOWER_X 0x78
#define LOWER_Z 0x7A
assert(std_String_fromCharCode(HYPHEN) === "-" &&
std_String_fromCharCode(DIGIT_ZERO) === "0" &&
std_String_fromCharCode(DIGIT_NINE) === "9" &&
std_String_fromCharCode(UPPER_A) === "A" &&
std_String_fromCharCode(UPPER_Z) === "Z" &&
std_String_fromCharCode(LOWER_A) === "a" &&
std_String_fromCharCode(LOWER_X) === "x" &&
std_String_fromCharCode(LOWER_Z) === "z",
"code unit constants should match the expected characters");
function nextToken() {
var type = NONE;
for (var i = index; i < locale.length; i++) {
var c = callFunction(std_String_charCodeAt, locale, i);
if ((UPPER_A <= c && c <= UPPER_Z) || (LOWER_A <= c && c <= LOWER_Z))
type |= ALPHA;
else if (DIGIT_ZERO <= c && c <= DIGIT_NINE)
type |= DIGIT;
else if (c === HYPHEN && i > index && i + 1 < locale.length)
break;
else
return false;
}
token = type;
tokenStart = index;
tokenLength = i - index;
index = i + 1;
return true;
}
var localeLowercase = callFunction(std_String_toLowerCase, locale);
function tokenStartCodeUnitLower() {
var c = callFunction(std_String_charCodeAt, localeLowercase, tokenStart);
assert((DIGIT_ZERO <= c && c <= DIGIT_NINE) || (LOWER_A <= c && c <= LOWER_Z),
"unexpected code unit");
return c;
}
function tokenStringLower() {
return Substring(localeLowercase, tokenStart, tokenLength);
}
if (!nextToken())
return null;
if (token !== ALPHA || tokenLength > 8)
return null;
assert(tokenLength > 0, "token length is not zero if type is ALPHA");
var language, extlang1, extlang2, extlang3, script, region, privateuse;
var variants = [];
var extensions = [];
if (tokenLength > 1) {
if (tokenLength <= 3) {
language = tokenStringLower();
if (!nextToken())
return null;
if (token === ALPHA && tokenLength === 3) {
extlang1 = tokenStringLower();
if (!nextToken())
return null;
if (token === ALPHA && tokenLength === 3) {
extlang2 = tokenStringLower();
if (!nextToken())
return null;
if (token === ALPHA && tokenLength === 3) {
extlang3 = tokenStringLower();
if (!nextToken())
return null;
}
}
}
} else {
assert(4 <= tokenLength && tokenLength <= 8, "reserved/registered language subtags");
language = tokenStringLower();
if (!nextToken())
return null;
}
if (tokenLength === 4 && token === ALPHA) {
script = tokenStringLower();
script = callFunction(std_String_toUpperCase, script[0]) +
Substring(script, 1, script.length - 1);
if (!nextToken())
return null;
}
if ((tokenLength === 2 && token === ALPHA) || (tokenLength === 3 && token === DIGIT)) {
region = tokenStringLower();
region = callFunction(std_String_toUpperCase, region);
if (!nextToken())
return null;
}
while ((5 <= tokenLength && tokenLength <= 8) ||
(tokenLength === 4 && tokenStartCodeUnitLower() <= DIGIT_NINE))
{
assert(!(tokenStartCodeUnitLower() <= DIGIT_NINE) ||
tokenStartCodeUnitLower() >= DIGIT_ZERO,
"token-start-code-unit <= '9' implies token-start-code-unit is in '0'..'9'");
var variant = tokenStringLower();
if (callFunction(ArrayIndexOf, variants, variant) !== -1)
return null;
_DefineDataProperty(variants, variants.length, variant);
if (!nextToken())
return null;
}
var seenSingletons = [];
while (tokenLength === 1) {
var extensionStart = tokenStart;
var singleton = tokenStartCodeUnitLower();
if (singleton === LOWER_X)
break;
assert(!(UPPER_A <= singleton && singleton <= UPPER_Z),
"unexpected upper-case code unit");
if (callFunction(ArrayIndexOf, seenSingletons, singleton) !== -1)
return null;
_DefineDataProperty(seenSingletons, seenSingletons.length, singleton);
if (!nextToken())
return null;
if (!(2 <= tokenLength && tokenLength <= 8))
return null;
do {
if (!nextToken())
return null;
} while (2 <= tokenLength && tokenLength <= 8);
var extension = Substring(localeLowercase, extensionStart,
(tokenStart - 1 - extensionStart));
_DefineDataProperty(extensions, extensions.length, extension);
}
}
if (tokenLength === 1 && tokenStartCodeUnitLower() === LOWER_X) {
var privateuseStart = tokenStart;
if (!nextToken())
return null;
if (!(1 <= tokenLength && tokenLength <= 8))
return null;
do {
if (!nextToken())
return null;
} while (1 <= tokenLength && tokenLength <= 8);
privateuse = Substring(localeLowercase, privateuseStart,
localeLowercase.length - privateuseStart);
}
if (token === NONE && !hasOwn(localeLowercase, grandfatheredMappings)) {
return {
language,
extlang1,
extlang2,
extlang3,
script,
region,
variants,
extensions,
privateuse,
};
}
while (token !== NONE) {
if (!nextToken())
return null;
}
if (hasOwn(localeLowercase, grandfatheredMappings)) {
return {
locale: grandfatheredMappings[localeLowercase],
grandfathered: true,
};
}
return null;
#undef NONE
#undef ALPHA
#undef DIGIT
#undef HYPHEN
#undef DIGIT_ZERO
#undef DIGIT_NINE
#undef UPPER_A
#undef UPPER_Z
#undef LOWER_A
#undef LOWER_X
#undef LOWER_Z
}
function IsStructurallyValidLanguageTag(locale) {
return parseLanguageTag(locale) !== null;
}
function CanonicalizeLanguageTagFromObject(localeObj) {
assert(IsObject(localeObj), "CanonicalizeLanguageTagFromObject");
if (hasOwn("grandfathered", localeObj))
return localeObj.locale;
updateLangTagMappings(localeObj);
var {
language,
extlang1,
extlang2,
extlang3,
script,
region,
variants,
extensions,
privateuse,
} = localeObj;
if (!language) {
assert(typeof privateuse === "string", "language or privateuse subtag required");
return privateuse;
}
if (hasOwn(language, languageMappings))
language = languageMappings[language];
var canonical = language;
if (extlang1) {
if (hasOwn(extlang1, extlangMappings) && extlangMappings[extlang1] === language)
canonical = extlang1;
else
canonical += "-" + extlang1;
}
if (extlang2)
canonical += "-" + extlang2;
if (extlang3)
canonical += "-" + extlang3;
if (script) {
assert(script.length === 4 &&
script ===
callFunction(std_String_toUpperCase, script[0]) +
callFunction(std_String_toLowerCase, Substring(script, 1, script.length - 1)),
"script must be [A-Z][a-z]{3}");
canonical += "-" + script;
}
if (region) {
if (hasOwn(region, regionMappings))
region = regionMappings[region];
assert((2 <= region.length && region.length <= 3) &&
region === callFunction(std_String_toUpperCase, region),
"region must be [A-Z]{2} or [0-9]{3}");
canonical += "-" + region;
}
if (variants.length > 0)
canonical += "-" + callFunction(std_Array_join, variants, "-");
if (extensions.length > 0) {
callFunction(ArraySort, extensions);
canonical += "-" + callFunction(std_Array_join, extensions, "-");
}
if (privateuse)
canonical += "-" + privateuse;
return canonical;
}
function CanonicalizeLanguageTag(locale) {
var localeObj = parseLanguageTag(locale);
assert(localeObj !== null, "CanonicalizeLanguageTag");
return CanonicalizeLanguageTagFromObject(localeObj);
}
function IsASCIIAlphaString(s) {
assert(typeof s === "string", "IsASCIIAlphaString");
for (var i = 0; i < s.length; i++) {
var c = callFunction(std_String_charCodeAt, s, i);
if (!((0x41 <= c && c <= 0x5A) || (0x61 <= c && c <= 0x7A)))
return false;
}
return true;
}
function ValidateAndCanonicalizeLanguageTag(locale) {
assert(typeof locale === "string", "ValidateAndCanonicalizeLanguageTag");
if (locale.length === 2 || (locale.length === 3 && locale[1] !== "-")) {
if (!IsASCIIAlphaString(locale))
ThrowRangeError(JSMSG_INVALID_LANGUAGE_TAG, locale);
assert(IsStructurallyValidLanguageTag(locale), "2*3ALPHA is a valid language tag");
locale = callFunction(std_String_toLowerCase, locale);
locale = hasOwn(locale, languageMappings)
? languageMappings[locale]
: locale;
assert(locale === CanonicalizeLanguageTag(locale), "expected same canonicalization");
return locale;
}
var localeObj = parseLanguageTag(locale);
if (localeObj === null)
ThrowRangeError(JSMSG_INVALID_LANGUAGE_TAG, locale);
return CanonicalizeLanguageTagFromObject(localeObj);
}
function lastDitchLocale() {
return "en-GB";
}
var oldStyleLanguageTagMappings = {
"pa-PK": "pa-Arab-PK",
"zh-CN": "zh-Hans-CN",
"zh-HK": "zh-Hant-HK",
"zh-SG": "zh-Hans-SG",
"zh-TW": "zh-Hant-TW",
};
var localeCandidateCache = {
runtimeDefaultLocale: undefined,
candidateDefaultLocale: undefined,
};
var localeCache = {
runtimeDefaultLocale: undefined,
defaultLocale: undefined,
};
function DefaultLocaleIgnoringAvailableLocales() {
const runtimeDefaultLocale = RuntimeDefaultLocale();
if (runtimeDefaultLocale === localeCandidateCache.runtimeDefaultLocale)
return localeCandidateCache.candidateDefaultLocale;
var candidate = parseLanguageTag(runtimeDefaultLocale);
if (candidate === null) {
candidate = lastDitchLocale();
} else {
candidate = CanonicalizeLanguageTagFromObject(candidate);
candidate = removeUnicodeExtensions(candidate);
if (hasOwn(candidate, oldStyleLanguageTagMappings))
candidate = oldStyleLanguageTagMappings[candidate];
}
localeCandidateCache.candidateDefaultLocale = candidate;
localeCandidateCache.runtimeDefaultLocale = runtimeDefaultLocale;
assertIsValidAndCanonicalLanguageTag(candidate, "the candidate locale");
assert(startOfUnicodeExtensions(candidate) < 0,
"the candidate must not contain a Unicode extension sequence");
return candidate;
}
function DefaultLocale() {
if (IsRuntimeDefaultLocale(localeCache.runtimeDefaultLocale))
return localeCache.defaultLocale;
var runtimeDefaultLocale = RuntimeDefaultLocale();
var candidate = DefaultLocaleIgnoringAvailableLocales();
var locale;
if (BestAvailableLocaleIgnoringDefault(callFunction(collatorInternalProperties.availableLocales,
collatorInternalProperties),
candidate) &&
BestAvailableLocaleIgnoringDefault(callFunction(numberFormatInternalProperties.availableLocales,
numberFormatInternalProperties),
candidate) &&
BestAvailableLocaleIgnoringDefault(callFunction(dateTimeFormatInternalProperties.availableLocales,
dateTimeFormatInternalProperties),
candidate))
{
locale = candidate;
} else {
locale = lastDitchLocale();
}
assertIsValidAndCanonicalLanguageTag(locale, "the computed default locale");
assert(startOfUnicodeExtensions(locale) < 0,
"the computed default locale must not contain a Unicode extension sequence");
localeCache.defaultLocale = locale;
localeCache.runtimeDefaultLocale = runtimeDefaultLocale;
return locale;
}
function addSpecialMissingLanguageTags(availableLocales) {
var oldStyleLocales = std_Object_getOwnPropertyNames(oldStyleLanguageTagMappings);
for (var i = 0; i < oldStyleLocales.length; i++) {
var oldStyleLocale = oldStyleLocales[i];
if (availableLocales[oldStyleLanguageTagMappings[oldStyleLocale]])
availableLocales[oldStyleLocale] = true;
}
var lastDitch = lastDitchLocale();
assert(lastDitch === "en-GB" && availableLocales.en,
"shouldn't be a need to add every locale implied by the last-" +
"ditch locale, merely just the last-ditch locale");
availableLocales[lastDitch] = true;
}
function CanonicalizeLocaleList(locales) {
if (locales === undefined)
return [];
if (typeof locales === "string")
return [ValidateAndCanonicalizeLanguageTag(locales)];
var seen = [];
var O = ToObject(locales);
var len = ToLength(O.length);
var k = 0;
while (k < len) {
if (k in O) {
var kValue = O[k];
if (!(typeof kValue === "string" || IsObject(kValue)))
ThrowTypeError(JSMSG_INVALID_LOCALES_ELEMENT);
var tag = ToString(kValue);
tag = ValidateAndCanonicalizeLanguageTag(tag);
if (callFunction(ArrayIndexOf, seen, tag) === -1)
_DefineDataProperty(seen, seen.length, tag);
}
k++;
}
return seen;
}
function BestAvailableLocaleHelper(availableLocales, locale, considerDefaultLocale) {
assertIsValidAndCanonicalLanguageTag(locale, "BestAvailableLocale locale");
assert(startOfUnicodeExtensions(locale) < 0, "locale must contain no Unicode extensions");
var defaultLocale;
if (considerDefaultLocale)
defaultLocale = DefaultLocale();
var candidate = locale;
while (true) {
if (availableLocales[candidate])
return candidate;
if (considerDefaultLocale && candidate.length <= defaultLocale.length) {
if (candidate === defaultLocale)
return candidate;
if (callFunction(std_String_startsWith, defaultLocale, candidate + "-"))
return candidate;
}
var pos = callFunction(std_String_lastIndexOf, candidate, "-");
if (pos === -1)
return undefined;
if (pos >= 2 && candidate[pos - 2] === "-")
pos -= 2;
candidate = callFunction(String_substring, candidate, 0, pos);
}
}
function BestAvailableLocale(availableLocales, locale) {
return BestAvailableLocaleHelper(availableLocales, locale, true);
}
function BestAvailableLocaleIgnoringDefault(availableLocales, locale) {
return BestAvailableLocaleHelper(availableLocales, locale, false);
}
function LookupMatcher(availableLocales, requestedLocales) {
var result = new Record();
for (var i = 0; i < requestedLocales.length; i++) {
var locale = requestedLocales[i];
var noExtensionsLocale = removeUnicodeExtensions(locale);
var availableLocale = BestAvailableLocale(availableLocales, noExtensionsLocale);
if (availableLocale !== undefined) {
result.locale = availableLocale;
if (locale !== noExtensionsLocale)
result.extension = getUnicodeExtensions(locale);
return result;
}
}
result.locale = DefaultLocale();
return result;
}
function BestFitMatcher(availableLocales, requestedLocales) {
return LookupMatcher(availableLocales, requestedLocales);
}
function UnicodeExtensionValue(extension, key) {
assert(typeof extension === "string", "extension is a string value");
assert(callFunction(std_String_startsWith, extension, "-u-") &&
getUnicodeExtensions("und" + extension) === extension,
"extension is a Unicode extension subtag");
assert(typeof key === "string", "key is a string value");
assert(key.length === 2, "key is a Unicode extension key subtag");
var size = extension.length;
var searchValue = "-" + key + "-";
var pos = callFunction(std_String_indexOf, extension, searchValue);
if (pos !== -1) {
var start = pos + 4;
var end = start;
var k = start;
while (true) {
var e = callFunction(std_String_indexOf, extension, "-", k);
var len = e === -1 ? size - k : e - k;
if (len === 2)
break;
if (e === -1) {
end = size;
break;
}
end = e;
k = e + 1;
}
return callFunction(String_substring, extension, start, end);
}
searchValue = "-" + key;
if (callFunction(std_String_endsWith, extension, searchValue))
return "";
}
function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData) {
var matcher = options.localeMatcher;
var r = (matcher === "lookup")
? LookupMatcher(availableLocales, requestedLocales)
: BestFitMatcher(availableLocales, requestedLocales);
var foundLocale = r.locale;
var extension = r.extension;
var result = new Record();
result.dataLocale = foundLocale;
var supportedExtension = "-u";
var localeDataProvider = localeData();
for (var i = 0; i < relevantExtensionKeys.length; i++) {
var key = relevantExtensionKeys[i];
var keyLocaleData = undefined;
var value = undefined;
var supportedExtensionAddition = "";
if (extension !== undefined) {
var requestedValue = UnicodeExtensionValue(extension, key);
if (requestedValue !== undefined) {
keyLocaleData = callFunction(localeDataProvider[key], null, foundLocale);
if (requestedValue !== "") {
if (callFunction(ArrayIndexOf, keyLocaleData, requestedValue) !== -1) {
value = requestedValue;
supportedExtensionAddition = "-" + key + "-" + value;
}
} else {
if (callFunction(ArrayIndexOf, keyLocaleData, "true") !== -1)
value = "true";
}
}
}
var optionsValue = options[key];
assert(typeof optionsValue === "string" ||
optionsValue === undefined ||
optionsValue === null,
"unexpected type for options value");
if (optionsValue !== undefined && optionsValue !== value) {
if (keyLocaleData === undefined)
keyLocaleData = callFunction(localeDataProvider[key], null, foundLocale);
if (callFunction(ArrayIndexOf, keyLocaleData, optionsValue) !== -1) {
value = optionsValue;
supportedExtensionAddition = "";
}
}
if (value === undefined) {
value = keyLocaleData === undefined
? callFunction(localeDataProvider.default[key], null, foundLocale)
: keyLocaleData[0];
}
assert(typeof value === "string" || value === null, "unexpected locale data value");
result[key] = value;
supportedExtension += supportedExtensionAddition;
}
if (supportedExtension.length > 2) {
assert(!callFunction(std_String_startsWith, foundLocale, "x-"),
"unexpected privateuse-only locale returned from ICU");
var privateIndex = callFunction(std_String_indexOf, foundLocale, "-x-");
if (privateIndex === -1) {
foundLocale += supportedExtension;
} else {
var preExtension = callFunction(String_substring, foundLocale, 0, privateIndex);
var postExtension = callFunction(String_substring, foundLocale, privateIndex);
foundLocale = preExtension + supportedExtension + postExtension;
}
assertIsValidAndCanonicalLanguageTag(foundLocale, "locale after concatenation");
}
result.locale = foundLocale;
return result;
}
function LookupSupportedLocales(availableLocales, requestedLocales) {
var subset = [];
for (var i = 0; i < requestedLocales.length; i++) {
var locale = requestedLocales[i];
var noExtensionsLocale = removeUnicodeExtensions(locale);
var availableLocale = BestAvailableLocale(availableLocales, noExtensionsLocale);
if (availableLocale !== undefined)
_DefineDataProperty(subset, subset.length, locale);
}
return subset;
}
function BestFitSupportedLocales(availableLocales, requestedLocales) {
return LookupSupportedLocales(availableLocales, requestedLocales);
}
function SupportedLocales(availableLocales, requestedLocales, options) {
var matcher;
if (options !== undefined) {
options = ToObject(options);
matcher = options.localeMatcher;
if (matcher !== undefined) {
matcher = ToString(matcher);
if (matcher !== "lookup" && matcher !== "best fit")
ThrowRangeError(JSMSG_INVALID_LOCALE_MATCHER, matcher);
}
}
return (matcher === undefined || matcher === "best fit")
? BestFitSupportedLocales(availableLocales, requestedLocales)
: LookupSupportedLocales(availableLocales, requestedLocales);
}
function GetOption(options, property, type, values, fallback) {
var value = options[property];
if (value !== undefined) {
if (type === "boolean")
value = ToBoolean(value);
else if (type === "string")
value = ToString(value);
else
assert(false, "GetOption");
if (values !== undefined && callFunction(ArrayIndexOf, values, value) === -1)
ThrowRangeError(JSMSG_INVALID_OPTION_VALUE, property, value);
return value;
}
return fallback;
}
function DefaultNumberOption(value, minimum, maximum, fallback) {
assert(typeof minimum === "number" && (minimum | 0) === minimum, "DefaultNumberOption");
assert(typeof maximum === "number" && (maximum | 0) === maximum, "DefaultNumberOption");
assert(typeof fallback === "number" && (fallback | 0) === fallback, "DefaultNumberOption");
assert(minimum <= fallback && fallback <= maximum, "DefaultNumberOption");
if (value !== undefined) {
value = ToNumber(value);
if (Number_isNaN(value) || value < minimum || value > maximum)
ThrowRangeError(JSMSG_INVALID_DIGITS_VALUE, value);
return std_Math_floor(value) | 0;
}
return fallback;
}
function GetNumberOption(options, property, minimum, maximum, fallback) {
return DefaultNumberOption(options[property], minimum, maximum, fallback);
}
var intlFallbackSymbolHolder = { value: undefined };
function intlFallbackSymbol() {
var fallbackSymbol = intlFallbackSymbolHolder.value;
if (!fallbackSymbol) {
fallbackSymbol = std_Symbol("IntlLegacyConstructedSymbol");
intlFallbackSymbolHolder.value = fallbackSymbol;
}
return fallbackSymbol;
}
function initializeIntlObject(obj, type, lazyData) {
assert(IsObject(obj), "Non-object passed to initializeIntlObject");
assert((type === "Collator" && GuardToCollator(obj) !== null) ||
(type === "DateTimeFormat" && GuardToDateTimeFormat(obj) !== null) ||
(type === "NumberFormat" && GuardToNumberFormat(obj) !== null) ||
(type === "PluralRules" && GuardToPluralRules(obj) !== null) ||
(type === "RelativeTimeFormat" && GuardToRelativeTimeFormat(obj) !== null),
"type must match the object's class");
assert(IsObject(lazyData), "non-object lazy data");
var internals = std_Object_create(null);
internals.type = type;
internals.lazyData = lazyData;
internals.internalProps = null;
assert(UnsafeGetReservedSlot(obj, INTL_INTERNALS_OBJECT_SLOT) === null,
"Internal slot already initialized?");
UnsafeSetReservedSlot(obj, INTL_INTERNALS_OBJECT_SLOT, internals);
}
function setInternalProperties(internals, internalProps) {
assert(IsObject(internals.lazyData), "lazy data must exist already");
assert(IsObject(internalProps), "internalProps argument should be an object");
internals.internalProps = internalProps;
internals.lazyData = null;
}
function maybeInternalProperties(internals) {
assert(IsObject(internals), "non-object passed to maybeInternalProperties");
var lazyData = internals.lazyData;
if (lazyData)
return null;
assert(IsObject(internals.internalProps), "missing lazy data and computed internals");
return internals.internalProps;
}
function getIntlObjectInternals(obj) {
assert(IsObject(obj), "getIntlObjectInternals called with non-Object");
assert(GuardToCollator(obj) !== null || GuardToDateTimeFormat(obj) !== null ||
GuardToNumberFormat(obj) !== null || GuardToPluralRules(obj) !== null ||
GuardToRelativeTimeFormat(obj) !== null,
"getIntlObjectInternals called with non-Intl object");
var internals = UnsafeGetReservedSlot(obj, INTL_INTERNALS_OBJECT_SLOT);
assert(IsObject(internals), "internals not an object");
assert(hasOwn("type", internals), "missing type");
assert((internals.type === "Collator" && GuardToCollator(obj) !== null) ||
(internals.type === "DateTimeFormat" && GuardToDateTimeFormat(obj) !== null) ||
(internals.type === "NumberFormat" && GuardToNumberFormat(obj) !== null) ||
(internals.type === "PluralRules" && GuardToPluralRules(obj) !== null) ||
(internals.type === "RelativeTimeFormat" && GuardToRelativeTimeFormat(obj) !== null),
"type must match the object's class");
assert(hasOwn("lazyData", internals), "missing lazyData");
assert(hasOwn("internalProps", internals), "missing internalProps");
return internals;
}
function getInternals(obj) {
var internals = getIntlObjectInternals(obj);
var internalProps = maybeInternalProperties(internals);
if (internalProps)
return internalProps;
var type = internals.type;
if (type === "Collator")
internalProps = resolveCollatorInternals(internals.lazyData);
else if (type === "DateTimeFormat")
internalProps = resolveDateTimeFormatInternals(internals.lazyData);
else if (type === "NumberFormat")
internalProps = resolveNumberFormatInternals(internals.lazyData);
else
internalProps = resolvePluralRulesInternals(internals.lazyData);
setInternalProperties(internals, internalProps);
return internalProps;
}