1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5 *******************************************************************************
6 * Copyright (C) 2010-2011, Google, International Business Machines            *
7 * Corporation and others. All Rights Reserved.                                *
8 *******************************************************************************
9 */
10package android.icu.text;
11
12import java.util.HashSet;
13import java.util.Set;
14
15import android.icu.lang.CharSequences;
16
17/**
18 * Simple internal utility class for helping with getSource/TargetSet
19 */
20class SourceTargetUtility {
21    final Transform<String, String> transform;
22    final UnicodeSet sourceCache;
23    final Set<String> sourceStrings;
24    static final UnicodeSet NON_STARTERS = new UnicodeSet("[:^ccc=0:]").freeze();
25    static Normalizer2 NFC = Normalizer2.getNFCInstance();
26    //static final UnicodeSet TRAILING_COMBINING = new UnicodeSet();
27
28    public SourceTargetUtility(Transform<String, String> transform) {
29        this(transform, null);
30    }
31
32    public SourceTargetUtility(Transform<String, String> transform, Normalizer2 normalizer) {
33        this.transform = transform;
34        if (normalizer != null) {
35//            synchronized (SourceTargetUtility.class) {
36//                if (NFC == null) {
37//                    NFC = Normalizer2.getInstance(null, "nfc", Mode.COMPOSE);
38//                    for (int i = 0; i <= 0x10FFFF; ++i) {
39//                        String d = NFC.getDecomposition(i);
40//                        if (d == null) {
41//                            continue;
42//                        }
43//                        String s = NFC.normalize(d);
44//                        if (!CharSequences.equals(i, s)) {
45//                            continue;
46//                        }
47//                        // composes
48//                        boolean first = false;
49//                        for (int trailing : CharSequences.codePoints(d)) {
50//                            if (first) {
51//                                first = false;
52//                            } else {
53//                                TRAILING_COMBINING.add(trailing);
54//                            }
55//                        }
56//                    }
57//                }
58//            }
59            sourceCache = new UnicodeSet("[:^ccc=0:]");
60        } else {
61            sourceCache = new UnicodeSet();
62        }
63        sourceStrings = new HashSet<String>();
64        for (int i = 0; i <= 0x10FFFF; ++i) {
65            String s = transform.transform(UTF16.valueOf(i));
66            boolean added = false;
67            if (!CharSequences.equals(i, s)) {
68                sourceCache.add(i);
69                added = true;
70            }
71            if (normalizer == null) {
72                continue;
73            }
74            String d = NFC.getDecomposition(i);
75            if (d == null) {
76                continue;
77            }
78            s = transform.transform(d);
79            if (!d.equals(s)) {
80                sourceStrings.add(d);
81            }
82            if (added) {
83                continue;
84            }
85            if (!normalizer.isInert(i)) {
86                sourceCache.add(i);
87                continue;
88            }
89            // see if any of the non-starters change s; if so, add i
90//            for (String ns : TRAILING_COMBINING) {
91//                String s2 = transform.transform(s + ns);
92//                if (!s2.startsWith(s)) {
93//                    sourceCache.add(i);
94//                    break;
95//                }
96//            }
97
98            // int endOfFirst = CharSequences.onCharacterBoundary(d, 1) ? 1 : 2;
99            // if (endOfFirst >= d.length()) {
100            // continue;
101            // }
102            // // now add all initial substrings
103            // for (int j = 1; j < d.length(); ++j) {
104            // if (!CharSequences.onCharacterBoundary(d, j)) {
105            // continue;
106            // }
107            // String dd = d.substring(0,j);
108            // s = transform.transform(dd);
109            // if (!dd.equals(s)) {
110            // sourceStrings.add(dd);
111            // }
112            // }
113        }
114        sourceCache.freeze();
115    }
116
117    public void addSourceTargetSet(Transliterator transliterator, UnicodeSet inputFilter, UnicodeSet sourceSet,
118            UnicodeSet targetSet) {
119        UnicodeSet myFilter = transliterator.getFilterAsUnicodeSet(inputFilter);
120        UnicodeSet affectedCharacters = new UnicodeSet(sourceCache).retainAll(myFilter);
121        sourceSet.addAll(affectedCharacters);
122        for (String s : affectedCharacters) {
123            targetSet.addAll(transform.transform(s));
124        }
125        for (String s : sourceStrings) {
126            if (myFilter.containsAll(s)) {
127                String t = transform.transform(s);
128                if (!s.equals(t)) {
129                    targetSet.addAll(t);
130                    sourceSet.addAll(s);
131                }
132            }
133        }
134    }
135}
136