Merge "removed dead code that was causing a warning"
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / model / parser / util / YangModelBuilderHelper.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\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/epl-v10.html\r
7  */\r
8 package org.opendaylight.controller.model.parser.util;\r
9 \r
10 import java.net.URI;\r
11 import java.util.ArrayList;\r
12 import java.util.Date;\r
13 import java.util.List;\r
14 import java.util.Stack;\r
15 \r
16 import org.antlr.v4.runtime.tree.ParseTree;\r
17 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bit_stmtContext;\r
18 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bits_specificationContext;\r
19 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Decimal64_specificationContext;\r
20 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;\r
21 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_specificationContext;\r
22 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_stmtContext;\r
23 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Fraction_digits_stmtContext;\r
24 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Length_stmtContext;\r
25 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Numerical_restrictionsContext;\r
26 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Pattern_stmtContext;\r
27 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Position_stmtContext;\r
28 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Range_stmtContext;\r
29 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;\r
30 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_argContext;\r
31 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;\r
32 import org.opendaylight.controller.antlrv4.code.gen.YangParser.StringContext;\r
33 import org.opendaylight.controller.antlrv4.code.gen.YangParser.String_restrictionsContext;\r
34 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;\r
35 import org.opendaylight.controller.model.api.type.BitsTypeDefinition;\r
36 import org.opendaylight.controller.model.api.type.EnumTypeDefinition;\r
37 import org.opendaylight.controller.model.api.type.LengthConstraint;\r
38 import org.opendaylight.controller.model.api.type.PatternConstraint;\r
39 import org.opendaylight.controller.model.api.type.RangeConstraint;\r
40 import org.opendaylight.controller.model.api.type.BitsTypeDefinition.Bit;\r
41 import org.opendaylight.controller.model.parser.api.SchemaNodeBuilder;\r
42 import org.opendaylight.controller.model.util.BaseConstraints;\r
43 import org.opendaylight.controller.model.util.UnknownType;\r
44 import org.opendaylight.controller.yang.common.QName;\r
45 import org.opendaylight.controller.yang.model.api.ExtensionDefinition;\r
46 import org.opendaylight.controller.yang.model.api.SchemaPath;\r
47 import org.opendaylight.controller.yang.model.api.Status;\r
48 import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
49 import org.slf4j.Logger;\r
50 import org.slf4j.LoggerFactory;\r
51 \r
52 public class YangModelBuilderHelper {\r
53 \r
54     private static final Logger logger = LoggerFactory\r
55             .getLogger(YangModelBuilderHelper.class);\r
56 \r
57     /**\r
58      * Get 'description', 'reference' and 'status' statements and fill in\r
59      * builder.\r
60      * \r
61      * @param ctx\r
62      *            context to parse\r
63      * @param builder\r
64      *            builder to fill in with parsed statements\r
65      */\r
66     public static void parseSchemaNodeArgs(ParseTree ctx,\r
67             SchemaNodeBuilder builder) {\r
68         for (int i = 0; i < ctx.getChildCount(); i++) {\r
69             ParseTree child = ctx.getChild(i);\r
70             if (child instanceof Description_stmtContext) {\r
71                 String desc = stringFromNode(child);\r
72                 builder.setDescription(desc);\r
73             } else if (child instanceof Reference_stmtContext) {\r
74                 String ref = stringFromNode(child);\r
75                 builder.setReference(ref);\r
76             } else if (child instanceof Status_stmtContext) {\r
77                 Status status = getStatus((Status_stmtContext) child);\r
78                 builder.setStatus(status);\r
79             }\r
80         }\r
81     }\r
82 \r
83     public static SchemaPath getActualSchemaPath(Stack<String> actualPath,\r
84             URI namespace, Date revision, String prefix) {\r
85         final List<QName> path = new ArrayList<QName>();\r
86         QName qname;\r
87         for (String pathElement : actualPath) {\r
88             qname = new QName(namespace, revision, prefix, pathElement);\r
89             path.add(qname);\r
90         }\r
91         return new SchemaPath(path, true);\r
92     }\r
93 \r
94     public static Status getStatus(Status_stmtContext ctx) {\r
95         for (int i = 0; i < ctx.getChildCount(); i++) {\r
96             ParseTree statusArg = ctx.getChild(i);\r
97             if (statusArg instanceof Status_argContext) {\r
98                 String statusArgStr = stringFromNode(statusArg);\r
99                 if (statusArgStr.equals("current")) {\r
100                     return Status.CURRENT;\r
101                 } else if (statusArgStr.equals("deprecated")) {\r
102                     return Status.DEPRECATED;\r
103                 } else if (statusArgStr.equals("obsolete")) {\r
104                     return Status.OBSOLOTE;\r
105                 } else {\r
106                     logger.warn("Invalid 'status' statement: " + statusArgStr);\r
107                 }\r
108             }\r
109         }\r
110         return null;\r
111     }\r
112 \r
113     public static String stringFromNode(final ParseTree treeNode) {\r
114         final String result = "";\r
115         for (int j = 0; j < treeNode.getChildCount(); ++j) {\r
116             if (treeNode.getChild(j) instanceof StringContext) {\r
117                 final StringContext context = (StringContext) treeNode\r
118                         .getChild(j);\r
119 \r
120                 if (context != null) {\r
121                     return context.getChild(0).getText().replace("\"", "");\r
122                 }\r
123             }\r
124         }\r
125         return result;\r
126     }\r
127 \r
128     public static SchemaPath parsePath(String augmentPath) {\r
129         boolean absolute = augmentPath.startsWith("/");\r
130         String[] splittedPath = augmentPath.split("/");\r
131         List<QName> path = new ArrayList<QName>();\r
132         QName name;\r
133         for (String pathElement : splittedPath) {\r
134             if (pathElement.length() > 0) {\r
135                 String[] splittedElement = pathElement.split(":");\r
136                 if (splittedElement.length == 1) {\r
137                     name = new QName(null, null, null, splittedElement[0]);\r
138                 } else {\r
139                     name = new QName(null, null, splittedElement[0],\r
140                             splittedElement[1]);\r
141                 }\r
142                 path.add(name);\r
143             }\r
144         }\r
145         return new SchemaPath(path, absolute);\r
146     }\r
147 \r
148     public static List<QName> createListKey(String keyDefinition,\r
149             URI namespace, Date revision, String prefix) {\r
150         List<QName> key = new ArrayList<QName>();\r
151         String[] splittedKey = keyDefinition.split(" ");\r
152 \r
153         QName qname = null;\r
154         for (String keyElement : splittedKey) {\r
155             if (keyElement.length() != 0) {\r
156                 qname = new QName(namespace, revision, prefix, keyElement);\r
157                 key.add(qname);\r
158             }\r
159         }\r
160         return key;\r
161     }\r
162 \r
163     public static TypeDefinition<?> parseUnknownType(QName typedefQName,\r
164             ParseTree ctx) {\r
165         UnknownType.Builder ut = new UnknownType.Builder(typedefQName);\r
166         for (int i = 0; i < ctx.getChildCount(); i++) {\r
167             ParseTree child = ctx.getChild(i);\r
168             if (child instanceof Type_body_stmtsContext) {\r
169                 for (int j = 0; j < child.getChildCount(); j++) {\r
170                     ParseTree typeBodyChild = child.getChild(j);\r
171                     // NUMERICAL RESTRICTIONS\r
172                     if (typeBodyChild instanceof Numerical_restrictionsContext) {\r
173                         for (int k = 0; k < typeBodyChild.getChildCount(); k++) {\r
174                             ParseTree numRestrictionsChild = typeBodyChild\r
175                                     .getChild(k);\r
176                             if (numRestrictionsChild instanceof Range_stmtContext) {\r
177                                 List<RangeConstraint> ranges = parseRangeConstraints((Range_stmtContext) numRestrictionsChild);\r
178                                 ut.rangeStatements(ranges);\r
179                             }\r
180                         }\r
181                         // STRING RESTRICTIONS\r
182                     } else if (typeBodyChild instanceof String_restrictionsContext) {\r
183                         List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();\r
184                         List<LengthConstraint> lengths = new ArrayList<LengthConstraint>();\r
185                         for (int k = 0; k < typeBodyChild.getChildCount(); k++) {\r
186                             ParseTree stringRestrictionsChild = typeBodyChild\r
187                                     .getChild(k);\r
188                             if (stringRestrictionsChild instanceof Pattern_stmtContext) {\r
189                                 patterns.add(parsePatternConstraint((Pattern_stmtContext) stringRestrictionsChild));\r
190                             } else if (stringRestrictionsChild instanceof Length_stmtContext) {\r
191                                 lengths = parseLengthConstraints((Length_stmtContext) stringRestrictionsChild);\r
192                             }\r
193                         }\r
194                         ut.patterns(patterns);\r
195                         ut.lengthStatements(lengths);\r
196                         // DECIMAL64\r
197                     } else if (typeBodyChild instanceof Decimal64_specificationContext) {\r
198                         for (int k = 0; k < typeBodyChild.getChildCount(); k++) {\r
199                             ParseTree fdChild = typeBodyChild.getChild(k);\r
200                             if (fdChild instanceof Fraction_digits_stmtContext) {\r
201                                 // TODO: implement fraction digits\r
202                                 // return\r
203                                 // Integer.valueOf(stringFromNode(fdChild));\r
204                             }\r
205                         }\r
206                     }\r
207 \r
208                 }\r
209             }\r
210         }\r
211         return ut.build();\r
212     }\r
213 \r
214     public static List<RangeConstraint> getRangeConstraints(\r
215             Type_body_stmtsContext ctx) {\r
216         List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();\r
217         for (int j = 0; j < ctx.getChildCount(); j++) {\r
218             ParseTree numRestrChild = ctx.getChild(j);\r
219             if (numRestrChild instanceof Numerical_restrictionsContext) {\r
220                 for (int k = 0; k < numRestrChild.getChildCount(); k++) {\r
221                     ParseTree rangeChild = numRestrChild.getChild(k);\r
222                     if (rangeChild instanceof Range_stmtContext) {\r
223                         rangeConstraints\r
224                                 .addAll(parseRangeConstraints((Range_stmtContext) rangeChild));\r
225                     }\r
226                 }\r
227             }\r
228         }\r
229         return rangeConstraints;\r
230     }\r
231 \r
232     private static List<RangeConstraint> parseRangeConstraints(\r
233             Range_stmtContext ctx) {\r
234         List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();\r
235         String description = null;\r
236         String reference = null;\r
237 \r
238         for (int i = 0; i < ctx.getChildCount(); i++) {\r
239             ParseTree child = ctx.getChild(i);\r
240             if (child instanceof Description_stmtContext) {\r
241                 description = stringFromNode(child);\r
242             } else if (child instanceof Reference_stmtContext) {\r
243                 reference = stringFromNode(child);\r
244             }\r
245         }\r
246 \r
247         String rangeStr = stringFromNode(ctx);\r
248         String trimmed = rangeStr.replace(" ", "");\r
249         String[] splittedRange = trimmed.split("\\|");\r
250         for (String rangeDef : splittedRange) {\r
251             // TODO: this needs to be refactored, because valid range can be\r
252             // also defined as "1..max"\r
253             String[] splittedRangeDef = rangeDef.split("\\.\\.");\r
254             Long min = Long.valueOf(splittedRangeDef[0]);\r
255             Long max = Long.valueOf(splittedRangeDef[1]);\r
256             RangeConstraint range = BaseConstraints.rangeConstraint(min, max,\r
257                     description, reference);\r
258             rangeConstraints.add(range);\r
259         }\r
260 \r
261         return rangeConstraints;\r
262     }\r
263 \r
264     public static Integer getFractionDigits(Type_body_stmtsContext ctx) {\r
265         for (int j = 0; j < ctx.getChildCount(); j++) {\r
266             ParseTree dec64specChild = ctx.getChild(j);\r
267             if (dec64specChild instanceof Decimal64_specificationContext) {\r
268                 for (int k = 0; k < dec64specChild.getChildCount(); k++) {\r
269                     ParseTree fdChild = dec64specChild.getChild(k);\r
270                     if (fdChild instanceof Fraction_digits_stmtContext) {\r
271                         return Integer.valueOf(stringFromNode(fdChild));\r
272                     }\r
273                 }\r
274             }\r
275         }\r
276         return null;\r
277     }\r
278 \r
279     public static List<EnumTypeDefinition.EnumPair> getEnumConstants(\r
280             Type_body_stmtsContext ctx) {\r
281         List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<EnumTypeDefinition.EnumPair>();\r
282 \r
283         out: for (int j = 0; j < ctx.getChildCount(); j++) {\r
284             ParseTree enumSpecChild = ctx.getChild(j);\r
285             if (enumSpecChild instanceof Enum_specificationContext) {\r
286                 for (int k = 0; k < enumSpecChild.getChildCount(); k++) {\r
287                     ParseTree enumChild = enumSpecChild.getChild(k);\r
288                     if (enumChild instanceof Enum_stmtContext) {\r
289                         enumConstants.add(createEnumPair(\r
290                                 (Enum_stmtContext) enumChild, k));\r
291                         if (k == enumSpecChild.getChildCount() - 1) {\r
292                             break out;\r
293                         }\r
294                     }\r
295                 }\r
296             }\r
297         }\r
298         return enumConstants;\r
299     }\r
300 \r
301     private static EnumTypeDefinition.EnumPair createEnumPair(\r
302             Enum_stmtContext ctx, final int value) {\r
303         final String name = stringFromNode(ctx);\r
304         return new EnumTypeDefinition.EnumPair() {\r
305 \r
306             @Override\r
307             public QName getQName() {\r
308                 // TODO Auto-generated method stub\r
309                 return null;\r
310             }\r
311 \r
312             @Override\r
313             public SchemaPath getPath() {\r
314                 // TODO Auto-generated method stub\r
315                 return null;\r
316             }\r
317 \r
318             @Override\r
319             public String getDescription() {\r
320                 // TODO Auto-generated method stub\r
321                 return null;\r
322             }\r
323 \r
324             @Override\r
325             public String getReference() {\r
326                 // TODO Auto-generated method stub\r
327                 return null;\r
328             }\r
329 \r
330             @Override\r
331             public Status getStatus() {\r
332                 // TODO Auto-generated method stub\r
333                 return null;\r
334             }\r
335 \r
336             @Override\r
337             public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
338                 // TODO Auto-generated method stub\r
339                 return null;\r
340             }\r
341 \r
342             @Override\r
343             public String getName() {\r
344                 return name;\r
345             }\r
346 \r
347             @Override\r
348             public Integer getValue() {\r
349                 return value;\r
350             }\r
351 \r
352             @Override\r
353             public String toString() {\r
354                 return EnumTypeDefinition.EnumPair.class.getSimpleName()\r
355                         + "[name=" + name + ", value=" + value + "]";\r
356             }\r
357         };\r
358     }\r
359 \r
360     public static List<LengthConstraint> getLengthConstraints(\r
361             Type_body_stmtsContext ctx) {\r
362         List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();\r
363         for (int j = 0; j < ctx.getChildCount(); j++) {\r
364             ParseTree stringRestrChild = ctx.getChild(j);\r
365             if (stringRestrChild instanceof String_restrictionsContext) {\r
366                 for (int k = 0; k < stringRestrChild.getChildCount(); k++) {\r
367                     ParseTree lengthChild = stringRestrChild.getChild(k);\r
368                     if (lengthChild instanceof Length_stmtContext) {\r
369                         lengthConstraints\r
370                                 .addAll(parseLengthConstraints((Length_stmtContext) lengthChild));\r
371                     }\r
372                 }\r
373             }\r
374         }\r
375         return lengthConstraints;\r
376     }\r
377 \r
378     private static List<LengthConstraint> parseLengthConstraints(\r
379             Length_stmtContext ctx) {\r
380         List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();\r
381         String description = null;\r
382         String reference = null;\r
383 \r
384         for (int i = 0; i < ctx.getChildCount(); i++) {\r
385             ParseTree child = ctx.getChild(i);\r
386             if (child instanceof Description_stmtContext) {\r
387                 description = stringFromNode(child);\r
388             } else if (child instanceof Reference_stmtContext) {\r
389                 reference = stringFromNode(child);\r
390             }\r
391         }\r
392 \r
393         String lengthStr = stringFromNode(ctx);\r
394         String trimmed = lengthStr.replace(" ", "");\r
395         String[] splittedRange = trimmed.split("\\|");\r
396         for (String rangeDef : splittedRange) {\r
397             // TODO: this needs to be refactored, because valid length can be\r
398             // also defined as "1"\r
399             String[] splittedRangeDef = rangeDef.split("\\.\\.");\r
400             Long min = Long.valueOf(splittedRangeDef[0]);\r
401             Long max = Long.valueOf(splittedRangeDef[1]);\r
402             LengthConstraint range = BaseConstraints.lengthConstraint(min, max,\r
403                     description, reference);\r
404             lengthConstraints.add(range);\r
405         }\r
406 \r
407         return lengthConstraints;\r
408     }\r
409 \r
410     public static List<PatternConstraint> getPatternConstraint(\r
411             Type_body_stmtsContext ctx) {\r
412         List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();\r
413 \r
414         out: for (int j = 0; j < ctx.getChildCount(); j++) {\r
415             ParseTree stringRestrChild = ctx.getChild(j);\r
416             if (stringRestrChild instanceof String_restrictionsContext) {\r
417                 for (int k = 0; k < stringRestrChild.getChildCount(); k++) {\r
418                     ParseTree lengthChild = stringRestrChild.getChild(k);\r
419                     if (lengthChild instanceof Pattern_stmtContext) {\r
420                         patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild));\r
421                         if (k == lengthChild.getChildCount() - 1) {\r
422                             break out;\r
423                         }\r
424                     }\r
425                 }\r
426             }\r
427         }\r
428         return patterns;\r
429     }\r
430 \r
431     /**\r
432      * Internal helper method.\r
433      * \r
434      * @param ctx\r
435      *            pattern context\r
436      * @return PatternConstraint object\r
437      */\r
438     private static PatternConstraint parsePatternConstraint(\r
439             Pattern_stmtContext ctx) {\r
440         String description = null;\r
441         String reference = null;\r
442         for (int i = 0; i < ctx.getChildCount(); i++) {\r
443             ParseTree child = ctx.getChild(i);\r
444             if (child instanceof Description_stmtContext) {\r
445                 description = stringFromNode(child);\r
446             } else if (child instanceof Reference_stmtContext) {\r
447                 reference = stringFromNode(child);\r
448             }\r
449         }\r
450         String pattern = stringFromNode(ctx);\r
451         return BaseConstraints.patternConstraint(pattern, description,\r
452                 reference);\r
453     }\r
454 \r
455     public static List<BitsTypeDefinition.Bit> getBits(\r
456             Type_body_stmtsContext ctx, Stack<String> actualPath,\r
457             URI namespace, Date revision, String prefix) {\r
458         List<BitsTypeDefinition.Bit> bits = new ArrayList<BitsTypeDefinition.Bit>();\r
459         for (int j = 0; j < ctx.getChildCount(); j++) {\r
460             ParseTree bitsSpecChild = ctx.getChild(j);\r
461             if (bitsSpecChild instanceof Bits_specificationContext) {\r
462                 for (int k = 0; k < bitsSpecChild.getChildCount(); k++) {\r
463                     ParseTree bitChild = bitsSpecChild.getChild(k);\r
464                     if (bitChild instanceof Bit_stmtContext) {\r
465                         bits.add(parseBit((Bit_stmtContext) bitChild,\r
466                                 actualPath, namespace, revision, prefix));\r
467                     }\r
468                 }\r
469             }\r
470         }\r
471         return bits;\r
472     }\r
473 \r
474     private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx,\r
475             Stack<String> actualPath, final URI namespace, final Date revision,\r
476             final String prefix) {\r
477         String name = stringFromNode(ctx);\r
478         final QName qname = new QName(namespace, revision, prefix, name);\r
479         Long position = null;\r
480 \r
481         String description = null;\r
482         String reference = null;\r
483         Status status = Status.CURRENT;\r
484 \r
485         Stack<String> bitPath = new Stack<String>();\r
486         bitPath.addAll(actualPath);\r
487         bitPath.add(name);\r
488 \r
489         SchemaPath schemaPath = getActualSchemaPath(bitPath, namespace,\r
490                 revision, prefix);\r
491 \r
492         for (int i = 0; i < ctx.getChildCount(); i++) {\r
493             ParseTree child = ctx.getChild(i);\r
494             if (child instanceof Position_stmtContext) {\r
495                 String positionStr = stringFromNode(child);\r
496                 position = Long.valueOf(positionStr);\r
497                 if (position < 0 || position > 4294967295L) {\r
498                     throw new IllegalArgumentException(\r
499                             "position value MUST be in the range 0 to 4294967295, but was: "\r
500                                     + position);\r
501                 }\r
502             } else if (child instanceof Description_stmtContext) {\r
503                 description = stringFromNode(child);\r
504             } else if (child instanceof Reference_stmtContext) {\r
505                 reference = stringFromNode(child);\r
506             } else if (child instanceof Status_stmtContext) {\r
507                 status = getStatus((Status_stmtContext) child);\r
508             }\r
509         }\r
510 \r
511         // TODO: extensionDefinitions\r
512         return createBit(qname, schemaPath, description, reference, status,\r
513                 null, position);\r
514     }\r
515 \r
516     private static BitsTypeDefinition.Bit createBit(final QName qname,\r
517             final SchemaPath schemaPath, final String description,\r
518             final String reference, final Status status,\r
519             final List<ExtensionDefinition> extensionDefinitions,\r
520             final Long position) {\r
521         return new BitsTypeDefinition.Bit() {\r
522 \r
523             @Override\r
524             public QName getQName() {\r
525                 return qname;\r
526             }\r
527 \r
528             @Override\r
529             public SchemaPath getPath() {\r
530                 return schemaPath;\r
531             }\r
532 \r
533             @Override\r
534             public String getDescription() {\r
535                 return description;\r
536             }\r
537 \r
538             @Override\r
539             public String getReference() {\r
540                 return reference;\r
541             }\r
542 \r
543             @Override\r
544             public Status getStatus() {\r
545                 return status;\r
546             }\r
547 \r
548             @Override\r
549             public List<ExtensionDefinition> getExtensionSchemaNodes() {\r
550                 return extensionDefinitions;\r
551             }\r
552 \r
553             @Override\r
554             public Long getPosition() {\r
555                 return position;\r
556             }\r
557 \r
558             @Override\r
559             public String getName() {\r
560                 return qname.getLocalName();\r
561             }\r
562 \r
563             @Override\r
564             public int hashCode() {\r
565                 final int prime = 31;\r
566                 int result = 1;\r
567                 result = prime * result\r
568                         + ((qname == null) ? 0 : qname.hashCode());\r
569                 result = prime * result\r
570                         + ((schemaPath == null) ? 0 : schemaPath.hashCode());\r
571                 result = prime * result\r
572                         + ((description == null) ? 0 : description.hashCode());\r
573                 result = prime * result\r
574                         + ((reference == null) ? 0 : reference.hashCode());\r
575                 result = prime * result\r
576                         + ((status == null) ? 0 : status.hashCode());\r
577                 result = prime * result\r
578                         + ((position == null) ? 0 : position.hashCode());\r
579                 result = prime\r
580                         * result\r
581                         + ((extensionDefinitions == null) ? 0\r
582                                 : extensionDefinitions.hashCode());\r
583                 return result;\r
584             }\r
585 \r
586             @Override\r
587             public boolean equals(Object obj) {\r
588                 if (this == obj) {\r
589                     return true;\r
590                 }\r
591                 if (obj == null) {\r
592                     return false;\r
593                 }\r
594                 if (getClass() != obj.getClass()) {\r
595                     return false;\r
596                 }\r
597                 Bit other = (Bit) obj;\r
598                 if (qname == null) {\r
599                     if (other.getQName() != null) {\r
600                         return false;\r
601                     }\r
602                 } else if (!qname.equals(other.getQName())) {\r
603                     return false;\r
604                 }\r
605                 if (schemaPath == null) {\r
606                     if (other.getPath() != null) {\r
607                         return false;\r
608                     }\r
609                 } else if (!schemaPath.equals(other.getPath())) {\r
610                     return false;\r
611                 }\r
612                 if (description == null) {\r
613                     if (other.getDescription() != null) {\r
614                         return false;\r
615                     }\r
616                 } else if (!description.equals(other.getDescription())) {\r
617                     return false;\r
618                 }\r
619                 if (reference == null) {\r
620                     if (other.getReference() != null) {\r
621                         return false;\r
622                     }\r
623                 } else if (!reference.equals(other.getReference())) {\r
624                     return false;\r
625                 }\r
626                 if (status == null) {\r
627                     if (other.getStatus() != null) {\r
628                         return false;\r
629                     }\r
630                 } else if (!status.equals(other.getStatus())) {\r
631                     return false;\r
632                 }\r
633                 if (extensionDefinitions == null) {\r
634                     if (other.getExtensionSchemaNodes() != null) {\r
635                         return false;\r
636                     }\r
637                 } else if (!extensionDefinitions.equals(other\r
638                         .getExtensionSchemaNodes())) {\r
639                     return false;\r
640                 }\r
641                 if (position == null) {\r
642                     if (other.getPosition() != null) {\r
643                         return false;\r
644                     }\r
645                 } else if (!position.equals(other.getPosition())) {\r
646                     return false;\r
647                 }\r
648                 return true;\r
649             }\r
650 \r
651             @Override\r
652             public String toString() {\r
653                 return Bit.class.getSimpleName() + "[name="\r
654                         + qname.getLocalName() + ", position=" + position + "]";\r
655             }\r
656         };\r
657     }\r
658 \r
659 }\r