Allows to specify matches, action parameters as strings in PI

Some PI elements can encode in their value a string (e.g., when
a P4Runtime translation is used), for this reason we allow users
to specify matches and action parameters as strings.
From southbound, during decode, we interpret the elements as
string if the P4 model suggests that.

Change-Id: I5884de1500437ab647abc200d65de442e23bd1a8
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java
index 69b31a8..d0a285e 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/ActionCodec.java
@@ -74,10 +74,14 @@
         final PiAction.Builder builder = PiAction.builder()
                 .withId(PiActionId.of(actionName));
         for (P4RuntimeOuterClass.Action.Param p : message.getParamsList()) {
-            final String paramName = paramInfo.getById(p.getParamId()).getName();
-            final ImmutableByteSequence value = ImmutableByteSequence.copyFrom(
-                    p.getValue().toByteArray());
-            builder.withParameter(new PiActionParam(PiActionParamId.of(paramName), value));
+            final P4InfoOuterClass.Action.Param actionParam = paramInfo.getById(p.getParamId());
+            final ImmutableByteSequence value;
+            if (browser.isTypeString(actionParam.getTypeName())) {
+                value = ImmutableByteSequence.copyFrom(new String(p.getValue().toByteArray()));
+            } else {
+                value = ImmutableByteSequence.copyFrom(p.getValue().toByteArray());
+            }
+            builder.withParameter(new PiActionParam(PiActionParamId.of(actionParam.getName()), value));
         }
         return builder.build();
     }
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java
index d42e6b9..6b01546 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/FieldMatchCodec.java
@@ -152,16 +152,23 @@
             PiPipeconf pipeconf, P4InfoBrowser browser)
             throws CodecException, P4InfoBrowser.NotFoundException {
 
-        String fieldMatchName = browser.matchFields(tablePreamble.getId())
-                .getById(message.getFieldId()).getName();
-        PiMatchFieldId headerFieldId = PiMatchFieldId.of(fieldMatchName);
+        final P4InfoOuterClass.MatchField matchField =
+                browser.matchFields(tablePreamble.getId())
+                        .getById(message.getFieldId());
+        final PiMatchFieldId headerFieldId = PiMatchFieldId.of(matchField.getName());
+        final boolean isSdnString = browser.isTypeString(matchField.getTypeName());
 
         P4RuntimeOuterClass.FieldMatch.FieldMatchTypeCase typeCase = message.getFieldMatchTypeCase();
 
         switch (typeCase) {
             case EXACT:
                 P4RuntimeOuterClass.FieldMatch.Exact exactFieldMatch = message.getExact();
-                ImmutableByteSequence exactValue = copyFrom(exactFieldMatch.getValue().asReadOnlyByteBuffer());
+                ImmutableByteSequence exactValue;
+                if (isSdnString) {
+                    exactValue = copyFrom(new String(exactFieldMatch.getValue().toByteArray()));
+                } else {
+                    exactValue = copyFrom(exactFieldMatch.getValue().asReadOnlyByteBuffer());
+                }
                 return new PiExactFieldMatch(headerFieldId, exactValue);
             case TERNARY:
                 P4RuntimeOuterClass.FieldMatch.Ternary ternaryFieldMatch = message.getTernary();
@@ -180,7 +187,12 @@
                 return new PiRangeFieldMatch(headerFieldId, rangeLowValue, rangeHighValue);
             case OPTIONAL:
                 P4RuntimeOuterClass.FieldMatch.Optional optionalFieldMatch = message.getOptional();
-                ImmutableByteSequence optionalValue = copyFrom(optionalFieldMatch.getValue().asReadOnlyByteBuffer());
+                ImmutableByteSequence optionalValue;
+                if (isSdnString) {
+                    optionalValue = copyFrom(new String(optionalFieldMatch.getValue().toByteArray()));
+                } else {
+                    optionalValue = copyFrom(optionalFieldMatch.getValue().asReadOnlyByteBuffer());
+                }
                 return new PiOptionalFieldMatch(headerFieldId, optionalValue);
             default:
                 throw new CodecException(format(
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/PacketMetadataCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/PacketMetadataCodec.java
index 3f78085..876f84c 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/PacketMetadataCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/PacketMetadataCodec.java
@@ -17,6 +17,7 @@
 package org.onosproject.p4runtime.ctl.codec;
 
 import com.google.protobuf.ByteString;
+import org.onlab.util.ImmutableByteSequence;
 import org.onosproject.net.pi.model.PiPacketMetadataId;
 import org.onosproject.net.pi.model.PiPipeconf;
 import org.onosproject.net.pi.runtime.PiPacketMetadata;
@@ -54,14 +55,18 @@
             P4InfoOuterClass.Preamble ctrlPktMetaPreamble,
             PiPipeconf pipeconf, P4InfoBrowser browser)
             throws P4InfoBrowser.NotFoundException {
-        final String packetMetadataName = browser
-                .packetMetadatas(ctrlPktMetaPreamble.getId())
-                .getById(message.getMetadataId()).getName();
-        final PiPacketMetadataId metadataId = PiPacketMetadataId
-                .of(packetMetadataName);
+        final P4InfoOuterClass.ControllerPacketMetadata.Metadata packetMetadata =
+                browser.packetMetadatas(ctrlPktMetaPreamble.getId())
+                .getById(message.getMetadataId());
+        final ImmutableByteSequence value;
+        if (browser.isTypeString(packetMetadata.getTypeName())) {
+            value = copyFrom(new String(message.getValue().toByteArray()));
+        } else {
+            value = copyFrom(message.getValue().asReadOnlyByteBuffer());
+        }
         return PiPacketMetadata.builder()
-                .withId(metadataId)
-                .withValue(copyFrom(message.getValue().asReadOnlyByteBuffer()))
+                .withId(PiPacketMetadataId.of(packetMetadata.getName()))
+                .withValue(value)
                 .build();
     }
 }