d49a6b799ed63f1a54fedee8ab2dc200c3a54a4a
[smo/teiv.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2024 Ericsson
4  *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21 package org.oran.smo.yangtools.parser.model.statements.yang;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.oran.smo.yangtools.parser.model.statements.StatementModuleAndName;
33
34 /**
35  * A class containing a number of constants in relation to the YANG core language.
36  *
37  * @author Mark Hollmann
38  */
39 public abstract class CY {
40
41     /*
42      * ----------- core language statement names ---------------
43      */
44
45     public static final String ACTION = "action";
46     public static final String ANYDATA = "anydata";
47     public static final String ANYXML = "anyxml";
48     public static final String ARGUMENT = "argument";
49     public static final String AUGMENT = "augment";
50     public static final String BASE = "base";
51     public static final String BELONGS_TO = "belongs-to";
52     public static final String BIT = "bit";
53     public static final String CASE = "case";
54     public static final String CHOICE = "choice";
55     public static final String CONFIG = "config";
56     public static final String CONTACT = "contact";
57     public static final String CONTAINER = "container";
58     public static final String DEFAULT = "default";
59     public static final String DESCRIPTION = "description";
60     public static final String DEVIATE = "deviate";
61     public static final String DEVIATION = "deviation";
62     public static final String ENUM = "enum";
63     public static final String ERROR_APP_TAG = "error-app-tag";
64     public static final String ERROR_MESSAGE = "error-message";
65     public static final String EXTENSION = "extension";
66     public static final String FEATURE = "feature";
67     public static final String FRACTION_DIGITS = "fraction-digits";
68     public static final String GROUPING = "grouping";
69     public static final String IDENTITY = "identity";
70     public static final String IF_FEATURE = "if-feature";
71     public static final String IMPORT = "import";
72     public static final String INCLUDE = "include";
73     public static final String INPUT = "input";
74     public static final String KEY = "key";
75     public static final String LEAF = "leaf";
76     public static final String LEAF_LIST = "leaf-list";
77     public static final String LENGTH = "length";
78     public static final String LIST = "list";
79     public static final String MANDATORY = "mandatory";
80     public static final String MAX_ELEMENTS = "max-elements";
81     public static final String MIN_ELEMENTS = "min-elements";
82     public static final String MODIFIER = "modifier";
83     public static final String MODULE = "module";
84     public static final String MUST = "must";
85     public static final String NAMESPACE = "namespace";
86     public static final String NOTIFICATION = "notification";
87     public static final String ORDERED_BY = "ordered-by";
88     public static final String ORGANIZATION = "organization";
89     public static final String OUTPUT = "output";
90     public static final String PATH = "path";
91     public static final String PATTERN = "pattern";
92     public static final String POSITION = "position";
93     public static final String PREFIX = "prefix";
94     public static final String PRESENCE = "presence";
95     public static final String RANGE = "range";
96     public static final String REFERENCE = "reference";
97     public static final String REFINE = "refine";
98     public static final String REQUIRE_INSTANCE = "require-instance";
99     public static final String REVISION = "revision";
100     public static final String REVISION_DATE = "revision-date";
101     public static final String RPC = "rpc";
102     public static final String STATUS = "status";
103     public static final String SUBMODULE = "submodule";
104     public static final String TYPE = "type";
105     public static final String TYPEDEF = "typedef";
106     public static final String UNIQUE = "unique";
107     public static final String UNITS = "units";
108     public static final String USES = "uses";
109     public static final String VALUE = "value";
110     public static final String WHEN = "when";
111     public static final String YANG_VERSION = "yang-version";
112     public static final String YIN_ELEMENT = "yin-element";
113
114     public static final Set<String> ALL_YANG_CORE_STATEMENT_NAMES = new HashSet<>(Arrays.asList(ACTION, ANYDATA, ANYXML,
115             ARGUMENT, AUGMENT, BASE, BELONGS_TO, BIT, CASE, CHOICE, CONFIG, CONTACT, CONTAINER, DEFAULT, DESCRIPTION,
116             DEVIATE, DEVIATION, ENUM, ERROR_APP_TAG, ERROR_MESSAGE, EXTENSION, FEATURE, FRACTION_DIGITS, GROUPING, IDENTITY,
117             IF_FEATURE, IMPORT, INCLUDE, INPUT, KEY, LEAF, LEAF_LIST, LENGTH, LIST, MANDATORY, MAX_ELEMENTS, MIN_ELEMENTS,
118             MODIFIER, MODULE, MUST, NAMESPACE, NOTIFICATION, ORDERED_BY, ORGANIZATION, OUTPUT, PATH, PATTERN, POSITION,
119             PREFIX, PRESENCE, RANGE, REFERENCE, REFINE, REQUIRE_INSTANCE, REVISION, REVISION_DATE, RPC, STATUS, SUBMODULE,
120             TYPE, TYPEDEF, UNIQUE, UNITS, USES, VALUE, WHEN, YANG_VERSION, YIN_ELEMENT));
121
122     /**
123      * Returns whether the supplied statement name is defined by the Yang core language.
124      */
125     public static boolean isYangCoreStatementName(final String statementName) {
126         return ALL_YANG_CORE_STATEMENT_NAMES.contains(statementName);
127     }
128
129     /*
130      * --------- core YANG statements encoded as module-name/statements -------------
131      */
132
133     /**
134      * There is no module name for YANG. The name chosen here is a fictitious, but illegal,
135      * module name (as it contains a space character), to avoid a potential clash with an actual,
136      * real, YANG module name.
137      */
138     public static final String YANG_CORE_MODULE_NAME = "YANG CORE";
139
140     public static final StatementModuleAndName STMT_ACTION = new StatementModuleAndName(YANG_CORE_MODULE_NAME, ACTION);
141     public static final StatementModuleAndName STMT_ANYDATA = new StatementModuleAndName(YANG_CORE_MODULE_NAME, ANYDATA);
142     public static final StatementModuleAndName STMT_ANYXML = new StatementModuleAndName(YANG_CORE_MODULE_NAME, ANYXML);
143     public static final StatementModuleAndName STMT_ARGUMENT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, ARGUMENT);
144     public static final StatementModuleAndName STMT_AUGMENT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, AUGMENT);
145     public static final StatementModuleAndName STMT_BASE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, BASE);
146     public static final StatementModuleAndName STMT_BELONGS_TO = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
147             BELONGS_TO);
148     public static final StatementModuleAndName STMT_BIT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, BIT);
149     public static final StatementModuleAndName STMT_CASE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, CASE);
150     public static final StatementModuleAndName STMT_CHOICE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, CHOICE);
151     public static final StatementModuleAndName STMT_CONFIG = new StatementModuleAndName(YANG_CORE_MODULE_NAME, CONFIG);
152     public static final StatementModuleAndName STMT_CONTACT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, CONTACT);
153     public static final StatementModuleAndName STMT_CONTAINER = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
154             CONTAINER);
155     public static final StatementModuleAndName STMT_DEFAULT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, DEFAULT);
156     public static final StatementModuleAndName STMT_DESCRIPTION = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
157             DESCRIPTION);
158     public static final StatementModuleAndName STMT_DEVIATE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, DEVIATE);
159     public static final StatementModuleAndName STMT_DEVIATION = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
160             DEVIATION);
161     public static final StatementModuleAndName STMT_ENUM = new StatementModuleAndName(YANG_CORE_MODULE_NAME, ENUM);
162     public static final StatementModuleAndName STMT_ERROR_APP_TAG = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
163             ERROR_APP_TAG);
164     public static final StatementModuleAndName STMT_ERROR_MESSAGE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
165             ERROR_MESSAGE);
166     public static final StatementModuleAndName STMT_EXTENSION = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
167             EXTENSION);
168     public static final StatementModuleAndName STMT_FEATURE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, FEATURE);
169     public static final StatementModuleAndName STMT_FRACTION_DIGITS = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
170             FRACTION_DIGITS);
171     public static final StatementModuleAndName STMT_GROUPING = new StatementModuleAndName(YANG_CORE_MODULE_NAME, GROUPING);
172     public static final StatementModuleAndName STMT_IDENTITY = new StatementModuleAndName(YANG_CORE_MODULE_NAME, IDENTITY);
173     public static final StatementModuleAndName STMT_IF_FEATURE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
174             IF_FEATURE);
175     public static final StatementModuleAndName STMT_IMPORT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, IMPORT);
176     public static final StatementModuleAndName STMT_INCLUDE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, INCLUDE);
177     public static final StatementModuleAndName STMT_INPUT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, INPUT);
178     public static final StatementModuleAndName STMT_KEY = new StatementModuleAndName(YANG_CORE_MODULE_NAME, KEY);
179     public static final StatementModuleAndName STMT_LEAF = new StatementModuleAndName(YANG_CORE_MODULE_NAME, LEAF);
180     public static final StatementModuleAndName STMT_LEAF_LIST = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
181             LEAF_LIST);
182     public static final StatementModuleAndName STMT_LENGTH = new StatementModuleAndName(YANG_CORE_MODULE_NAME, LENGTH);
183     public static final StatementModuleAndName STMT_LIST = new StatementModuleAndName(YANG_CORE_MODULE_NAME, LIST);
184     public static final StatementModuleAndName STMT_MANDATORY = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
185             MANDATORY);
186     public static final StatementModuleAndName STMT_MAX_ELEMENTS = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
187             MAX_ELEMENTS);
188     public static final StatementModuleAndName STMT_MIN_ELEMENTS = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
189             MIN_ELEMENTS);
190     public static final StatementModuleAndName STMT_MODIFIER = new StatementModuleAndName(YANG_CORE_MODULE_NAME, MODIFIER);
191     public static final StatementModuleAndName STMT_MODULE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, MODULE);
192     public static final StatementModuleAndName STMT_MUST = new StatementModuleAndName(YANG_CORE_MODULE_NAME, MUST);
193     public static final StatementModuleAndName STMT_NAMESPACE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
194             NAMESPACE);
195     public static final StatementModuleAndName STMT_NOTIFICATION = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
196             NOTIFICATION);
197     public static final StatementModuleAndName STMT_ORDERED_BY = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
198             ORDERED_BY);
199     public static final StatementModuleAndName STMT_ORGANIZATION = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
200             ORGANIZATION);
201     public static final StatementModuleAndName STMT_OUTPUT = new StatementModuleAndName(YANG_CORE_MODULE_NAME, OUTPUT);
202     public static final StatementModuleAndName STMT_PATH = new StatementModuleAndName(YANG_CORE_MODULE_NAME, PATH);
203     public static final StatementModuleAndName STMT_PATTERN = new StatementModuleAndName(YANG_CORE_MODULE_NAME, PATTERN);
204     public static final StatementModuleAndName STMT_POSITION = new StatementModuleAndName(YANG_CORE_MODULE_NAME, POSITION);
205     public static final StatementModuleAndName STMT_PREFIX = new StatementModuleAndName(YANG_CORE_MODULE_NAME, PREFIX);
206     public static final StatementModuleAndName STMT_PRESENCE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, PRESENCE);
207     public static final StatementModuleAndName STMT_RANGE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, RANGE);
208     public static final StatementModuleAndName STMT_REFERENCE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
209             REFERENCE);
210     public static final StatementModuleAndName STMT_REFINE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, REFINE);
211     public static final StatementModuleAndName STMT_REQUIRE_INSTANCE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
212             REQUIRE_INSTANCE);
213     public static final StatementModuleAndName STMT_REVISION = new StatementModuleAndName(YANG_CORE_MODULE_NAME, REVISION);
214     public static final StatementModuleAndName STMT_REVISION_DATE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
215             REVISION_DATE);
216     public static final StatementModuleAndName STMT_RPC = new StatementModuleAndName(YANG_CORE_MODULE_NAME, RPC);
217     public static final StatementModuleAndName STMT_STATUS = new StatementModuleAndName(YANG_CORE_MODULE_NAME, STATUS);
218     public static final StatementModuleAndName STMT_SUBMODULE = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
219             SUBMODULE);
220     public static final StatementModuleAndName STMT_TYPE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, TYPE);
221     public static final StatementModuleAndName STMT_TYPEDEF = new StatementModuleAndName(YANG_CORE_MODULE_NAME, TYPEDEF);
222     public static final StatementModuleAndName STMT_UNIQUE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, UNIQUE);
223     public static final StatementModuleAndName STMT_UNITS = new StatementModuleAndName(YANG_CORE_MODULE_NAME, UNITS);
224     public static final StatementModuleAndName STMT_USES = new StatementModuleAndName(YANG_CORE_MODULE_NAME, USES);
225     public static final StatementModuleAndName STMT_VALUE = new StatementModuleAndName(YANG_CORE_MODULE_NAME, VALUE);
226     public static final StatementModuleAndName STMT_WHEN = new StatementModuleAndName(YANG_CORE_MODULE_NAME, WHEN);
227     public static final StatementModuleAndName STMT_YANG_VERSION = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
228             YANG_VERSION);
229     public static final StatementModuleAndName STMT_YIN_ELEMENT = new StatementModuleAndName(YANG_CORE_MODULE_NAME,
230             YIN_ELEMENT);
231
232     public static final Set<StatementModuleAndName> ALL_YANG_CORE_STATEMENTS = new HashSet<>(Arrays.asList(STMT_ACTION,
233             STMT_ANYDATA, STMT_ANYXML, STMT_ARGUMENT, STMT_AUGMENT, STMT_BASE, STMT_BELONGS_TO, STMT_BIT, STMT_CASE,
234             STMT_CHOICE, STMT_CONFIG, STMT_CONTACT, STMT_CONTAINER, STMT_DEFAULT, STMT_DESCRIPTION, STMT_DEVIATE,
235             STMT_DEVIATION, STMT_ENUM, STMT_ERROR_APP_TAG, STMT_ERROR_MESSAGE, STMT_EXTENSION, STMT_FEATURE,
236             STMT_FRACTION_DIGITS, STMT_GROUPING, STMT_IDENTITY, STMT_IF_FEATURE, STMT_IMPORT, STMT_INCLUDE, STMT_INPUT,
237             STMT_KEY, STMT_LEAF, STMT_LEAF_LIST, STMT_LENGTH, STMT_LIST, STMT_MANDATORY, STMT_MAX_ELEMENTS,
238             STMT_MIN_ELEMENTS, STMT_MODIFIER, STMT_MODULE, STMT_MUST, STMT_NAMESPACE, STMT_NOTIFICATION, STMT_ORDERED_BY,
239             STMT_ORGANIZATION, STMT_OUTPUT, STMT_PATH, STMT_PATTERN, STMT_POSITION, STMT_PREFIX, STMT_PRESENCE, STMT_RANGE,
240             STMT_REFERENCE, STMT_REFINE, STMT_REQUIRE_INSTANCE, STMT_REVISION, STMT_REVISION_DATE, STMT_RPC, STMT_STATUS,
241             STMT_SUBMODULE, STMT_TYPE, STMT_TYPEDEF, STMT_UNIQUE, STMT_UNITS, STMT_USES, STMT_VALUE, STMT_WHEN,
242             STMT_YANG_VERSION, STMT_YIN_ELEMENT));
243
244     public static boolean isYangCoreStatement(final StatementModuleAndName statementModuleAndName) {
245         return ALL_YANG_CORE_STATEMENTS.contains(statementModuleAndName);
246     }
247
248     private static final Map<String, StatementModuleAndName> STATEMENT_NAME_TO_STATEMENT = new HashMap<>();
249
250     static {
251         ALL_YANG_CORE_STATEMENTS.forEach(sman -> STATEMENT_NAME_TO_STATEMENT.put(sman.getStatementName(), sman));
252     }
253
254     /**
255      * Given the statement name, will return the corresponding statement. Will return null if the statement
256      * is not one of the core YANG statements.
257      */
258     public static StatementModuleAndName getStatementForName(final String statementName) {
259         return STATEMENT_NAME_TO_STATEMENT.get(statementName);
260     }
261
262     /*
263      * -------- children handling, i.e. the statements that can occur under other statements --------
264      */
265
266     private static final List<String> NO_CHILDREN = Collections.<String> emptyList();
267     private static final List<String> DESCRIPTION_AND_REFERENCE_CHILDREN = Arrays.asList(DESCRIPTION, REFERENCE);
268
269     private static final Map<String, List<String>> optionalSingleChildren = new HashMap<>();
270     private static final Map<String, List<String>> optionalMultipleChildren = new HashMap<>();
271     private static final Map<String, List<String>> mandatorySingleChildren = new HashMap<>();
272     private static final Map<String, List<String>> mandatoryMultipleChildren = new HashMap<>();
273
274     /**
275      * Returns a list of statements that may occur 0..1 under the supplied statement.
276      */
277     public static final List<String> getOptionalSingleChildren(final String forYangCoreStatement) {
278
279         final List<String> result = optionalSingleChildren.get(forYangCoreStatement);
280         /*
281          * We are kind and explicitly allow both 'description' and 'reference' on any statement
282          * that does not have an explicit list of children. According to RFC this isn't really
283          * syntactically correct, but sometimes model designers will add descriptions and
284          * references although they don't have to (or where they shouldn't) and we are lenient
285          * towards that.
286          */
287         return result == null ? DESCRIPTION_AND_REFERENCE_CHILDREN : result;
288     }
289
290     /**
291      * Returns a list of statements that may occur 0..n under the supplied statement.
292      */
293     public static final List<String> getOptionalMultipleChildren(final String forYangCoreStatement) {
294         final List<String> result = optionalMultipleChildren.get(forYangCoreStatement);
295         return result == null ? NO_CHILDREN : result;
296     }
297
298     /**
299      * Returns a list of statements that must occur exactly once under the supplied statement.
300      */
301     public static final List<String> getMandatorySingleChildren(final String forYangCoreStatement) {
302         final List<String> result = mandatorySingleChildren.get(forYangCoreStatement);
303         return result == null ? NO_CHILDREN : result;
304     }
305
306     /**
307      * Returns a list of statements that must occur once or more under the supplied statement.
308      */
309     public static final List<String> getMandatoryMultipleChildren(final String forYangCoreStatement) {
310         final List<String> result = mandatoryMultipleChildren.get(forYangCoreStatement);
311         return result == null ? NO_CHILDREN : result;
312     }
313
314     static {
315
316         /*
317                 +--------------+---------+-------------+
318                 | substatement | section | cardinality |
319                 +--------------+---------+-------------+
320                 | description  | 7.21.3  | 0..1 |
321                 | grouping     | 7.12    | 0..n |
322                 | if-feature   | 7.20.2  | 0..n |
323                 | input        | 7.14.2  | 0..1 |
324                 | output       | 7.14.3  | 0..1 |
325                 | reference    | 7.21.4  | 0..1 |
326                 | status       | 7.21.2  | 0..1 |
327                 | typedef      | 7.3     | 0..n |
328                 +--------------+---------+-------------+
329          */
330         optionalSingleChildren.put(ACTION, Arrays.asList(DESCRIPTION, INPUT, OUTPUT, REFERENCE, STATUS));
331         optionalMultipleChildren.put(ACTION, Arrays.asList(GROUPING, IF_FEATURE, TYPEDEF));
332
333         /*
334                 +--------------+---------+-------------+
335                 | substatement | section | cardinality |
336                 +--------------+---------+-------------+
337                 | config       | 7.21.1  | 0..1 |
338                 | description  | 7.21.3  | 0..1 |
339                 | if-feature   | 7.20.2  | 0..n |
340                 | mandatory    | 7.6.5   | 0..1 |
341                 | must         | 7.5.3   | 0..n |
342                 | reference    | 7.21.4  | 0..1 |
343                 | status       | 7.21.2  | 0..1 |
344                 | when         | 7.21.5  | 0..1 |
345                 +--------------+---------+-------------+
346          */
347         optionalSingleChildren.put(ANYDATA, Arrays.asList(CONFIG, DESCRIPTION, MANDATORY, REFERENCE, STATUS, WHEN));
348         optionalMultipleChildren.put(ANYDATA, Arrays.asList(IF_FEATURE, MUST));
349
350         /*
351                 +--------------+---------+-------------+
352                 | substatement | section | cardinality |
353                 +--------------+---------+-------------+
354                 | config       | 7.21.1  | 0..1 |
355                 | description  | 7.21.3  | 0..1 |
356                 | if-feature   | 7.20.2  | 0..n |
357                 | mandatory    | 7.6.5   | 0..1 |
358                 | must         | 7.5.3   | 0..n |
359                 | reference    | 7.21.4  | 0..1 |
360                 | status       | 7.21.2  | 0..1 |
361                 | when         | 7.21.5  | 0..1 |
362                 +--------------+---------+-------------+
363          */
364         optionalSingleChildren.put(ANYXML, Arrays.asList(CONFIG, DESCRIPTION, MANDATORY, REFERENCE, STATUS, WHEN));
365         optionalMultipleChildren.put(ANYXML, Arrays.asList(IF_FEATURE, MUST));
366
367         /*
368                 +--------------+----------+-------------+
369                 | substatement | section  | cardinality |
370                 +--------------+----------+-------------+
371                 | yin-element  | 7.19.2.2 | 0..1 |
372                 +--------------+----------+-------------+
373          */
374         optionalSingleChildren.put(ARGUMENT, Arrays.asList(DESCRIPTION, REFERENCE, YIN_ELEMENT));
375
376         /*
377                 +--------------+---------+-------------+
378                 | substatement | section | cardinality |
379                 +--------------+---------+-------------+
380                 | action       | 7.15    | 0..n |
381                 | anydata      | 7.10    | 0..n |
382                 | anyxml       | 7.11    | 0..n |
383                 | case         | 7.9.2   | 0..n |
384                 | choice       | 7.9     | 0..n |
385                 | container    | 7.5     | 0..n |
386                 | description  | 7.21.3  | 0..1 |
387                 | if-feature   | 7.20.2  | 0..n |
388                 | leaf         | 7.6     | 0..n |
389                 | leaf-list    | 7.7     | 0..n |
390                 | list         | 7.8     | 0..n |
391                 | notification | 7.16    | 0..n |
392                 | reference    | 7.21.4  | 0..1 |
393                 | status       | 7.21.2  | 0..1 |
394                 | uses         | 7.13    | 0..n |
395                 | when         | 7.21.5  | 0..1 |
396                 +--------------+---------+-------------+
397          */
398         optionalSingleChildren.put(AUGMENT, Arrays.asList(DESCRIPTION, REFERENCE, STATUS, WHEN));
399         optionalMultipleChildren.put(AUGMENT, Arrays.asList(ACTION, ANYDATA, ANYXML, CASE, CHOICE, CONTAINER, IF_FEATURE,
400                 LEAF, LEAF_LIST, LIST, NOTIFICATION, USES));
401
402         /*
403                 +--------------+---------+-------------+
404                 | substatement | section | cardinality |
405                 +--------------+---------+-------------+
406                 | prefix       | 7.1.4   |    1        |
407                 +--------------+---------+-------------+
408          */
409         optionalSingleChildren.put(BELONGS_TO, DESCRIPTION_AND_REFERENCE_CHILDREN);
410         mandatorySingleChildren.put(BELONGS_TO, Arrays.asList(PREFIX));
411
412         /*
413                 +--------------+---------+-------------+
414                 | substatement | section | cardinality |
415                 +--------------+---------+-------------+
416                 | description  | 7.21.3  | 0..1 |
417                 | if-feature   | 7.20.2  | 0..n |
418                 | position     | 9.7.4.2 | 0..1 |
419                 | reference    | 7.21.4  | 0..1 |
420                 | status       | 7.21.2  | 0..1 |
421                 +--------------+---------+-------------+
422          */
423         optionalSingleChildren.put(BIT, Arrays.asList(DESCRIPTION, POSITION, REFERENCE, STATUS));
424         optionalMultipleChildren.put(BIT, Arrays.asList(IF_FEATURE));
425
426         /*
427                 +--------------+---------+-------------+
428                 | substatement | section | cardinality |
429                 +--------------+---------+-------------+
430                 | anydata      | 7.10    | 0..n |
431                 | anyxml       | 7.11    | 0..n |
432                 | choice       | 7.9     | 0..n |
433                 | container    | 7.5     | 0..n |
434                 | description  | 7.21.3  | 0..1 |
435                 | if-feature   | 7.20.2  | 0..n |
436                 | leaf         | 7.6     | 0..n |
437                 | leaf-list    | 7.7     | 0..n |
438                 | list         | 7.8     | 0..n |
439                 | reference    | 7.21.4  | 0..1 |
440                 | status       | 7.21.2  | 0..1 |
441                 | uses         | 7.13    | 0..n |
442                 | when         | 7.21.5  | 0..1 |
443                 +--------------+---------+-------------+
444          */
445         optionalSingleChildren.put(CASE, Arrays.asList(DESCRIPTION, REFERENCE, STATUS, WHEN));
446         optionalMultipleChildren.put(CASE, Arrays.asList(ANYDATA, ANYXML, CHOICE, CONTAINER, IF_FEATURE, LEAF, LEAF_LIST,
447                 LIST, USES));
448
449         /*
450                 +--------------+---------+-------------+
451                 | substatement | section | cardinality |
452                 +--------------+---------+-------------+
453                 | anydata      | 7.10    | 0..n |
454                 | anyxml       | 7.11    | 0..n |
455                 | case         | 7.9.2   | 0..n |
456                 | choice       | 7.9     | 0..n |
457                 | config       | 7.21.1  | 0..1 |
458                 | container    | 7.5     | 0..n |
459                 | default      | 7.9.3   | 0..1 |
460                 | description  | 7.21.3  | 0..1 |
461                 | if-feature   | 7.20.2  | 0..n |
462                 | leaf         | 7.6     | 0..n |
463                 | leaf-list    | 7.7     | 0..n |
464                 | list         | 7.8     | 0..n |
465                 | mandatory    | 7.9.4   | 0..1 |
466                 | reference    | 7.21.4  | 0..1 |
467                 | status       | 7.21.2  | 0..1 |
468                 | when         | 7.21.5  | 0..1 |
469                 +--------------+---------+-------------+
470          */
471         optionalSingleChildren.put(CHOICE, Arrays.asList(CONFIG, DEFAULT, DESCRIPTION, MANDATORY, REFERENCE, STATUS, WHEN));
472         optionalMultipleChildren.put(CHOICE, Arrays.asList(ANYDATA, ANYXML, CASE, CHOICE, CONTAINER, IF_FEATURE, LEAF,
473                 LEAF_LIST, LIST));
474
475         /*
476                 +--------------+---------+-------------+
477                 | substatement | section | cardinality |
478                 +--------------+---------+-------------+
479                 | action       | 7.15    | 0..n |
480                 | anydata      | 7.10    | 0..n |
481                 | anyxml       | 7.11    | 0..n |
482                 | choice       | 7.9     | 0..n |
483                 | config       | 7.21.1  | 0..1 |
484                 | container    | 7.5     | 0..n |
485                 | description  | 7.21.3  | 0..1 |
486                 | grouping     | 7.12    | 0..n |
487                 | if-feature   | 7.20.2  | 0..n |
488                 | leaf         | 7.6     | 0..n |
489                 | leaf-list    | 7.7     | 0..n |
490                 | list         | 7.8     | 0..n |
491                 | must         | 7.5.3   | 0..n |
492                 | notification | 7.16    | 0..n |
493                 | presence     | 7.5.5   | 0..1 |
494                 | reference    | 7.21.4  | 0..1 |
495                 | status       | 7.21.2  | 0..1 |
496                 | typedef      | 7.3     | 0..n |
497                 | uses         | 7.13    | 0..n |
498                 | when         | 7.21.5  | 0..1 |
499                 +--------------+---------+-------------+
500          */
501         optionalSingleChildren.put(CONTAINER, Arrays.asList(CONFIG, DESCRIPTION, PRESENCE, REFERENCE, STATUS, WHEN));
502         optionalMultipleChildren.put(CONTAINER, Arrays.asList(ACTION, ANYDATA, ANYXML, CHOICE, CONTAINER, GROUPING,
503                 IF_FEATURE, LEAF, LEAF_LIST, LIST, MUST, NOTIFICATION, TYPEDEF, USES));
504
505         /*
506                 +--------------+---------+-------------+
507          */
508         optionalSingleChildren.put(DESCRIPTION, NO_CHILDREN);
509
510         /*
511                 +--------------+--------------+-------------+
512                 | substatement | section      | cardinality |
513                 +--------------+--------------+-------------+
514                 | config       | 7.21.1       |  0..1  |
515                 | default      | 7.6.4, 7.7.4 |  0..n  |
516                 | mandatory    | 7.6.5        |  0..1  |
517                 | max-elements | 7.7.6        |  0..1  |
518                 | min-elements | 7.7.5        |  0..1  |
519                 | must         | 7.5.3        |  0..n  |
520                 | type         | 7.4          |  0..1  |
521                 | unique       | 7.8.3        |  0..n  |
522                 | units        | 7.3.3        |  0..1  |
523                 +--------------+--------------+-------------+
524          */
525         optionalSingleChildren.put(DEVIATE, Arrays.asList(CONFIG, DESCRIPTION, MANDATORY, MAX_ELEMENTS, MIN_ELEMENTS,
526                 REFERENCE, TYPE, UNITS));
527         optionalMultipleChildren.put(DEVIATE, Arrays.asList(DEFAULT, MUST, UNIQUE));
528
529         /*
530                 +--------------+----------+-------------+
531                 | substatement | section  | cardinality |
532                 +--------------+----------+-------------+
533                 | description  | 7.21.3   |  0..1  |
534                 | deviate      | 7.20.3.2 |  1..n  |
535                 | reference    | 7.21.4   |  0..1  |
536                 +--------------+----------+-------------+
537          */
538         optionalSingleChildren.put(DEVIATION, Arrays.asList(DESCRIPTION, REFERENCE));
539         mandatoryMultipleChildren.put(DEVIATION, Arrays.asList(DEVIATE));
540
541         /*
542                 +--------------+---------+-------------+
543                 | substatement | section | cardinality |
544                 +--------------+---------+-------------+
545                 | description  | 7.21.3  |  0..1  |
546                 | if-feature   | 7.20.2  |  0..n  |
547                 | reference    | 7.21.4  |  0..1  |
548                 | status       | 7.21.2  |  0..1  |
549                 | value        | 9.6.4.2 |  0..1  |
550                 +--------------+---------+-------------+
551          */
552         optionalSingleChildren.put(ENUM, Arrays.asList(DESCRIPTION, REFERENCE, STATUS, VALUE));
553         optionalMultipleChildren.put(ENUM, Arrays.asList(IF_FEATURE));
554
555         /*
556                 +--------------+---------+-------------+
557                 | substatement | section | cardinality |
558                 +--------------+---------+-------------+
559                 | argument     | 7.19.2  |  0..1  |
560                 | description  | 7.21.3  |  0..1  |
561                 | reference    | 7.21.4  |  0..1  |
562                 | status       | 7.21.2  |  0..1  |
563                 +--------------+---------+-------------+
564          */
565         optionalSingleChildren.put(EXTENSION, Arrays.asList(ARGUMENT, DESCRIPTION, REFERENCE, STATUS));
566
567         /*
568                 +--------------+---------+-------------+
569                 | substatement | section | cardinality |
570                 +--------------+---------+-------------+
571                 | description  | 7.21.3  |  0..1  |
572                 | if-feature   | 7.20.2  |  0..n  |
573                 | reference    | 7.21.4  |  0..1  |
574                 | status       | 7.21.2  |  0..1  |
575                 +--------------+---------+-------------+
576          */
577         optionalSingleChildren.put(FEATURE, Arrays.asList(DESCRIPTION, REFERENCE, STATUS));
578         optionalMultipleChildren.put(FEATURE, Arrays.asList(IF_FEATURE));
579
580         /*
581                 +--------------+---------+-------------+
582                 | substatement | section | cardinality |
583                 +--------------+---------+-------------+
584                 | action       | 7.15    |  0..n  |
585                 | anydata      | 7.10    |  0..n  |
586                 | anyxml       | 7.11    |  0..n  |
587                 | choice       | 7.9     |  0..n  |
588                 | container    | 7.5     |  0..n  |
589                 | description  | 7.21.3  |  0..1  |
590                 | grouping     | 7.12    |  0..n  |
591                 | leaf         | 7.6     |  0..n  |
592                 | leaf-list    | 7.7     |  0..n  |
593                 | list         | 7.8     |  0..n  |
594                 | notification | 7.16    |  0..n  |
595                 | reference    | 7.21.4  |  0..1  |
596                 | status       | 7.21.2  |  0..1  |
597                 | typedef      | 7.3     |  0..n  |
598                 | uses         | 7.13    |  0..n  |
599                 +--------------+---------+-------------+
600          */
601         optionalSingleChildren.put(GROUPING, Arrays.asList(DESCRIPTION, REFERENCE, STATUS));
602         optionalMultipleChildren.put(GROUPING, Arrays.asList(ACTION, ANYDATA, ANYXML, CHOICE, CONTAINER, GROUPING, LEAF,
603                 LEAF_LIST, LIST, NOTIFICATION, TYPEDEF, USES));
604
605         /*
606                 +--------------+---------+-------------+
607                 | substatement | section | cardinality |
608                 +--------------+---------+-------------+
609                 | base         | 7.18.2  |  0..n  |
610                 | description  | 7.21.3  |  0..1  |
611                 | if-feature   | 7.20.2  |  0..n  |
612                 | reference    | 7.21.4  |  0..1  |
613                 | status       | 7.21.2  |  0..1  |
614                 +--------------+---------+-------------+
615          */
616         optionalSingleChildren.put(IDENTITY, Arrays.asList(DESCRIPTION, REFERENCE, STATUS));
617         optionalMultipleChildren.put(IDENTITY, Arrays.asList(BASE, IF_FEATURE));
618
619         /*
620                 +---------------+---------+-------------+
621                 | substatement  | section | cardinality |
622                 +---------------+---------+-------------+
623                 | description   | 7.21.3  |  0..1  |
624                 | prefix        | 7.1.4   |    1   |
625                 | reference     | 7.21.4  |  0..1  |
626                 | revision-date | 7.1.5.1 |  0..1  |
627                 +---------------+---------+-------------+
628          */
629         optionalSingleChildren.put(IMPORT, Arrays.asList(DESCRIPTION, REFERENCE, REVISION_DATE));
630         mandatorySingleChildren.put(IMPORT, Arrays.asList(PREFIX));
631
632         /*
633                 +---------------+---------+-------------+
634                 | substatement  | section | cardinality |
635                 +---------------+---------+-------------+
636                 | description   | 7.21.3  |  0..1  |
637                 | reference     | 7.21.4  |  0..1  |
638                 | revision-date | 7.1.5.1 |  0..1  |
639                 +---------------+---------+-------------+
640          */
641         optionalSingleChildren.put(INCLUDE, Arrays.asList(DESCRIPTION, REFERENCE, REVISION_DATE));
642
643         /*
644                 +--------------+---------+-------------+
645                 | substatement | section | cardinality |
646                 +--------------+---------+-------------+
647                 | anydata      | 7.10    |  0..n  |
648                 | anyxml       | 7.11    |  0..n  |
649                 | choice       | 7.9     |  0..n  |
650                 | container    | 7.5     |  0..n  |
651                 | grouping     | 7.12    |  0..n  |
652                 | leaf         | 7.6     |  0..n  |
653                 | leaf-list    | 7.7     |  0..n  |
654                 | list         | 7.8     |  0..n  |
655                 | must         | 7.5.3   |  0..n  |
656                 | typedef      | 7.3     |  0..n  |
657                 | uses         | 7.13    |  0..n  |
658                 +--------------+---------+-------------+
659          */
660         optionalSingleChildren.put(INPUT, Arrays.asList(DESCRIPTION, REFERENCE));
661         optionalMultipleChildren.put(INPUT, Arrays.asList(ANYDATA, ANYXML, CHOICE, CONTAINER, GROUPING, LEAF, LEAF_LIST,
662                 LIST, MUST, TYPEDEF, USES));
663
664         /*
665                 +--------------+---------+-------------+
666                 | substatement | section | cardinality |
667                 +--------------+---------+-------------+
668                 | config       | 7.21.1  |  0..1  |
669                 | default      | 7.6.4   |  0..1  |
670                 | description  | 7.21.3  |  0..1  |
671                 | if-feature   | 7.20.2  |  0..n  |
672                 | mandatory    | 7.6.5   |  0..1  |
673                 | must         | 7.5.3   |  0..n  |
674                 | reference    | 7.21.4  |  0..1  |
675                 | status       | 7.21.2  |  0..1  |
676                 | type         | 7.6.3   |    1   |
677                 | units        | 7.3.3   |  0..1  |
678                 | when         | 7.21.5  |  0..1  |
679                 +--------------+---------+-------------+
680          */
681         optionalSingleChildren.put(LEAF, Arrays.asList(CONFIG, DEFAULT, DESCRIPTION, MANDATORY, REFERENCE, STATUS, UNITS,
682                 WHEN));
683         optionalMultipleChildren.put(LEAF, Arrays.asList(IF_FEATURE, MUST));
684         mandatorySingleChildren.put(LEAF, Arrays.asList(TYPE));
685
686         /*
687                 +--------------+---------+-------------+
688                 | substatement | section | cardinality |
689                 +--------------+---------+-------------+
690                 | config       | 7.21.1  |  0..1  |
691                 | default      | 7.7.4   |  0..n  |
692                 | description  | 7.21.3  |  0..1  |
693                 | if-feature   | 7.20.2  |  0..n  |
694                 | max-elements | 7.7.6   |  0..1  |
695                 | min-elements | 7.7.5   |  0..1  |
696                 | must         | 7.5.3   |  0..n  |
697                 | ordered-by   | 7.7.7   |  0..1  |
698                 | reference    | 7.21.4  |  0..1  |
699                 | status       | 7.21.2  |  0..1  |
700                 | type         | 7.4     |    1   |
701                 | units        | 7.3.3   |  0..1  |
702                 | when         | 7.21.5  |  0..1  |
703                 +--------------+---------+-------------+
704          */
705         optionalSingleChildren.put(LEAF_LIST, Arrays.asList(CONFIG, DESCRIPTION, MAX_ELEMENTS, MIN_ELEMENTS, ORDERED_BY,
706                 REFERENCE, STATUS, UNITS, WHEN));
707         optionalMultipleChildren.put(LEAF_LIST, Arrays.asList(DEFAULT, IF_FEATURE, MUST));
708         mandatorySingleChildren.put(LEAF_LIST, Arrays.asList(TYPE));
709
710         /*
711                 +---------------+---------+-------------+
712                 | substatement  | section | cardinality |
713                 +---------------+---------+-------------+
714                 | description   | 7.19.3  | 0..1 |
715                 | error-app-tag | 7.5.4.2 | 0..1 |
716                 | error-message | 7.5.4.1 | 0..1 |
717                 | reference     | 7.19.4  | 0..1 |
718                 +---------------+---------+-------------+
719          */
720         optionalSingleChildren.put(LENGTH, Arrays.asList(DESCRIPTION, ERROR_APP_TAG, ERROR_MESSAGE, REFERENCE));
721
722         /*
723                 +--------------+---------+-------------+
724                 | substatement | section | cardinality |
725                 +--------------+---------+-------------+
726                 | action       | 7.15    |  0..n  |
727                 | anydata      | 7.10    |  0..n  |
728                 | anyxml       | 7.11    |  0..n  |
729                 | choice       | 7.9     |  0..n  |
730                 | config       | 7.19.1  |  0..1  |
731                 | container    | 7.5     |  0..n  |
732                 | description  | 7.19.3  |  0..1  |
733                 | grouping     | 7.11    |  0..n  |
734                 | if-feature   | 7.18.2  |  0..n  |
735                 | key          | 7.8.2   |  0..1  |
736                 | leaf         | 7.6     |  0..n  |
737                 | leaf-list    | 7.7     |  0..n  |
738                 | list         | 7.8     |  0..n  |
739                 | max-elements | 7.7.4   |  0..1  |
740                 | min-elements | 7.7.3   |  0..1  |
741                 | must         | 7.5.3   |  0..n  |
742                 | notification | 7.5.3   |  0..n  |
743                 | ordered-by   | 7.7.5   |  0..1  |
744                 | reference    | 7.19.4  |  0..1  |
745                 | status       | 7.19.2  |  0..1  |
746                 | typedef      | 7.3     |  0..n  |
747                 | unique       | 7.8.3   |  0..n  |
748                 | uses         | 7.12    |  0..n  |
749                 | when         | 7.19.5  |  0..1  |
750                 +--------------+---------+-------------+
751          */
752         optionalSingleChildren.put(LIST, Arrays.asList(CONFIG, DESCRIPTION, KEY, MAX_ELEMENTS, MIN_ELEMENTS, ORDERED_BY,
753                 REFERENCE, STATUS, WHEN));
754         optionalMultipleChildren.put(LIST, Arrays.asList(ACTION, ANYDATA, ANYXML, CHOICE, CONTAINER, GROUPING, IF_FEATURE,
755                 LEAF, LEAF_LIST, LIST, MUST, NOTIFICATION, TYPEDEF, UNIQUE, USES));
756
757         /*
758                 +--------------+---------+-------------+
759                 | substatement | section | cardinality |
760                 +--------------+---------+-------------+
761                 | anydata      | 7.10    |  0..n  |
762                 | anyxml       | 7.11    |  0..n  |
763                 | augment      | 7.17    |  0..n  |
764                 | choice       | 7.9     |  0..n  |
765                 | contact      | 7.1.8   |  0..1  |
766                 | container    | 7.5     |  0..n  |
767                 | description  | 7.21.3  |  0..1  |
768                 | deviation    | 7.20.3  |  0..n  |
769                 | extension    | 7.19    |  0..n  |
770                 | feature      | 7.20.1  |  0..n  |
771                 | grouping     | 7.12    |  0..n  |
772                 | identity     | 7.18    |  0..n  |
773                 | import       | 7.1.5   |  0..n  |
774                 | include      | 7.1.6   |  0..n  |
775                 | leaf         | 7.6     |  0..n  |
776                 | leaf-list    | 7.7     |  0..n  |
777                 | list         | 7.8     |  0..n  |
778                 | namespace    | 7.1.3   |    1   |
779                 | notification | 7.16    |  0..n  |
780                 | organization | 7.1.7   |  0..1  |
781                 | prefix       | 7.1.4   |    1   |
782                 | reference    | 7.21.4  |  0..1  |
783                 | revision     | 7.1.9   |  0..n  |
784                 | rpc          | 7.14    |  0..n  |
785                 | typedef      | 7.3     |  0..n  |
786                 | uses         | 7.13    |  0..n  |
787                 | yang-version | 7.1.2   |    1   |
788                 +--------------+---------+-------------+
789
790                 Note that in YANG 1.0 the cardinality for the 'yang-version' statement is '0..1'. To remain
791                 backwards-compatible, this statement remains optional during parsing.
792          */
793         optionalSingleChildren.put(MODULE, Arrays.asList(CONTACT, DESCRIPTION, ORGANIZATION, REFERENCE, YANG_VERSION));
794         optionalMultipleChildren.put(MODULE, Arrays.asList(ANYDATA, ANYXML, AUGMENT, CHOICE, CONTAINER, DEVIATION,
795                 EXTENSION, FEATURE, GROUPING, IDENTITY, IMPORT, INCLUDE, LEAF, LEAF_LIST, LIST, NOTIFICATION, REVISION, RPC,
796                 TYPEDEF, USES));
797         mandatorySingleChildren.put(MODULE, Arrays.asList(NAMESPACE, PREFIX));
798
799         /*
800                 +---------------+---------+-------------+
801                 | substatement  | section | cardinality |
802                 +---------------+---------+-------------+
803                 | description   | 7.21.3  | 0..1 |
804                 | error-app-tag | 7.5.4.2 | 0..1 |
805                 | error-message | 7.5.4.1 | 0..1 |
806                 | reference     | 7.21.4  | 0..1 |
807                 +---------------+---------+-------------+
808          */
809         optionalSingleChildren.put(MUST, Arrays.asList(DESCRIPTION, ERROR_APP_TAG, ERROR_MESSAGE, REFERENCE));
810
811         /*
812                 +--------------+---------+-------------+
813                 | substatement | section | cardinality |
814                 +--------------+---------+-------------+
815                 | anydata      | 7.10    | 0..n |
816                 | anyxml       | 7.11    | 0..n |
817                 | choice       | 7.9     | 0..n |
818                 | container    | 7.5     | 0..n |
819                 | description  | 7.21.3  | 0..1 |
820                 | grouping     | 7.12    | 0..n |
821                 | if-feature   | 7.20.2  | 0..n |
822                 | leaf         | 7.6     | 0..n |
823                 | leaf-list    | 7.7     | 0..n |
824                 | list         | 7.8     | 0..n |
825                 | must         | 7.5.3   | 0..n |
826                 | reference    | 7.21.4  | 0..1 |
827                 | status       | 7.21.2  | 0..1 |
828                 | typedef      | 7.3     | 0..n |
829                 | uses         | 7.13    | 0..n |
830                 +--------------+---------+-------------+
831          */
832         optionalSingleChildren.put(NOTIFICATION, Arrays.asList(DESCRIPTION, REFERENCE, STATUS));
833         optionalMultipleChildren.put(NOTIFICATION, Arrays.asList(ANYDATA, ANYXML, CHOICE, CONTAINER, GROUPING, IF_FEATURE,
834                 LEAF, LEAF_LIST, LIST, MUST, TYPEDEF, USES));
835
836         /*
837                 +--------------+---------+-------------+
838                 | substatement | section | cardinality |
839                 +--------------+---------+-------------+
840                 | anydata      | 7.10    |  0..n  |
841                 | anyxml       | 7.11    |  0..n  |
842                 | choice       | 7.9     |  0..n  |
843                 | container    | 7.5     |  0..n  |
844                 | grouping     | 7.12    |  0..n  |
845                 | leaf         | 7.6     |  0..n  |
846                 | leaf-list    | 7.7     |  0..n  |
847                 | list         | 7.8     |  0..n  |
848                 | must         | 7.5.3   |  0..n  |
849                 | typedef      | 7.3     |  0..n  |
850                 | uses         | 7.13    |  0..n  |
851                 +--------------+---------+-------------+
852          */
853         optionalSingleChildren.put(OUTPUT, Arrays.asList(DESCRIPTION, REFERENCE));
854         optionalMultipleChildren.put(OUTPUT, Arrays.asList(ANYDATA, ANYXML, CHOICE, CONTAINER, GROUPING, LEAF, LEAF_LIST,
855                 LIST, MUST, TYPEDEF, USES));
856
857         /*
858                 +---------------+---------+-------------+
859                 | substatement  | section | cardinality |
860                 +---------------+---------+-------------+
861                 | description   | 7.21.3  |  0..1  |
862                 | error-app-tag | 7.5.4.2 |  0..1  |
863                 | error-message | 7.5.4.1 |  0..1  |
864                 | modifier      | 9.4.6   |  0..1  |
865                 | reference     | 7.21.4  |  0..1  |
866                 +---------------+---------+-------------+
867          */
868         optionalSingleChildren.put(PATTERN, Arrays.asList(DESCRIPTION, ERROR_APP_TAG, ERROR_MESSAGE, MODIFIER, REFERENCE));
869
870         /*
871                 +---------------+---------+-------------+
872                 | substatement  | section | cardinality |
873                 +---------------+---------+-------------+
874                 | description   | 7.21.3  |  0..1  |
875                 | error-app-tag | 7.5.4.2 |  0..1  |
876                 | error-message | 7.5.4.1 |  0..1  |
877                 | reference     | 7.21.4  |  0..1  |
878                 +---------------+---------+-------------+
879          */
880         optionalSingleChildren.put(RANGE, Arrays.asList(DESCRIPTION, ERROR_APP_TAG, ERROR_MESSAGE, REFERENCE));
881
882         /*
883                 +--------------+---------+-------------+
884          */
885         optionalSingleChildren.put(REFERENCE, NO_CHILDREN);
886
887         /*
888                 +--------------+---------+-------------+
889          */
890         optionalSingleChildren.put(REFINE, Arrays.asList(CONFIG, DESCRIPTION, MANDATORY, MAX_ELEMENTS, MIN_ELEMENTS,
891                 PRESENCE, REFERENCE));
892         optionalMultipleChildren.put(REFINE, Arrays.asList(DEFAULT, IF_FEATURE, MUST));
893
894         /*
895                 +--------------+---------+-------------+
896                 | substatement | section | cardinality |
897                 +--------------+---------+-------------+
898                 | description  | 7.21.3  | 0..1 |
899                 | grouping     | 7.12    | 0..n |
900                 | if-feature   | 7.20.2  | 0..n |
901                 | input        | 7.14.2  | 0..1 |
902                 | output       | 7.14.3  | 0..1 |
903                 | reference    | 7.21.4  | 0..1 |
904                 | status       | 7.21.2  | 0..1 |
905                 | typedef      | 7.3     | 0..n |
906                 +--------------+---------+-------------+
907          */
908         optionalSingleChildren.put(RPC, Arrays.asList(DESCRIPTION, INPUT, OUTPUT, REFERENCE, STATUS));
909         optionalMultipleChildren.put(RPC, Arrays.asList(GROUPING, IF_FEATURE, TYPEDEF));
910
911         /*
912                 +--------------+---------+-------------+
913                 | substatement | section | cardinality |
914                 +--------------+---------+-------------+
915                 | anydata      | 7.10    | 0..n |
916                 | anyxml       | 7.11    | 0..n |
917                 | augment      | 7.17    | 0..n |
918                 | belongs-to   | 7.2.2   |   1  |
919                 | choice       | 7.9     | 0..n |
920                 | contact      | 7.1.8   | 0..1 |
921                 | container    | 7.5     | 0..n |
922                 | description  | 7.21.3  | 0..1 |
923                 | deviation    | 7.20.3  | 0..n |
924                 | extension    | 7.19    | 0..n |
925                 | feature      | 7.20.1  | 0..n |
926                 | grouping     | 7.12    | 0..n |
927                 | identity     | 7.18    | 0..n |
928                 | import       | 7.1.5   | 0..n |
929                 | include      | 7.1.6   | 0..n |
930                 | leaf         | 7.6     | 0..n |
931                 | leaf-list    | 7.7     | 0..n |
932                 | list         | 7.8     | 0..n |
933                 | notification | 7.16    | 0..n |
934                 | organization | 7.1.7   | 0..1 |
935                 | reference    | 7.21.4  | 0..1 |
936                 | revision     | 7.1.9   | 0..n |
937                 | rpc          | 7.14    | 0..n |
938                 | typedef      | 7.3     | 0..n |
939                 | uses         | 7.13    | 0..n |
940                 | yang-version | 7.1.2   |  1   |
941                 +--------------+---------+-------------+
942
943                 Note that in YANG 1.0 the cardinality for the 'yang-version' statement is '0..1'. To remain
944                 backwards-compatible, this statement remains optional during parsing.
945          */
946         optionalSingleChildren.put(SUBMODULE, Arrays.asList(CONTACT, DESCRIPTION, ORGANIZATION, REFERENCE, YANG_VERSION));
947         optionalMultipleChildren.put(SUBMODULE, Arrays.asList(ANYDATA, ANYXML, AUGMENT, CHOICE, CONTAINER, DEVIATION,
948                 EXTENSION, FEATURE, GROUPING, IDENTITY, IMPORT, INCLUDE, LEAF, LEAF_LIST, LIST, NOTIFICATION, REVISION, RPC,
949                 TYPEDEF, USES));
950         mandatorySingleChildren.put(SUBMODULE, Arrays.asList(BELONGS_TO));
951
952         /*
953                 +------------------+---------+-------------+
954                 | substatement     | section | cardinality |
955                 +------------------+---------+-------------+
956                 | base             | 7.18.2  | 0..n |
957                 | bit              | 9.7.4   | 0..n |
958                 | enum             | 9.6.4   | 0..n |
959                 | fraction-digits  | 9.3.4   | 0..1 |
960                 | length           | 9.4.4   | 0..1 |
961                 | path             | 9.9.2   | 0..1 |
962                 | pattern          | 9.4.5   | 0..n |
963                 | range            | 9.2.4   | 0..1 |
964                 | require-instance | 9.9.3   | 0..1 |
965                 | type             | 7.4     | 0..n |
966                 +------------------+---------+-------------+
967          */
968         optionalSingleChildren.put(TYPE, Arrays.asList(DESCRIPTION, FRACTION_DIGITS, LENGTH, PATH, RANGE,
969                 REQUIRE_INSTANCE));
970         optionalMultipleChildren.put(TYPE, Arrays.asList(BASE, BIT, ENUM, PATTERN, TYPE));
971
972         /*
973                 +--------------+---------+-------------+
974                 | substatement | section | cardinality |
975                 +--------------+---------+-------------+
976                 | default      | 7.3.4   | 0..1 |
977                 | description  | 7.21.3  | 0..1 |
978                 | reference    | 7.21.4  | 0..1 |
979                 | status       | 7.21.2  | 0..1 |
980                 | type         | 7.3.2   |   1  |
981                 | units        | 7.3.3   | 0..1 |
982                 +--------------+---------+-------------+
983          */
984         optionalSingleChildren.put(TYPEDEF, Arrays.asList(DEFAULT, DESCRIPTION, REFERENCE, STATUS, UNITS));
985         mandatorySingleChildren.put(TYPEDEF, Arrays.asList(TYPE));
986
987         /*
988                 +--------------+---------+-------------+
989                 | substatement | section | cardinality |
990                 +--------------+---------+-------------+
991                 | augment      | 7.17    | 0..n |
992                 | description  | 7.21.3  | 0..1 |
993                 | if-feature   | 7.20.2  | 0..n |
994                 | reference    | 7.21.4  | 0..1 |
995                 | refine       | 7.13.2  | 0..n |
996                 | status       | 7.21.2  | 0..1 |
997                 | when         | 7.21.5  | 0..1 |
998                 +--------------+---------+-------------+
999          */
1000         optionalSingleChildren.put(USES, Arrays.asList(DESCRIPTION, REFERENCE, STATUS, WHEN));
1001         optionalMultipleChildren.put(USES, Arrays.asList(AUGMENT, IF_FEATURE, REFINE));
1002     }
1003
1004     public static final Map<String, List<String>> HANDLED_STATEMENTS = new HashMap<>();
1005
1006     static {
1007         HANDLED_STATEMENTS.put(YANG_CORE_MODULE_NAME, new ArrayList<>(ALL_YANG_CORE_STATEMENT_NAMES));
1008     }
1009 }