*
* 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/eplv10.html
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
*/
+
package org.opendaylight.yangtools.yang.parser.impl;
import static com.google.common.base.Preconditions.checkState;
-
+import com.google.common.base.CharMatcher;
import com.google.common.base.Optional;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import java.math.BigDecimal;
-import java.net.URI;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Date;
+import java.util.Iterator;
import java.util.List;
-import java.util.Stack;
+import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.opendaylight.yangtools.yang.model.util.Decimal64;
import org.opendaylight.yangtools.yang.model.util.EnumerationType;
import org.opendaylight.yangtools.yang.model.util.ExtendedType;
-import org.opendaylight.yangtools.yang.model.util.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
import org.opendaylight.yangtools.yang.model.util.Int16;
import org.opendaylight.yangtools.yang.model.util.Int32;
import org.opendaylight.yangtools.yang.model.util.Int64;
import org.opendaylight.yangtools.yang.model.util.Uint32;
import org.opendaylight.yangtools.yang.model.util.Uint64;
import org.opendaylight.yangtools.yang.model.util.Uint8;
-import org.opendaylight.yangtools.yang.model.util.UnknownType;
import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
import org.opendaylight.yangtools.yang.parser.builder.api.ConstraintsBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.RefineBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.RefineHolderImpl;
+import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
import org.opendaylight.yangtools.yang.parser.util.TypeConstraints;
import org.opendaylight.yangtools.yang.parser.util.UnknownBoundaryNumber;
import org.slf4j.LoggerFactory;
public final class ParserListenerUtils {
+ private static final int UNICODE_SCRIPT_FIX_COUNTER = 30;
private static final Logger LOG = LoggerFactory.getLogger(ParserListenerUtils.class);
+ private static final Splitter KEYDEF_SPLITTER = Splitter.on(' ').omitEmptyStrings();
+ private static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults();
+ private static final Splitter DOT_DOT_SPLITTER = Splitter.on("..").trimResults();
+ private static final CharMatcher DOUBLE_QUOTE_MATCHER = CharMatcher.is('"');
+ private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher.is('\'');
+ private static final Pattern BETWEEN_CURLY_BRACES_PATTERN = Pattern.compile("\\{(.+?)\\}");
+ private static final Set<String> JAVA_UNICODE_BLOCKS = ImmutableSet.<String>builder()
+ .add("AegeanNumbers")
+ .add("AlchemicalSymbols")
+ .add("AlphabeticPresentationForms")
+ .add("AncientGreekMusicalNotation")
+ .add("AncientGreekNumbers")
+ .add("AncientSymbols")
+ .add("Arabic")
+ .add("ArabicPresentationForms-A")
+ .add("ArabicPresentationForms-B")
+ .add("ArabicSupplement")
+ .add("Armenian")
+ .add("Arrows")
+ .add("Avestan")
+ .add("Balinese")
+ .add("Bamum")
+ .add("BamumSupplement")
+ .add("BasicLatin")
+ .add("Batak")
+ .add("Bengali")
+ .add("BlockElements")
+ .add("Bopomofo")
+ .add("BopomofoExtended")
+ .add("BoxDrawing")
+ .add("Brahmi")
+ .add("BraillePatterns")
+ .add("Buginese")
+ .add("Buhid")
+ .add("ByzantineMusicalSymbols")
+ .add("Carian")
+ .add("Cham")
+ .add("Cherokee")
+ .add("CJKCompatibility")
+ .add("CJKCompatibilityForms")
+ .add("CJKCompatibilityIdeographs")
+ .add("CJKCompatibilityIdeographsSupplement")
+ .add("CJKRadicalsSupplement")
+ .add("CJKStrokes")
+ .add("CJKSymbolsandPunctuation")
+ .add("CJKUnifiedIdeographs")
+ .add("CJKUnifiedIdeographsExtensionA")
+ .add("CJKUnifiedIdeographsExtensionB")
+ .add("CJKUnifiedIdeographsExtensionC")
+ .add("CJKUnifiedIdeographsExtensionD")
+ .add("CombiningDiacriticalMarks")
+ .add("CombiningDiacriticalMarksSupplement")
+ .add("CombiningHalfMarks")
+ .add("CombiningDiacriticalMarksforSymbols")
+ .add("CommonIndicNumberForms")
+ .add("ControlPictures")
+ .add("Coptic")
+ .add("CountingRodNumerals")
+ .add("Cuneiform")
+ .add("CuneiformNumbersandPunctuation")
+ .add("CurrencySymbols")
+ .add("CypriotSyllabary")
+ .add("Cyrillic")
+ .add("CyrillicExtended-A")
+ .add("CyrillicExtended-B")
+ .add("CyrillicSupplementary")
+ .add("Deseret")
+ .add("Devanagari")
+ .add("DevanagariExtended")
+ .add("Dingbats")
+ .add("DominoTiles")
+ .add("EgyptianHieroglyphs")
+ .add("Emoticons")
+ .add("EnclosedAlphanumericSupplement")
+ .add("EnclosedAlphanumerics")
+ .add("EnclosedCJKLettersandMonths")
+ .add("EnclosedIdeographicSupplement")
+ .add("Ethiopic")
+ .add("EthiopicExtended")
+ .add("EthiopicExtended-A")
+ .add("EthiopicSupplement")
+ .add("GeneralPunctuation")
+ .add("GeometricShapes")
+ .add("Georgian")
+ .add("GeorgianSupplement")
+ .add("Glagolitic")
+ .add("Gothic")
+ .add("GreekandCoptic")
+ .add("GreekExtended")
+ .add("Gujarati")
+ .add("Gurmukhi")
+ .add("HalfwidthandFullwidthForms")
+ .add("HangulCompatibilityJamo")
+ .add("HangulJamo")
+ .add("HangulJamoExtended-A")
+ .add("HangulJamoExtended-B")
+ .add("HangulSyllables")
+ .add("Hanunoo")
+ .add("Hebrew")
+ .add("HighPrivateUseSurrogates")
+ .add("HighSurrogates")
+ .add("Hiragana")
+ .add("IdeographicDescriptionCharacters")
+ .add("ImperialAramaic")
+ .add("InscriptionalPahlavi")
+ .add("InscriptionalParthian")
+ .add("IPAExtensions")
+ .add("Javanese")
+ .add("Kaithi")
+ .add("KanaSupplement")
+ .add("Kanbun")
+ .add("Kangxi Radicals")
+ .add("Kannada")
+ .add("Katakana")
+ .add("KatakanaPhoneticExtensions")
+ .add("KayahLi")
+ .add("Kharoshthi")
+ .add("Khmer")
+ .add("KhmerSymbols")
+ .add("Lao")
+ .add("Latin-1Supplement")
+ .add("LatinExtended-A")
+ .add("LatinExtendedAdditional")
+ .add("LatinExtended-B")
+ .add("LatinExtended-C")
+ .add("LatinExtended-D")
+ .add("Lepcha")
+ .add("LetterlikeSymbols")
+ .add("Limbu")
+ .add("LinearBIdeograms")
+ .add("LinearBSyllabary")
+ .add("Lisu")
+ .add("LowSurrogates")
+ .add("Lycian")
+ .add("Lydian")
+ .add("MahjongTiles")
+ .add("Malayalam")
+ .add("Mandaic")
+ .add("MathematicalAlphanumericSymbols")
+ .add("MathematicalOperators")
+ .add("MeeteiMayek")
+ .add("MiscellaneousMathematicalSymbols-A")
+ .add("MiscellaneousMathematicalSymbols-B")
+ .add("MiscellaneousSymbols")
+ .add("MiscellaneousSymbolsandArrows")
+ .add("MiscellaneousSymbolsAndPictographs")
+ .add("MiscellaneousTechnical")
+ .add("ModifierToneLetters")
+ .add("Mongolian")
+ .add("MusicalSymbols")
+ .add("Myanmar")
+ .add("MyanmarExtended-A")
+ .add("NewTaiLue")
+ .add("NKo")
+ .add("NumberForms")
+ .add("Ogham")
+ .add("OlChiki")
+ .add("OldItalic")
+ .add("OldPersian")
+ .add("OldSouthArabian")
+ .add("OldTurkic")
+ .add("OpticalCharacterRecognition")
+ .add("Oriya")
+ .add("Osmanya")
+ .add("Phags-pa")
+ .add("PhaistosDisc")
+ .add("Phoenician")
+ .add("PhoneticExtensions")
+ .add("PhoneticExtensionsSupplement")
+ .add("PlayingCards")
+ .add("PrivateUseArea")
+ .add("Rejang")
+ .add("RumiNumeralSymbols")
+ .add("Runic")
+ .add("Samaritan")
+ .add("Saurashtra")
+ .add("Shavian")
+ .add("Sinhala")
+ .add("SmallFormVariants")
+ .add("SpacingModifierLetters")
+ .add("Specials")
+ .add("Sundanese")
+ .add("SuperscriptsandSubscripts")
+ .add("SupplementalArrows-A")
+ .add("SupplementalArrows-B")
+ .add("SupplementalMathematicalOperators")
+ .add("SupplementalPunctuation")
+ .add("SupplementaryPrivateUseArea-A")
+ .add("SupplementaryPrivateUseArea-B")
+ .add("SylotiNagri")
+ .add("Syriac")
+ .add("Tagalog")
+ .add("Tagbanwa")
+ .add("Tags")
+ .add("TaiLe")
+ .add("TaiTham")
+ .add("TaiViet")
+ .add("TaiXuanJingSymbols")
+ .add("Tamil")
+ .add("Telugu")
+ .add("Thaana")
+ .add("Thai")
+ .add("Tibetan")
+ .add("Tifinagh")
+ .add("TransportAndMapSymbols")
+ .add("Ugaritic")
+ .add("UnifiedCanadianAboriginalSyllabics")
+ .add("UnifiedCanadianAboriginalSyllabicsExtended")
+ .add("Vai")
+ .add("VariationSelectors")
+ .add("VariationSelectorsSupplement")
+ .add("VedicExtensions")
+ .add("VerticalForms")
+ .add("YiRadicals")
+ .add("YiSyllables")
+ .add("YijingHexagramSymbols").build();
private ParserListenerUtils() {
}
public static String stringFromNode(final ParseTree treeNode) {
String result = "";
for (int i = 0; i < treeNode.getChildCount(); ++i) {
- if (treeNode.getChild(i) instanceof StringContext) {
- final StringContext context = (StringContext) treeNode.getChild(i);
- if (context != null) {
- return stringFromStringContext(context);
-
- }
+ final ParseTree child = treeNode.getChild(i);
+ if (child instanceof StringContext) {
+ return stringFromStringContext((StringContext)child);
}
}
return result;
}
private static String stringFromStringContext(final StringContext context) {
- StringBuilder str = new StringBuilder();
+ StringBuilder sb = new StringBuilder();
for (TerminalNode stringNode : context.STRING()) {
- String result = stringNode.getText();
- if(!result.contains("\"")){
- str.append(result);
- } else if (!(result.startsWith("\"")) && result.endsWith("\"")) {
- LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(context),
- context.getStart().getLine());
+ final String str = stringNode.getText();
+ char firstChar = str.charAt(0);
+ final CharMatcher quoteMatcher;
+ if(SINGLE_QUOTE_MATCHER.matches(firstChar)) {
+ quoteMatcher = SINGLE_QUOTE_MATCHER;
+ } else if (DOUBLE_QUOTE_MATCHER.matches(firstChar)) {
+ quoteMatcher = DOUBLE_QUOTE_MATCHER;
} else {
- str.append(result.replace("\"", ""));
+ sb.append(str);
+ continue;
}
- }
- return str.toString();
+ /*
+ *
+ * It is safe not to check last argument to be same
+ * grammars enforces that.
+ *
+ * FIXME: Introduce proper escaping and translation of escaped
+ * characters here.
+ *
+ */
+ sb.append(quoteMatcher.removeFrom(str.substring(1, str.length()-1)));
+ }
+ return sb.toString();
}
private static String getParentModule(final ParseTree ctx) {
* context to parse
* @param builder
* builder to fill in with parsed statements
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
*/
+ @Deprecated
public static void parseSchemaNodeArgs(final ParseTree ctx, final SchemaNodeBuilder builder) {
for (int i = 0; i < ctx.getChildCount(); i++) {
final ParseTree child = ctx.getChild(i);
* statement
*/
public static String parseUnits(final ParseTree ctx) {
- String units = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Units_stmtContext) {
- units = stringFromNode(child);
- break;
+ return stringFromNode(child);
}
}
- return units;
+ return null;
}
/**
* default statement
*/
public static String parseDefault(final ParseTree ctx) {
- String defaultValue = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Default_stmtContext) {
- defaultValue = stringFromNode(child);
- break;
+ return stringFromNode(child);
}
}
- return defaultValue;
- }
-
- /**
- * Create SchemaPath from actualPath and new node name.
- *
- * @param actualPath
- * current position in model
- * @return SchemaPath object
- */
- public static SchemaPath createActualSchemaPath(final Stack<QName> actualPath) {
- return SchemaPath.create(actualPath, true);
+ return null;
}
/**
- * Create java.util.List of key node names.
+ * Create java.util.LinkedHashSet of key node names.
*
* @param ctx
* Key_stmtContext context
- * @return YANG list key as java.util.List of key node names
+ * @return YANG list key as java.util.LinkedHashSet of key node names
*/
- public static List<String> createListKey(final Key_stmtContext ctx) {
- String keyDefinition = stringFromNode(ctx);
- List<String> keys = new ArrayList<>();
- String[] splittedKey = keyDefinition.split(" ");
- for (String keyElement : splittedKey) {
- if (!keyElement.isEmpty()) {
- keys.add(keyElement);
- }
- }
- return keys;
+ public static Set<String> createListKey(final Key_stmtContext ctx) {
+ final String keyDefinition = stringFromNode(ctx);
+ return Sets.<String>newLinkedHashSet(KEYDEF_SPLITTER.split(keyDefinition));
}
/**
* @return List of EnumPair object parsed from given context
*/
private static List<EnumTypeDefinition.EnumPair> getEnumConstants(final Type_body_stmtsContext ctx,
- final Stack<QName> path, final String moduleName) {
+ final SchemaPath path, final String moduleName) {
List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<>();
for (int i = 0; i < ctx.getChildCount(); i++) {
* @return EnumPair object parsed from given context
*/
private static EnumTypeDefinition.EnumPair createEnumPair(final Enum_stmtContext ctx, final int highestValue,
- final Stack<QName> actualPath, final String moduleName) {
+ final SchemaPath actualPath, final String moduleName) {
final String name = stringFromNode(ctx);
SchemaPath path = createTypePath(actualPath, name);
Integer value = null;
ParseTree child = ctx.getChild(i);
if (child instanceof Value_stmtContext) {
String valueStr = stringFromNode(child);
- value = Integer.valueOf(valueStr);
+ try {
+ // yang enum value has same restrictions as JAVA Integer
+ value = Integer.valueOf(valueStr);
+ } catch (NumberFormatException e) {
+ String err = String
+ .format("Error on enum '%s': the enum value MUST be in the range from -2147483648 to 2147483647, but was: %s",
+ name, valueStr);
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), err, e);
+ }
} else if (child instanceof Description_stmtContext) {
description = stringFromNode(child);
} else if (child instanceof Reference_stmtContext) {
if (value == null) {
value = highestValue + 1;
}
- if (value < -2147483648 || value > 2147483647) {
- throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on enum '" + name
- + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " + value);
- }
EnumPairImpl result = new EnumPairImpl();
result.qname = path.getPathTowardsRoot().iterator().next();
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((qname == null) ? 0 : qname.hashCode());
- result = prime * result + ((path == null) ? 0 : path.hashCode());
- result = prime * result + ((unknownNodes == null) ? 0 : unknownNodes.hashCode());
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + ((value == null) ? 0 : value.hashCode());
+ result = prime * result + Objects.hashCode(qname);
+ result = prime * result + Objects.hashCode(path);
+ result = prime * result + Objects.hashCode(unknownNodes);
+ result = prime * result + Objects.hashCode(name);
+ result = prime * result + Objects.hashCode(value);
return result;
}
* @return List of RangeConstraint created from this context
*/
private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
- List<RangeConstraint> rangeConstraints = Collections.emptyList();
- outer: for (int i = 0; i < ctx.getChildCount(); i++) {
+ for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree numRestrChild = ctx.getChild(i);
if (numRestrChild instanceof Numerical_restrictionsContext) {
for (int j = 0; j < numRestrChild.getChildCount(); j++) {
ParseTree rangeChild = numRestrChild.getChild(j);
if (rangeChild instanceof Range_stmtContext) {
- rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
- break outer;
+ return parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
}
}
}
for (int k = 0; k < decRestr.getChildCount(); k++) {
ParseTree rangeChild = decRestr.getChild(k);
if (rangeChild instanceof Range_stmtContext) {
- rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
- break outer;
+ return parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
}
}
-
}
}
}
}
- return rangeConstraints;
+ return Collections.emptyList();
}
/**
*/
private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx, final String moduleName) {
final int line = ctx.getStart().getLine();
- List<RangeConstraint> rangeConstraints = new ArrayList<>();
- String description = null;
- String reference = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.fromNullable(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.fromNullable(stringFromNode(child));
}
}
- String rangeStr = stringFromNode(ctx);
- String trimmed = rangeStr.replace(" ", "");
- String[] splittedRange = trimmed.split("\\|");
- for (String rangeDef : splittedRange) {
- String[] splittedRangeDef = rangeDef.split("\\.\\.");
- Number min;
- Number max;
- if (splittedRangeDef.length == 1) {
- min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+ List<RangeConstraint> rangeConstraints = new ArrayList<>();
+ for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) {
+ final Iterator<String> split = DOT_DOT_SPLITTER.split(def).iterator();
+ final Number min = parseNumberConstraintValue(split.next(), moduleName, line);
+
+ final Number max;
+ if (split.hasNext()) {
+ max = parseNumberConstraintValue(split.next(), moduleName, line);
+ if (split.hasNext()) {
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Malformed length constraint \"" + def + "\".");
+ }
} else {
- min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
- max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
+ max = min;
}
- RangeConstraint range = BaseConstraints.rangeConstraint(min, max, description, reference);
+
+ RangeConstraint range = BaseConstraints.newRangeConstraint(min, max, description, reference);
rangeConstraints.add(range);
}
* @return List of LengthConstraint created from this context
*/
private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
- List<LengthConstraint> lengthConstraints = Collections.emptyList();
- outer: for (int i = 0; i < ctx.getChildCount(); i++) {
+ for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree stringRestrChild = ctx.getChild(i);
if (stringRestrChild instanceof String_restrictionsContext) {
for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
ParseTree lengthChild = stringRestrChild.getChild(j);
if (lengthChild instanceof Length_stmtContext) {
- lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
- break outer;
+ return parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
}
}
}
}
- return lengthConstraints;
+ return Collections.emptyList();
}
/**
*/
private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx, final String moduleName) {
final int line = ctx.getStart().getLine();
- List<LengthConstraint> lengthConstraints = new ArrayList<>();
- String description = null;
- String reference = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.fromNullable(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.fromNullable(stringFromNode(child));
}
}
- String lengthStr = stringFromNode(ctx);
- String trimmed = lengthStr.replace(" ", "");
- String[] splittedRange = trimmed.split("\\|");
- for (String rangeDef : splittedRange) {
- String[] splittedRangeDef = rangeDef.split("\\.\\.");
- Number min;
- Number max;
- if (splittedRangeDef.length == 1) {
- min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+ List<LengthConstraint> lengthConstraints = new ArrayList<>();
+ for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) {
+ final Iterator<String> split = DOT_DOT_SPLITTER.split(def).iterator();
+ final Number min = parseNumberConstraintValue(split.next(), moduleName, line);
+
+ final Number max;
+ if (split.hasNext()) {
+ max = parseNumberConstraintValue(split.next(), moduleName, line);
+ if (split.hasNext()) {
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Malformed length constraint \"" + def + "\".");
+ }
} else {
- min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
- max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
+ max = min;
}
- LengthConstraint range = BaseConstraints.lengthConstraint(min, max, description, reference);
+
+ LengthConstraint range = BaseConstraints.newLengthConstraint(min, max, description, reference);
lengthConstraints.add(range);
}
result = new UnknownBoundaryNumber(value);
} else {
try {
- if (value.contains(".")) {
+ if (value.indexOf('.') != -1) {
result = new BigDecimal(value);
} else {
- result = Long.valueOf(value);
+ result = new BigInteger(value);
}
} catch (NumberFormatException e) {
throw new YangParseException(moduleName, line, "Unable to parse range value '" + value + "'.", e);
* type body
* @return list of pattern constraints
*/
- private static List<PatternConstraint> getPatternConstraint(final Type_body_stmtsContext ctx) {
+ private static List<PatternConstraint> getPatternConstraint(final Type_body_stmtsContext ctx, final String moduleName) {
List<PatternConstraint> patterns = new ArrayList<>();
for (int i = 0; i < ctx.getChildCount(); i++) {
for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
ParseTree lengthChild = stringRestrChild.getChild(j);
if (lengthChild instanceof Pattern_stmtContext) {
- patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild));
+ final PatternConstraint constraint = parsePatternConstraint((Pattern_stmtContext) lengthChild,
+ moduleName);
+ if (constraint != null) {
+ patterns.add(constraint);
+ }
}
}
}
* pattern context
* @return PatternConstraint object
*/
- private static PatternConstraint parsePatternConstraint(final Pattern_stmtContext ctx) {
- String description = null;
- String reference = null;
+ private static PatternConstraint parsePatternConstraint(final Pattern_stmtContext ctx, final String moduleName) {
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.of(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.of(stringFromNode(child));
+ }
+ }
+ final String rawPattern = parsePatternString(ctx);
+ final String fixedRawPattern = fixUnicodeScriptPattern(rawPattern);
+ final String pattern = wrapPattern(fixedRawPattern);
+ if (isValidPattern(pattern, ctx, moduleName)) {
+ return BaseConstraints.newPatternConstraint(pattern, description, reference);
+ }
+ return null;
+ }
+
+ private static String fixUnicodeScriptPattern(String rawPattern) {
+ for (int i = 0; i < UNICODE_SCRIPT_FIX_COUNTER; i++) {
+ try {
+ Pattern.compile(rawPattern);
+ return rawPattern;
+ } catch(PatternSyntaxException ex) {
+ LOG.debug("Invalid regex pattern syntax in: {}", rawPattern, ex);
+ if (ex.getMessage().contains("Unknown character script name")) {
+ rawPattern = fixUnknownScripts(ex.getMessage(), rawPattern);
+ } else {
+ return rawPattern;
+ }
}
}
- String pattern = parsePatternString(ctx);
- return BaseConstraints.patternConstraint(pattern, description, reference);
+
+ LOG.warn("Regex pattern could not be fixed: {}", rawPattern);
+ return rawPattern;
+ }
+
+ private static String fixUnknownScripts(final String exMessage, final String rawPattern) {
+ StringBuilder result = new StringBuilder(rawPattern);
+ Matcher matcher = BETWEEN_CURLY_BRACES_PATTERN.matcher(exMessage);
+ if (matcher.find()) {
+ String capturedGroup = matcher.group(1);
+ if (JAVA_UNICODE_BLOCKS.contains(capturedGroup)) {
+ int idx = rawPattern.indexOf("Is" + capturedGroup);
+ result = result.replace(idx, idx + 2, "In");
+ }
+ }
+ return result.toString();
+ }
+
+ private static String wrapPattern(final String rawPattern) {
+ final StringBuilder wrapPatternBuilder = new StringBuilder(rawPattern.length() + 2);
+ wrapPatternBuilder.append('^');
+ wrapPatternBuilder.append(rawPattern);
+ wrapPatternBuilder.append('$');
+ return wrapPatternBuilder.toString();
+ }
+
+ private static boolean isValidPattern(final String pattern, final Pattern_stmtContext ctx, final String moduleName) {
+ try {
+ Pattern.compile(pattern);
+ return true;
+ } catch (PatternSyntaxException ex) {
+ LOG.warn("Unable to compile pattern defined in module {} at line {}. Error message: {}",
+ moduleName, ctx.getStart().getLine(), ex.getMessage());
+ }
+ return false;
}
/**
* current module name
* @return List of Bit objects created from this context
*/
- private static List<BitsTypeDefinition.Bit> getBits(final Type_body_stmtsContext ctx, final Stack<QName> actualPath,
+ private static List<BitsTypeDefinition.Bit> getBits(final Type_body_stmtsContext ctx, final SchemaPath actualPath,
final String moduleName) {
final List<BitsTypeDefinition.Bit> bits = new ArrayList<>();
for (int j = 0; j < ctx.getChildCount(); j++) {
* @return Bit object parsed from this context
*/
private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, final long highestPosition,
- final Stack<QName> actualPath, final String moduleName) {
+ final SchemaPath actualPath, final String moduleName) {
String name = stringFromNode(ctx);
Long position = null;
* @param line
* line in current module
* @return config statement parsed from given context
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
*/
+ @Deprecated
public static boolean getConfig(final ParseTree ctx, final Builder node, final String moduleName, final int line) {
boolean result;
// parse configuration statement
return result;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static boolean getParentConfig(final Builder node) {
Builder parent = node.getParent();
boolean config;
}
/**
- * Parse type body and create UnknownType definition.
+ * Parse unknown type with body.
*
- * @param typedefQName
- * qname of current type
- * @param ctx
+ * @param typeBody
* type body
- * @param actualPath
- * actual path in model
- * @param namespace
- * module namespace
- * @param revision
- * module revision
- * @param prefix
- * module prefix
* @param parent
* current node parent
- * @return UnknownType object with constraints from parsed type body
+ * @param prefixedQName
+ * type qname with prefix
+ * @param moduleBuilder
+ * current module builder
+ * @param moduleQName
+ * current module qname
+ * @param actualPath
+ * actual path in model
+ *
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
*/
- public static TypeDefinition<?> parseUnknownTypeWithBody(final QName typedefQName,
- final Type_body_stmtsContext ctx, final Stack<QName> actualPath, final URI namespace, final Date revision,
- final String prefix, final Builder parent) {
- String moduleName = parent.getModuleName();
- String typeName = typedefQName.getLocalName();
-
- UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName);
-
- if (ctx != null) {
- List<RangeConstraint> rangeStatements = getRangeConstraints(ctx, moduleName);
- List<LengthConstraint> lengthStatements = getLengthConstraints(ctx, moduleName);
- List<PatternConstraint> patternStatements = getPatternConstraint(ctx);
- Integer fractionDigits = getFractionDigits(ctx, moduleName);
-
- if (parent instanceof TypeDefinitionBuilder) {
- TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent;
- typedef.setRanges(rangeStatements);
- typedef.setLengths(lengthStatements);
- typedef.setPatterns(patternStatements);
- typedef.setFractionDigits(fractionDigits);
- return unknownType.build();
- } else {
- TypeDefinition<?> baseType = unknownType.build();
- QName qname = new QName(namespace, revision, prefix, typeName);
- SchemaPath schemaPath = createTypePath(actualPath, typeName);
+ @Deprecated
+ public static void parseUnknownTypeWithBody(final Type_body_stmtsContext typeBody, final TypeAwareBuilder parent,
+ final QName prefixedQName, final ModuleBuilder moduleBuilder, final QName moduleQName, final SchemaPath actualPath) {
+ final int line = typeBody.getStart().getLine();
- ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, null, null, schemaPath);
- typeBuilder.ranges(rangeStatements);
- typeBuilder.lengths(lengthStatements);
- typeBuilder.patterns(patternStatements);
- typeBuilder.fractionDigits(fractionDigits);
+ List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody, moduleBuilder.getName());
+ List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody, moduleBuilder.getName());
+ List<PatternConstraint> patternStatements = getPatternConstraint(typeBody, moduleBuilder.getName());
+ Integer fractionDigits = getFractionDigits(typeBody, moduleBuilder.getName());
- return typeBuilder.build();
- }
+ if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
+ TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent;
+ typedef.setRanges(rangeStatements);
+ typedef.setLengths(lengthStatements);
+ typedef.setPatterns(patternStatements);
+ typedef.setFractionDigits(fractionDigits);
+ typedef.setTypeQName(prefixedQName);
+ // add parent node of this type statement to dirty nodes
+ moduleBuilder.markActualNodeDirty();
+ } else {
+ QName qname = QName.create(moduleQName, prefixedQName.getLocalName());
+ SchemaPath schemaPath = createTypePath(actualPath, prefixedQName.getLocalName());
+ TypeDefinitionBuilder typeBuilder = new TypeDefinitionBuilderImpl(moduleBuilder.getName(), line, qname, schemaPath);
+ typeBuilder.setRanges(rangeStatements);
+ typeBuilder.setLengths(lengthStatements);
+ typeBuilder.setPatterns(patternStatements);
+ typeBuilder.setFractionDigits(fractionDigits);
+ typeBuilder.setTypeQName(prefixedQName);
+ parent.setTypedef(typeBuilder);
+ moduleBuilder.getDirtyNodes().add(typeBuilder);
}
-
- return unknownType.build();
}
/**
* type body context
* @param actualPath
* current path in schema
- * @param namespace
- * current namespace
- * @param revision
- * current revision
- * @param prefix
- * current prefix
+ * @param moduleQName
+ * current module qname
* @param parent
* parent builder
* @return TypeDefinition object based on parsed values.
+ *
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
*/
+ @Deprecated
public static TypeDefinition<?> parseTypeWithBody(final String typeName, final Type_body_stmtsContext typeBody,
- final Stack<QName> actualPath, final URI namespace, final Date revision, final String prefix,
- final Builder parent) {
+ final SchemaPath actualPath, final QName moduleQName, final Builder parent) {
final String moduleName = parent.getModuleName();
final int line = typeBody.getStart().getLine();
Integer fractionDigits = getFractionDigits(typeBody, moduleName);
List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody, moduleName);
- List<PatternConstraint> patternStatements = getPatternConstraint(typeBody);
+ List<PatternConstraint> patternStatements = getPatternConstraint(typeBody, moduleName);
List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody, moduleName);
TypeConstraints constraints = new TypeConstraints(moduleName, line);
constraints.addRanges(rangeStatements);
SchemaPath baseTypePath = createBaseTypePath(actualPath, typeName);
- SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, namespace, revision, prefix, typeName);
+ SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, moduleQName, typeName);
if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
extBaseTypePath = baseTypePath;
if ("decimal64".equals(typeName)) {
if (rangeStatements.isEmpty()) {
try {
- return new Decimal64(baseTypePath, fractionDigits);
+ return Decimal64.create(baseTypePath, fractionDigits);
} catch(Exception e) {
throw new YangParseException(moduleName, line, e.getMessage());
}
}
- Decimal64 decimalType = new Decimal64(extBaseTypePath, fractionDigits);
+ Decimal64 decimalType = Decimal64.create(extBaseTypePath, fractionDigits);
constraints.addRanges(decimalType.getRangeConstraints());
baseType = decimalType;
} else if (typeName.startsWith("int")) {
baseType = uintType;
} else if ("enumeration".equals(typeName)) {
List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, moduleName);
- return new EnumerationType(baseTypePath, enumConstants);
+ return EnumerationType.create(baseTypePath, enumConstants, Optional.<EnumPair> absent());
} else if ("string".equals(typeName)) {
StringTypeDefinition stringType = StringType.getInstance();
constraints.addLengths(stringType.getLengthConstraints());
baseType = stringType;
} else if ("bits".equals(typeName)) {
- return new BitsType(baseTypePath, getBits(typeBody, actualPath, moduleName));
+ return BitsType.create(baseTypePath, getBits(typeBody, actualPath, moduleName));
} else if ("leafref".equals(typeName)) {
final String path = parseLeafrefPath(typeBody);
final boolean absolute = path.startsWith("/");
constraints.addLengths(binaryType.getLengthConstraints());
baseType = binaryType;
} else if ("instance-identifier".equals(typeName)) {
- boolean requireInstance = isRequireInstance(typeBody);
- return new InstanceIdentifier(null, requireInstance);
+ return InstanceIdentifierType.create(isRequireInstance(typeBody));
}
if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
return baseType;
}
- List<QName> path = new ArrayList<>(actualPath);
- path.add(new QName(namespace, revision, prefix, typeName));
- SchemaPath schemaPath = SchemaPath.create(path, true);
-
- QName qname = schemaPath.getPath().get(schemaPath.getPath().size() - 1);
- ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", schemaPath);
+ QName qname = QName.create(moduleQName, typeName);
+ SchemaPath schemaPath = actualPath.createChild(qname);
+ final Optional<String> opt = Optional.of("");
+ ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, opt, opt, schemaPath);
typeBuilder.ranges(constraints.getRange());
typeBuilder.lengths(constraints.getLength());
return typeBuilder.build();
}
- private static SchemaPath createTypePath(final Stack<QName> actual, final String typeName) {
- QName last = actual.peek();
- QName typeQName = new QName(last.getNamespace(), last.getRevision(), last.getPrefix(), typeName);
- List<QName> path = new ArrayList<>(actual);
- path.add(typeQName);
- return SchemaPath.create(path, true);
+ private static SchemaPath createTypePath(final SchemaPath actual, final String typeName) {
+ QName last = actual.getLastComponent();
+ return actual.createChild(QName.create(last, typeName));
}
- private static SchemaPath createBaseTypePath(final Stack<QName> actual, final String typeName) {
- List<QName> path = new ArrayList<>(actual);
- path.add(BaseTypes.constructQName(typeName));
- return SchemaPath.create(path, true);
+ private static SchemaPath createBaseTypePath(final SchemaPath actual, final String typeName) {
+ return actual.createChild(BaseTypes.constructQName(typeName));
}
- private static SchemaPath createExtendedBaseTypePath(final Stack<QName> actual, final URI namespace, final Date revision,
- final String prefix, final String typeName) {
- QName extTypeName = new QName(namespace, revision, prefix, typeName);
- QName baseTypeName = BaseTypes.constructQName(typeName);
- List<QName> path = new ArrayList<>(actual);
- path.add(extTypeName);
- path.add(baseTypeName);
- return SchemaPath.create(path, true);
+ private static SchemaPath createExtendedBaseTypePath(final SchemaPath actual, final QName moduleQName, final String typeName) {
+ return actual.createChild(
+ QName.create(moduleQName, typeName),
+ BaseTypes.constructQName(typeName));
}
/**
*/
private static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) {
StringBuilder mustText = new StringBuilder();
- String description = null;
- String reference = null;
- String errorAppTag = null;
- String errorMessage = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
+ Optional<String> errorAppTag = Optional.absent();
+ Optional<String> errorMessage = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); ++i) {
ParseTree child = ctx.getChild(i);
if (child instanceof StringContext) {
}
}
} else if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.of(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.of(stringFromNode(child));
} else if (child instanceof Error_app_tag_stmtContext) {
- errorAppTag = stringFromNode(child);
+ errorAppTag = Optional.of(stringFromNode(child));
} else if (child instanceof Error_message_stmtContext) {
- errorMessage = stringFromNode(child);
+ errorMessage = Optional.of(stringFromNode(child));
}
}
- return new MustDefinitionImpl(mustText.toString(), description, reference, errorAppTag, errorMessage);
+ return MustDefinitionImpl.create(mustText.toString(), description, reference, errorAppTag, errorMessage);
}
/**
* context to parse
* @param constraints
* ConstraintsBuilder to fill
+ *
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
*/
+ @Deprecated
public static void parseConstraints(final ParseTree ctx, final ConstraintsBuilder constraints) {
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree childNode = ctx.getChild(i);
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree maxArg = ctx.getChild(i);
if (maxArg instanceof Max_value_argContext) {
- result = Integer.valueOf(stringFromNode(maxArg));
+ String maxValue = stringFromNode(maxArg);
+ if ("unbounded".equals(maxValue)) {
+ result = Integer.MAX_VALUE;
+ } else {
+ result = Integer.valueOf(maxValue);
+ }
}
}
if (result == null) {
* @param moduleName
* name of current module
* @return RefineHolder object representing this refine statement
+ *
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
*/
+ @Deprecated
public static RefineHolderImpl parseRefine(final Refine_stmtContext refineCtx, final String moduleName) {
final String refineTarget = stringFromNode(refineCtx);
final RefineHolderImpl refine = new RefineHolderImpl(moduleName, refineCtx.getStart().getLine(), refineTarget);
return refine;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static void parseRefineDefault(final RefineHolderImpl refine, final ParseTree refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);
}
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_leaf_stmtsContext refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);
return refine;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static RefineBuilder parseRefine(final RefineBuilder refine, final Refine_container_stmtsContext refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);
return refine;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_list_stmtsContext refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);
return refine;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_leaf_list_stmtsContext refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);
return refine;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_choice_stmtsContext refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);
return refine;
}
+ /**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+ @Deprecated
private static RefineBuilder parseRefine(final RefineBuilder refine, final Refine_anyxml_stmtsContext refineStmt) {
for (int i = 0; i < refineStmt.getChildCount(); i++) {
ParseTree refineArg = refineStmt.getChild(i);