PROTON-2430: Changed python binding to use pn_message_set/get_id/correlation_id

Stop using pn_message_id/pn_message_correlation_id which are inherently
ineefficient and should be deprecated.

Added in a SWIG typemap for pn_msgid_t that knows the types that are
necessary for msgid types.
diff --git a/python/cproton.i b/python/cproton.i
index 2a7bff9..f863cc7 100644
--- a/python/cproton.i
+++ b/python/cproton.i
@@ -96,10 +96,8 @@
 
 // These are not used/needed in the python binding
 %ignore pn_dtag;
-%ignore pn_message_get_id;
-%ignore pn_message_set_id;
-%ignore pn_message_get_correlation_id;
-%ignore pn_message_set_correlation_id;
+%ignore pn_message_id;
+%ignore pn_message_correlation_id;
 
 %ignore pn_list;
 %ignore pn_list_size;
@@ -163,6 +161,7 @@
   $result = PyLong_FromVoidPtr((void*)$1);
 }
 
+
 %typemap(in) pn_bytes_t {
   if ($input == Py_None) {
     $1.start = NULL;
@@ -181,6 +180,81 @@
   $result = PyBytes_FromStringAndSize($1.start, $1.size);
 }
 
+%typemap(in) pn_msgid_t {
+  if (PyTuple_Check($input)) {
+    pn_type_t type = PyLong_AsUnsignedLong(PyTuple_GetItem($input, 0));
+    PyObject* obj =  PyTuple_GetItem($input, 1);
+    switch (type) {
+      case PN_NULL:
+        break;
+      case PN_ULONG:
+        $1.u.as_ulong = PyLong_AsUnsignedLong(obj);
+        break;
+      case PN_UUID:
+        if (PyBytes_Check(obj)) {
+          memmove(&$1.u.as_uuid, PyBytes_AsString(obj), (PyBytes_Size(obj) < 16 ? PyBytes_Size(obj) : 16));
+          break;
+        }
+        type = PN_NULL;
+        break;
+      case PN_BINARY:
+        if (PyBytes_Check(obj)) {
+          $1.u.as_bytes = (pn_bytes_t){.size=PyBytes_Size(obj), .start=PyBytes_AsString(obj)};
+          break;
+        }
+        type = PN_NULL;
+        break;
+      case PN_STRING:
+        if (PyBytes_Check(obj)) {
+          $1.u.as_bytes = (pn_bytes_t){.size=PyBytes_Size(obj), .start=PyBytes_AsString(obj)};
+          break;
+        }
+      default:
+        type = PN_NULL;
+        break;
+    }
+    $1.type = type;
+  } else if (PyLong_Check($input)) {
+    $1.type = PN_ULONG;
+    $1.u.as_ulong = PyLong_AsUnsignedLong($input);
+  } else if (PyBytes_Check($input)) {
+    $1.type = PN_BINARY;
+    $1.u.as_bytes = (pn_bytes_t){.size=PyBytes_Size($input), .start=PyBytes_AsString($input)};
+  } else if (PyUnicode_Check($input)) {
+    $1.type = PN_STRING;
+    Py_ssize_t utf8size;
+    const char *utf8 = PyUnicode_AsUTF8AndSize($input, &utf8size);
+    $1.u.as_bytes = (pn_bytes_t){.size=utf8size, .start=utf8};
+  } else {
+    $1.type = PN_NULL;
+  }
+}
+
+%typemap(out) pn_msgid_t {
+  switch ($1.type) {
+    case PN_NULL:
+      $result = Py_None;
+      break;
+    case PN_ULONG:
+      $result = PyLong_FromUnsignedLong($1.u.as_ulong);
+      break;
+    case PN_BINARY:
+      $result = PyBytes_FromStringAndSize($1.u.as_bytes.start, $1.u.as_bytes.size);
+      break;
+    case PN_STRING:
+      $result = PyUnicode_FromStringAndSize($1.u.as_bytes.start, $1.u.as_bytes.size);
+      break;
+    case PN_UUID:
+      $result = PyTuple_New(2);
+      PyTuple_SetItem($result, 0, PyLong_FromUnsignedLong($1.type));
+      PyTuple_SetItem($result, 1, PyBytes_FromStringAndSize($1.u.as_uuid.bytes, 16));
+      break;
+    default:
+      $result = Py_None;
+      break;
+  }
+}
+
 %typemap(out) pn_delivery_tag_t {
   $result = PyBytes_FromStringAndSize($1.bytes, $1.size);
 }
diff --git a/python/proton/_message.py b/python/proton/_message.py
index 6952c8a..cf0f7b9 100644
--- a/python/proton/_message.py
+++ b/python/proton/_message.py
@@ -19,17 +19,17 @@
 
 from __future__ import absolute_import
 
-from cproton import PN_DEFAULT_PRIORITY, PN_OVERFLOW, pn_error_text, pn_message, \
-    pn_message_annotations, pn_message_body, pn_message_clear, pn_message_correlation_id, pn_message_decode, \
+from cproton import PN_DEFAULT_PRIORITY, PN_STRING, PN_UUID, PN_OVERFLOW, pn_error_text, pn_message, \
+    pn_message_annotations, pn_message_body, pn_message_clear, pn_message_decode, \
     pn_message_encode, pn_message_error, pn_message_free, pn_message_get_address, pn_message_get_content_encoding, \
-    pn_message_get_content_type, pn_message_get_creation_time, pn_message_get_delivery_count, \
-    pn_message_get_expiry_time, pn_message_get_group_id, pn_message_get_group_sequence, pn_message_get_priority, \
+    pn_message_get_content_type, pn_message_get_correlation_id, pn_message_get_creation_time, pn_message_get_delivery_count, \
+    pn_message_get_expiry_time, pn_message_get_group_id, pn_message_get_group_sequence, pn_message_get_id, pn_message_get_priority, \
     pn_message_get_reply_to, pn_message_get_reply_to_group_id, pn_message_get_subject, pn_message_get_ttl, \
-    pn_message_get_user_id, pn_message_id, pn_message_instructions, pn_message_is_durable, \
+    pn_message_get_user_id, pn_message_instructions, pn_message_is_durable, \
     pn_message_is_first_acquirer, pn_message_is_inferred, pn_message_properties, pn_message_set_address, \
-    pn_message_set_content_encoding, pn_message_set_content_type, pn_message_set_creation_time, \
+    pn_message_set_content_encoding, pn_message_set_content_type, pn_message_set_correlation_id, pn_message_set_creation_time, \
     pn_message_set_delivery_count, pn_message_set_durable, pn_message_set_expiry_time, pn_message_set_first_acquirer, \
-    pn_message_set_group_id, pn_message_set_group_sequence, pn_message_set_inferred, pn_message_set_priority, \
+    pn_message_set_group_id, pn_message_set_group_sequence, pn_message_set_id, pn_message_set_inferred, pn_message_set_priority, \
     pn_message_set_reply_to, pn_message_set_reply_to_group_id, pn_message_set_subject, \
     pn_message_set_ttl, pn_message_set_user_id
 
@@ -37,12 +37,12 @@
 from ._data import char, Data, symbol, ulong, AnnotationDict
 from ._endpoints import Link
 from ._exceptions import EXCEPTIONS, MessageException
+from uuid import UUID
 from typing import Dict, Optional, Union, TYPE_CHECKING, overload
 
 if TYPE_CHECKING:
     from proton._delivery import Delivery
     from proton._endpoints import Sender, Receiver
-    from uuid import UUID
     from proton._data import Described, PythonAMQPData
 
 
@@ -69,8 +69,6 @@
             **kwargs
     ) -> None:
         self._msg = pn_message()
