Merge "BUG-576: fixed javadoc warnings."
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / ParserListenerUtils.java
index 2757c10e1e755162440c1102b5d0ee37108e75b3..933ac6b6d4f17f489efb3fa878ea868bbf7bfb94 100644 (file)
@@ -11,14 +11,17 @@ 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.Preconditions;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;
+
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
@@ -105,7 +108,7 @@ import org.opendaylight.yangtools.yang.model.util.BitsType;
 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;
@@ -118,15 +121,17 @@ import org.opendaylight.yangtools.yang.model.util.Uint16;
 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;
@@ -139,7 +144,8 @@ public final class ParserListenerUtils {
     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 QUOTE_MATCHER = CharMatcher.is('"');
+    private static final CharMatcher DOUBLE_QUOTE_MATCHER = CharMatcher.is('"');
+    private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher.is('\'');
 
     private ParserListenerUtils() {
     }
@@ -166,33 +172,26 @@ public final class ParserListenerUtils {
         StringBuilder sb = new StringBuilder();
         for (TerminalNode stringNode : context.STRING()) {
             final String str = stringNode.getText();
-            final int i = str.indexOf('"');
-
-            if (i == -1) {
+            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 {
                 sb.append(str);
                 continue;
             }
-
             /*
-             * The string contains quotes, so we have to tread carefully.
-             *
-             * FIXME: I think this code is broken, but proving that requires
-             *        making sense of the parser/lexer and how they tie into
-             *        this method. Especially what format 'str' can have and
-             *        how we need to handle it. The original check was:
-             *
-             *        if (!(result.startsWith("\"")) && result.endsWith("\""))
-             *
-             *        Looking at the parentheses it is hard to justify the
-             *        pair right after negation -- the intent may have been
-             *        to negate the entire expression.
+             * 
+             * It is safe not to check last argument to be same
+             * grammars enforces that.
+             * 
+             * FIXME: Introduce proper escaping and translation of escaped
+             * characters here.
+             * 
              */
-            if (i != 0 && str.endsWith("\"")) {
-                LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(context),
-                        context.getStart().getLine());
-            } else {
-                sb.append(QUOTE_MATCHER.removeFrom(str));
-            }
+            sb.append(quoteMatcher.removeFrom(str.substring(1, str.length()-1)));
         }
         return sb.toString();
     }
@@ -1036,60 +1035,51 @@ public final class ParserListenerUtils {
     }
 
     /**
-     * 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
      */
-    public static TypeDefinition<?> parseUnknownTypeWithBody(final QName typedefQName,
-            final Type_body_stmtsContext ctx, final SchemaPath actualPath, final QName moduleQName, 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 = QName.create(moduleQName, typeName);
-                SchemaPath schemaPath = createTypePath(actualPath, typeName);
+    public static void parseUnknownTypeWithBody(Type_body_stmtsContext typeBody, TypeAwareBuilder parent,
+            QName prefixedQName, ModuleBuilder moduleBuilder, QName moduleQName, SchemaPath actualPath) {
+        final int line = typeBody.getStart().getLine();
 
-                ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, Optional.<String>absent(), Optional.<String>absent(), 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);
+        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();
     }
 
     /**
@@ -1101,12 +1091,8 @@ public final class ParserListenerUtils {
      *            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.
@@ -1208,7 +1194,7 @@ public final class ParserListenerUtils {
             constraints.addLengths(binaryType.getLengthConstraints());
             baseType = binaryType;
         } else if ("instance-identifier".equals(typeName)) {
-            return InstanceIdentifier.create(isRequireInstance(typeBody));
+            return InstanceIdentifierType.create(isRequireInstance(typeBody));
         }
 
         if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {