ONOS-7078 Fixed inconsistencies when encoding/decoding P4Runtime msgs

Now P4InfoBrowser permits looking up entities by name only, not alias.
Applications should use names as defined in the P4Info when
creating PI IDs (e.g. PiCounterId). However, to avoid breaking support
with BMv2-based pipeline models, when referring to header fields in
tables, i.e. match fields, application should drop any scope identifier
from field names, e.g. "hdr.ethernet.src_addr" should be referred by
applications as "ethernet.src_addr". Such inconsistency will be fixed
with ONOS-7066.

Change-Id: I4d6dceadd233a293b845dba84e62a49680ac930b
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiCounterId.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiCounterId.java
index dcc7c02..015d86b 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiCounterId.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiCounterId.java
@@ -18,6 +18,7 @@
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
+import org.onlab.util.Identifier;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -26,12 +27,15 @@
  * Identifier of a counter of a protocol-independent pipeline.
  */
 @Beta
-public final class PiCounterId {
+public final class PiCounterId extends Identifier<String> {
 
+    private final String scope;
     private final String name;
     private final PiCounterType type;
 
-    private PiCounterId(String name, PiCounterType type) {
+    private PiCounterId(String scope, String name, PiCounterType type) {
+        super((!scope.isEmpty() ? scope + "." : "") + name);
+        this.scope = scope;
         this.name = name;
         this.type = type;
     }
@@ -47,7 +51,33 @@
         checkNotNull(name);
         checkNotNull(type);
         checkArgument(!name.isEmpty(), "Name can't be empty");
-        return new PiCounterId(name, type);
+        return new PiCounterId("", name, type);
+    }
+
+    /**
+     * Returns a counter identifier for the given scope, name, and type.
+     *
+     * @param scope counter scope
+     * @param name  counter name
+     * @param type  counter type
+     * @return counter identifier
+     */
+    public static PiCounterId of(String scope, String name, PiCounterType type) {
+        checkNotNull(scope);
+        checkNotNull(name);
+        checkNotNull(type);
+        checkArgument(!scope.isEmpty(), "Scope can't be empty");
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiCounterId(scope, name, type);
+    }
+
+    /**
+     * Returns the scope of the counter.
+     *
+     * @return counter scope
+     */
+    public String scope() {
+        return this.scope;
     }
 
     /**
@@ -77,17 +107,12 @@
             return false;
         }
         PiCounterId that = (PiCounterId) o;
-        return Objects.equal(name, that.name) &&
+        return Objects.equal(id(), that.id()) &&
                 type == that.type;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(name, type);
-    }
-
-    @Override
-    public String toString() {
-        return type.name().toLowerCase() + ":" + name;
+        return Objects.hashCode(id(), type);
     }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java
index 6af08ef..99f7e75 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java
@@ -26,6 +26,10 @@
  */
 public final class PiHeaderFieldId extends Identifier<String> {
 
+    // FIXME: this abstraction is brittle and we should drop any string-composition logic.
+    // e.g. in P4_14 there is no scope for match fields.
+    // In light of ONOS-7066, the best solution seems to have IDs defined as arbitrary
+    // strings equal to the entity names defined in the P4Info.
     private final String headerName;
     private final String fieldName;
     private final int index;