import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.KeywordContext;
import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.UnquotedStringContext;
-import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.Concatenation;
-import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.DoubleQuoted;
-import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.Identifier;
import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.Single;
-import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.SingleQuoted;
-import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.Unquoted;
import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword.Qualified;
import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword.Unqualified;
public final class AntlrSupport {
private static final CharMatcher WHITESPACE_MATCHER = CharMatcher.whitespace();
- private final Map<String, DoubleQuoted> dquotArguments = new HashMap<>();
- private final Map<String, SingleQuoted> squotArguments = new HashMap<>();
- private final Map<String, Unquoted> uquotArguments = new HashMap<>();
- private final Map<String, Identifier> idenArguments = new HashMap<>();
+ private final Map<String, Single> dquotArguments = new HashMap<>();
+ private final Map<String, Single> squotArguments = new HashMap<>();
+ private final Map<String, Single> uquotArguments = new HashMap<>();
+ private final Map<String, Single> idenArguments = new HashMap<>();
private final Map<String, Unqualified> uqualKeywords = new HashMap<>();
private final Map<Entry<String, String>, Qualified> qualKeywords = new HashMap<>();
private final Map<String, String> strings = new HashMap<>();
final Token keywordToken = ((TerminalNode) keywordStart).getSymbol();
final IRKeyword keyword = switch (firstChild.getChildCount()) {
- case 1 -> uqualKeywords.computeIfAbsent(strOf(keywordToken), Unqualified::new);
+ case 1 -> uqualKeywords.computeIfAbsent(strOf(keywordToken), Unqualified::of);
case 3 -> qualKeywords.computeIfAbsent(Map.entry(strOf(keywordToken), strOf(firstChild.getChild(2))),
- entry -> new Qualified(entry.getKey(), entry.getValue()));
+ entry -> Qualified.of(entry.getKey(), entry.getValue()));
default -> throw new VerifyException("Unexpected keyword " + firstChild);
};
final IRArgument argument = createArgument(stmt);
final int line = keywordToken.getLine();
final int column = keywordToken.getCharPositionInLine();
- return switch (statements.size()) {
- case 0 -> statementOf(keyword, argument, line, column);
- case 1 -> new IRStatement144(keyword, argument, statements.get(0), line, column);
- default -> new IRStatementL44(keyword, argument, statements, line, column);
- };
- }
-
- private static @NonNull IRStatement statementOf(final IRKeyword keyword, final IRArgument argument,
- final int line, final int column) {
- if (line >= 0 && column >= 0) {
- if (line <= 65535 && column <= 65535) {
- return new IRStatement022(keyword, argument, line, column);
- }
- if (line <= 16777215 && column <= 255) {
- return new IRStatement031(keyword, argument, line, column);
- }
- }
- return new IRStatement044(keyword, argument, line, column);
+ return IRStatement.of(keyword, argument, line, column, statements);
}
private IRArgument createArgument(final StatementContext stmt) {
}
}
- return switch (parts.size()) {
- // A concatenation of empty strings, fall back to a single unquoted string
- case 0 -> SingleQuoted.EMPTY;
- // A single string concatenated with empty string(s), use just the significant portion
- case 1 -> parts.get(0);
- // TODO: perform concatenation of single-quoted strings. For double-quoted strings this may not be as nice,
- // but for single-quoted strings we do not need further validation in in the reactor and can use them
- // as raw literals. This saves some indirection overhead (on memory side) and can slightly improve
- // execution speed when we process the same IR multiple times.
- default -> new Concatenation(parts);
- };
+ return IRArgument.of(parts);
}
private Single createQuoted(final ArgumentContext argument) {
};
}
- private DoubleQuoted createDoubleQuoted(final Token token) {
+ private Single createDoubleQuoted(final Token token) {
// Whitespace normalization happens irrespective of further handling and has no effect on the result
final String str = intern(trimWhitespace(token.getText(), token.getCharPositionInLine() - 1));
// This may look unimportant, but there are scenarios where we process the same AST multiple times
// and remembering this detail saves a string scan.
- return dquotArguments.computeIfAbsent(str, DoubleQuoted::new);
+ return dquotArguments.computeIfAbsent(str, IRArgument::doubleQuoted);
}
- private IRArgument createSimple(final ArgumentContext argument) {
+ private Single createSimple(final ArgumentContext argument) {
final ParseTree child = argument.getChild(0);
if (child instanceof TerminalNode terminal) {
final Token token = terminal.getSymbol();
return switch (token.getType()) {
// This is as simple as it gets: we are dealing with an identifier here.
- case YangStatementParser.IDENTIFIER -> idenArguments.computeIfAbsent(strOf(token), Identifier::new);
+ case YangStatementParser.IDENTIFIER -> idenArguments.computeIfAbsent(strOf(token),
+ IRArgument::identifier);
// This is an empty string, the difference between double and single quotes does not exist. Single
// quotes have more stringent semantics, hence use those.
- case YangStatementParser.DQUOT_END, YangStatementParser.SQUOT_END -> SingleQuoted.EMPTY;
+ case YangStatementParser.DQUOT_END, YangStatementParser.SQUOT_END -> IRArgument.empty();
default -> throw new VerifyException("Unexpected token " + token);
};
}
verify(child instanceof UnquotedStringContext, "Unexpected shape of %s", argument);
// TODO: check non-presence of quotes and create a different subclass, so that ends up treated as if it
// was single-quoted, i.e. bypass the check implied by IRArgument.Single#needQuoteCheck().
- return uquotArguments.computeIfAbsent(strOf(child), Unquoted::new);
+ return uquotArguments.computeIfAbsent(strOf(child), IRArgument::unquoted);
}
- private SingleQuoted createSingleQuoted(final Token token) {
- return squotArguments.computeIfAbsent(strOf(token), SingleQuoted::new);
+ private Single createSingleQuoted(final Token token) {
+ return squotArguments.computeIfAbsent(strOf(token), IRArgument::singleQuoted);
}
private ImmutableList<IRStatement> createStatements(final StatementContext stmt) {
public static final class Concatenation extends IRArgument {
private final @NonNull ImmutableList<Single> parts;
- Concatenation(final List<Single> parts) {
+ private Concatenation(final List<Single> parts) {
this.parts = ImmutableList.copyOf(parts);
}
public abstract static sealed class Single extends IRArgument {
private final @NonNull String string;
- Single(final String string) {
+ private Single(final String string) {
this.string = requireNonNull(string);
}
}
}
- static final class DoubleQuoted extends Single {
- DoubleQuoted(final String string) {
+ private static final class DoubleQuoted extends Single {
+ private DoubleQuoted(final String string) {
super(string);
}
}
}
- static final class SingleQuoted extends Single {
+ private static final class SingleQuoted extends Single {
static final @NonNull SingleQuoted EMPTY = new SingleQuoted("");
- SingleQuoted(final String string) {
+ private SingleQuoted(final String string) {
super(string);
}
}
}
- static final class Identifier extends Single {
- Identifier(final String string) {
+ private static final class Identifier extends Single {
+ private Identifier(final String string) {
super(string);
}
}
- static final class Unquoted extends Single {
- Unquoted(final String string) {
+ private static final class Unquoted extends Single {
+ private Unquoted(final String string) {
super(string);
}
}
- IRArgument() {
+ private IRArgument() {
// Hidden on purpose
}
+
+ public static @NonNull Single empty() {
+ return SingleQuoted.EMPTY;
+ }
+
+ public static @NonNull Single identifier(final String string) {
+ return new Identifier(string);
+ }
+
+ public static @NonNull Single singleQuoted(final String string) {
+ return new SingleQuoted(string);
+ }
+
+ public static @NonNull Single doubleQuoted(final String string) {
+ return new DoubleQuoted(string);
+ }
+
+ public static @NonNull Single unquoted(final String string) {
+ return new Unquoted(string);
+ }
+
+ public static @NonNull IRArgument of(final List<Single> parts) {
+ return switch (parts.size()) {
+ // A concatenation of empty strings, fall back to a single unquoted string
+ case 0 -> empty();
+ // A single string concatenated with empty string(s), use just the significant portion
+ case 1 -> parts.get(0);
+ // TODO: perform concatenation of single-quoted strings. For double-quoted strings this may not be as nice,
+ // but for single-quoted strings we do not need further validation in in the reactor and can use them
+ // as raw literals. This saves some indirection overhead (on memory side) and can slightly improve
+ // execution speed when we process the same IR multiple times.
+ default -> new Concatenation(parts);
+ };
+ }
}
import static java.util.Objects.requireNonNull;
-import com.google.common.annotations.Beta;
import java.util.Objects;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
* Naming in this class prefers the formal ABNF specification and draws value-space and type-safety implications from
* that connection, rather than following the RFC-assigned names.
*/
-@Beta
public abstract sealed class IRKeyword extends AbstractIRObject {
- @Beta
public static final class Qualified extends IRKeyword {
private final @NonNull String prefix;
- Qualified(final String prefix, final String localName) {
+ private Qualified(final String prefix, final String localName) {
super(localName);
this.prefix = requireNonNull(prefix);
}
+ public static @NonNull Qualified of(final String prefix, final String localName) {
+ return new Qualified(prefix, localName);
+ }
+
@Override
public @NonNull String prefix() {
return prefix;
}
}
- @Beta
public static final class Unqualified extends IRKeyword {
- Unqualified(final String localName) {
+ private Unqualified(final String localName) {
super(localName);
}
+ public static @NonNull Unqualified of(final String localName) {
+ return new Unqualified(localName);
+ }
+
@Override
public String prefix() {
return null;
import static java.util.Objects.requireNonNull;
-import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Objects;
* <li>zero or more nested statements</li>
* </ul>
*/
-@Beta
-public abstract sealed class IRStatement extends AbstractIRObject
- permits IRStatement022, IRStatement031, IRStatement044 {
+public abstract sealed class IRStatement extends AbstractIRObject {
+ private static final class Z22 extends IRStatement {
+ private final short startLine;
+ private final short startColumn;
+
+ Z22(final IRKeyword keyword, final IRArgument argument, final int startLine, final int startColumn) {
+ super(keyword, argument);
+ this.startLine = (short) startLine;
+ this.startColumn = (short) startColumn;
+ }
+
+ @Override
+ public int startLine() {
+ return Short.toUnsignedInt(startLine);
+ }
+
+ @Override
+ public int startColumn() {
+ return Short.toUnsignedInt(startColumn);
+ }
+ }
+
+ private static final class Z31 extends IRStatement {
+ private final int value;
+
+ Z31(final IRKeyword keyword, final IRArgument argument, final int startLine, final int startColumn) {
+ super(keyword, argument);
+ value = startLine << 8 | startColumn & 0xFF;
+ }
+
+ @Override
+ public int startLine() {
+ return value >>> 8;
+ }
+
+ @Override
+ public int startColumn() {
+ return value & 0xFF;
+ }
+ }
+
+ private static sealed class Z44 extends IRStatement permits O44, L44 {
+ private final int startLine;
+ private final int startColumn;
+
+ Z44(final IRKeyword keyword, final IRArgument argument, final int startLine, final int startColumn) {
+ super(keyword, argument);
+ this.startLine = startLine;
+ this.startColumn = startColumn;
+ }
+
+ @Override
+ public final int startLine() {
+ return startLine;
+ }
+
+ @Override
+ public final int startColumn() {
+ return startColumn;
+ }
+ }
+
+ private static final class O44 extends Z44 {
+ private final @NonNull IRStatement statement;
+
+ O44(final IRKeyword keyword, final IRArgument argument, final IRStatement statement, final int startLine,
+ final int startColumn) {
+ super(keyword, argument, startLine, startColumn);
+ this.statement = requireNonNull(statement);
+ }
+
+ @Override
+ public ImmutableList<IRStatement> statements() {
+ return ImmutableList.of(statement);
+ }
+ }
+
+ private static final class L44 extends Z44 {
+ private final @NonNull ImmutableList<IRStatement> statements;
+
+ L44(final IRKeyword keyword, final IRArgument argument, final ImmutableList<IRStatement> statements,
+ final int startLine, final int startColumn) {
+ super(keyword, argument, startLine, startColumn);
+ this.statements = requireNonNull(statements);
+ }
+
+ @Override
+ public ImmutableList<IRStatement> statements() {
+ return statements;
+ }
+ }
+
private final @NonNull IRKeyword keyword;
private final IRArgument argument;
this.argument = argument;
}
+ public static @NonNull IRStatement of(final IRKeyword keyword, final IRArgument argument, final int line,
+ final int column, final ImmutableList<IRStatement> statements) {
+ return switch (statements.size()) {
+ case 0 -> {
+ if (line >= 0 && column >= 0) {
+ if (line <= 65535 && column <= 65535) {
+ yield new Z22(keyword, argument, line, column);
+ }
+ if (line <= 16777215 && column <= 255) {
+ yield new Z31(keyword, argument, line, column);
+ }
+ }
+ yield new Z44(keyword, argument, line, column);
+ }
+ case 1 -> new O44(keyword, argument, statements.get(0), line, column);
+ default -> new L44(keyword, argument, statements, line, column);
+ };
+ }
+
/**
* Return this statement's keyword.
*
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.ir;
-
-final class IRStatement022 extends IRStatement {
- private final short startLine;
- private final short startColumn;
-
- IRStatement022(final IRKeyword keyword, final IRArgument argument, final int startLine, final int startColumn) {
- super(keyword, argument);
- this.startLine = (short) startLine;
- this.startColumn = (short) startColumn;
- }
-
- @Override
- public int startLine() {
- return Short.toUnsignedInt(startLine);
- }
-
- @Override
- public int startColumn() {
- return Short.toUnsignedInt(startColumn);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.ir;
-
-final class IRStatement031 extends IRStatement {
- private final int value;
-
- IRStatement031(final IRKeyword keyword, final IRArgument argument, final int startLine, final int startColumn) {
- super(keyword, argument);
- this.value = startLine << 8 | startColumn & 0xFF;
- }
-
- @Override
- public int startLine() {
- return value >>> 8;
- }
-
- @Override
- public int startColumn() {
- return value & 0xFF;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.ir;
-
-sealed class IRStatement044 extends IRStatement permits IRStatement144, IRStatementL44 {
- private final int startLine;
- private final int startColumn;
-
- IRStatement044(final IRKeyword keyword, final IRArgument argument, final int startLine, final int startColumn) {
- super(keyword, argument);
- this.startLine = startLine;
- this.startColumn = startColumn;
- }
-
- @Override
- public final int startLine() {
- return startLine;
- }
-
- @Override
- public final int startColumn() {
- return startColumn;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.ir;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNull;
-
-final class IRStatement144 extends IRStatement044 {
- private final @NonNull IRStatement statement;
-
- IRStatement144(final IRKeyword keyword, final IRArgument argument, final IRStatement statement,
- final int startLine, final int startColumn) {
- super(keyword, argument, startLine, startColumn);
- this.statement = requireNonNull(statement);
- }
-
- @Override
- public ImmutableList<IRStatement> statements() {
- return ImmutableList.of(statement);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.ir;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNull;
-
-final class IRStatementL44 extends IRStatement044 {
- private final @NonNull ImmutableList<IRStatement> statements;
-
- IRStatementL44(final IRKeyword keyword, final IRArgument argument, final ImmutableList<IRStatement> statements,
- final int startLine, final int startColumn) {
- super(keyword, argument, startLine, startColumn);
- this.statements = requireNonNull(statements);
- }
-
- @Override
- public ImmutableList<IRStatement> statements() {
- return statements;
- }
-}