Skip to content

Commit fb847bb

Browse files
author
Justin Lu
committedFeb 7, 2025
8349493: Replace sun.util.locale.ParseStatus usage with java.text.ParsePosition
Reviewed-by: naoto
1 parent 7cd5cb2 commit fb847bb

File tree

3 files changed

+60
-126
lines changed

3 files changed

+60
-126
lines changed
 

‎src/java.base/share/classes/java/util/Locale.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
4747
import java.io.Serializable;
4848
import java.text.NumberFormat;
4949
import java.text.MessageFormat;
50+
import java.text.ParsePosition;
5051
import java.util.concurrent.ConcurrentHashMap;
5152
import java.util.function.Function;
5253
import java.util.spi.LocaleNameProvider;
@@ -63,7 +64,6 @@
6364
import sun.util.locale.LocaleMatcher;
6465
import sun.util.locale.LocaleSyntaxException;
6566
import sun.util.locale.LocaleUtils;
66-
import sun.util.locale.ParseStatus;
6767
import sun.util.locale.provider.LocaleProviderAdapter;
6868
import sun.util.locale.provider.LocaleResources;
6969
import sun.util.locale.provider.LocaleServiceProviderPool;
@@ -1919,7 +1919,8 @@ public static String caseFoldLanguageTag(String languageTag) {
19191919
* @since 1.7
19201920
*/
19211921
public static Locale forLanguageTag(String languageTag) {
1922-
LanguageTag tag = LanguageTag.parse(languageTag, null);
1922+
LanguageTag tag = LanguageTag.parse(
1923+
languageTag, new ParsePosition(0), true);
19231924
InternalLocaleBuilder bldr = new InternalLocaleBuilder();
19241925
bldr.setLanguageTag(tag);
19251926
BaseLocale base = bldr.getBaseLocale();
@@ -2789,11 +2790,8 @@ public Builder setLocale(Locale locale) {
27892790
* @see Locale#forLanguageTag(String)
27902791
*/
27912792
public Builder setLanguageTag(String languageTag) {
2792-
ParseStatus sts = new ParseStatus();
2793-
LanguageTag tag = LanguageTag.parse(languageTag, sts);
2794-
if (sts.isError()) {
2795-
throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
2796-
}
2793+
LanguageTag tag = LanguageTag.parse(
2794+
languageTag, new ParsePosition(0), false);
27972795
localeBuilder.setLanguageTag(tag);
27982796
return this;
27992797
}

‎src/java.base/share/classes/sun/util/locale/LanguageTag.java

+54-54
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
3131
*/
3232
package sun.util.locale;
3333

34+
import java.text.ParsePosition;
3435
import java.util.ArrayList;
3536
import java.util.Collections;
3637
import java.util.HashMap;
@@ -180,14 +181,10 @@ private LanguageTag() {
180181
* privateuse = "x" 1*("-" (1*8alphanum))
181182
*
182183
*/
183-
public static LanguageTag parse(String languageTag, ParseStatus sts) {
184-
if (sts == null) {
185-
sts = new ParseStatus();
186-
} else {
187-
sts.reset();
188-
}
189-
184+
public static LanguageTag parse(String languageTag, ParsePosition pp,
185+
boolean lenient) {
190186
StringTokenIterator itr;
187+
var errorMsg = new StringBuilder();
191188

192189
// Check if the tag is a legacy language tag
193190
String[] gfmap = LEGACY.get(LocaleUtils.toLowerString(languageTag));
@@ -201,32 +198,38 @@ public static LanguageTag parse(String languageTag, ParseStatus sts) {
201198
LanguageTag tag = new LanguageTag();
202199

203200
// langtag must start with either language or privateuse
204-
if (tag.parseLanguage(itr, sts)) {
205-
tag.parseExtlangs(itr, sts);
206-
tag.parseScript(itr, sts);
207-
tag.parseRegion(itr, sts);
208-
tag.parseVariants(itr, sts);
209-
tag.parseExtensions(itr, sts);
210-
}
211-
tag.parsePrivateuse(itr, sts);
212-
if (!itr.isDone() && !sts.isError()) {
201+
if (tag.parseLanguage(itr, pp)) {
202+
tag.parseExtlangs(itr, pp);
203+
tag.parseScript(itr, pp);
204+
tag.parseRegion(itr, pp);
205+
tag.parseVariants(itr, pp);
206+
tag.parseExtensions(itr, pp, errorMsg);
207+
}
208+
tag.parsePrivateuse(itr, pp, errorMsg);
209+
210+
if (!itr.isDone() && pp.getErrorIndex() == -1) {
213211
String s = itr.current();
214-
sts.errorIndex = itr.currentStart();
212+
pp.setErrorIndex(itr.currentStart());
215213
if (s.isEmpty()) {
216-
sts.errorMsg = "Empty subtag";
214+
errorMsg.append("Empty subtag");
217215
} else {
218-
sts.errorMsg = "Invalid subtag: " + s;
216+
errorMsg.append("Invalid subtag: ").append(s);
219217
}
220218
}
219+
220+
if (!lenient && pp.getErrorIndex() != -1) {
221+
throw new IllformedLocaleException(errorMsg.toString(), pp.getErrorIndex());
222+
}
223+
221224
return tag;
222225
}
223226

224227
//
225228
// Language subtag parsers
226229
//
227230

228-
private boolean parseLanguage(StringTokenIterator itr, ParseStatus sts) {
229-
if (itr.isDone() || sts.isError()) {
231+
private boolean parseLanguage(StringTokenIterator itr, ParsePosition pp) {
232+
if (itr.isDone() || pp.getErrorIndex() != -1) {
230233
return false;
231234
}
232235

@@ -236,15 +239,15 @@ private boolean parseLanguage(StringTokenIterator itr, ParseStatus sts) {
236239
if (isLanguage(s)) {
237240
found = true;
238241
language = s;
239-
sts.parseLength = itr.currentEnd();
242+
pp.setIndex(itr.currentEnd());
240243
itr.next();
241244
}
242245

243246
return found;
244247
}
245248

246-
private boolean parseExtlangs(StringTokenIterator itr, ParseStatus sts) {
247-
if (itr.isDone() || sts.isError()) {
249+
private boolean parseExtlangs(StringTokenIterator itr, ParsePosition pp) {
250+
if (itr.isDone() || pp.getErrorIndex() != -1) {
248251
return false;
249252
}
250253

@@ -260,7 +263,7 @@ private boolean parseExtlangs(StringTokenIterator itr, ParseStatus sts) {
260263
extlangs = new ArrayList<>(3);
261264
}
262265
extlangs.add(s);
263-
sts.parseLength = itr.currentEnd();
266+
pp.setIndex(itr.currentEnd());
264267
itr.next();
265268

266269
if (extlangs.size() == 3) {
@@ -272,8 +275,8 @@ private boolean parseExtlangs(StringTokenIterator itr, ParseStatus sts) {
272275
return found;
273276
}
274277

275-
private boolean parseScript(StringTokenIterator itr, ParseStatus sts) {
276-
if (itr.isDone() || sts.isError()) {
278+
private boolean parseScript(StringTokenIterator itr, ParsePosition pp) {
279+
if (itr.isDone() || pp.getErrorIndex() != -1) {
277280
return false;
278281
}
279282

@@ -283,15 +286,15 @@ private boolean parseScript(StringTokenIterator itr, ParseStatus sts) {
283286
if (isScript(s)) {
284287
found = true;
285288
script = s;
286-
sts.parseLength = itr.currentEnd();
289+
pp.setIndex(itr.currentEnd());
287290
itr.next();
288291
}
289292

290293
return found;
291294
}
292295

293-
private boolean parseRegion(StringTokenIterator itr, ParseStatus sts) {
294-
if (itr.isDone() || sts.isError()) {
296+
private boolean parseRegion(StringTokenIterator itr, ParsePosition pp) {
297+
if (itr.isDone() || pp.getErrorIndex() != -1) {
295298
return false;
296299
}
297300

@@ -301,15 +304,15 @@ private boolean parseRegion(StringTokenIterator itr, ParseStatus sts) {
301304
if (isRegion(s)) {
302305
found = true;
303306
region = s;
304-
sts.parseLength = itr.currentEnd();
307+
pp.setIndex(itr.currentEnd());
305308
itr.next();
306309
}
307310

308311
return found;
309312
}
310313

311-
private boolean parseVariants(StringTokenIterator itr, ParseStatus sts) {
312-
if (itr.isDone() || sts.isError()) {
314+
private boolean parseVariants(StringTokenIterator itr, ParsePosition pp) {
315+
if (itr.isDone() || pp.getErrorIndex() != -1) {
313316
return false;
314317
}
315318

@@ -325,15 +328,16 @@ private boolean parseVariants(StringTokenIterator itr, ParseStatus sts) {
325328
variants = new ArrayList<>(3);
326329
}
327330
variants.add(s);
328-
sts.parseLength = itr.currentEnd();
331+
pp.setIndex(itr.currentEnd());
329332
itr.next();
330333
}
331334

332335
return found;
333336
}
334337

335-
private boolean parseExtensions(StringTokenIterator itr, ParseStatus sts) {
336-
if (itr.isDone() || sts.isError()) {
338+
private boolean parseExtensions(StringTokenIterator itr, ParsePosition pp,
339+
StringBuilder err) {
340+
if (itr.isDone() || pp.getErrorIndex() != -1) {
337341
return false;
338342
}
339343

@@ -351,16 +355,16 @@ private boolean parseExtensions(StringTokenIterator itr, ParseStatus sts) {
351355
s = itr.current();
352356
if (isExtensionSubtag(s)) {
353357
sb.append(SEP).append(s);
354-
sts.parseLength = itr.currentEnd();
358+
pp.setIndex(itr.currentEnd());
355359
} else {
356360
break;
357361
}
358362
itr.next();
359363
}
360364

361-
if (sts.parseLength <= start) {
362-
sts.errorIndex = start;
363-
sts.errorMsg = "Incomplete extension '" + singleton + "'";
365+
if (pp.getIndex() <= start) {
366+
pp.setErrorIndex(start);
367+
err.append("Incomplete extension '").append(singleton).append("'");
364368
break;
365369
}
366370

@@ -376,8 +380,9 @@ private boolean parseExtensions(StringTokenIterator itr, ParseStatus sts) {
376380
return found;
377381
}
378382

379-
private boolean parsePrivateuse(StringTokenIterator itr, ParseStatus sts) {
380-
if (itr.isDone() || sts.isError()) {
383+
private boolean parsePrivateuse(StringTokenIterator itr, ParsePosition pp,
384+
StringBuilder err) {
385+
if (itr.isDone() || pp.getErrorIndex() != -1) {
381386
return false;
382387
}
383388

@@ -395,15 +400,15 @@ private boolean parsePrivateuse(StringTokenIterator itr, ParseStatus sts) {
395400
break;
396401
}
397402
sb.append(SEP).append(s);
398-
sts.parseLength = itr.currentEnd();
403+
pp.setIndex(itr.currentEnd());
399404

400405
itr.next();
401406
}
402407

403-
if (sts.parseLength <= start) {
408+
if (pp.getIndex() <= start) {
404409
// need at least 1 private subtag
405-
sts.errorIndex = start;
406-
sts.errorMsg = "Incomplete privateuse";
410+
pp.setErrorIndex(start);
411+
err.append("Incomplete privateuse");
407412
} else {
408413
privateuse = sb.toString();
409414
found = true;
@@ -414,13 +419,8 @@ private boolean parsePrivateuse(StringTokenIterator itr, ParseStatus sts) {
414419
}
415420

416421
public static String caseFoldTag(String tag) {
417-
ParseStatus sts = new ParseStatus();
418-
parse(tag, sts);
419-
// Illegal tags
420-
if (sts.errorMsg != null) {
421-
throw new IllformedLocaleException(String.format("Ill formed tag:" +
422-
" %s", sts.errorMsg));
423-
}
422+
parse(tag, new ParsePosition(0), false);
423+
424424
// Legacy tags
425425
String potentialLegacy = tag.toLowerCase(Locale.ROOT);
426426
if (LEGACY.containsKey(potentialLegacy)) {

‎src/java.base/share/classes/sun/util/locale/ParseStatus.java

-64
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.