Populate xpath/ hierarchy
[yangtools.git] / parser / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / antlr / CompactTokenFactory.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.parser.rfc7950.antlr;
9
10 import org.antlr.v4.runtime.CharStream;
11 import org.antlr.v4.runtime.CommonTokenFactory;
12 import org.antlr.v4.runtime.Token;
13 import org.antlr.v4.runtime.TokenFactory;
14 import org.antlr.v4.runtime.TokenSource;
15 import org.antlr.v4.runtime.misc.Pair;
16 import org.eclipse.jdt.annotation.NonNull;
17
18 /**
19  * A token factory which is more memory-efficient than {@link CommonTokenFactory}. We try to mimic behavior of common
20  * tokens, but do so at lower memory overheads, potentially sacrificing some performance.
21  */
22 final class CompactTokenFactory implements TokenFactory<Token> {
23     static final @NonNull CompactTokenFactory INSTANCE = new CompactTokenFactory();
24
25     private CompactTokenFactory() {
26         // Hidden on purpose
27     }
28
29     @Override
30     public Token create(final Pair<TokenSource, CharStream> source, final int type, final String text,
31             final int channel, final int start, final int stop, final int line, final int charPositionInLine) {
32         if (channel != Token.DEFAULT_CHANNEL || text != null) {
33             // Non-default channel or text present, defer to common token factory
34             return CommonTokenFactory.DEFAULT.create(source, type, text, channel, start, stop, line,
35                 charPositionInLine);
36         }
37
38         // Can we fit token type into a single byte? This should always be true
39         if (type >= Byte.MIN_VALUE && type <= Byte.MAX_VALUE) {
40             // Can we fit line in an unsigned short? This is usually be true
41             if (line >= 0 && line <= 65535) {
42                 // Can we fit position in line into an unsigned byte? This is usually true
43                 if (charPositionInLine >= 0 && charPositionInLine <= 255) {
44                     // Can we fit start/stop into an an unsigned short?
45                     if (start >= 0 && start <= 65535 && stop >= 0 && stop <= 65535) {
46                         return new Token12122(source, type, line, charPositionInLine, start, stop);
47                     }
48                     return new Token12144(source, type, line, charPositionInLine, start, stop);
49                 }
50             }
51         }
52
53         return new Token44444(source, type, line, charPositionInLine, start, stop);
54     }
55
56     @Override
57     public Token create(final int type, final String text) {
58         return new ExplicitTextToken(type, text);
59     }
60 }