001package Torello.CSS;
002
003import Torello.Java.Additional.ByRef;
004import java.util.function.Consumer;
005
006/** The root abstract-parent class for all CSSToken Sub-Classes. */
007public abstract class CSSToken
008    implements CharSequence, java.io.Serializable, Comparable<CharSequence>
009{
010    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
011    protected static final long serialVersionUID = 1;
012
013
014    // ********************************************************************************************
015    // ********************************************************************************************
016    // Public & Final Fields
017    // ********************************************************************************************
018    // ********************************************************************************************
019
020
021    /**
022     * The "Reconstituted Character Data" (re-built from the input Code-Points array) that comprise
023     * this {@code CSSToken}.
024     */
025    public final String str;
026
027
028    // ********************************************************************************************
029    // ********************************************************************************************
030    // Private Constructor
031    // ********************************************************************************************
032    // ********************************************************************************************
033
034
035    CSSToken(int[] cssCodePoints, int sPos, int ePos)
036    { this.str = new String(cssCodePoints, sPos, ePos - sPos); }
037
038    // This is used by Punct, CDO, CDC and Delimiter **ONLY**
039    CSSToken(String str)
040    { this.str = str; }
041
042
043    // ********************************************************************************************
044    // ********************************************************************************************
045    // java.lang.CharSequence
046    // ********************************************************************************************
047    // ********************************************************************************************
048
049
050    public final char charAt(int index)
051    { return str.charAt(index); }
052
053    public final int length()
054    { return str.length(); }
055
056    public final String subSequence(int start, int end)
057    { return str.substring(start, end); }
058
059    public final String toString()
060    { return str; }
061
062
063    // ********************************************************************************************
064    // ********************************************************************************************
065    // java.lang.Object, java.lang.Comparable
066    // ********************************************************************************************
067    // ********************************************************************************************
068
069
070    public final int compareTo(CharSequence other)
071    { return str.compareTo(other.toString()); }
072
073    public final boolean equals(Object other)
074    {
075        if (this == other) return true;
076
077        if (! other.getClass().equals(this.getClass()))return false;
078
079        return ((CSSToken) other).str.equals(this.str);
080    }
081
082
083    // ********************************************************************************************
084    // ********************************************************************************************
085    // User's Constructor: Static "build" Method (and associated Helper-Interfaces)
086    // ********************************************************************************************
087    // ********************************************************************************************
088
089
090    /*
091    // These Package-Private Methods (for internal use only) are for creating a CSSToken instance
092    // using a User-Provided String - RATHER THAN A STRING THAT HAS BEEN EXTRACTED BY THE TOKENIZER
093    // This whole process is a little tricky because, generally, a constructor makes a lot more
094    // sense to the End-User.
095    // 
096    // However, there are two major stipulations behind the Java-HTML CSS-Tokenizer:
097    // 
098    //      * First, as with the Java-HTML HTML-Parser:the sum of all CSSTokens must be identical
099    //        to the Origina-File.
100    // 
101    //      * The tokenizer must implement the CSS Working-Group Website's "Pass-1 CSS-Tokenizer"
102    //        EXACTLY, as specified.  Because all of that Web-Site's Algorithm's 'consume' methods
103    //        make invocations to each other, using Constructors would make the code next to
104    //        unreadable.
105    //
106    // Futhermore, since it wasn't until JDK-22's release that "Statements before this() and
107    // super()" inside of a constructor were even legal, and since this code is currently living in
108    // "Java 11" - since the JavaDoc-Upgrader's "Upgrade to JDK-21" is a few more months away - it
109    // is simply not possible to avoid "Static-Builder's" rather than constructors.
110    //
111    // TLDR ==>  Constructor's are usually much easier to read, and explaining things is usually
112    //           much more direct.  Howeveer since that isn't possible, static build-methods are
113    //           provided instead.
114    //
115    // Because the Token-Classes in Torello.CSS were all written using the CSS-WG Site, the
116    // "consume" methods are all intended to be used by the parser-tokenizer "Main Tokenize Loop".
117    //
118    // It is some work (but only a few lines) to convert the CSSToken class' "consume" methods into
119    // "build" methods that are suitable for an "End-User" to build their own Tokens.
120    */
121
122    // Please don't ask...  This cute little thing is not that hard.  It's just a function-pointer
123    @FunctionalInterface
124    static interface TokenConsumer4
125    {
126        public void consume(
127            final int[]                     css,
128            final ByRef<Integer>            POS,
129            final Consumer<CSSToken>        returnParsedToken,
130            final Consumer<TokenizeError>   errorEncountered
131        );
132    }
133
134    // Function-Pointer for "consme" methods that take 3-arguments (no error-out), instead of 4
135    @FunctionalInterface
136    static interface TokenConsumer3
137    {
138        public void consume(
139            final int[]                     css,
140            final ByRef<Integer>            POS,
141            final Consumer<CSSToken>        returnParsedToken
142        );
143    }
144
145    // Each Sub-Class has a "Check for Errors" Function-Pointer that throws "TokenizeException"
146    @FunctionalInterface
147    interface InputChecker { public void check(int[] css); }
148
149
150    // This Build Method is for CSSToken classes whose consume-method accepts 3 parameters
151    //
152    // The 'TokenConsumer4' accepts:
153    //      int[] css                               ==> The CSS-as-a-String (of Code-Points)
154    //      ByRef<Integer> pos                      ==> Pointer to the next location in the array
155    //                                                  to be processed.  
156    //      Consumer<CSSToken> returnParsedToken    ==> This is the "Convoluted-Way" for returning
157    //                                                  the CSS-Token to the "build" method
158    //      Consumer<TokenizeError> errorEncountered==> If an error occurs, this is also the
159    //                                                  "Convoluted-Way" for returning the error
160    //
161    // NOTE: These "Convoluted" (Consumer) things are a very simple and straight-foward way to add
162    //       newly constructed tokens to the output-vector - FROM THE PERSPECTIVE OF THE TOKENIZE
163    //       algorithm.
164    //
165    // FROM THE PERSPECTIVE OF A "BUILD" METHOD, THEY MAY (PERHAPS) SEEM A LITTLE BACKWARDS.
166    // Main Point Being: The individual CSSToken Classes "Consume" method can be used by EITHER the
167    // Tokenizer or a User's String input.
168
169    static CSSToken build(
170            final String            inputStr,   // The User's Input-String which he-or-she would 
171                                                // like to convert into a CSSToken instance
172            final InputChecker      inputChecker,
173            final TokenConsumer4    tokenConsumer   // "4" ==> css, pos, output, error-output
174        )
175    {
176        if (inputStr.length() == 0) throw new TokenizeException();
177
178        final int[] css = inputStr.codePoints().toArray();
179
180        inputChecker.check(css);
181
182        final ByRef<CSSToken> R = new ByRef<>(null);
183
184        // All this is doing is calling the relevant/pertinent "consume" method (which was passed 
185        // by the 'tokenConsumer' function-pointer).  
186
187        tokenConsumer.consume(
188            css,
189            new ByRef<>(0),
190            (CSSToken t) -> R.f = t,
191            (TokenizeError te) -> te.throwException()
192        );
193
194        // Need to guarantee that the entire String was consumed in the process of tokenizing the
195        // input String.  'TokenzeException' has a nicely worded Esception-Message to explain what
196        // has occured here.
197
198        if (inputStr.length() != R.f.str.length()) throw new TokenizeException(inputStr, R.f.str);
199
200        return R.f;
201    }
202
203    // SAME AS ABOVE - EXCEPT THIS METHOD CAN BE INVOKED BY CSSToken Classes whose "consume" method
204    // only acdepts three parameters.  Just to be aware the fourth parameter that is left out is
205    // one that accepts "TokenizeError" instances.
206    //
207    // Many of the CSSToken classes do need to check for input-error.  This is primarily becuase
208    // in as-many-cases-as-possible, the tokenizer will check for validity before attempting to
209    // invoke a token's "consume" method.
210
211    static CSSToken build(
212            final String            inputStr,       // The User's Input-String which he-or-she 
213                                                    // would like to convert into a CSSToken
214            final InputChecker      inputChecker,
215            final TokenConsumer3    tokenConsumer   // "3" ==> css, pos, output
216        )
217    {
218        if (inputStr.length() == 0) throw new TokenizeException();
219
220        final int[] css = inputStr.codePoints().toArray();
221
222        inputChecker.check(css);
223
224        final ByRef<CSSToken> R = new ByRef<>(null);
225
226        tokenConsumer.consume(
227            css,
228            new ByRef<>(0),
229            (CSSToken t) -> R.f = t
230        );
231
232        // Need to guarantee that the entire String was consumed in the process of tokenizing the
233        // input String.  'TokenzeException' has a nicely worded Esception-Message to explain what
234        // has occured here.
235
236        if (inputStr.length() != R.f.str.length()) throw new TokenizeException(inputStr, R.f.str);
237
238        return R.f;
239    }
240
241
242    // ********************************************************************************************
243    // ********************************************************************************************
244    // "is"
245    // ********************************************************************************************
246    // ********************************************************************************************
247
248
249    /**
250     * <EMBED CLASS=defs DATA-TOK=AtKeyword>
251     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
252     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
253     * @see AtKeyword#isAtKeyword()
254     */
255    public boolean isAtKeyword() { return false; }
256
257    /**
258     * <EMBED CLASS=defs DATA-TOK=BadStr>
259     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
260     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
261     * @see BadStr#isBadStr()
262     */
263    public boolean isBadStr() { return false; }
264
265    /**
266     * <EMBED CLASS=defs DATA-TOK=BadURL>
267     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
268     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
269     * @see BadURL#isBadURL()
270     */
271    public boolean isBadURL() { return false; }
272
273    /**
274     * <EMBED CLASS=defs DATA-TOK=CDC>
275     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
276     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
277     * @see CDC#isCDC()
278     */
279    public boolean isCDC() { return false; }
280
281    /**
282     * <EMBED CLASS=defs DATA-TOK=CDO>
283     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
284     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
285     * @see CDO#isCDO()
286     */
287    public boolean isCDO() { return false; }
288
289    /**
290     * <EMBED CLASS=defs DATA-TOK=Comment>
291     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
292     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
293     * @see Comment#isComment()
294     */
295    public boolean isComment() { return false; }
296
297    /**
298     * <EMBED CLASS=defs DATA-TOK=Delimiter>
299     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
300     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
301     * @see Delimiter#isDelimiter()
302     */
303    public boolean isDelimiter() { return false; }
304
305    /**
306     * Checks whether {@code 'this'} instance is a {@code Delimiter} instance.
307     * @param c Any Java {@code char}.
308     * @return {@code TRUE} if {@code 'this'} is a delimiter containing {@code 'c'}.
309     */
310    public boolean isDelimiter(char c)
311    { return this.isDelimiter() && (((Delimiter) this).c == c); }
312
313    /**
314     * <EMBED CLASS=defs DATA-TOK=Dimension>
315     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
316     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
317     * @see Dimension#isDimension()
318     */
319    public boolean isDimension() { return false; }
320
321    /**
322     * <EMBED CLASS=defs DATA-TOK=Func>
323     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
324     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
325     * @see Func#isFunc()
326     */
327    public boolean isFunc() { return false; }
328
329    /**
330     * <EMBED CLASS=defs DATA-TOK=Hash>
331     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
332     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
333     * @see Hash#isHash()
334     */
335    public boolean isHash() { return false; }
336
337    /**
338     * <EMBED CLASS=defs DATA-TOK=Identifier>
339     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
340     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
341     * @see Identifier#isIdentifier()
342     */
343    public boolean isIdentifier() { return false; }
344
345    /**
346     * <EMBED CLASS=defs DATA-TOK=Num>
347     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
348     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
349     * @see Num#isNum()
350     */
351    public boolean isNum() { return false; }
352
353    /**
354     * <EMBED CLASS=defs DATA-TOK=Percentage>
355     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
356     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
357     * @see Percentage#isPercentage()
358     */
359    public boolean isPercentage() { return false; }
360
361    /**
362     * <EMBED CLASS=defs DATA-TOK=Punct>
363     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
364     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
365     * @see Punct#isPunct()
366     */
367    public boolean isPunct() { return false; }
368
369    /**
370     * Checks whether {@code 'this'} instance is a punctuation character
371     * @param c Any Java {@code char}.
372     * @return {@code TRUE} if {@code 'this'} is a punctuation of {@code 'c'}.
373     */
374    public final boolean isPunct(char c)
375    { return isPunct() && (((Punct) this).c == c); }
376
377    /**
378     * <EMBED CLASS=defs DATA-TOK=Str>
379     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
380     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
381     * @see Str#isStr()
382     */
383    public boolean isStr() { return false; }
384
385    /**
386     * <EMBED CLASS=defs DATA-TOK=UnicodeRange>
387     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
388     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
389     * @see UnicodeRange#isUnicodeRange()
390     */
391    public boolean isUnicodeRange() { return false; }
392
393    /**
394     * <EMBED CLASS=defs DATA-TOK=URLToken>
395     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
396     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
397     * @see URLToken#isURL()
398     */
399    public boolean isURL() { return false; }
400
401    /**
402     * <EMBED CLASS=defs DATA-TOK=Whitespace>
403     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_DESCRIPTION>
404     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IS_RETURNS>
405     * @see Whitespace#isWhitespace()
406     */
407    public boolean isWhitespace() { return false; }
408
409
410    // ********************************************************************************************
411    // ********************************************************************************************
412    // "as"
413    // ********************************************************************************************
414    // ********************************************************************************************
415
416
417    /**
418     * <EMBED CLASS=defs DATA-TOK=AtKeyword>
419     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
420     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
421     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
422     */
423    public final AtKeyword asAtKeyword() { return AtKeyword.class.cast(this); }
424
425    /**
426     * <EMBED CLASS=defs DATA-TOK=BadStr>
427     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
428     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
429     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
430     */
431    public final BadStr asBadStr() { return BadStr.class.cast(this); }
432
433    /**
434     * <EMBED CLASS=defs DATA-TOK=BadURL>
435     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
436     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
437     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
438     */
439    public final BadURL asBadURL() { return BadURL.class.cast(this); }
440
441    /**
442     * <EMBED CLASS=defs DATA-TOK=CDC>
443     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
444     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
445     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
446     */
447    public final CDC asCDC() { return CDC.class.cast(this); }
448
449    /**
450     * <EMBED CLASS=defs DATA-TOK=CDO>
451     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
452     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
453     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
454     */
455    public final CDO asCDO() { return CDO.class.cast(this); }
456
457    /**
458     * <EMBED CLASS=defs DATA-TOK=Comment>
459     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
460     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
461     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
462     */
463    public final Comment asComment() { return Comment.class.cast(this); }
464
465    /**
466     * <EMBED CLASS=defs DATA-TOK=Delimiter>
467     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
468     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
469     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
470     */
471    public final Delimiter asDelimiter() { return Delimiter.class.cast(this); }
472
473    /**
474     * <EMBED CLASS=defs DATA-TOK=Dimension>
475     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
476     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
477     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
478     */
479    public final Dimension asDimension() { return Dimension.class.cast(this); }
480
481    /**
482     * <EMBED CLASS=defs DATA-TOK=Func>
483     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
484     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
485     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
486     */
487    public final Func asFunc() { return Func.class.cast(this); }
488
489    /**
490     * <EMBED CLASS=defs DATA-TOK=Hash>
491     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
492     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
493     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
494     */
495    public final Hash asHash() { return Hash.class.cast(this); }
496
497    /**
498     * <EMBED CLASS=defs DATA-TOK=Identifier>
499     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
500     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
501     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
502     */
503    public final Identifier asIdentifier() { return Identifier.class.cast(this); }
504
505    /**
506     * <EMBED CLASS=defs DATA-TOK=Num>
507     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
508     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
509     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
510     */
511    public final Num asNum() { return Num.class.cast(this); }
512
513    /**
514     * <EMBED CLASS=defs DATA-TOK=Percentage>
515     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
516     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
517     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
518     */
519    public final Percentage asPercentage() { return Percentage.class.cast(this); }
520
521    /**
522     * <EMBED CLASS=defs DATA-TOK=Punct>
523     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
524     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
525     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
526     */
527    public final Punct asPunct() { return Punct.class.cast(this); }
528
529    /**
530     * <EMBED CLASS=defs DATA-TOK=Str>
531     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
532     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
533     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
534     */
535    public final Str asStr() { return Str.class.cast(this); }
536
537    /**
538     * <EMBED CLASS=defs DATA-TOK=UnicodeRange>
539     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
540     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
541     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
542     */
543    public final UnicodeRange asUnicodeRange() { return UnicodeRange.class.cast(this); }
544
545    /**
546     * <EMBED CLASS=defs DATA-TOK=URLToken>
547     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
548     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
549     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
550     */
551    public final URLToken asURL() { return URLToken.class.cast(this); }
552
553    /**
554     * <EMBED CLASS=defs DATA-TOK=Whitespace>
555     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_DESCRIPTION>
556     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_AS_RETURNS>
557     * @throws <EMBED CLASS='external-html' DATA-FILE-ID=CCST_AS_CCEX>
558     */
559    public final Whitespace asWhitespace() { return Whitespace.class.cast(this); }
560
561
562    // ********************************************************************************************
563    // ********************************************************************************************
564    // "if"
565    // ********************************************************************************************
566    // ********************************************************************************************
567
568
569    /**
570     * <EMBED CLASS=defs DATA-TOK=AtKeyword>
571     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
572     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
573     * @see AtKeyword#ifAtKeyword()
574     */
575    public AtKeyword ifAtKeyword() { return null; }
576
577    /**
578     * <EMBED CLASS=defs DATA-TOK=BadStr>
579     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
580     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
581     * @see BadStr#ifBadStr()
582     */
583    public BadStr ifBadStr() { return null; }
584
585    /**
586     * <EMBED CLASS=defs DATA-TOK=BadURL>
587     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
588     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
589     * @see BadURL#ifBadURL()
590     */
591    public BadURL ifBadURL() { return null; }
592
593    /**
594     * <EMBED CLASS=defs DATA-TOK=CDC>
595     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
596     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
597     * @see CDC#ifCDC()
598     */
599    public CDC ifCDC() { return null; }
600
601    /**
602     * <EMBED CLASS=defs DATA-TOK=CDO>
603     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
604     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
605     * @see CDO#ifCDO()
606     */
607    public CDO ifCDO() { return null; }
608
609    /**
610     * <EMBED CLASS=defs DATA-TOK=Comment>
611     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
612     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
613     * @see Comment#ifComment()
614     */
615    public Comment ifComment() { return null; }
616
617    /**
618     * <EMBED CLASS=defs DATA-TOK=Delimiter>
619     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
620     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
621     * @see Delimiter#ifDelimiter()
622     */
623    public Delimiter ifDelimiter() { return null; }
624
625    /**
626     * This one actually does this cute little dance, and then and goes and makes funny
627     * faces at your mother.
628     * 
629     * @param c The Delimiter Character.
630     * 
631     * @return {@code TRUE} if and only {@code 'this'} is an instance of {@link Delimiter}, and one
632     * whose {@link Delimiter#c} matches parameter {@code 'c'}.
633     * 
634     * @see Delimiter#isDelimiter()
635     */
636    public final Delimiter ifDelimiter(char c)
637    { return isDelimiter() && (((Delimiter) this).c == c) ? Delimiter.class.cast(this) : null; }
638
639    /**
640     * <EMBED CLASS=defs DATA-TOK=Dimension>
641     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
642     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
643     * @see Dimension#ifDimension()
644     */
645    public Dimension ifDimension() { return null; }
646
647    /**
648     * <EMBED CLASS=defs DATA-TOK=Func>
649     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
650     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
651     * @see Func#ifFunc()
652     */
653    public Func ifFunc() { return null; }
654
655    /**
656     * <EMBED CLASS=defs DATA-TOK=Hash>
657     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
658     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
659     * @see Hash#ifHash()
660     */
661    public Hash ifHash() { return null; }
662
663    /**
664     * <EMBED CLASS=defs DATA-TOK=Identifier>
665     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
666     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
667     * @see Identifier#ifIdentifier()
668     */
669    public Identifier ifIdentifier() { return null; }
670
671    /**
672     * <EMBED CLASS=defs DATA-TOK=Num>
673     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
674     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
675     * @see Num#ifNum()
676     */
677    public Num ifNum() { return null; }
678
679    /**
680     * <EMBED CLASS=defs DATA-TOK=Percentage>
681     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
682     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
683     * @see Percentage#ifPercentage()
684     */
685    public Percentage ifPercentage() { return null; }
686
687    /**
688     * <EMBED CLASS=defs DATA-TOK=Punct>
689     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
690     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
691     * @see Punct#ifPunct()
692     */
693    public Punct ifPunct() { return null; }
694
695    /**
696     * This one actually does this cute little dance, and then and goes and makes funny
697     * faces at your mother.
698     * 
699     * @param c The Punctuation Character.
700     * 
701     * @return {@code TRUE} if and only {@code 'this'} is an instance of {@link Punct}, and one
702     * whose {@link Punct#c c field} matches parameter {@code 'c'}.
703     * 
704     * @see Punct#isPunct()
705     */
706    public final Punct ifPunct(char c)
707    { return this.isPunct() && (((Punct) this).c == c) ? Punct.class.cast(this) : null; }
708
709    /**
710     * <EMBED CLASS=defs DATA-TOK=Str>
711     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
712     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
713     * @see Str#ifStr()
714     */
715    public Str ifStr() { return null; }
716
717    /**
718     * <EMBED CLASS=defs DATA-TOK=UnicodeRange>
719     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
720     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
721     * @see UnicodeRange#ifUnicodeRange()
722     */
723    public UnicodeRange ifUnicodeRange() { return null; }
724
725    /**
726     * <EMBED CLASS=defs DATA-TOK=URLToken>
727     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
728     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
729     * @see URLToken#ifURL()
730     */
731    public URLToken ifURL() { return null; }
732
733    /**
734     * <EMBED CLASS=defs DATA-TOK=Whitespace>
735     * <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_DESCRIPTION>
736     * @return <EMBED CLASS='external-html' DATA-FILE-ID=CSST_IF_RETURNS>
737     * @see Whitespace#ifWhitespace()
738     */
739    public Whitespace ifWhitespace() { return null; }
740
741}