-        self._id = Data(pn_message_id(self._msg))
-        self._correlation_id = Data(pn_message_correlation_id(self._msg))
         self.instructions = None
         self.annotations = None
         self.properties = None
@@ -273,14 +271,19 @@
                * ``bytes``
                * ``str``
         """
-        return self._id.get_object()
+        value = pn_message_get_id(self._msg)
+        if isinstance(value, tuple):
+            if value[0] == PN_UUID:
+                value = UUID(bytes=value[1])
+        return value
 
     @id.setter
     def id(self, value: Optional[Union[str, bytes, 'UUID', int]]) -> None:
         if isinteger(value):
             value = ulong(value)
-        self._id.rewind()
-        self._id.put_object(value)
+        elif isinstance(value, UUID):
+            value = (PN_UUID, value.bytes)
+        pn_message_set_id(self._msg, value)
 
     @property
     def user_id(self) -> bytes:
@@ -341,14 +344,19 @@
                * ``bytes``
                * ``str``
         """
-        return self._correlation_id.get_object()
+        value = pn_message_get_correlation_id(self._msg)
+        if isinstance(value, tuple):
+            if value[0] == PN_UUID:
+                value = UUID(bytes=value[1])
+        return value
 
     @correlation_id.setter
     def correlation_id(self, value: Optional[Union[str, bytes, 'UUID', int]]) -> None:
         if isinteger(value):
             value = ulong(value)
-        self._correlation_id.rewind()
-        self._correlation_id.put_object(value)
+        elif isinstance(value, UUID):
+            value = (PN_UUID, value.bytes)
+        pn_message_set_correlation_id(self._msg, value)
 
     @property
     def content_type(self) -> symbol: