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