2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/eplv10.html
\r
8 package org.opendaylight.controller.yang.model.parser.util;
\r
10 import java.net.URI;
\r
11 import java.util.ArrayList;
\r
12 import java.util.Collections;
\r
13 import java.util.Date;
\r
14 import java.util.List;
\r
15 import java.util.Stack;
\r
17 import org.antlr.v4.runtime.tree.ParseTree;
\r
18 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
\r
19 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bit_stmtContext;
\r
20 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bits_specificationContext;
\r
21 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_argContext;
\r
22 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_stmtContext;
\r
23 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Decimal64_specificationContext;
\r
24 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;
\r
25 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_specificationContext;
\r
26 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_stmtContext;
\r
27 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Fraction_digits_stmtContext;
\r
28 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leafref_specificationContext;
\r
29 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Length_stmtContext;
\r
30 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_argContext;
\r
31 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_stmtContext;
\r
32 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Max_elements_stmtContext;
\r
33 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Min_elements_stmtContext;
\r
34 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Must_stmtContext;
\r
35 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Numerical_restrictionsContext;
\r
36 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_argContext;
\r
37 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;
\r
38 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Path_stmtContext;
\r
39 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Pattern_stmtContext;
\r
40 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Position_stmtContext;
\r
41 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Range_stmtContext;
\r
42 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;
\r
43 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Require_instance_argContext;
\r
44 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Require_instance_stmtContext;
\r
45 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_argContext;
\r
46 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;
\r
47 import org.opendaylight.controller.antlrv4.code.gen.YangParser.StringContext;
\r
48 import org.opendaylight.controller.antlrv4.code.gen.YangParser.String_restrictionsContext;
\r
49 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;
\r
50 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Units_stmtContext;
\r
51 import org.opendaylight.controller.antlrv4.code.gen.YangParser.When_stmtContext;
\r
52 import org.opendaylight.controller.yang.common.QName;
\r
53 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
\r
54 import org.opendaylight.controller.yang.model.api.SchemaPath;
\r
55 import org.opendaylight.controller.yang.model.api.Status;
\r
56 import org.opendaylight.controller.yang.model.api.TypeDefinition;
\r
57 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
\r
58 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition;
\r
59 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
\r
60 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
\r
61 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
\r
62 import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
\r
63 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
\r
64 import org.opendaylight.controller.yang.model.parser.builder.api.SchemaNodeBuilder;
\r
65 import org.opendaylight.controller.yang.model.parser.builder.impl.ConstraintsBuilder;
\r
66 import org.opendaylight.controller.yang.model.util.BaseConstraints;
\r
67 import org.opendaylight.controller.yang.model.util.BinaryType;
\r
68 import org.opendaylight.controller.yang.model.util.BitsType;
\r
69 import org.opendaylight.controller.yang.model.util.EnumerationType;
\r
70 import org.opendaylight.controller.yang.model.util.InstanceIdentifier;
\r
71 import org.opendaylight.controller.yang.model.util.Leafref;
\r
72 import org.opendaylight.controller.yang.model.util.RevisionAwareXPathImpl;
\r
73 import org.opendaylight.controller.yang.model.util.StringType;
\r
74 import org.opendaylight.controller.yang.model.util.UnknownType;
\r
75 import org.opendaylight.controller.yang.model.util.YangTypesConverter;
\r
76 import org.slf4j.Logger;
\r
77 import org.slf4j.LoggerFactory;
\r
79 public class YangModelBuilderUtil {
\r
81 private static final Logger logger = LoggerFactory
\r
82 .getLogger(YangModelBuilderUtil.class);
\r
85 * Parse given tree and get first string value.
\r
89 * @return first string value from given tree
\r
91 public static String stringFromNode(final ParseTree treeNode) {
\r
92 final String result = "";
\r
93 for (int i = 0; i < treeNode.getChildCount(); ++i) {
\r
94 if (treeNode.getChild(i) instanceof StringContext) {
\r
95 final StringContext context = (StringContext) treeNode
\r
97 if (context != null) {
\r
98 return context.getChild(0).getText().replace("\"", "");
\r
106 * Parse 'description', 'reference' and 'status' statements and fill in
\r
112 * builder to fill in with parsed statements
\r
114 public static void parseSchemaNodeArgs(ParseTree ctx,
\r
115 SchemaNodeBuilder builder) {
\r
116 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
117 ParseTree child = ctx.getChild(i);
\r
118 if (child instanceof Description_stmtContext) {
\r
119 String desc = stringFromNode(child);
\r
120 builder.setDescription(desc);
\r
121 } else if (child instanceof Reference_stmtContext) {
\r
122 String ref = stringFromNode(child);
\r
123 builder.setReference(ref);
\r
124 } else if (child instanceof Status_stmtContext) {
\r
125 Status status = parseStatus((Status_stmtContext) child);
\r
126 builder.setStatus(status);
\r
132 * Parse given context and return its value;
\r
136 * @return value parsed from context
\r
138 public static Status parseStatus(Status_stmtContext ctx) {
\r
139 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
140 ParseTree statusArg = ctx.getChild(i);
\r
141 if (statusArg instanceof Status_argContext) {
\r
142 String statusArgStr = stringFromNode(statusArg);
\r
143 if (statusArgStr.equals("current")) {
\r
144 return Status.CURRENT;
\r
145 } else if (statusArgStr.equals("deprecated")) {
\r
146 return Status.DEPRECATED;
\r
147 } else if (statusArgStr.equals("obsolete")) {
\r
148 return Status.OBSOLETE;
\r
150 logger.warn("Invalid 'status' statement: " + statusArgStr);
\r
158 * Parse given tree and returns units statement as string.
\r
162 * @return value of units statement as string or null if there is no units
\r
165 public static String parseUnits(ParseTree ctx) {
\r
166 String units = null;
\r
167 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
168 ParseTree child = ctx.getChild(i);
\r
169 if (child instanceof Units_stmtContext) {
\r
170 units = stringFromNode(child);
\r
178 * Create SchemaPath object from given path list with namespace, revision
\r
179 * and prefix based on given values.
\r
181 * @param actualPath
\r
185 * @return SchemaPath object.
\r
187 public static SchemaPath createActualSchemaPath(List<String> actualPath,
\r
188 URI namespace, Date revision, String prefix) {
\r
189 final List<QName> path = new ArrayList<QName>();
\r
191 for (String pathElement : actualPath) {
\r
192 qname = new QName(namespace, revision, prefix, pathElement);
\r
195 return new SchemaPath(path, true);
\r
199 * Create SchemaPath from given string.
\r
201 * @param augmentPath
\r
202 * string representation of path
\r
203 * @return SchemaPath object
\r
205 public static SchemaPath parseAugmentPath(String augmentPath) {
\r
206 boolean absolute = augmentPath.startsWith("/");
\r
207 String[] splittedPath = augmentPath.split("/");
\r
208 List<QName> path = new ArrayList<QName>();
\r
210 for (String pathElement : splittedPath) {
\r
211 if (pathElement.length() > 0) {
\r
212 String[] splittedElement = pathElement.split(":");
\r
213 if (splittedElement.length == 1) {
\r
214 name = new QName(null, null, null, splittedElement[0]);
\r
216 name = new QName(null, null, splittedElement[0],
\r
217 splittedElement[1]);
\r
222 return new SchemaPath(path, absolute);
\r
226 * Create java.util.List of QName objects from given key definition as
\r
229 * @param keyDefinition
\r
230 * key definition as string
\r
232 * current namespace
\r
237 * @return YANG list key as java.util.List of QName objects
\r
239 public static List<QName> createListKey(String keyDefinition,
\r
240 URI namespace, Date revision, String prefix) {
\r
241 List<QName> key = new ArrayList<QName>();
\r
242 String[] splittedKey = keyDefinition.split(" ");
\r
244 QName qname = null;
\r
245 for (String keyElement : splittedKey) {
\r
246 if (keyElement.length() != 0) {
\r
247 qname = new QName(namespace, revision, prefix, keyElement);
\r
254 private static List<EnumTypeDefinition.EnumPair> getEnumConstants(
\r
255 Type_body_stmtsContext ctx, List<String> path, URI namespace,
\r
256 Date revision, String prefix) {
\r
257 List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<EnumTypeDefinition.EnumPair>();
\r
259 out: for (int j = 0; j < ctx.getChildCount(); j++) {
\r
260 ParseTree enumSpecChild = ctx.getChild(j);
\r
261 if (enumSpecChild instanceof Enum_specificationContext) {
\r
262 for (int k = 0; k < enumSpecChild.getChildCount(); k++) {
\r
263 ParseTree enumChild = enumSpecChild.getChild(k);
\r
264 if (enumChild instanceof Enum_stmtContext) {
\r
265 enumConstants.add(createEnumPair(
\r
266 (Enum_stmtContext) enumChild, k, path,
\r
267 namespace, revision, prefix));
\r
268 if (k == enumSpecChild.getChildCount() - 1) {
\r
275 return enumConstants;
\r
278 private static EnumTypeDefinition.EnumPair createEnumPair(
\r
279 Enum_stmtContext ctx, final int value, List<String> path,
\r
280 final URI namespace, final Date revision, final String prefix) {
\r
281 final String name = stringFromNode(ctx);
\r
282 final QName qname = new QName(namespace, revision, prefix, name);
\r
283 String description = null;
\r
284 String reference = null;
\r
285 Status status = null;
\r
286 List<String> enumPairPath = new ArrayList<String>(path);
\r
287 enumPairPath.add(name);
\r
289 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
290 ParseTree child = ctx.getChild(i);
\r
291 if (child instanceof Description_stmtContext) {
\r
292 description = stringFromNode(child);
\r
293 } else if (child instanceof Reference_stmtContext) {
\r
294 reference = stringFromNode(child);
\r
295 } else if (child instanceof Status_stmtContext) {
\r
296 status = parseStatus((Status_stmtContext) child);
\r
300 EnumPairImpl result = new EnumPairImpl();
\r
301 result.qname = qname;
\r
302 result.path = createActualSchemaPath(enumPairPath, namespace, revision,
\r
304 result.description = description;
\r
305 result.reference = reference;
\r
306 result.status = status;
\r
307 // TODO: extensionSchemaNodes
\r
308 result.name = name;
\r
309 result.value = value;
\r
313 private static class EnumPairImpl implements EnumTypeDefinition.EnumPair {
\r
315 private QName qname;
\r
316 private SchemaPath path;
\r
317 private String description;
\r
318 private String reference;
\r
319 private Status status;
\r
320 private List<UnknownSchemaNode> extensionSchemaNodes = Collections
\r
322 private String name;
\r
323 private Integer value;
\r
326 public QName getQName() {
\r
331 public SchemaPath getPath() {
\r
336 public String getDescription() {
\r
337 return description;
\r
341 public String getReference() {
\r
346 public Status getStatus() {
\r
351 public List<UnknownSchemaNode> getUnknownSchemaNodes() {
\r
352 return extensionSchemaNodes;
\r
356 public String getName() {
\r
361 public Integer getValue() {
\r
366 public int hashCode() {
\r
367 final int prime = 31;
\r
369 result = prime * result + ((qname == null) ? 0 : qname.hashCode());
\r
370 result = prime * result + ((path == null) ? 0 : path.hashCode());
\r
371 result = prime * result
\r
372 + ((description == null) ? 0 : description.hashCode());
\r
373 result = prime * result
\r
374 + ((reference == null) ? 0 : reference.hashCode());
\r
375 result = prime * result
\r
376 + ((status == null) ? 0 : status.hashCode());
\r
379 + ((extensionSchemaNodes == null) ? 0
\r
380 : extensionSchemaNodes.hashCode());
\r
381 result = prime * result + ((name == null) ? 0 : name.hashCode());
\r
382 result = prime * result + ((value == null) ? 0 : value.hashCode());
\r
387 public boolean equals(Object obj) {
\r
394 if (getClass() != obj.getClass()) {
\r
397 EnumPairImpl other = (EnumPairImpl) obj;
\r
398 if (qname == null) {
\r
399 if (other.qname != null) {
\r
402 } else if (!qname.equals(other.qname)) {
\r
405 if (path == null) {
\r
406 if (other.path != null) {
\r
409 } else if (!path.equals(other.path)) {
\r
412 if (description == null) {
\r
413 if (other.description != null) {
\r
416 } else if (!description.equals(other.description)) {
\r
419 if (reference == null) {
\r
420 if (other.reference != null) {
\r
423 } else if (!reference.equals(other.reference)) {
\r
426 if (status == null) {
\r
427 if (other.status != null) {
\r
430 } else if (!status.equals(other.status)) {
\r
433 if (extensionSchemaNodes == null) {
\r
434 if (other.extensionSchemaNodes != null) {
\r
437 } else if (!extensionSchemaNodes.equals(other.extensionSchemaNodes)) {
\r
440 if (name == null) {
\r
441 if (other.name != null) {
\r
444 } else if (!name.equals(other.name)) {
\r
447 if (value == null) {
\r
448 if (other.value != null) {
\r
451 } else if (!value.equals(other.value)) {
\r
458 public String toString() {
\r
459 return EnumTypeDefinition.EnumPair.class.getSimpleName() + "[name="
\r
460 + name + ", value=" + value + "]";
\r
464 private static List<RangeConstraint> getRangeConstraints(
\r
465 Type_body_stmtsContext ctx) {
\r
466 final List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();
\r
467 for (int j = 0; j < ctx.getChildCount(); j++) {
\r
468 ParseTree numRestrChild = ctx.getChild(j);
\r
469 if (numRestrChild instanceof Numerical_restrictionsContext) {
\r
470 for (int k = 0; k < numRestrChild.getChildCount(); k++) {
\r
471 ParseTree rangeChild = numRestrChild.getChild(k);
\r
472 if (rangeChild instanceof Range_stmtContext) {
\r
474 .addAll(parseRangeConstraints((Range_stmtContext) rangeChild));
\r
480 return rangeConstraints;
\r
483 private static List<RangeConstraint> parseRangeConstraints(
\r
484 Range_stmtContext ctx) {
\r
485 List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();
\r
486 String description = null;
\r
487 String reference = null;
\r
489 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
490 ParseTree child = ctx.getChild(i);
\r
491 if (child instanceof Description_stmtContext) {
\r
492 description = stringFromNode(child);
\r
493 } else if (child instanceof Reference_stmtContext) {
\r
494 reference = stringFromNode(child);
\r
498 String rangeStr = stringFromNode(ctx);
\r
499 String trimmed = rangeStr.replace(" ", "");
\r
500 String[] splittedRange = trimmed.split("\\|");
\r
501 for (String rangeDef : splittedRange) {
\r
502 String[] splittedRangeDef = rangeDef.split("\\.\\.");
\r
505 if (splittedRangeDef.length == 1) {
\r
506 min = max = parseRangeValue(splittedRangeDef[0]);
\r
508 min = parseRangeValue(splittedRangeDef[0]);
\r
509 max = parseRangeValue(splittedRangeDef[1]);
\r
511 RangeConstraint range = BaseConstraints.rangeConstraint(min, max,
\r
512 description, reference);
\r
513 rangeConstraints.add(range);
\r
516 return rangeConstraints;
\r
519 private static List<LengthConstraint> getLengthConstraints(
\r
520 Type_body_stmtsContext ctx) {
\r
521 List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();
\r
522 for (int j = 0; j < ctx.getChildCount(); j++) {
\r
523 ParseTree stringRestrChild = ctx.getChild(j);
\r
524 if (stringRestrChild instanceof String_restrictionsContext) {
\r
525 for (int k = 0; k < stringRestrChild.getChildCount(); k++) {
\r
526 ParseTree lengthChild = stringRestrChild.getChild(k);
\r
527 if (lengthChild instanceof Length_stmtContext) {
\r
529 .addAll(parseLengthConstraints((Length_stmtContext) lengthChild));
\r
534 return lengthConstraints;
\r
537 private static List<LengthConstraint> parseLengthConstraints(
\r
538 Length_stmtContext ctx) {
\r
539 List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();
\r
540 String description = null;
\r
541 String reference = null;
\r
543 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
544 ParseTree child = ctx.getChild(i);
\r
545 if (child instanceof Description_stmtContext) {
\r
546 description = stringFromNode(child);
\r
547 } else if (child instanceof Reference_stmtContext) {
\r
548 reference = stringFromNode(child);
\r
552 String lengthStr = stringFromNode(ctx);
\r
553 String trimmed = lengthStr.replace(" ", "");
\r
554 String[] splittedRange = trimmed.split("\\|");
\r
555 for (String rangeDef : splittedRange) {
\r
556 String[] splittedRangeDef = rangeDef.split("\\.\\.");
\r
559 if (splittedRangeDef.length == 1) {
\r
560 min = max = parseRangeValue(splittedRangeDef[0]);
\r
562 min = parseRangeValue(splittedRangeDef[0]);
\r
563 max = parseRangeValue(splittedRangeDef[1]);
\r
565 LengthConstraint range = BaseConstraints.lengthConstraint(min, max,
\r
566 description, reference);
\r
567 lengthConstraints.add(range);
\r
570 return lengthConstraints;
\r
573 private static Long parseRangeValue(String value) {
\r
574 Long result = null;
\r
575 if (value.equals("min")) {
\r
576 result = Long.MIN_VALUE;
\r
577 } else if (value.equals("max")) {
\r
578 result = Long.MAX_VALUE;
\r
580 result = Long.valueOf(value);
\r
585 private static List<PatternConstraint> getPatternConstraint(
\r
586 Type_body_stmtsContext ctx) {
\r
587 List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
\r
589 out: for (int j = 0; j < ctx.getChildCount(); j++) {
\r
590 ParseTree stringRestrChild = ctx.getChild(j);
\r
591 if (stringRestrChild instanceof String_restrictionsContext) {
\r
592 for (int k = 0; k < stringRestrChild.getChildCount(); k++) {
\r
593 ParseTree lengthChild = stringRestrChild.getChild(k);
\r
594 if (lengthChild instanceof Pattern_stmtContext) {
\r
595 patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild));
\r
596 if (k == lengthChild.getChildCount() - 1) {
\r
607 * Internal helper method.
\r
611 * @return PatternConstraint object
\r
613 private static PatternConstraint parsePatternConstraint(
\r
614 Pattern_stmtContext ctx) {
\r
615 String description = null;
\r
616 String reference = null;
\r
617 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
618 ParseTree child = ctx.getChild(i);
\r
619 if (child instanceof Description_stmtContext) {
\r
620 description = stringFromNode(child);
\r
621 } else if (child instanceof Reference_stmtContext) {
\r
622 reference = stringFromNode(child);
\r
625 String pattern = patternStringFromNode(ctx);
\r
626 return BaseConstraints.patternConstraint(pattern, description,
\r
630 public static String patternStringFromNode(final Pattern_stmtContext treeNode) {
\r
631 String result = "";
\r
632 for (int i = 0; i < treeNode.getChildCount(); ++i) {
\r
633 ParseTree child = treeNode.getChild(i);
\r
634 if (child instanceof StringContext) {
\r
635 for(int j = 0; j < child.getChildCount(); j++) {
\r
637 String patternToken = child.getChild(j).getText();
\r
638 result += patternToken.substring(1, patternToken.length()-1);
\r
646 private static Integer getFractionDigits(Type_body_stmtsContext ctx) {
\r
647 for (int j = 0; j < ctx.getChildCount(); j++) {
\r
648 ParseTree dec64specChild = ctx.getChild(j);
\r
649 if (dec64specChild instanceof Decimal64_specificationContext) {
\r
650 return parseFractionDigits((Decimal64_specificationContext) dec64specChild);
\r
656 private static Integer parseFractionDigits(
\r
657 Decimal64_specificationContext ctx) {
\r
658 for (int k = 0; k < ctx.getChildCount(); k++) {
\r
659 ParseTree fdChild = ctx.getChild(k);
\r
660 if (fdChild instanceof Fraction_digits_stmtContext) {
\r
661 return Integer.valueOf(stringFromNode(fdChild));
\r
667 private static List<BitsTypeDefinition.Bit> getBits(
\r
668 Type_body_stmtsContext ctx, List<String> actualPath, URI namespace,
\r
669 Date revision, String prefix) {
\r
670 List<BitsTypeDefinition.Bit> bits = new ArrayList<BitsTypeDefinition.Bit>();
\r
671 for (int j = 0; j < ctx.getChildCount(); j++) {
\r
672 ParseTree bitsSpecChild = ctx.getChild(j);
\r
673 if (bitsSpecChild instanceof Bits_specificationContext) {
\r
674 for (int k = 0; k < bitsSpecChild.getChildCount(); k++) {
\r
675 ParseTree bitChild = bitsSpecChild.getChild(k);
\r
676 if (bitChild instanceof Bit_stmtContext) {
\r
677 bits.add(parseBit((Bit_stmtContext) bitChild,
\r
678 actualPath, namespace, revision, prefix));
\r
686 private static boolean isRequireInstance(Type_body_stmtsContext ctx) {
\r
687 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
688 ParseTree child = ctx.getChild(i);
\r
689 if (child instanceof Require_instance_stmtContext) {
\r
690 for (int j = 0; j < child.getChildCount(); j++) {
\r
691 ParseTree reqArg = child.getChild(j);
\r
692 if (reqArg instanceof Require_instance_argContext) {
\r
693 return Boolean.valueOf(stringFromNode(reqArg));
\r
701 private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx,
\r
702 List<String> actualPath, final URI namespace, final Date revision,
\r
703 final String prefix) {
\r
704 String name = stringFromNode(ctx);
\r
705 final QName qname = new QName(namespace, revision, prefix, name);
\r
706 Long position = null;
\r
708 String description = null;
\r
709 String reference = null;
\r
710 Status status = Status.CURRENT;
\r
712 Stack<String> bitPath = new Stack<String>();
\r
713 bitPath.addAll(actualPath);
\r
716 SchemaPath schemaPath = createActualSchemaPath(bitPath, namespace,
\r
719 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
720 ParseTree child = ctx.getChild(i);
\r
721 if (child instanceof Position_stmtContext) {
\r
722 String positionStr = stringFromNode(child);
\r
723 position = Long.valueOf(positionStr);
\r
724 if (position < 0 || position > 4294967295L) {
\r
725 throw new IllegalArgumentException(
\r
726 "position value MUST be in the range 0 to 4294967295, but was: "
\r
729 } else if (child instanceof Description_stmtContext) {
\r
730 description = stringFromNode(child);
\r
731 } else if (child instanceof Reference_stmtContext) {
\r
732 reference = stringFromNode(child);
\r
733 } else if (child instanceof Status_stmtContext) {
\r
734 status = parseStatus((Status_stmtContext) child);
\r
738 // TODO: extensionDefinitions
\r
739 return createBit(qname, schemaPath, description, reference, status,
\r
743 private static BitsTypeDefinition.Bit createBit(final QName qname,
\r
744 final SchemaPath schemaPath, final String description,
\r
745 final String reference, final Status status,
\r
746 final List<UnknownSchemaNode> extensionDefinitions,
\r
747 final Long position) {
\r
748 return new BitsTypeDefinition.Bit() {
\r
751 public QName getQName() {
\r
756 public SchemaPath getPath() {
\r
761 public String getDescription() {
\r
762 return description;
\r
766 public String getReference() {
\r
771 public Status getStatus() {
\r
776 public List<UnknownSchemaNode> getUnknownSchemaNodes() {
\r
777 return extensionDefinitions;
\r
781 public Long getPosition() {
\r
786 public String getName() {
\r
787 return qname.getLocalName();
\r
791 public int hashCode() {
\r
792 final int prime = 31;
\r
794 result = prime * result
\r
795 + ((qname == null) ? 0 : qname.hashCode());
\r
796 result = prime * result
\r
797 + ((schemaPath == null) ? 0 : schemaPath.hashCode());
\r
798 result = prime * result
\r
799 + ((description == null) ? 0 : description.hashCode());
\r
800 result = prime * result
\r
801 + ((reference == null) ? 0 : reference.hashCode());
\r
802 result = prime * result
\r
803 + ((status == null) ? 0 : status.hashCode());
\r
804 result = prime * result
\r
805 + ((position == null) ? 0 : position.hashCode());
\r
808 + ((extensionDefinitions == null) ? 0
\r
809 : extensionDefinitions.hashCode());
\r
814 public boolean equals(Object obj) {
\r
821 if (getClass() != obj.getClass()) {
\r
824 Bit other = (Bit) obj;
\r
825 if (qname == null) {
\r
826 if (other.getQName() != null) {
\r
829 } else if (!qname.equals(other.getQName())) {
\r
832 if (schemaPath == null) {
\r
833 if (other.getPath() != null) {
\r
836 } else if (!schemaPath.equals(other.getPath())) {
\r
839 if (description == null) {
\r
840 if (other.getDescription() != null) {
\r
843 } else if (!description.equals(other.getDescription())) {
\r
846 if (reference == null) {
\r
847 if (other.getReference() != null) {
\r
850 } else if (!reference.equals(other.getReference())) {
\r
853 if (status == null) {
\r
854 if (other.getStatus() != null) {
\r
857 } else if (!status.equals(other.getStatus())) {
\r
860 if (extensionDefinitions == null) {
\r
861 if (other.getUnknownSchemaNodes() != null) {
\r
864 } else if (!extensionDefinitions.equals(other
\r
865 .getUnknownSchemaNodes())) {
\r
868 if (position == null) {
\r
869 if (other.getPosition() != null) {
\r
872 } else if (!position.equals(other.getPosition())) {
\r
879 public String toString() {
\r
880 return Bit.class.getSimpleName() + "[name="
\r
881 + qname.getLocalName() + ", position=" + position + "]";
\r
887 * Parse orderedby statement.
\r
890 * Ordered_by_stmtContext
\r
891 * @return true, if orderedby contains value 'user' or false otherwise
\r
893 public static boolean parseUserOrdered(Ordered_by_stmtContext childNode) {
\r
894 boolean result = false;
\r
895 for (int j = 0; j < childNode.getChildCount(); j++) {
\r
896 ParseTree orderArg = childNode.getChild(j);
\r
897 if (orderArg instanceof Ordered_by_argContext) {
\r
898 String orderStr = stringFromNode(orderArg);
\r
899 if (orderStr.equals("system")) {
\r
901 } else if (orderStr.equals("user")) {
\r
904 logger.warn("Invalid 'orderedby' statement.");
\r
912 * Parse given config context and return true if it contains string 'true',
\r
916 * config context to parse.
\r
917 * @return true if given context contains string 'true', false otherwise
\r
919 public static boolean parseConfig(final Config_stmtContext ctx) {
\r
921 for (int i = 0; i < ctx.getChildCount(); ++i) {
\r
922 final ParseTree configContext = ctx.getChild(i);
\r
923 if (configContext instanceof Config_argContext) {
\r
924 final String value = stringFromNode(configContext);
\r
925 if (value.equals("true")) {
\r
935 * Parse given type body and creates UnknownType definition.
\r
937 * @param typedefQName
\r
938 * qname of current type
\r
941 * @return UnknownType object with constraints from parsed type body
\r
943 public static TypeDefinition<?> parseUnknownTypeBody(QName typedefQName,
\r
944 Type_body_stmtsContext ctx) {
\r
945 UnknownType.Builder ut = new UnknownType.Builder(typedefQName);
\r
948 List<RangeConstraint> rangeStatements = getRangeConstraints(ctx);
\r
949 List<LengthConstraint> lengthStatements = getLengthConstraints(ctx);
\r
950 List<PatternConstraint> patternStatements = getPatternConstraint(ctx);
\r
951 Integer fractionDigits = getFractionDigits(ctx);
\r
953 ut.rangeStatements(rangeStatements);
\r
954 ut.lengthStatements(lengthStatements);
\r
955 ut.patterns(patternStatements);
\r
956 ut.fractionDigits(fractionDigits);
\r
963 * Create TypeDefinition object based on given type name and type body.
\r
969 * @param actualPath
\r
970 * current path in schema
\r
972 * current namespace
\r
977 * @return TypeDefinition object based on parsed values.
\r
979 public static TypeDefinition<?> parseTypeBody(String typeName,
\r
980 Type_body_stmtsContext typeBody, List<String> actualPath,
\r
981 URI namespace, Date revision, String prefix) {
\r
982 TypeDefinition<?> type = null;
\r
984 List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody);
\r
985 Integer fractionDigits = getFractionDigits(typeBody);
\r
986 List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody);
\r
987 List<PatternConstraint> patternStatements = getPatternConstraint(typeBody);
\r
988 List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, namespace, revision, prefix);
\r
990 if (typeName.equals("decimal64")) {
\r
991 type = YangTypesConverter.javaTypeForBaseYangDecimal64Type(
\r
992 rangeStatements, fractionDigits);
\r
993 } else if (typeName.startsWith("int")) {
\r
994 type = YangTypesConverter.javaTypeForBaseYangSignedIntegerType(typeName,
\r
996 } else if(typeName.startsWith("uint")) {
\r
997 type = YangTypesConverter.javaTypeForBaseYangUnsignedIntegerType(typeName,
\r
999 } else if (typeName.equals("enumeration")) {
\r
1000 type = new EnumerationType(enumConstants);
\r
1001 } else if (typeName.equals("string")) {
\r
1002 type = new StringType(lengthStatements, patternStatements);
\r
1003 } else if (typeName.equals("bits")) {
\r
1004 type = new BitsType(getBits(typeBody, actualPath, namespace,
\r
1005 revision, prefix));
\r
1006 } else if (typeName.equals("leafref")) {
\r
1007 final String path = parseLeafrefPath(typeBody);
\r
1008 final boolean absolute = path.startsWith("/");
\r
1009 RevisionAwareXPath xpath = new RevisionAwareXPathImpl(path,
\r
1011 type = new Leafref(actualPath, namespace, revision, xpath);
\r
1012 } else if (typeName.equals("binary")) {
\r
1013 type = new BinaryType(null, lengthStatements, null);
\r
1014 } else if (typeName.equals("instance-identifier")) {
\r
1015 boolean requireInstance = isRequireInstance(typeBody);
\r
1016 type = new InstanceIdentifier(null, requireInstance);
\r
1021 private static String parseLeafrefPath(Type_body_stmtsContext ctx) {
\r
1022 for (int i = 0; i < ctx.getChildCount(); i++) {
\r
1023 ParseTree child = ctx.getChild(i);
\r
1024 if (child instanceof Leafref_specificationContext) {
\r
1025 for (int j = 0; j < child.getChildCount(); j++) {
\r
1026 ParseTree leafRefSpec = child.getChild(j);
\r
1027 if (leafRefSpec instanceof Path_stmtContext) {
\r
1028 return stringFromNode(leafRefSpec);
\r
1037 * Internal helper method for parsing Must_stmtContext.
\r
1040 * Must_stmtContext
\r
1041 * @return an array of strings with following fields: [0] must text [1]
\r
1042 * description [2] reference
\r
1044 public static String[] parseMust(YangParser.Must_stmtContext ctx) {
\r
1045 String[] params = new String[3];
\r
1047 String mustText = "";
\r
1048 String description = null;
\r
1049 String reference = null;
\r
1050 for (int i = 0; i < ctx.getChildCount(); ++i) {
\r
1051 ParseTree child = ctx.getChild(i);
\r
1052 if (child instanceof StringContext) {
\r
1053 final StringContext context = (StringContext) child;
\r
1054 for (int j = 0; j < context.getChildCount(); j++) {
\r
1055 String mustPart = context.getChild(j).getText();
\r
1057 mustText += mustPart
\r
1058 .substring(0, mustPart.length() - 1);
\r
1062 mustText += mustPart.substring(1);
\r
1065 } else if (child instanceof Description_stmtContext) {
\r
1066 description = stringFromNode(child);
\r
1067 } else if (child instanceof Reference_stmtContext) {
\r
1068 reference = stringFromNode(child);
\r
1071 params[0] = mustText;
\r
1072 params[1] = description;
\r
1073 params[2] = reference;
\r
1079 * Parse given tree and set constraints to given builder.
\r
1082 * Context to search.
\r
1083 * @param constraintsBuilder
\r
1084 * ConstraintsBuilder to fill.
\r
1086 public static void parseConstraints(ParseTree ctx,
\r
1087 ConstraintsBuilder constraintsBuilder) {
\r
1088 for (int i = 0; i < ctx.getChildCount(); ++i) {
\r
1089 final ParseTree childNode = ctx.getChild(i);
\r
1090 if (childNode instanceof Max_elements_stmtContext) {
\r
1091 Integer max = Integer.valueOf(stringFromNode(childNode));
\r
1092 constraintsBuilder.setMinElements(max);
\r
1093 } else if (childNode instanceof Min_elements_stmtContext) {
\r
1094 Integer min = Integer.valueOf(stringFromNode(childNode));
\r
1095 constraintsBuilder.setMinElements(min);
\r
1096 } else if (childNode instanceof Must_stmtContext) {
\r
1097 String[] mustParams = parseMust((Must_stmtContext) childNode);
\r
1098 constraintsBuilder.addMustDefinition(mustParams[0],
\r
1099 mustParams[1], mustParams[2]);
\r
1100 } else if (childNode instanceof Mandatory_stmtContext) {
\r
1101 for (int j = 0; j < childNode.getChildCount(); j++) {
\r
1102 ParseTree mandatoryTree = ctx.getChild(j);
\r
1103 if (mandatoryTree instanceof Mandatory_argContext) {
\r
1104 Boolean mandatory = Boolean
\r
1105 .valueOf(stringFromNode(mandatoryTree));
\r
1106 constraintsBuilder.setMandatory(mandatory);
\r
1109 } else if (childNode instanceof When_stmtContext) {
\r
1110 constraintsBuilder.addWhenCondition(stringFromNode(childNode));
\r