New P4RuntimeClient implementation that supports batching and error reporting

The new client API supports batching and provides detailed response for
write requests (e.g. if entity already exists when inserting), which was
not possible with the old one.

This patch includes:
- New more efficient implementation of P4RuntimeClient (no more locking,
use native gRPC executor, use stub deadlines)
- Ported all codecs to new AbstractCodec-based implementation (needed to
implement codec cache in the future)
- Uses batching in P4RuntimeFlowRuleProgrammable and
P4RuntimeGroupActionProgrammable
- Minor changes to PI framework runtime classes

Change-Id: I3fac42057bb4e1389d761006a32600c786598683
(cherry picked from commit 4c289b731d950ea5a0d49582b7cecd636cf62727)
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
index cada0f9..1d1301e 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
@@ -17,6 +17,7 @@
 package org.onosproject.net.pi.model;
 
 import com.google.common.annotations.Beta;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.driver.HandlerBehaviour;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -108,14 +109,16 @@
             throws PiInterpreterException;
 
     /**
-     * Returns an inbound packet equivalent to the given PI packet operation.
+     * Returns an inbound packet equivalent to the given PI packet-in operation
+     * for the given device.
      *
      * @param packetOperation packet operation
+     * @param deviceId        ID of the device that originated the packet-in
      * @return inbound packet
      * @throws PiInterpreterException if the packet operation cannot be mapped
      *                                to an inbound packet
      */
-    InboundPacket mapInboundPacket(PiPacketOperation packetOperation)
+    InboundPacket mapInboundPacket(PiPacketOperation packetOperation, DeviceId deviceId)
             throws PiInterpreterException;
 
     /**