8215f164210a731ccc019bfcb9b82fd8694363e2
[mdsal.git] / binding / yang-binding / src / main / java / org / opendaylight / yangtools / yang / binding / BindingStreamEventWriter.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.binding;
9
10 import java.io.Closeable;
11 import java.io.Flushable;
12 import java.io.IOException;
13
14
15 /**
16  * Event Stream Writer for Binding Representation
17  *
18  *
19  * <h3>Emmiting Event Stream</h3>
20  *
21  * <ul>
22  * <li><code>container</code> - Container node representation, start event is
23  * emitted using {@link #startContainerNode(Class, int)} and node end event is
24  * emitted using {@link #endNode()}. Container node is implementing
25  * {@link DataObject} interface.
26  *
27  * <li><code>list</code> - YANG list statement has two representation in event
28  * stream - unkeyed list and map. Unkeyed list is YANG list which did not
29  * specify key.
30  *
31  * <ul>
32  * <li><code>Map</code> - Map start event is emitted using
33  * {@link #startMapNode(Class, int)} and is ended using {@link #endNode()}. Each map
34  * entry start is emitted using {@link #startMapEntryNode(Identifier, int)} with Map of keys
35  * and finished using {@link #endNode()}.</li>
36  *
37  * <li><code>UnkeyedList</code> - Unkeyed list represent list without keys,
38  * unkeyed list start is emitted using {@link #startUnkeyedList(Class, int)} list
39  * end is emitted using {@link #endNode()}. Each list item is emitted using
40  * {@link #startUnkeyedListItem(int)} and ended using {@link #endNode()}.</li>
41  * </ul></li>
42  *
43  * <li><code>leaf</code> - Leaf node event is emitted using
44  * {@link #leafNode(String, Object)}. {@link #endNode()} MUST be not emitted for
45  * leaf node.</li>
46  *
47  * <li><code>leaf-list</code> - Leaf list start is emitted using
48  * {@link #startLeafSet(String, int)}. Leaf list end is emitted using
49  * {@link #endNode()}. Leaf list entries are emitted using
50  * {@link #leafSetEntryNode(Object)}.
51  *
52  * <li><code>anyxml - Anyxml node event is emitted using
53  * {@link #leafNode(String, Object)}. {@link #endNode()} MUST be not emitted
54  * for anyxml node.</code></li>
55  *
56  *
57  * <li><code>choice</code> Choice node event is emitted by
58  * {@link #startChoiceNode(Class, int)} event and must be immediately followed by
59  * {@link #startCase(Class, int)} event. Choice node is finished by emitting an
60  * {@link #endNode()} event.</li>
61  *
62  * <li>
63  * <code>case</code> - Case node may be emitted only inside choice node by
64  * invoking {@link #startCase(Class, int)}. Case node is finished be emitting an
65  * {@link #endNode()} event.</li>
66  *
67  * <li>
68  * <code>augment</code> - Represents augmentation, augmentation node is started
69  * by invoking {@link #startAugmentationNode(Class)} and
70  * finished by invoking {@link #endNode()}.</li>
71  *
72  * </ul>
73  *
74  * <h3>Implementation notes</h3> This interface is not intended to be
75  * implemented by users of generated Binding DTOs but to be used by utilities,
76  * which needs to emit NormalizedNode model from Binding DTOs.
77  * <p>
78  * This interface is intended as API definition of facade for real Event /
79  * Stream Writer, without explicitly requiring stream writer and related
80  * interfaces to be imported by all generated Binding DTOs.
81  * <p>
82  * Existence of this interface in base Java Binding package is required to
83  * support runtime generation of users of this interface in OSGI and OSGI-like
84  * environment, since this package is only package which is imported by all
85  * generated Binding DTOs and wired in OSGI.
86  *
87  *
88  */
89 public interface BindingStreamEventWriter extends Closeable, Flushable {
90
91     /**
92      * Methods in this interface allow users to hint the underlying
93      * implementation about the sizing of container-like constructors
94      * (leafLists, containers, etc.). These hints may be taken into account by a
95      * particular implementation to improve performance, but clients are not
96      * required to provide hints. This constant should be used by clients who
97      * either do not have the sizing information, or do not wish to divulge it
98      * (for whatever reasons). Implementations are free to ignore these hints
99      * completely, but if they do use them, they are expected to be resilient in
100      * face of missing and mismatched hints, which is to say the user can
101      * specify startLeafSet(..., 1) and then call leafNode() 15 times.
102      * <p>
103      * The acceptable hint values are non-negative integers and this constant,
104      * all other values will result, based on implementation preference, in the
105      * hint being completely ignored or IllegalArgumentException being thrown.
106      */
107     int UNKNOWN_SIZE = -1;
108
109     /**
110      *
111      * Emits a leaf node event with supplied value.
112      *
113      * @param localName
114      *            name of node as defined in schema, namespace and revision are
115      *            derived from parent node.
116      * @param value
117      *            Value of leaf node.
118      * @throws IllegalArgumentException
119      *             If emitted leaf node has invalid value in current context or
120      *             was emitted multiple times.
121      * @throws IllegalStateException
122      *             If node was emitted inside <code>map</code>,
123      *             <code>choice</code> <code>unkeyed list</code> node.
124      * @throws IOException if an underlying IO error occurs
125      */
126     void leafNode(String localName, Object value) throws IOException, IllegalArgumentException;
127
128     /**
129      *
130      * Emits a start of leaf set (leaf-list).
131      * <p>
132      * Emits start of leaf set, during writing leaf set event, only
133      * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
134      * finished by calling {@link #endNode()}.
135      *
136      * @param localName
137      *            name of node as defined in schema, namespace and revision are
138      *            derived from parent node.
139      * @param childSizeHint
140      *            Non-negative count of expected direct child nodes or
141      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
142      *            and should not fail writing of child events, if there are more
143      *            events than count.
144      * @throws IllegalArgumentException
145      *             If emitted leaf node is invalid in current context or was
146      *             emitted multiple times.
147      * @throws IllegalStateException
148      *             If node was emitted inside <code>map</code>,
149      *             <code>choice</code> <code>unkeyed list</code> node.
150      * @throws IOException if an underlying IO error occurs
151      */
152     void startLeafSet(String localName, int childSizeHint) throws IOException, IllegalArgumentException;
153
154     /**
155      *
156      * Emits a start of leaf set (leaf-list).
157      * <p>
158      * Emits start of leaf set, during writing leaf set event, only
159      * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
160      * finished by calling {@link #endNode()}.
161      *
162      * @param localName
163      *            name of node as defined in schema, namespace and revision are
164      *            derived from parent node.
165      * @param childSizeHint
166      *            Non-negative count of expected direct child nodes or
167      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
168      *            and should not fail writing of child events, if there are more
169      *            events than count.
170      * @throws IllegalArgumentException
171      *             If emitted leaf node is invalid in current context or was
172      *             emitted multiple times.
173      * @throws IllegalStateException
174      *             If node was emitted inside <code>map</code>,
175      *             <code>choice</code> <code>unkeyed list</code> node.
176      * @throws IOException if an underlying IO error occurs
177      */
178     void startOrderedLeafSet(String localName, int childSizeHint) throws IOException, IllegalArgumentException;
179
180     /**
181      * Emits a leaf set entry node
182      *
183      * @param value
184      *            Value of leaf set entry node.
185      * @throws IllegalArgumentException
186      *             If emitted leaf node has invalid value.
187      * @throws IllegalStateException
188      *             If node was emitted outside <code>leaf set</code> node.
189      * @throws IOException if an underlying IO error occurs
190      */
191     void leafSetEntryNode(Object value) throws IOException, IllegalArgumentException;
192
193     /**
194      *
195      * Emits start of new container.
196      *
197      * <p>
198      * End of container event is emitted by invoking {@link #endNode()}.
199      *
200      * <p>
201      * Valid sub-events are:
202      * <ul>
203      * <li>{@link #leafNode(String, Object)}</li>
204      * <li>{@link #startContainerNode(Class, int)}</li>
205      * <li>{@link #startChoiceNode(Class, int)}</li>
206      * <li>{@link #startLeafSet(String, int)}</li>
207      * <li>{@link #startMapNode(Class, int)}</li>
208      * <li>{@link #startUnkeyedList(Class, int)}</li>
209      * <li>{@link #startAugmentationNode(Class)}</li>
210      * </ul>
211      *
212      * @param container
213      *            name of node as defined in schema, namespace and revision are
214      *            derived from parent node.
215      * @param childSizeHint
216      *            Non-negative count of expected direct child nodes or
217      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
218      *            and should not fail writing of child events, if there are more
219      *            events than count.
220      * @throws IllegalArgumentException
221      *             If emitted node is invalid in current context or was emitted
222      *             multiple times.
223      * @throws IllegalStateException
224      *             If node was emitted inside <code>map</code>,
225      *             <code>choice</code> <code>unkeyed list</code> node.
226      * @throws IOException if an underlying IO error occurs
227      */
228     void startContainerNode(Class<? extends DataObject> container, int childSizeHint) throws IOException, IllegalArgumentException;
229
230     /**
231      *
232      * Emits start of unkeyed list node event.
233      *
234      * <p>
235      * End of unkeyed list event is emitted by invoking {@link #endNode()}.
236      * Valid subevents is only {@link #startUnkeyedListItem(int)}. All other
237      * methods will throw {@link IllegalArgumentException}.
238      *
239      * @param localName
240      *            name of node as defined in schema, namespace and revision are
241      *            derived from parent node.
242      * @param childSizeHint
243      *            Non-negative count of expected direct child nodes or
244      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
245      *            and should not fail writing of child events, if there are more
246      *            events than count.
247      * @throws IllegalArgumentException
248      *             If emitted node is invalid in current context or was emitted
249      *             multiple times.
250      * @throws IllegalStateException
251      *             If node was emitted inside <code>map</code>,
252      *             <code>choice</code> <code>unkeyed list</code> node.
253      * @throws IOException if an underlying IO error occurs
254      */
255     void startUnkeyedList(Class<? extends DataObject> localName, int childSizeHint) throws IOException, IllegalArgumentException;
256
257     /**
258      * Emits start of new unkeyed list item.
259      *
260      * <p>
261      * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
262      * sub-events are:
263      * <p>
264      * Valid sub-events are:
265      *
266      * <ul>
267      * <li>{@link #leafNode(String, Object)}</li>
268      * <li>{@link #startContainerNode(Class, int)}</li>
269      * <li>{@link #startChoiceNode(Class, int)}</li>
270      * <li>{@link #startLeafSet(String, int)}</li>
271      * <li>{@link #startMapNode(Class, int)}</li>
272      * <li>{@link #startUnkeyedList(Class, int)}</li>
273      * <li>{@link #startAugmentationNode(Class)}</li>
274      * </ul>
275      *
276      *
277      * @param childSizeHint
278      *            Non-negative count of expected direct child nodes or
279      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
280      *            and should not fail writing of child events, if there are more
281      *            events than count.
282      * @throws IllegalStateException
283      *             If node was emitted outside <code>unkeyed list</code> node.
284      * @throws IOException if an underlying IO error occurs
285      */
286     void startUnkeyedListItem(int childSizeHint) throws IOException, IllegalStateException;
287
288     /**
289      *
290      * Emits start of unordered map node event.
291      *
292      * <p>
293      * End of map node event is emitted by invoking {@link #endNode()}. Valid
294      * subevents is only {@link #startMapEntryNode(Identifier, int)}. All other methods will
295      * throw {@link IllegalArgumentException}.
296      *
297      * @param mapEntryType
298      *            Class of list item, which has defined key.
299      * @param childSizeHint
300      *            Non-negative count of expected direct child nodes or
301      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
302      *            and should not fail writing of child events, if there are more
303      *            events than count.
304      * @throws IllegalArgumentException
305      * @throws IllegalStateException
306      *             If node was emitted inside <code>map</code>,
307      *             <code>choice</code> <code>unkeyed list</code> node.
308      * @throws IOException if an underlying IO error occurs
309      */
310     <T extends DataObject & Identifiable<?>> void startMapNode(Class<T> mapEntryType, int childSizeHint)
311             throws IOException, IllegalArgumentException;
312
313     /**
314      *
315      * Emits start of ordered map node event.
316      *
317      * <p>
318      * End of map node event is emitted by invoking {@link #endNode()}. Valid
319      * subevents is only {@link #startMapEntryNode(Identifier, int)}. All other methods will
320      * throw {@link IllegalArgumentException}.
321      *
322      * @param mapEntryType
323      *            Class of list item, which has defined key.
324      * @param childSizeHint
325      *            Non-negative count of expected direct child nodes or
326      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
327      *            and should not fail writing of child events, if there are more
328      *            events than count.
329      * @throws IllegalArgumentException
330      * @throws IllegalStateException
331      *             If node was emitted inside <code>map</code>,
332      *             <code>choice</code> <code>unkeyed list</code> node.
333      * @throws IOException if an underlying IO error occurs
334      */
335     <T extends DataObject & Identifiable<?>> void startOrderedMapNode(Class<T> mapEntryType, int childSizeHint)
336            throws IOException, IllegalArgumentException;
337
338     /**
339      *
340      * Emits start of map entry.
341      *
342      * <p>
343      * End of map entry event is emitted by invoking {@link #endNode()}.
344      *
345      * <p>
346      * Valid sub-events are:
347      * <ul>
348      * <li>{@link #leafNode(String, Object)}</li>
349      * <li>{@link #startContainerNode(Class, int)}</li>
350      * <li>{@link #startChoiceNode(Class, int)}</li>
351      * <li>{@link #startLeafSet(String, int)}</li>
352      * <li>{@link #startMapNode(Class, int)}</li>
353      * <li>{@link #startUnkeyedList(Class, int)}</li>
354      * <li>{@link #startAugmentationNode(Class)}</li>
355      * </ul>
356      *
357      * @param keyValues
358      *            Key of map entry node
359      * @param childSizeHint
360      *            Non-negative count of expected direct child nodes or
361      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
362      *            and should not fail writing of child events, if there are more
363      *            events than count.
364      * @throws IllegalArgumentException
365      *             If key contains incorrect value.
366      * @throws IllegalStateException
367      *             If node was emitted outside <code>map entry</code> node.
368      * @throws IOException if an underlying IO error occurs
369      */
370     void startMapEntryNode(Identifier<?> keyValues, int childSizeHint) throws IOException, IllegalArgumentException;
371
372     /**
373      * Emits start of choice node.
374      *
375      * <p>
376      * Valid sub-event in {@link #startCase(Class, int)}, which selects case
377      * which should be written.
378      *
379      * @param choice
380      *            Choice class.
381      * @param childSizeHint
382      *            Non-negative count of expected direct child nodes or
383      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
384      *            and should not fail writing of child events, if there are more
385      *            events than count.
386      * @throws IllegalArgumentException
387      * @throws IllegalStateException
388      *             If node was emitted inside <code>map</code>, <code>choice</code>,
389      *             <code>unkeyed list</code> node.
390      * @throws IOException if an underlying IO error occurs
391      */
392     void startChoiceNode(Class<? extends DataContainer> choice, int childSizeHint) throws IOException, IllegalArgumentException;
393
394     /**
395      *
396      * Starts a case node.
397      *
398      * <p>
399      * Valid sub-events are:
400      * <ul>
401      * <li>{@link #leafNode(String, Object)}</li>
402      * <li>{@link #startContainerNode(Class, int)}</li>
403      * <li>{@link #startChoiceNode(Class, int)}</li>
404      * <li>{@link #startLeafSet(String, int)}</li>
405      * <li>{@link #startMapNode(Class, int)}</li>
406      * <li>{@link #startUnkeyedList(Class, int)}</li>
407      * <li>{@link #startAugmentationNode(Class)}</li>
408      * </ul>
409      *
410      * @param caze Case class
411      * @throws IllegalArgumentException
412      * @throws IOException if an underlying IO error occurs
413      */
414     void startCase(Class<? extends DataObject> caze, int childSizeHint) throws IOException, IllegalArgumentException;
415
416     /**
417      * Emits start of augmentation node.
418      *
419      * <p>
420      * End of augmentation event is emitted by invoking {@link #endNode()}.
421      *
422      * <p>
423      * Valid sub-events are:
424      *
425      * <ul>
426      * <li>{@link #leafNode(String, Object)}</li>
427      * <li>{@link #startContainerNode(Class, int)}</li>
428      * <li>{@link #startChoiceNode(Class, int)}</li>
429      * <li>{@link #startLeafSet(String, int)}</li>
430      * <li>{@link #startMapNode(Class, int)}</li>
431      * <li>{@link #startUnkeyedList(Class, int)}</li>
432      * </ul>
433      *
434      * <p>
435      * Note this is only method, which does not require childSizeHint, since
436      * maximum value is always size of <code>possibleChildren</code>.
437      *
438      * @param augmentationType augmentation class
439      * @throws IllegalArgumentException
440      *             If augmentation is invalid in current context.
441      * @throws IOException if an underlying IO error occurs
442      */
443     void startAugmentationNode(Class<? extends Augmentation<?>> augmentationType) throws IOException, IllegalArgumentException;
444
445     /**
446      * Emits anyxml node event.
447      *
448      * @param name
449      * @param value
450      * @throws IllegalArgumentException
451      * @throws IllegalStateException
452      *             If node was emitted inside <code>map</code>,
453      *             <code>choice</code> <code>unkeyed list</code> node.
454      * @throws IOException if an underlying IO error occurs
455      */
456     void anyxmlNode(String name, Object value) throws IOException, IllegalArgumentException;
457
458     /**
459      * Emits end event for node.
460      *
461      * @throws IllegalStateException If there is no open node.
462      * @throws IOException if an underlying IO error occurs
463      */
464     void endNode() throws IOException, IllegalStateException;
465
466     @Override
467     void flush() throws IOException;
468
469     @Override
470     void close() throws IOException;
471 }