[ONOS-7602]Implement support for P4Data in PI framework and P4Runtime southbound
Change-Id: I9c0c76fb29b8c3aa36f39bde62e825f0f0094253
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiData.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiData.java
new file mode 100644
index 0000000..97d5290
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiData.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Representation of data that can be used for runtime operations of a protocol-independent pipeline.
+ */
+@Beta
+public interface PiData {
+ /**
+ * Types of data in a protocol-independent pipeline.
+ */
+ enum Type {
+ /**
+ * Bit String.
+ */
+ BITSTRING,
+
+ /**
+ * Bool.
+ */
+ BOOL,
+
+ /**
+ * Tuple.
+ */
+ TUPLE,
+
+ /**
+ * Struct.
+ */
+ STRUCT,
+
+ /**
+ * Header.
+ */
+ HEADER,
+
+ /**
+ * Header Stack.
+ */
+ HEADERSTACK,
+
+ /**
+ * Header Union.
+ */
+ HEADERUNION,
+
+ /**
+ * Header Union Stack.
+ */
+ HEADERUNIONSTACK,
+
+ /**
+ * Enum String.
+ */
+ ENUMSTRING,
+
+ /**
+ * Error String.
+ */
+ ERRORSTRING
+ }
+
+ /**
+ * Returns the type of this protocol-independent data.
+ * @return the type of this instance
+ */
+ Type type();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBitString.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBitString.java
new file mode 100644
index 0000000..544f5df
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBitString.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * BitString entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiBitString implements PiData {
+ private final ImmutableByteSequence bitString;
+
+ /**
+ * Creates a new protocol-independent bit string instance.
+ *
+ * @param bitString bitString
+ */
+ private PiBitString(ImmutableByteSequence bitString) {
+ this.bitString = bitString;
+ }
+
+ /**
+ * Returns a new protocol-independent BitString.
+ * @param bitString bitString
+ * @return BitString
+ */
+ public static PiBitString of(ImmutableByteSequence bitString) {
+ return new PiBitString(bitString);
+ }
+
+ /**
+ * Return protocol-independent bitString instance.
+ *
+ * @return bitString
+ */
+ public ImmutableByteSequence bitString() {
+ return this.bitString;
+ }
+
+ @Override
+ public Type type() {
+ return Type.BITSTRING;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiBitString bitStr = (PiBitString) o;
+ return Objects.equal(bitString, bitStr.bitString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(bitString);
+ }
+
+ @Override
+ public String toString() {
+ return bitString.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBool.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBool.java
new file mode 100644
index 0000000..e100f03
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBool.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * Boolean entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiBool implements PiData {
+ private final Boolean bool;
+
+ /**
+ * Creates a new protocol-independent Bool instance.
+ *
+ * @param bool boolean
+ */
+ private PiBool(Boolean bool) {
+ this.bool = bool;
+ }
+
+ /**
+ * Returns a new protocol-independent Bool.
+ * @param bool boolean
+ * @return protocol-independent Bool
+ */
+ public static PiBool of(Boolean bool) {
+ return new PiBool(bool);
+ }
+
+ /**
+ * Return protocol-independent Boolean instance.
+ *
+ * @return bool
+ */
+ public Boolean bool() {
+ return this.bool;
+ }
+
+ @Override
+ public Type type() {
+ return Type.BOOL;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiBool boolValue = (PiBool) o;
+ return Objects.equal(bool, boolValue.bool);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(bool);
+ }
+
+ @Override
+ public String toString() {
+ return bool.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiEnumString.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiEnumString.java
new file mode 100644
index 0000000..74481ea
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiEnumString.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * EnumString entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiEnumString implements PiData {
+ private final String enumString;
+
+ /**
+ * Creates a new protocol-independent enum string instance.
+ *
+ * @param enumString enum string
+ */
+ private PiEnumString(String enumString) {
+ this.enumString = enumString;
+ }
+
+ /**
+ * Returns a new protocol-independent enum string.
+ * @param enumString enum string
+ * @return enum string
+ */
+ public static PiEnumString of(String enumString) {
+ return new PiEnumString(enumString);
+ }
+
+ /**
+ * Return protocol-independent enum string instance.
+ *
+ * @return enum string
+ */
+ public String enumString() {
+ return this.enumString;
+ }
+
+ @Override
+ public Type type() {
+ return Type.ENUMSTRING;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiEnumString enumStr = (PiEnumString) o;
+ return Objects.equal(enumString, enumStr.enumString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(enumString);
+ }
+
+ @Override
+ public String toString() {
+ return enumString;
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiErrorString.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiErrorString.java
new file mode 100644
index 0000000..ff4e172
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiErrorString.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * ErrorString entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiErrorString implements PiData {
+ private final String errorString;
+
+ /**
+ * Creates a new protocol-independent error string instance.
+ *
+ * @param errorString error string
+ */
+ private PiErrorString(String errorString) {
+ this.errorString = errorString;
+ }
+
+ /**
+ * Returns a new protocol-independent error string.
+ * @param errorString error string
+ * @return error string
+ */
+ public static PiErrorString of(String errorString) {
+ return new PiErrorString(errorString);
+ }
+
+ /**
+ * Return protocol-independent error string instance.
+ *
+ * @return error string
+ */
+ public String errorString() {
+ return this.errorString;
+ }
+
+ @Override
+ public Type type() {
+ return Type.ERRORSTRING;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiErrorString errorStr = (PiErrorString) o;
+ return Objects.equal(errorString, errorStr.errorString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(errorString);
+ }
+
+ @Override
+ public String toString() {
+ return errorString;
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeader.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeader.java
new file mode 100644
index 0000000..bbc0f8e
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeader.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Instance of a PiHeader in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeader implements PiData {
+ private final Boolean isValid;
+ private final ImmutableList<ImmutableByteSequence> bitStrings;
+
+ /**
+ * Creates a new protocol-independent header instance.
+ *
+ * @param isValid whether the header is valid
+ * @param bitStrings bitstrings
+ */
+ private PiHeader(Boolean isValid, List<ImmutableByteSequence> bitStrings) {
+ this.isValid = isValid;
+ this.bitStrings = ImmutableList.copyOf(bitStrings);
+ }
+
+ /**
+ * Returns a new protocol-independent header.
+ * @param isValid whether the header is valid
+ * @param bitStrings bitstrings
+ * @return header
+ */
+ public static PiHeader of(Boolean isValid, List<ImmutableByteSequence> bitStrings) {
+ return new PiHeader(isValid, bitStrings);
+ }
+
+ /**
+ * Return whether the header is valid.
+ *
+ * @return bool
+ */
+ public Boolean isValid() {
+ return this.isValid;
+ }
+
+ /**
+ * Return the header bit strings.
+ *
+ * @return the list of bit string
+ */
+ public List<ImmutableByteSequence> bitStrings() {
+ return this.bitStrings;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADER;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeader header = (PiHeader) o;
+ return Objects.equal(isValid, header.isValid) &&
+ Objects.equal(bitStrings, header.bitStrings);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(isValid, bitStrings);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.bitStrings().forEach(p -> stringParams.add(p.toString()));
+ return MoreObjects.toStringHelper(getClass())
+ .add("bitString", stringParams)
+ .add("isValid", isValid)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderStack.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderStack.java
new file mode 100644
index 0000000..ccf8af8
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderStack.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Instance of a PiHeaderStack in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeaderStack implements PiData {
+ private final ImmutableList<PiHeader> headers;
+
+ /**
+ * Creates a new protocol-independent header stack instance for the given collection of Header.
+ *
+ * @param headers the collection of header
+ */
+ private PiHeaderStack(List<PiHeader> headers) {
+ this.headers = ImmutableList.copyOf(headers);
+ }
+
+ /**
+ * Returns a new protocol-independent header stack.
+ * @param headers the list of header
+ * @return header stack
+ */
+ public static PiHeaderStack of(List<PiHeader> headers) {
+ return new PiHeaderStack(headers);
+ }
+
+ /**
+ * Return the list of header.
+ *
+ * @return the list of header
+ */
+ public List<PiHeader> headers() {
+ return this.headers;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADERSTACK;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeaderStack stack = (PiHeaderStack) o;
+ return Objects.equal(headers, stack.headers);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(headers);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.headers().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnion.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnion.java
new file mode 100644
index 0000000..189318c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnion.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * PiHeaderUnion entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeaderUnion implements PiData {
+ private final String validHeaderName;
+ private final PiHeader header;
+ private final boolean isValid;
+
+ /**
+ * Creates a new protocol-independent header union instance for the given header name and header.
+ *
+ * @param isValid indicates whether this header union is valid
+ * @param validHeaderName header name
+ * @param header the header
+ */
+ private PiHeaderUnion(boolean isValid, String validHeaderName, PiHeader header) {
+ this.isValid = isValid;
+ this.validHeaderName = validHeaderName;
+ this.header = header;
+ }
+
+ /**
+ * Returns a new invalid protocol-independent header union.
+ *
+ * @return header union
+ */
+ public static PiHeaderUnion ofInvalid() {
+ return new PiHeaderUnion(false, null, null);
+ }
+
+ /**
+ * Returns a new valid protocol-independent header union.
+ * @param validHeaderName header name
+ * @param header the header
+ * @return header union
+ */
+ public static PiHeaderUnion of(String validHeaderName, PiHeader header) {
+ checkNotNull(validHeaderName);
+ checkArgument(!validHeaderName.isEmpty(), "The header name must not be empty");
+ checkNotNull(header);
+ return new PiHeaderUnion(true, validHeaderName, header);
+ }
+
+ /**
+ * Returns true if this header is valid, false otherwise.
+ *
+ * @return a boolean value
+ */
+ public boolean isValid() {
+ return this.isValid;
+ }
+
+ /**
+ * Return the header name.
+ *
+ * @return header name, return null if the header union invalid
+ */
+ public String headerName() {
+ return this.validHeaderName;
+ }
+
+ /**
+ * Return the header.
+ *
+ * @return header, return null if the header union invalid
+ */
+ public PiHeader header() {
+ return this.header;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADERUNION;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeaderUnion headerUnion = (PiHeaderUnion) o;
+ return Objects.equal(validHeaderName, headerUnion.validHeaderName) &&
+ Objects.equal(header, headerUnion.header);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(validHeaderName, header);
+ }
+
+ @Override
+ public String toString() {
+ return !isValid ? "INVALID" : validHeaderName + ":" + header.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnionStack.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnionStack.java
new file mode 100644
index 0000000..a1e39b8
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnionStack.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * PiHeaderUnionStack entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeaderUnionStack implements PiData {
+ private final ImmutableList<PiHeaderUnion> headerUnions;
+
+ /**
+ * Creates a new protocol-independent header union stack instance for the given collection of HeaderUnion.
+ *
+ * @param headerUnions the collection of headerUnion
+ */
+ private PiHeaderUnionStack(List<PiHeaderUnion> headerUnions) {
+ this.headerUnions = ImmutableList.copyOf(headerUnions);
+ }
+
+ /**
+ * Returns a new protocol-independent header union stack.
+ * @param headerUnions the list of headerUnion
+ * @return header union stack
+ */
+ public static PiHeaderUnionStack of(List<PiHeaderUnion> headerUnions) {
+ return new PiHeaderUnionStack(headerUnions);
+ }
+
+ /**
+ * Return the collection of header union.
+ *
+ * @return the collection header union
+ */
+ public Collection<PiHeaderUnion> headerUnions() {
+ return this.headerUnions;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADERUNIONSTACK;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeaderUnionStack headerUnionStack = (PiHeaderUnionStack) o;
+ return Objects.equal(headerUnions, headerUnionStack.headerUnions);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(headerUnions);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.headerUnions().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiStruct.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiStruct.java
new file mode 100644
index 0000000..7c60c16
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiStruct.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Struct entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiStruct implements PiData {
+ private final ImmutableList<PiData> struct;
+
+ /**
+ * Creates a new protocol-independent struct instance for the given collection of PiData.
+ *
+ * @param struct the collection of PiData
+ */
+ private PiStruct(List<PiData> struct) {
+ this.struct = ImmutableList.copyOf(struct);
+ }
+
+ /**
+ * Returns a new protocol-independent struct.
+ * @param struct the list of PiData
+ * @return struct
+ */
+ public static PiStruct of(List<PiData> struct) {
+ return new PiStruct(struct);
+ }
+
+ /**
+ * Return protocol-independent struct instance.
+ *
+ * @return the list of PiData
+ */
+ public List<PiData> struct() {
+ return this.struct;
+ }
+
+ @Override
+ public Type type() {
+ return Type.STRUCT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiStruct st = (PiStruct) o;
+ return Objects.equal(struct, st.struct);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(struct);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.struct().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiTuple.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiTuple.java
new file mode 100644
index 0000000..e88fede
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiTuple.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Tuple entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiTuple implements PiData {
+ private final ImmutableList<PiData> tuple;
+
+ /**
+ * Creates a new protocol-independent tuple instance for the given collection of PiData.
+ *
+ * @param tuple the collection of PiData
+ */
+ private PiTuple(List<PiData> tuple) {
+ this.tuple = ImmutableList.copyOf(tuple);
+ }
+
+ /**
+ * Returns a new protocol-independent tuple.
+ * @param tuple the list of PiData
+ * @return tuple
+ */
+ public static PiTuple of(List<PiData> tuple) {
+ return new PiTuple(tuple);
+ }
+
+ /**
+ * Return protocol-independent tuple instance.
+ *
+ * @return the list of PiData
+ */
+ public List<PiData> tuple() {
+ return this.tuple;
+ }
+
+ @Override
+ public Type type() {
+ return Type.TUPLE;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiTuple tp = (PiTuple) o;
+ return Objects.equal(tuple, tp.tuple);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(tuple);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.tuple().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/package-info.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/package-info.java
new file mode 100644
index 0000000..86fa76b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Classes abstracting data that can be used for runtime operations of a protocol-independent pipeline.
+ */
+
+package org.onosproject.net.pi.runtime.data;
\ No newline at end of file
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiDataTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiDataTest.java
new file mode 100644
index 0000000..2915156
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiDataTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.net.pi.runtime;
+
+import com.google.common.collect.Lists;
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiData;
+import org.onosproject.net.pi.runtime.data.PiBitString;
+import org.onosproject.net.pi.runtime.data.PiBool;
+import org.onosproject.net.pi.runtime.data.PiEnumString;
+import org.onosproject.net.pi.runtime.data.PiErrorString;
+import org.onosproject.net.pi.runtime.data.PiHeader;
+import org.onosproject.net.pi.runtime.data.PiHeaderStack;
+import org.onosproject.net.pi.runtime.data.PiHeaderUnion;
+import org.onosproject.net.pi.runtime.data.PiHeaderUnionStack;
+import org.onosproject.net.pi.runtime.data.PiStruct;
+import org.onosproject.net.pi.runtime.data.PiTuple;
+
+import static org.junit.Assert.assertEquals;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Unit tests for PiData class.
+ */
+public class PiDataTest {
+ private final PiData bitString1 = PiBitString.of(ImmutableByteSequence.copyFrom(10));
+ private final PiData sameAsBitString1 = PiBitString.of(ImmutableByteSequence.copyFrom(10));
+ private final PiData bitString2 = PiBitString.of(ImmutableByteSequence.copyFrom(20));
+
+ private final PiData bool1 = PiBool.of(true);
+ private final PiData sameAsBool1 = PiBool.of(true);
+ private final PiData bool2 = PiBool.of(false);
+
+ private final PiData tuple1 = PiTuple.of(Lists.newArrayList(bool1));
+ private final PiData sameAsTuple1 = PiTuple.of(Lists.newArrayList(bool1));
+ private final PiData tuple2 = PiTuple.of(Lists.newArrayList(bitString1));
+
+ private final PiData struct1 = PiStruct.of(Lists.newArrayList(bool1));
+ private final PiData sameAsStruct1 = PiStruct.of(Lists.newArrayList(bool1));
+ private final PiData struct2 = PiStruct.of(Lists.newArrayList(bitString1));
+
+ private final PiData header1 = PiHeader.of(true,
+ Lists.newArrayList(ImmutableByteSequence.copyFrom(10)));
+ private final PiData sameAsHeader1 = PiHeader.of(true,
+ Lists.newArrayList(ImmutableByteSequence.copyFrom(10)));
+ private final PiData header2 = PiHeader.of(true,
+ Lists.newArrayList(ImmutableByteSequence.copyFrom(20)));
+
+ private final PiData headerUnion1 = PiHeaderUnion.of("port", (PiHeader) header1);
+ private final PiData sameAsHeaderUnion1 = PiHeaderUnion.of("port", (PiHeader) header1);
+ private final PiData headerUnion2 = PiHeaderUnion.of("port", (PiHeader) header2);
+
+ private final PiData inValidHeaderUnion1 = PiHeaderUnion.ofInvalid();
+ private final PiData sameAsInvalidHeaderUnion1 = PiHeaderUnion.ofInvalid();
+
+ private final PiData headerStack1 = PiHeaderStack.of(Lists.newArrayList((PiHeader) header1));
+ private final PiData sameAsHeaderStack1 = PiHeaderStack.of(Lists.newArrayList((PiHeader) header1));
+ private final PiData headerStack2 = PiHeaderStack.of(Lists.newArrayList((PiHeader) header2));
+
+ private final PiData headerUnionStack1 = PiHeaderUnionStack.of(Lists.newArrayList(
+ (PiHeaderUnion) headerUnion1));
+ private final PiData sameAsHeaderUnionStack1 = PiHeaderUnionStack.of(Lists.newArrayList(
+ (PiHeaderUnion) headerUnion1));
+ private final PiData headerUnionStack2 = PiHeaderUnionStack.of(Lists.newArrayList(
+ (PiHeaderUnion) headerUnion2));
+
+ private final PiData enumString1 = PiEnumString.of("test");
+ private final PiData sameAsEnumString1 = PiEnumString.of("test");
+ private final PiData enumString2 = PiEnumString.of("test1");
+
+ private final PiData errorString1 = PiErrorString.of("failed");
+ private final PiData sameAsErrorString1 = PiErrorString.of("failed");
+ private final PiData errorString2 = PiErrorString.of("success");
+
+ /**
+ * Checks that the PiData classes is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(PiBitString.class);
+ assertThatClassIsImmutable(PiBool.class);
+ assertThatClassIsImmutable(PiTuple.class);
+ assertThatClassIsImmutable(PiStruct.class);
+ assertThatClassIsImmutable(PiHeader.class);
+ assertThatClassIsImmutable(PiHeaderStack.class);
+ assertThatClassIsImmutable(PiHeaderUnion.class);
+ assertThatClassIsImmutable(PiHeaderUnionStack.class);
+ assertThatClassIsImmutable(PiEnumString.class);
+ assertThatClassIsImmutable(PiErrorString.class);
+ }
+
+ /**
+ * Checks the PiData type.
+ */
+ @Test
+ public void testPiDataType() {
+ assertEquals(bitString1.type(), PiData.Type.BITSTRING);
+ assertEquals(bool1.type(), PiData.Type.BOOL);
+ assertEquals(tuple1.type(), PiData.Type.TUPLE);
+ assertEquals(struct1.type(), PiData.Type.STRUCT);
+ assertEquals(header1.type(), PiData.Type.HEADER);
+ assertEquals(headerUnion1.type(), PiData.Type.HEADERUNION);
+ assertEquals(headerStack1.type(), PiData.Type.HEADERSTACK);
+ assertEquals(headerUnionStack1.type(), PiData.Type.HEADERUNIONSTACK);
+ assertEquals(enumString1.type(), PiData.Type.ENUMSTRING);
+ assertEquals(errorString1.type(), PiData.Type.ERRORSTRING);
+ }
+
+ /**
+ * Checks the operation of equals(), hashCode() and toString() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(bitString1, sameAsBitString1)
+ .addEqualityGroup(bitString2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(bool1, sameAsBool1)
+ .addEqualityGroup(bool2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(tuple1, sameAsTuple1)
+ .addEqualityGroup(tuple2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(struct1, sameAsStruct1)
+ .addEqualityGroup(struct2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(header1, sameAsHeader1)
+ .addEqualityGroup(header2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(headerUnion1, sameAsHeaderUnion1)
+ .addEqualityGroup(headerUnion2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(inValidHeaderUnion1, sameAsInvalidHeaderUnion1)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(headerStack1, sameAsHeaderStack1)
+ .addEqualityGroup(headerStack2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(headerUnionStack1, sameAsHeaderUnionStack1)
+ .addEqualityGroup(headerUnionStack2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(enumString1, sameAsEnumString1)
+ .addEqualityGroup(enumString2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(errorString1, sameAsErrorString1)
+ .addEqualityGroup(errorString2)
+ .testEquals();
+ }
+
+}
diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4DataCodec.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4DataCodec.java
new file mode 100644
index 0000000..5b0a2c5
--- /dev/null
+++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4DataCodec.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.p4runtime.ctl;
+
+import com.google.protobuf.ByteString;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.runtime.data.PiBitString;
+import org.onosproject.net.pi.runtime.data.PiBool;
+import org.onosproject.net.pi.model.PiData;
+import org.onosproject.net.pi.runtime.data.PiEnumString;
+import org.onosproject.net.pi.runtime.data.PiErrorString;
+import org.onosproject.net.pi.runtime.data.PiHeader;
+import org.onosproject.net.pi.runtime.data.PiHeaderStack;
+import org.onosproject.net.pi.runtime.data.PiHeaderUnion;
+import org.onosproject.net.pi.runtime.data.PiHeaderUnionStack;
+import org.onosproject.net.pi.runtime.data.PiStruct;
+import org.onosproject.net.pi.runtime.data.PiTuple;
+import org.slf4j.Logger;
+import p4.P4Types;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Encoder/decoder of PI Data entry to P4 Data entry protobuf
+ * messages, and vice versa.
+ */
+final class P4DataCodec {
+
+ private static final Logger log = getLogger(P4DataCodec.class);
+
+ private P4DataCodec() {
+ // Hides constructor.
+ }
+
+ private static P4Types.P4Header encodeHeader(PiHeader piHeader) {
+ P4Types.P4Header.Builder builder = P4Types.P4Header.newBuilder();
+ int i = 0;
+ for (ImmutableByteSequence bitString : piHeader.bitStrings()) {
+ builder.setBitstrings(i, ByteString.copyFrom(bitString.asArray()));
+ i++;
+ }
+ return builder.setIsValid(piHeader.isValid()).build();
+ }
+
+ private static PiHeader decodeHeader(P4Types.P4Header p4Header) {
+ List<ImmutableByteSequence> bitStrings = p4Header.getBitstringsList().stream()
+ .map(bit -> ImmutableByteSequence.copyFrom(bit.asReadOnlyByteBuffer()))
+ .collect(Collectors.toList());
+
+ return PiHeader.of(p4Header.getIsValid(), bitStrings);
+ }
+
+ private static P4Types.P4HeaderUnion encodeHeaderUnion(PiHeaderUnion headerUnion) {
+
+ P4Types.P4HeaderUnion.Builder builder = P4Types.P4HeaderUnion.newBuilder();
+ if (headerUnion.isValid()) {
+ builder.setValidHeader(encodeHeader(headerUnion.header()));
+ builder.setValidHeaderName(headerUnion.headerName());
+ } else {
+ // An empty string indicates that none of the union members are valid and
+ // valid_header must therefore be unset.
+ builder.setValidHeaderName("");
+ }
+
+ return builder.build();
+ }
+
+ private static PiHeaderUnion decodeHeaderUnion(P4Types.P4HeaderUnion p4HeaderUnion) {
+
+ return PiHeaderUnion.of(p4HeaderUnion.getValidHeaderName(),
+ decodeHeader(p4HeaderUnion.getValidHeader()));
+ }
+
+ private static P4Types.P4StructLike encodeStruct(PiStruct piStruct) {
+ P4Types.P4StructLike.Builder builder = P4Types.P4StructLike.newBuilder();
+ builder.addAllMembers(piStruct.struct().stream()
+ .map(piData -> encodeP4Data(piData))
+ .collect(Collectors.toList()));
+ return builder.build();
+ }
+
+ private static PiStruct decodeStruct(P4Types.P4StructLike p4StructLike) {
+
+ return PiStruct.of(p4StructLike.getMembersList().stream()
+ .map(p4Data -> decodeP4Data(p4Data))
+ .collect(Collectors.toList()));
+ }
+
+ private static P4Types.P4StructLike encodeTuple(PiTuple piTuple) {
+ P4Types.P4StructLike.Builder builder = P4Types.P4StructLike.newBuilder();
+ builder.addAllMembers(piTuple.tuple().stream()
+ .map(piData -> encodeP4Data(piData))
+ .collect(Collectors.toList()));
+ return builder.build();
+ }
+
+ private static PiTuple decodeTuple(P4Types.P4StructLike p4StructLike) {
+
+ return PiTuple.of(p4StructLike.getMembersList().stream()
+ .map(p4Data -> decodeP4Data(p4Data))
+ .collect(Collectors.toList()));
+ }
+
+ static P4Types.P4Data encodeP4Data(PiData piData) {
+
+ P4Types.P4Data.Builder builder = P4Types.P4Data.newBuilder();
+ switch (piData.type()) {
+ case BITSTRING:
+ builder.setBitstring(ByteString.copyFrom(((PiBitString) piData).bitString().asArray()));
+ break;
+ case ENUMSTRING:
+ builder.setEnum(((PiEnumString) piData).enumString());
+ break;
+ case ERRORSTRING:
+ builder.setError(((PiErrorString) piData).errorString());
+ break;
+ case BOOL:
+ builder.setBool(((PiBool) piData).bool());
+ break;
+ case STRUCT:
+ builder.setStruct(encodeStruct((PiStruct) piData));
+ break;
+ case TUPLE:
+ builder.setTuple(encodeTuple((PiTuple) piData));
+ break;
+ case HEADER:
+ builder.setHeader(encodeHeader((PiHeader) piData));
+ break;
+ case HEADERSTACK:
+ P4Types.P4HeaderStack.Builder headerStack = P4Types.P4HeaderStack.newBuilder();
+ int i = 0;
+ for (PiHeader header : ((PiHeaderStack) piData).headers()) {
+ headerStack.setEntries(i, encodeHeader(header));
+ i++;
+ }
+ builder.setHeaderStack(headerStack.build());
+ break;
+ case HEADERUNION:
+ builder.setHeaderUnion(encodeHeaderUnion((PiHeaderUnion) piData));
+ break;
+ case HEADERUNIONSTACK:
+ P4Types.P4HeaderUnionStack.Builder headerUnionStack = P4Types.P4HeaderUnionStack.newBuilder();
+ int j = 0;
+ for (PiHeaderUnion headerUnion : ((PiHeaderUnionStack) piData).headerUnions()) {
+ headerUnionStack.setEntries(j, encodeHeaderUnion(headerUnion));
+ j++;
+ }
+ builder.setHeaderUnionStack(headerUnionStack.build());
+ break;
+ default:
+ break;
+ }
+
+ return builder.build();
+ }
+
+ static PiData decodeP4Data(P4Types.P4Data p4Data) {
+ PiData piData = null;
+
+ switch (p4Data.getDataCase()) {
+ case BITSTRING:
+ piData = PiBitString.of(ImmutableByteSequence.copyFrom(p4Data.getBitstring().asReadOnlyByteBuffer()));
+ break;
+ case BOOL:
+ piData = PiBool.of(p4Data.getBool());
+ break;
+ case TUPLE:
+ piData = decodeTuple(p4Data.getTuple());
+ break;
+ case STRUCT:
+ piData = decodeStruct(p4Data.getStruct());
+ break;
+ case HEADER:
+ piData = decodeHeader(p4Data.getHeader());
+ break;
+ case HEADER_UNION:
+ piData = decodeHeaderUnion(p4Data.getHeaderUnion());
+ break;
+ case HEADER_STACK:
+ piData = PiHeaderStack.of(p4Data.getHeaderStack().getEntriesList().stream()
+ .map(p4header -> decodeHeader(p4header))
+ .collect(Collectors.toList()));
+ break;
+ case HEADER_UNION_STACK:
+ piData = PiHeaderUnionStack.of(p4Data.getHeaderUnionStack()
+ .getEntriesList().stream()
+ .map(p4HeaderUnion -> decodeHeaderUnion(p4HeaderUnion))
+ .collect(Collectors.toList()));
+ break;
+ case ENUM:
+ piData = PiEnumString.of(p4Data.getEnum());
+ break;
+ case ERROR:
+ piData = PiErrorString.of(p4Data.getError());
+ break;
+ case DATA_NOT_SET:
+ break;
+ default:
+ break;
+ }
+
+ return piData;
+ }
+}
\ No newline at end of file