[ONOS-5793] YANG Runtime service and serializer APIs

Change-Id: Ifee8ec96cd4bf063c8e131964741b9cef72a55d2
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/AnnotatedNodeInfo.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/AnnotatedNodeInfo.java
new file mode 100644
index 0000000..2ed3c4d
--- /dev/null
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/AnnotatedNodeInfo.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.api;
+
+import org.onosproject.yang.model.ResourceId;
+
+import java.util.List;
+
+/**
+ * Representation of annotated nodes information.
+ */
+public interface AnnotatedNodeInfo {
+
+    /**
+     * Returns resource identifier of the annotated node.
+     *
+     * @return resource identifier
+     */
+    ResourceId resourceId();
+
+    /**
+     * Sets resource identifier of the annotated node.
+     *
+     * @param id resource identifier
+     */
+    void resourceId(ResourceId id);
+
+    /**
+     * Returns annotations associated with the node.
+     *
+     * @return annotations
+     */
+    List<Annotation> annotations();
+
+    /**
+     * Adds annotation to a node.
+     *
+     * @param annotation annotation information
+     */
+    void addAnnotation(Annotation annotation);
+}
+
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/Annotation.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/Annotation.java
new file mode 100644
index 0000000..317e5e7
--- /dev/null
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/Annotation.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.api;
+
+/**
+ * Representation of annotated attribute.
+ */
+public interface Annotation {
+
+    /**
+     * Returns name of an annotated attribute.
+     *
+     * @return name of the attribute
+     */
+    String name();
+
+    /**
+     * Sets name of the annotated attribute.
+     *
+     * @param name of the attribute
+     */
+    void name(String name);
+
+    /**
+     * Returns value of the annotation.
+     *
+     * @return annotation value
+     */
+    String value();
+
+    /**
+     * Sets value of the annotation.
+     *
+     * @param value value of the annotation
+     */
+    void value(String value);
+}
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/CompositeData.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/CompositeData.java
new file mode 100644
index 0000000..8809609
--- /dev/null
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/CompositeData.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.api;
+
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ResourceId;
+
+import java.util.List;
+
+/**
+ * Representation of an entity which is comprised of composite data having
+ * resource identifier with list of data node.
+ */
+public interface CompositeData {
+
+    /**
+     * Returns list of data nodes.
+     *
+     * @return list of data nodes
+     */
+    List<DataNode> dataNodes();
+
+    /**
+     * Adds a data node.
+     *
+     * @param node data node
+     */
+    void addDataNode(DataNode node);
+
+    /**
+     * Returns resource identifier.
+     *
+     * @return resource identifier
+     */
+    ResourceId resourceId();
+
+    /**
+     * Sets resource identifier.
+     *
+     * @param identifier resource identifier
+     */
+    void resourceId(ResourceId identifier);
+}
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/CompositeStream.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/CompositeStream.java
new file mode 100644
index 0000000..7468362
--- /dev/null
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/CompositeStream.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.api;
+
+import java.io.InputStream;
+
+/**
+ * Representation of composite stream comprising of resource identifier and
+ * its data.
+ */
+public interface CompositeStream {
+
+    /**
+     * Retrieves the resource identifier stream on which the operation is being
+     * performed.
+     *
+     * @return string representation of the resource being identified
+     */
+    String resourceId();
+
+    /**
+     * Sets resource identifier on which operation is to be performed.
+     *
+     * @param uri resource identifier string as per RFC 3986
+     */
+    void resourceId(String uri);
+
+    /**
+     * Retrieves the resource data stream in the protocol encoding format.
+     *
+     * @return resource data
+     */
+    InputStream resourceData();
+
+    /**
+     * Sets resource data stream in the protocol encoding format.
+     *
+     * @param stream resource data
+     */
+    void resourceData(InputStream stream);
+}
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/DecodedOutput.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/DecodedOutput.java
new file mode 100644
index 0000000..600acaa
--- /dev/null
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/DecodedOutput.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.api;
+
+import java.util.List;
+
+/**
+ * Representation of parameters which are provided by serializers as decoding
+ * output.
+ */
+public interface DecodedOutput {
+
+    /**
+     * Returns composite node.
+     *
+     * @return composite node
+     */
+    CompositeData getCompositeNode();
+
+    /**
+     * Sets composite node.
+     *
+     * @param node composite node
+     */
+    void setCompositeNode(CompositeData node);
+
+    /**
+     * Returns annotated nodes information.
+     *
+     * @return annotated nodes information
+     */
+    List<AnnotatedNodeInfo> getAnnotatedNodesInfo();
+
+    /**
+     * Adds information about annotated node.
+     *
+     * @param info annotated node information
+     */
+    void addAnnotatedNodeInfo(AnnotatedNodeInfo info);
+}
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeException.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeException.java
new file mode 100644
index 0000000..f6b6f24
--- /dev/null
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeException.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.api;
+
+/**
+ * Represents base class for exceptions in YANG runtime operations.
+ */
+public class YangRuntimeException extends RuntimeException {
+
+    private static final long serialVersionUID = 20161028L;
+
+    /**
+     * Creates a new YANG runtime exception with given message. Exception
+     * message received from serializer is conveyed in this message.
+     *
+     * @param message the detail of exception in string
+     */
+    public YangRuntimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new YANG runtime exception from given message and cause.
+     * Exception message and cause received from serializer is conveyed in this
+     * message.
+     *
+     * @param message the detail of exception in string
+     * @param cause   underlying cause of the error
+     */
+    public YangRuntimeException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new YANG runtime exception with given message. Exception
+     * cause received from serializer is conveyed in this message.
+     *
+     * @param cause underlying cause of the error
+     */
+    public YangRuntimeException(final Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeService.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeService.java
index 745eaf5..ef966cf 100644
--- a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeService.java
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangRuntimeService.java
@@ -16,9 +16,7 @@
 
 package org.onosproject.yang.runtime.api;
 
-import org.onosproject.yang.model.DataNode;
-
-import java.io.InputStream;
+import java.util.List;
 
 /**
  * Service for encoding and decoding between internal and external model
@@ -28,24 +26,56 @@
 
     /**
      * Decodes the external representation of a configuration model from the
-     * specified input stream and into an in-memory representation.
+     * specified composite stream into an in-memory representation.
+     * <p>
+     * Resource identifier stream "URI" will get decoded to resource identifier
+     * and resource data stream will get decoded to data node.
+     * <p>
+     * Protocols like NETCONF may opt only to have resource data without
+     * resource identifier, which implies the data node construction from
+     * logical root resource ("/").
+     * <p>
+     * Also protocols like NETCONF will have decorations around the input stream
+     * which will be reported back to protocol in output. Produced
+     * annotations will be in order of preorder traversal.
      *
-     * @param external input stream carrying external representation of
-     *                 configuration data
-     * @param format   data format of the provided external representation
-     * @return in-memory representation of configuration data
+     * @param external      composite input stream carrying external
+     *                      representation of configuration data
+     * @param dataFormat    data format of the provided external representation
+     * @param nodeAnnotated true if annotations are expected, false otherwise
+     * @return in-memory representation of configuration data with decorated
+     * node information
+     * @throws YangRuntimeException when fails to perform decode operation
      */
-    DataNode decode(InputStream external, DataFormat format);
+    DecodedOutput decode(CompositeStream external, String dataFormat,
+                         boolean nodeAnnotated);
 
     /**
      * Encodes the internal in-memory representation of a configuration model
      * to an external representation consumable from the resulting input stream.
+     * <p>
+     * Resource identifier in composite data will get encoded to resource
+     * identifier stream and data node will be encoded to resource data
+     * stream.
+     * <p>
+     * Logical root node "/" will be removed during encoding and will not be
+     * part of either resource identifier or data node.
+     * <p>
+     * Protocols like NETCONF may opt only to have data node with
+     * resource identifier as null in order to only get complete output in
+     * form of body without URI.
+     * <p>
+     * Also protocols like NETCONF would like to provide additional
+     * decorations for the node. These decoration should be in preorder
+     * traversal order.
      *
-     * @param internal in-memory representation of configuration data
-     * @param format   expected data format of the external representation
+     * @param internal   in-memory representation of configuration data
+     * @param dataFormat expected data format of the external representation
+     * @param info       decorated node information
      * @return input stream carrying external representation of
      * configuration data
+     * @throws YangRuntimeException when fails to perform encode operation
      */
-    InputStream encode(DataNode internal, DataFormat format);
-
+    CompositeStream encode(CompositeData internal, String dataFormat,
+                           List<AnnotatedNodeInfo> info);
 }
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializer.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializer.java
index 3409d0b..5021a27 100644
--- a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializer.java
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializer.java
@@ -18,7 +18,7 @@
 
 import org.onosproject.yang.model.DataNode;
 
-import java.io.InputStream;
+import java.util.List;
 
 /**
  * Abstraction of entity capable of encoding and decoding arbitrary
@@ -36,30 +36,56 @@
      *
      * @return supported data format
      */
-    DataFormat supportsFormat();
+    String supportsFormat();
 
     /**
      * Decodes the external representation of a configuration model from the
-     * specified input stream and into an in-memory representation.
+     * specified composite stream into an in-memory representation.
+     * <p>
+     * Resource identifier stream "URI" will get decoded to resource identifier
+     * and resource data stream will get decoded to data node.
+     * <p>
+     * Protocols like NETCONF may opt only to have resource data without
+     * resource identifier, which implies the data node construction from
+     * logical root resource ("/").
+     * <p>
+     * Also protocols like NETCONF will have decorations around the input stream
+     * which will be reported back to protocol in output. Produced
+     * annotations will be in order of preorder traversal.
      *
-     * @param external input stream carrying external representation of
-     *                 configuration data
-     * @param context  serialization context containing information required
-     *                 for the serializer, e.g. access to model schemas
-     * @return in-memory representation of configuration data
+     * @param external composite input stream carrying external
+     *                 representation of configuration data
+     * @param context  YANG serializer context
+     * @return in-memory representation of configuration data with decorated
+     * node information
+     * @throws YangRuntimeException when fails to perform decode operation
      */
-    DataNode decode(InputStream external, YangSerializerContext context);
+    DecodedOutput decode(CompositeStream external, YangSerializerContext context);
 
     /**
      * Encodes the internal in-memory representation of a configuration model
      * to an external representation consumable from the resulting input stream.
+     * <p>
+     * Resource identifier in composite data will get encoded to resource
+     * identifier stream and data node will be encoded to resource data
+     * stream.
+     * <p>
+     * Logical root node "/" will be removed during encoding and will not be
+     * part of either resource identifier or data node.
+     * <p>
+     * Protocols like NETCONF may opt only to have data node with
+     * resource identifier as null in order to only get complete output in
+     * form of body without URI.
+     * <p>
+     * Also protocols like NETCONF would like to provide additional
+     * decorations for the node. These decoration should be in preorder
+     * traversal order.
      *
      * @param internal in-memory representation of configuration data
-     * @param context  serialization context containing information required
-     *                 for the serializer, e.g. access to model schemas
+     * @param info     decorated node information
      * @return input stream carrying external representation of
      * configuration data
+     * @throws YangRuntimeException when fails to perform decode operation
      */
-    InputStream encode(DataNode internal, YangSerializerContext context);
-
+    CompositeStream encode(CompositeData internal, List<AnnotatedNodeInfo> info);
 }
diff --git a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializerContext.java b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializerContext.java
index dbc543e..790d8fd 100644
--- a/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializerContext.java
+++ b/runtime/api/src/main/java/org/onosproject/yang/runtime/api/YangSerializerContext.java
@@ -16,12 +16,24 @@
 
 package org.onosproject.yang.runtime.api;
 
+import org.onosproject.yang.model.SchemaContext;
+
 /**
- * Representation of a context for encoding and decoding YANG models via
- * serializers.
+ * Representation of a context for decoding YANG models via serializers.
  */
 public interface YangSerializerContext {
 
-    // any required facilitites for serialization go here
-    //
+    /**
+     * Provides information about whether node annotation is expected.
+     *
+     * @return true if node can be annotated, false otherwise
+     */
+    boolean isNodeAnnotated();
+
+    /**
+     * Returns schema context of root node "/".
+     *
+     * @return schema context provider
+     */
+    SchemaContext getContext();
 }