THRIFT-5591 Add uuid type to IDL and implement reference code (+ improved self-tests)
Client: compiler general, netstd, Delphi
Patch: Jens Geyer
diff --git a/.gitignore b/.gitignore
index 6278185..85b694c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -201,9 +201,9 @@
 /lib/delphi/*.local
 /lib/delphi/*.identcache
 /lib/delphi/test/skip/bin
-/lib/delphi/test/serializer/*.dat
+/lib/delphi/test/serializer/**/*.dat
 /lib/delphi/test/serializer/bin
-/lib/delphi/test/thrift-testing
+/lib/delphi/test/thrift-testing/*.thrift
 /lib/delphi/**/*.identcache
 /lib/delphi/**/*.local
 /lib/delphi/**/*.dcu
diff --git a/compiler/cpp/src/thrift/common.cc b/compiler/cpp/src/thrift/common.cc
index 6dcd855..3a28407 100644
--- a/compiler/cpp/src/thrift/common.cc
+++ b/compiler/cpp/src/thrift/common.cc
@@ -23,6 +23,7 @@
 t_type* g_type_void;
 t_type* g_type_string;
 t_type* g_type_binary;
+t_type* g_type_uuid;
 t_type* g_type_bool;
 t_type* g_type_i8;
 t_type* g_type_i16;
@@ -35,6 +36,7 @@
   g_type_string = new t_base_type("string", t_base_type::TYPE_STRING);
   g_type_binary = new t_base_type("string", t_base_type::TYPE_STRING);
   ((t_base_type*)g_type_binary)->set_binary(true);
+  g_type_uuid = new t_base_type("string", t_base_type::TYPE_UUID);
   g_type_bool = new t_base_type("bool", t_base_type::TYPE_BOOL);
   g_type_i8 = new t_base_type("i8", t_base_type::TYPE_I8);
   g_type_i16 = new t_base_type("i16", t_base_type::TYPE_I16);
@@ -46,6 +48,8 @@
 void clearGlobals() {
   delete g_type_void;
   delete g_type_string;
+  delete g_type_binary;
+  delete g_type_uuid;
   delete g_type_bool;
   delete g_type_i8;
   delete g_type_i16;
diff --git a/compiler/cpp/src/thrift/common.h b/compiler/cpp/src/thrift/common.h
index 06392cd..059421d 100644
--- a/compiler/cpp/src/thrift/common.h
+++ b/compiler/cpp/src/thrift/common.h
@@ -29,6 +29,7 @@
 extern t_type* g_type_void;
 extern t_type* g_type_string;
 extern t_type* g_type_binary;
+extern t_type* g_type_uuid;
 extern t_type* g_type_bool;
 extern t_type* g_type_i8;
 extern t_type* g_type_i16;
diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
index 8cb82c1..4ce9c5f 100644
--- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
@@ -723,6 +723,8 @@
       return "T_I64";
     case t_base_type::TYPE_DOUBLE:
       return "T_DOUBLE";
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "T_I32";
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index d9898b7..0420e62 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -689,7 +689,7 @@
       out << tenum->get_name() << "::type&";
     }
     out << " val) " ;
-	scope_up(out);
+    scope_up(out);
 
     out << indent() << "std::map<int, const char*>::const_iterator it = _"
              << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl;
@@ -1221,7 +1221,7 @@
 
   // Declare all fields
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-	generate_java_doc(out, *m_iter);
+    generate_java_doc(out, *m_iter);
     indent(out) << declare_field(*m_iter,
                                  false,
                                  (pointers && !(*m_iter)->get_type()->is_xception()),
@@ -2475,11 +2475,11 @@
   indent_up();
   if (style != "Cob") {
     f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr
-		<< " prot";
-	if (style == "Concurrent") {
-		f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
-	}
-	f_header_ << ") ";
+        << " prot";
+    if (style == "Concurrent") {
+        f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
+    }
+    f_header_ << ") ";
 
     if (extends.empty()) {
       if (style == "Concurrent") {
@@ -2498,12 +2498,12 @@
     }
 
     f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr
-		<< " iprot, " << prot_ptr << " oprot";
-	if (style == "Concurrent") {
-		f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
-	}
-	f_header_ << ") ";
-	
+        << " iprot, " << prot_ptr << " oprot";
+    if (style == "Concurrent") {
+        f_header_ << ", std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync";
+    }
+    f_header_ << ") ";
+    
     if (extends.empty()) {
       if (style == "Concurrent") {
         f_header_ << ": sync_(sync)" << endl;
@@ -4660,6 +4660,8 @@
       return "::apache::thrift::protocol::T_I64";
     case t_base_type::TYPE_DOUBLE:
       return "::apache::thrift::protocol::T_DOUBLE";
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "::apache::thrift::protocol::T_I32";
diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc
index afae5b5..f9e4856 100644
--- a/compiler/cpp/src/thrift/generate/t_d_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc
@@ -74,9 +74,9 @@
 
   // D reserved words are suffixed with an underscore
   static string suffix_if_reserved(const string& name) {
-	const bool isIn = std::binary_search(std::begin(d_reserved_words), std::end(d_reserved_words), name);
-	string ret = isIn ? name + "_" : name;
-	return ret;
+    const bool isIn = std::binary_search(std::begin(d_reserved_words), std::end(d_reserved_words), name);
+    string ret = isIn ? name + "_" : name;
+    return ret;
   }
 
   void init_generator() override {
@@ -403,8 +403,8 @@
       out << indent() << "// Your implementation goes here." << endl << indent() << "writeln(\""
           << suffix_if_reserved((*f_iter)->get_name()) << " called\");" << endl;
 
-	  t_type* rt = (*f_iter)->get_returntype();
-	  if (!rt->is_void()) {
+      t_type* rt = (*f_iter)->get_returntype();
+      if (!rt->is_void()) {
         indent(out) << "return typeof(return).init;" << endl;
       }
 
diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
index 65d0f53..61cd981 100644
--- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
@@ -2216,6 +2216,8 @@
       case t_base_type::TYPE_DOUBLE:
         result += " = 0.0";
         break;
+      default:
+        throw "compiler error: unhandled type";
       }
 
     } else if (ttype->is_enum()) {
@@ -2297,6 +2299,8 @@
       return "TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType.DOUBLE";
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "TType.I32";
@@ -2351,6 +2355,8 @@
   case t_base_type::TYPE_STRING:
     result = "";
     break;
+  default:
+    throw "compiler error: unhandled type";
   }
 
   return result;
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 2d0af11..f35ffcb 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -1024,6 +1024,7 @@
   // known base types
   types_known[type_name(g_type_string)] = 1;
   types_known[type_name(g_type_binary)] = 1;
+  types_known[type_name(g_type_uuid)] = 1;
   types_known[type_name(g_type_bool)] = 1;
   types_known[type_name(g_type_i8)] = 1;
   types_known[type_name(g_type_i16)] = 1;
@@ -1398,6 +1399,9 @@
     case t_base_type::TYPE_STRING:
       render << "'" << get_escaped_string(value) << "'";
       break;
+    case t_base_type::TYPE_UUID:
+      render << "['{" << value->get_uuid() << "}']";
+      break;
     case t_base_type::TYPE_BOOL:
       render << ((value->get_integer() > 0) ? "True" : "False");
       break;
@@ -2709,6 +2713,9 @@
           out << "ReadString();";
         }
         break;
+      case t_base_type::TYPE_UUID:
+        out << "ReadUuid();";
+        break;
       case t_base_type::TYPE_BOOL:
         out << "ReadBool();";
         break;
@@ -2910,6 +2917,9 @@
         }
         out << name << ");";
         break;
+      case t_base_type::TYPE_UUID:
+        out << "WriteUuid(" << name << ");";
+        break;
       case t_base_type::TYPE_BOOL:
         out << "WriteBool(" << name << ");";
         break;
@@ -3195,6 +3205,7 @@
 
     // these should be const'ed for optimal performamce
     case t_base_type::TYPE_STRING: // refcounted pointer
+    case t_base_type::TYPE_UUID:   // refcounted pointer
     case t_base_type::TYPE_I64:    // larger than 32 bit
     case t_base_type::TYPE_DOUBLE: // larger than 32 bit
       return "const ";
@@ -3247,6 +3258,8 @@
     } else {
       return com_types_ ? "System.WideString" : "System.string";
     }
+  case t_base_type::TYPE_UUID:
+    return "System.TGuid";
   case t_base_type::TYPE_BOOL:
     return "System.Boolean";
   case t_base_type::TYPE_I8:
@@ -3413,6 +3426,8 @@
       throw "NO T_VOID CONSTRUCT";
     case t_base_type::TYPE_STRING:
       return "TType.String_";
+    case t_base_type::TYPE_UUID:
+      return "TType.Uuid";
     case t_base_type::TYPE_BOOL:
       return "TType.Bool_";
     case t_base_type::TYPE_I8:
@@ -3461,6 +3476,8 @@
       } else {
         return "''";
       }
+    case t_base_type::TYPE_UUID:
+      return "System.TGuid.Empty";
     case t_base_type::TYPE_BOOL:
       return "False";
     case t_base_type::TYPE_I8:
@@ -4065,6 +4082,9 @@
                        << type_name(ttype, false, true, false, false) 
                        << ">.ToString( System.Ord( Self." 
                        << prop_name((*f_iter), is_exception) << ")));" << endl;
+    } else if (ttype->is_uuid()) {
+      indent_impl(out) << tmp_sb << ".Append( GUIDToString(Self." << prop_name((*f_iter), is_exception) << "));"
+                       << endl;
     } else {
       indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");"
                        << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index c06ea43..1f4fd50 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -1168,6 +1168,8 @@
       return "?tType_I64";
     case t_base_type::TYPE_DOUBLE:
       return "?tType_DOUBLE";
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "?tType_I32";
@@ -1211,6 +1213,8 @@
       return "i64";
     case t_base_type::TYPE_DOUBLE:
       return "double";
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "i32";
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc
index f4b94a4..90f34c8 100644
--- a/compiler/cpp/src/thrift/generate/t_go_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc
@@ -368,6 +368,8 @@
       } else {
         return value->get_double() == 0.;
       }
+    default:
+      throw "compiler error: unhandled type";
     }
   }
   return false;
@@ -420,6 +422,8 @@
     case t_base_type::TYPE_I64:
     case t_base_type::TYPE_DOUBLE:
       return !has_default;
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return !has_default;
@@ -4057,6 +4061,9 @@
 
     case t_base_type::TYPE_DOUBLE:
       return "thrift.DOUBLE";
+
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "thrift.I32";
@@ -4144,6 +4151,9 @@
 
     case t_base_type::TYPE_DOUBLE:
       return maybe_pointer + "float64";
+
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return maybe_pointer + publicize(type_name(type));
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index 757f207..fdd21f2 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -2698,6 +2698,8 @@
       case t_base_type::TYPE_DOUBLE:
         result += " = (double)0";
         break;
+      default:
+        throw "unhandled type";
       }
 
     } else if (ttype->is_enum()) {
@@ -2805,6 +2807,8 @@
       return "TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType.DOUBLE";
+    default:
+      break;
     }
   } else if (type->is_enum()) {
     return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 7dfd10f..743d150 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -1833,6 +1833,8 @@
           break;
         case t_base_type::TYPE_VOID:
           break;
+        default:
+          throw "compiler error: unhandled type";
         }
       }
     }
@@ -1931,6 +1933,8 @@
           break;
         case t_base_type::TYPE_VOID:
           break;
+        default:
+          throw "compiler error: unhandled type";
         }
       }
     }
@@ -4666,6 +4670,8 @@
       case t_base_type::TYPE_DOUBLE:
         result += " = (double)0";
         break;
+      default:
+        throw "compiler error: unhandled type";
       }
     } else if (ttype->is_enum()) {
       result += " = null";
@@ -4843,6 +4849,8 @@
       return "org.apache.thrift.protocol.TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "org.apache.thrift.protocol.TType.DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "org.apache.thrift.protocol.TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
index b37a43b..4da0869 100644
--- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
@@ -2869,6 +2869,8 @@
       case t_base_type::TYPE_DOUBLE:
         result += " = (double)0";
         break;
+      default:
+        throw "compiler error: unhandled type";
       }
 
     } else if (ttype->is_enum()) {
@@ -2951,6 +2953,8 @@
       return "TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType.DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index 5fcac16..03a307f 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -2697,6 +2697,8 @@
       return "Thrift.Type.I64";
     case t_base_type::TYPE_DOUBLE:
       return "Thrift.Type.DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "Thrift.Type.I32";
@@ -2745,6 +2747,9 @@
       break;
     case t_base_type::TYPE_VOID:
       ts_type = "void";
+      break;
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum() || type->is_struct() || type->is_xception()) {
     std::string type_name;
diff --git a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc
index 3a2afe6..3a3543e 100644
--- a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc
@@ -1892,6 +1892,8 @@
       return "org.apache.thrift.protocol.TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "org.apache.thrift.protocol.TType.DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "org.apache.thrift.protocol.TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index de3b890..a4b4a37 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -1146,6 +1146,8 @@
       return "TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType.DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc
index 17e90f7..0f6aa22 100644
--- a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc
@@ -199,7 +199,7 @@
         string fn_name = (*fn_iter)->get_name(); 
         filling.emplace_back();
         fill = &filling.back();
-        (*fill)[1] = "	[ &bull; " + fn_name + "](" 
+        (*fill)[1] = "    [ &bull; " + fn_name + "](" 
           + make_file_link(fname) 
           + "#function-" + str_to_id(name + fn_name) + ")";
       }
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
index ad9e579..5474571 100644
--- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
@@ -636,6 +636,9 @@
                 render << '"' << get_escaped_string(value) << '"';
             }
             break;
+        case t_base_type::TYPE_UUID:
+            render << "new System.Guid(\"" << get_escaped_string(value) << "\")";
+            break;
         case t_base_type::TYPE_BOOL:
             render << ((value->get_integer() > 0) ? "true" : "false");
             break;
@@ -2703,6 +2706,9 @@
                     out << "ReadStringAsync(" << CANCELLATION_TOKEN_NAME << ");";
                 }
                 break;
+            case t_base_type::TYPE_UUID:
+                out << "ReadUuidAsync(" << CANCELLATION_TOKEN_NAME << ");";
+                break;
             case t_base_type::TYPE_BOOL:
                 out << "ReadBoolAsync(" << CANCELLATION_TOKEN_NAME << ");";
                 break;
@@ -2906,6 +2912,9 @@
                 }
                 out << name << ", " << CANCELLATION_TOKEN_NAME << ");";
                 break;
+            case t_base_type::TYPE_UUID:
+                out << "WriteUuidAsync(" << nullable_name << ", " << CANCELLATION_TOKEN_NAME << ");";
+                break;
             case t_base_type::TYPE_BOOL:
                 out << "WriteBoolAsync(" << nullable_name << ", " << CANCELLATION_TOKEN_NAME << ");";
                 break;
@@ -3453,7 +3462,7 @@
     if (ttype->is_set())
     {
         t_set* tset = static_cast<t_set*>(ttype);
-		return "HashSet<" + type_name(tset->get_elem_type()) + ">";
+        return "HashSet<" + type_name(tset->get_elem_type()) + ">";
     }
 
     if (ttype->is_list())
@@ -3492,6 +3501,8 @@
         } else {
             return "string";
         }
+    case t_base_type::TYPE_UUID:
+        return "global::System.Guid";
     case t_base_type::TYPE_BOOL:
         return "bool";
     case t_base_type::TYPE_I8:
@@ -3614,6 +3625,9 @@
                 return " = null";
             }
             break;
+        case t_base_type::TYPE_UUID:
+            return " = System.Guid.Empty";
+            break;
         case t_base_type::TYPE_BOOL:
             return " = false";
             break;
@@ -3725,6 +3739,8 @@
             throw "NO T_VOID CONSTRUCT";
         case t_base_type::TYPE_STRING:
             return "TType.String";
+        case t_base_type::TYPE_UUID:
+            return "TType.Uuid";
         case t_base_type::TYPE_BOOL:
             return "TType.Bool";
         case t_base_type::TYPE_I8:
diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
index 0a96146..300b5ac 100644
--- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
@@ -1698,6 +1698,8 @@
       return "Protocol.T_I64";
     case t_base_type::TYPE_DOUBLE:
       return "Protocol.T_DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "Protocol.T_I32";
@@ -1739,6 +1741,8 @@
       return "Int64.t";
     case t_base_type::TYPE_DOUBLE:
       return "float";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return capitalize(((t_enum*)type)->get_name()) + ".t";
diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
index 68bd57f..72de698 100644
--- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
@@ -1003,12 +1003,12 @@
       f_service_ << indent() << "my $" << (*a_iter)->get_name() << " = (" << req << ") ? " << req
                  << " : undef;" << endl;
       /* slist no longer supported
-	  if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) {
+      if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) {
         f_service_ << indent() << "my @" << (*a_iter)->get_name() << " = split(/,/, $"
                    << (*a_iter)->get_name() << ");" << endl << indent() << "$"
                    << (*a_iter)->get_name() << " = \\@" << (*a_iter)->get_name() << endl;
       }
-	  */
+      */
     }
     f_service_ << indent() << "return $self->{impl}->" << (*f_iter)->get_name() << "("
                << argument_list((*f_iter)->get_arglist()) << ");" << endl;
@@ -1666,6 +1666,8 @@
       return "Thrift::TType::I64";
     case t_base_type::TYPE_DOUBLE:
       return "Thrift::TType::DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "Thrift::TType::I32";
diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc
index 39968a6..c6e60c8 100644
--- a/compiler/cpp/src/thrift/generate/t_php_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc
@@ -62,7 +62,7 @@
     validate_ = false;
     json_serializable_ = false;
     getters_setters_ = false;
-	    
+        
     nsglobal_ = ""; // by default global namespace is empty
     classmap_ = false;
     for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
@@ -874,8 +874,8 @@
  * Generates a setter for the generated private fields
  */
 void t_php_generator::generate_reflection_setters(ostringstream& out,
-						  string field_name,
-						  string cap_name) {
+                          string field_name,
+                          string cap_name) {
 
   out << indent() << "public function set" << cap_name << "(" << "$" << field_name << ")" << endl
       << indent() << "{" << endl;
@@ -2798,6 +2798,8 @@
       return "TType::I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType::DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "TType::I32";
@@ -2839,6 +2841,8 @@
       return "int";
     case t_base_type::TYPE_DOUBLE:
       return "double";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "int";
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index 7f3cae5..33437fd 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -2767,6 +2767,8 @@
       return "TType.I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType.DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "TType.I32";
diff --git a/compiler/cpp/src/thrift/generate/t_rb_generator.cc b/compiler/cpp/src/thrift/generate/t_rb_generator.cc
index 116ccaa..2ec5787 100644
--- a/compiler/cpp/src/thrift/generate/t_rb_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rb_generator.cc
@@ -1171,6 +1171,8 @@
       return "::Thrift::Types::I64";
     case t_base_type::TYPE_DOUBLE:
       return "::Thrift::Types::DOUBLE";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "::Thrift::Types::I32";
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index 6ce4027..5946e1d 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -1551,6 +1551,8 @@
     case t_base_type::TYPE_DOUBLE:
       f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << endl;
       return;
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (ttype->is_typedef()) {
     t_typedef* ttypedef = (t_typedef*) ttype;
@@ -1926,6 +1928,8 @@
     case t_base_type::TYPE_DOUBLE:
       f_gen_ << indent() << "let " << type_var << " = OrderedFloat::from(i_prot.read_double()?);" << endl;
       return;
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (ttype->is_typedef()) {
     // FIXME: not a fan of separate `is_boxed` parameter
@@ -3025,6 +3029,8 @@
       return "i64";
     case t_base_type::TYPE_DOUBLE:
       return "OrderedFloat<f64>";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (ttype->is_typedef()) {
     t_typedef* ttypedef = (t_typedef*)ttype;
@@ -3085,6 +3091,8 @@
       return "TType::I64";
     case t_base_type::TYPE_DOUBLE:
       return "TType::Double";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (ttype->is_enum()) {
     return "TType::I32";
@@ -3123,6 +3131,8 @@
       return "Some(0)";
     case t_base_type::TYPE_DOUBLE:
       return "Some(OrderedFloat::from(0.0))";
+    default:
+      throw "compiler error: unhandled type";
     }
 
   } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) {
diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc
index 109adc7..5edb852 100644
--- a/compiler/cpp/src/thrift/generate/t_st_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc
@@ -1037,6 +1037,8 @@
       return "TType i64";
     case t_base_type::TYPE_DOUBLE:
       return "TType double";
+    default:
+      throw "compiler error: unhandled type";
     }
   } else if (type->is_enum()) {
     return "TType i32";
diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
index d8eb733..834e31d 100644
--- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
@@ -51,7 +51,7 @@
                     const string& option_string)
     : t_oop_generator(program) {
     update_keywords();
-	
+    
     (void)option_string;
     map<string, string>::const_iterator iter;
 
@@ -292,7 +292,7 @@
 
 protected:
   std::set<std::string> lang_keywords() const override {
-	  return {};
+      return {};
   }
 };
 
@@ -3136,6 +3136,8 @@
           return result + "i64";
         case t_base_type::TYPE_DOUBLE:
           return result + "double";
+        default:
+          throw "compiler error: unhandled type";
       }
     } else if (type->is_enum()) {
       return result + "i32";
@@ -3168,6 +3170,8 @@
           return result + "I64";
         case t_base_type::TYPE_DOUBLE:
           return result + "DOUBLE";
+        default:
+          throw "compiler error: unhandled type";
       }
     } else if (type->is_enum()) {
       return result + "I32";
diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc
index c5aa65f..a07f429 100644
--- a/compiler/cpp/src/thrift/main.cc
+++ b/compiler/cpp/src/thrift/main.cc
@@ -738,6 +738,12 @@
         throw "type error: const \"" + name + "\" was declared as string";
       }
       break;
+    case t_base_type::TYPE_UUID:
+      if (value->get_type() != t_const_value::CV_STRING) {
+        throw "type error: const \"" + name + "\" was declared as uuid";
+      }
+      value->get_uuid(); // validates constant
+      break;
     case t_base_type::TYPE_BOOL:
       if (value->get_type() != t_const_value::CV_INTEGER) {
         throw "type error: const \"" + name + "\" was declared as bool";
diff --git a/compiler/cpp/src/thrift/parse/t_base_type.h b/compiler/cpp/src/thrift/parse/t_base_type.h
index 5676f04..4e5228d 100644
--- a/compiler/cpp/src/thrift/parse/t_base_type.h
+++ b/compiler/cpp/src/thrift/parse/t_base_type.h
@@ -36,6 +36,7 @@
   enum t_base {
     TYPE_VOID,
     TYPE_STRING,
+    TYPE_UUID,
     TYPE_BOOL,
     TYPE_I8,
     TYPE_I16,
@@ -55,6 +56,8 @@
 
   bool is_bool() const override { return base_ == TYPE_BOOL; }
 
+  bool is_uuid() const override { return base_ == TYPE_UUID; }
+
   void set_binary(bool val) { binary_ = val; }
 
   bool is_binary() const override { return binary_ && (base_ == TYPE_STRING); }
@@ -69,6 +72,9 @@
     case TYPE_STRING:
       return "string";
       break;
+    case TYPE_UUID:
+      return "uuid";
+      break;
     case TYPE_BOOL:
       return "bool";
       break;
diff --git a/compiler/cpp/src/thrift/parse/t_const_value.h b/compiler/cpp/src/thrift/parse/t_const_value.h
index 5b8156f..452a90c 100644
--- a/compiler/cpp/src/thrift/parse/t_const_value.h
+++ b/compiler/cpp/src/thrift/parse/t_const_value.h
@@ -85,6 +85,17 @@
     }
   }
 
+  void set_uuid(std::string val) {
+    validate_uuid(val);
+    valType_ = CV_STRING;
+    stringVal_ = val;
+  }
+
+  std::string get_uuid() const {
+    validate_uuid(stringVal_);
+    return stringVal_;
+  }
+
   void set_double(double val) {
     valType_ = CV_DOUBLE;
     doubleVal_ = val;
@@ -199,6 +210,34 @@
   t_enum* enum_;
 
   t_const_value_type valType_;
+  
+  void validate_uuid(std::string uuid) const {
+    bool valid = (uuid.length() == 36);
+    const std::string HEXCHARS = std::string("0123456789ABCDEFabcdef");
+
+    // canonical format "01234567-9012-4567-9012-456789012345" expected
+    for( size_t i = 0; valid && (i < uuid.length()); ++i) {
+      switch(i) {
+        case 8:
+        case 13:
+        case 18:
+        case 23:
+          if(uuid[i] != '-') {
+            valid = false;
+          }			  
+          break;
+        default:
+          if(HEXCHARS.find(uuid[i]) == std::string::npos) {
+            valid = false;
+          }			  
+          break;
+      }        
+    }
+
+    if( ! valid) {
+      throw "invalid uuid " + uuid;
+    }
+  }
 };
 
 #endif
diff --git a/compiler/cpp/src/thrift/parse/t_scope.h b/compiler/cpp/src/thrift/parse/t_scope.h
index 17a360f..71ab4f3 100644
--- a/compiler/cpp/src/thrift/parse/t_scope.h
+++ b/compiler/cpp/src/thrift/parse/t_scope.h
@@ -166,6 +166,9 @@
           case t_base_type::TYPE_STRING:
             const_val->set_string(constant->get_value()->get_string());
             break;
+          case t_base_type::TYPE_UUID:
+            const_val->set_uuid(constant->get_value()->get_uuid());
+            break;
           case t_base_type::TYPE_DOUBLE:
             const_val->set_double(constant->get_value()->get_double());
             break;
diff --git a/compiler/cpp/src/thrift/parse/t_type.h b/compiler/cpp/src/thrift/parse/t_type.h
index 63f99ed..8dbeb9e 100644
--- a/compiler/cpp/src/thrift/parse/t_type.h
+++ b/compiler/cpp/src/thrift/parse/t_type.h
@@ -47,6 +47,7 @@
   virtual bool is_void() const { return false; }
   virtual bool is_base_type() const { return false; }
   virtual bool is_string() const { return false; }
+  virtual bool is_uuid() const { return false; }
   virtual bool is_binary() const { return false; }
   virtual bool is_bool() const { return false; }
   virtual bool is_typedef() const { return false; }
diff --git a/compiler/cpp/src/thrift/thriftl.ll b/compiler/cpp/src/thrift/thriftl.ll
index 810a983..d60e846 100644
--- a/compiler/cpp/src/thrift/thriftl.ll
+++ b/compiler/cpp/src/thrift/thriftl.ll
@@ -239,6 +239,7 @@
 "double"             { return tok_double;               }
 "string"             { return tok_string;               }
 "binary"             { return tok_binary;               }
+"uuid"               { return tok_uuid;                 }
 "slist" {
   error_no_longer_supported("slist","string");
 }
diff --git a/compiler/cpp/src/thrift/thrifty.yy b/compiler/cpp/src/thrift/thrifty.yy
index a062a0e..40c2a93 100644
--- a/compiler/cpp/src/thrift/thrifty.yy
+++ b/compiler/cpp/src/thrift/thrifty.yy
@@ -134,6 +134,7 @@
 %token tok_bool
 %token tok_string
 %token tok_binary
+%token tok_uuid
 %token tok_i8
 %token tok_i16
 %token tok_i32
@@ -1002,6 +1003,11 @@
       pdebug("BaseType -> tok_binary");
       $$ = g_type_binary;
     }
+| tok_uuid
+    {
+      pdebug("BaseType -> tok_uuid");
+      $$ = g_type_uuid;
+    }
 | tok_bool
     {
       pdebug("BaseType -> tok_bool");
diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas
index 3a1dbfd..02a19ea 100644
--- a/lib/delphi/src/Thrift.Protocol.Compact.pas
+++ b/lib/delphi/src/Thrift.Protocol.Compact.pas
@@ -77,7 +77,8 @@
       LIST          = $09,
       SET_          = $0A,
       MAP           = $0B,
-      STRUCT        = $0C
+      STRUCT        = $0C,
+      UUID          = $0D
     );
 
   private type
@@ -100,7 +101,8 @@
       Types.STRUCT,         // Struct  = 12,
       Types.MAP,            // Map     = 13,
       Types.SET_,           // Set_    = 14,
-      Types.LIST            // List    = 15,
+      Types.LIST,           // List    = 15,
+      Types.UUID            // Uuid    = 16
     );
 
     tcompactTypeToType : array[Types] of TType = (
@@ -116,7 +118,8 @@
       TType.List,       // LIST
       TType.Set_,       // SET_
       TType.Map,        // MAP
-      TType.Struct      // STRUCT
+      TType.Struct,     // STRUCT
+      TType.Uuid        // UUID
     );
 
   strict private
@@ -173,6 +176,7 @@
     procedure WriteI64( const i64: Int64); override;
     procedure WriteDouble( const dub: Double); override;
     procedure WriteBinary( const b: TBytes); overload; override;
+    procedure WriteUuid( const uuid: TGuid); override;
 
   private  // unit visible stuff
     class function  DoubleToInt64Bits( const db : Double) : Int64;
@@ -219,6 +223,7 @@
     function  ReadI64: Int64; override;
     function  ReadDouble:Double; override;
     function  ReadBinary: TBytes; overload; override;
+    function  ReadUuid: TGuid; override;
 
   private
     // Internal Reading methods
@@ -537,6 +542,14 @@
   Transport.Write( b);
 end;
 
+procedure TCompactProtocolImpl.WriteUuid( const uuid: TGuid);
+var network : TGuid;  // in network order (Big Endian)
+begin
+  ASSERT( SizeOf(uuid) = 16);
+  network := uuid.SwapByteOrder;
+  Transport.Write( @network, 0, SizeOf(network));
+end;
+
 procedure TCompactProtocolImpl.WriteMessageEnd;
 begin
   // nothing to do
@@ -850,6 +863,14 @@
   then Transport.ReadAll( result, 0, length);
 end;
 
+function TCompactProtocolImpl.ReadUuid: TGuid;
+var network : TGuid;  // in network order (Big Endian)
+begin
+  ASSERT( SizeOf(result) = 16);
+  FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
+  result := network.SwapByteOrder;
+end;
+
 
 procedure TCompactProtocolImpl.ReadMessageEnd;
 begin
@@ -994,6 +1015,7 @@
     TType.Map:     result := SizeOf(Byte);  // element count
     TType.Set_:    result := SizeOf(Byte);  // element count
     TType.List:    result := SizeOf(Byte);  // element count
+    TType.Uuid:    result := SizeOf(TGuid);
   else
     raise TTransportExceptionBadArgs.Create('Unhandled type code');
   end;
diff --git a/lib/delphi/src/Thrift.Protocol.JSON.pas b/lib/delphi/src/Thrift.Protocol.JSON.pas
index 52909b7..2a9682c 100644
--- a/lib/delphi/src/Thrift.Protocol.JSON.pas
+++ b/lib/delphi/src/Thrift.Protocol.JSON.pas
@@ -198,6 +198,7 @@
     procedure WriteDouble( const d: Double); override;
     procedure WriteString( const s: string );   override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteUuid( const uuid: TGuid); override;
     //
     function ReadMessageBegin: TThriftMessage; override;
     procedure ReadMessageEnd(); override;
@@ -219,6 +220,7 @@
     function ReadDouble:Double; override;
     function ReadString : string;  override;
     function ReadBinary: TBytes; override;
+    function ReadUuid: TGuid; override;
 
 
   strict private
@@ -288,6 +290,7 @@
   NAME_MAP    = 'map';
   NAME_LIST   = 'lst';
   NAME_SET    = 'set';
+  NAME_UUID   = 'uid';
 
   INVARIANT_CULTURE : TFormatSettings
                     = ( ThousandSeparator: ',';
@@ -317,6 +320,7 @@
     TType.Map:      result := NAME_MAP;
     TType.Set_:     result := NAME_SET;
     TType.List:     result := NAME_LIST;
+    TType.Uuid:     result := NAME_UUID;
   else
     raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+IntToStr(Ord(typeID))+')');
   end;
@@ -336,6 +340,7 @@
   else if name = NAME_MAP    then result := TType.Map
   else if name = NAME_LIST   then result := TType.List
   else if name = NAME_SET    then result := TType.Set_
+  else if name = NAME_UUID   then result := TType.Uuid
   else raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+name+')');
 end;
 
@@ -831,6 +836,11 @@
   WriteJSONBase64( b);
 end;
 
+procedure TJSONProtocolImpl.WriteUuid( const uuid: TGuid);
+begin
+  WriteString( Copy( GuidToString(uuid), 2, 36));  // strip off the { braces }
+end;
+
 
 function TJSONProtocolImpl.ReadJSONString( skipContext : Boolean) : TBytes;
 var buffer : TThriftMemoryStream;
@@ -1237,6 +1247,12 @@
 end;
 
 
+function TJSONProtocolImpl.ReadUuid: TGuid;
+begin
+  result := StringToGUID( '{' + ReadString + '}');
+end;
+
+
 function TJSONProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
 // Return the minimum number of bytes a type will consume on the wire
 begin
@@ -1254,6 +1270,7 @@
     TType.Map:     result := 2;  // empty map
     TType.Set_:    result := 2;  // empty set
     TType.List:    result := 2;  // empty list
+    TType.Uuid:    result := 36; // "E236974D-F0B0-4E05-8F29-0B455D41B1A1"
   else
     raise TTransportExceptionBadArgs.Create('Unhandled type code');
   end;
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 9f2cac8..636f201 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -49,7 +49,8 @@
     Struct = 12,
     Map = 13,
     Set_ = 14,
-    List = 15
+    List = 15,
+    Uuid = 16
   );
 
   TMessageType = (
@@ -62,7 +63,7 @@
 const
   VALID_TTYPES = [
     TType.Stop, TType.Void,
-    TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_,
+    TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid,
     TType.Struct, TType.Map, TType.Set_, TType.List
   ];
 
@@ -221,6 +222,7 @@
     procedure WriteAnsiString( const s: AnsiString);
     procedure WriteBinary( const b: TBytes); overload;
     procedure WriteBinary( const b: IThriftBytes); overload;
+    procedure WriteUuid( const uuid: TGuid);
 
     function ReadMessageBegin: TThriftMessage;
     procedure ReadMessageEnd();
@@ -242,6 +244,7 @@
     function ReadDouble:Double;
     function ReadBinary: TBytes;  // IMPORTANT: this is NOT safe across module boundaries
     function ReadBinaryCOM : IThriftBytes;
+    function ReadUuid: TGuid;
     function ReadString: string;
     function ReadAnsiString: AnsiString;
 
@@ -297,6 +300,7 @@
     procedure WriteString( const s: string ); virtual;
     procedure WriteAnsiString( const s: AnsiString); virtual;
     procedure WriteBinary( const b: TBytes); overload; virtual; abstract;
+    procedure WriteUuid( const b: TGuid); virtual; abstract;
 
     function ReadMessageBegin: TThriftMessage; virtual; abstract;
     procedure ReadMessageEnd(); virtual; abstract;
@@ -317,6 +321,7 @@
     function ReadI64: Int64; virtual; abstract;
     function ReadDouble:Double; virtual; abstract;
     function ReadBinary: TBytes; virtual; abstract;
+    function ReadUuid: TGuid; virtual; abstract;
     function ReadString: string; virtual;
     function ReadAnsiString: AnsiString; virtual;
 
@@ -415,6 +420,7 @@
     procedure WriteI64( const i64: Int64); override;
     procedure WriteDouble( const d: Double); override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteUuid( const uuid: TGuid); override;
 
     function ReadMessageBegin: TThriftMessage; override;
     procedure ReadMessageEnd(); override;
@@ -435,6 +441,7 @@
     function ReadI64: Int64; override;
     function ReadDouble:Double; override;
     function ReadBinary: TBytes; override;
+    function ReadUuid: TGuid; override;
 
   end;
 
@@ -479,6 +486,7 @@
     procedure WriteString( const s: string ); override;
     procedure WriteAnsiString( const s: AnsiString); override;
     procedure WriteBinary( const b: TBytes); override;
+    procedure WriteUuid( const uuid: TGuid); override;
 
     function ReadMessageBegin: TThriftMessage; override;
     procedure ReadMessageEnd(); override;
@@ -499,6 +507,7 @@
     function ReadI64: Int64; override;
     function ReadDouble:Double; override;
     function ReadBinary: TBytes; override;
+    function ReadUuid: TGuid; override;
     function ReadString: string; override;
     function ReadAnsiString: AnsiString; override;
   end;
@@ -800,6 +809,7 @@
     TType.I64     :  prot.ReadI64();
     TType.Double_ :  prot.ReadDouble();
     TType.String_ :  prot.ReadBinary();// Don't try to decode the string, just skip it.
+    TType.Uuid    :  prot.ReadUuid();
 
     // structured types
     TType.Struct :  begin
@@ -874,6 +884,14 @@
   Result := buf;
 end;
 
+function TBinaryProtocolImpl.ReadUuid : TGuid;
+var network : TGuid;  // in network order (Big Endian)
+begin
+  ASSERT( SizeOf(result) = 16);
+  FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network));
+  result := network.SwapByteOrder;
+end;
+
 function TBinaryProtocolImpl.ReadBool: Boolean;
 begin
   Result := (ReadByte = 1);
@@ -1042,6 +1060,14 @@
   if iLen > 0 then FTrans.Write(b, 0, iLen);
 end;
 
+procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid);
+var network : TGuid;  // in network order (Big Endian)
+begin
+  ASSERT( SizeOf(uuid) = 16);
+  network := uuid.SwapByteOrder;
+  Transport.Write( @network, 0, SizeOf(network));
+end;
+
 procedure TBinaryProtocolImpl.WriteBool(b: Boolean);
 begin
   if b then begin
@@ -1191,6 +1217,7 @@
     TType.Map:     result := SizeOf(Int32);  // element count
     TType.Set_:    result := SizeOf(Int32);  // element count
     TType.List:    result := SizeOf(Int32);  // element count
+    TType.Uuid:    result := SizeOf(TGuid);
   else
     raise TTransportExceptionBadArgs.Create('Unhandled type code');
   end;
@@ -1437,6 +1464,12 @@
 end;
 
 
+procedure TProtocolDecorator.WriteUuid( const uuid: TGuid);
+begin
+  FWrappedProtocol.WriteUuid( uuid);
+end;
+
+
 function TProtocolDecorator.ReadMessageBegin: TThriftMessage;
 begin
   result := FWrappedProtocol.ReadMessageBegin;
@@ -1551,6 +1584,12 @@
 end;
 
 
+function TProtocolDecorator.ReadUuid: TGuid;
+begin
+  result := FWrappedProtocol.ReadUuid;
+end;
+
+
 function TProtocolDecorator.ReadString: string;
 begin
   result := FWrappedProtocol.ReadString;
diff --git a/lib/delphi/src/Thrift.Utils.pas b/lib/delphi/src/Thrift.Utils.pas
index 4a75af8..1226535 100644
--- a/lib/delphi/src/Thrift.Utils.pas
+++ b/lib/delphi/src/Thrift.Utils.pas
@@ -84,11 +84,34 @@
     class function IsHtmlDoctype( const fourBytes : Integer) : Boolean; static;
   end;
 
+
+  IntegerUtils = class sealed
+  strict private
+    class procedure SwapBytes( var one, two : Byte); static; inline;
+    class procedure Swap2( const pValue : Pointer); static;
+    class procedure Swap4( const pValue : Pointer); static;
+    class procedure Swap8( const pValue : Pointer); static;
+  public
+    class procedure SwapByteOrder( const pValue : Pointer; const size : Integer); overload; static;
+  end;
+
+
+  TGuidHelper = record helper for System.TGuid
+  public
+    function SwapByteOrder : TGuid;
+
+    {$IFDEF Debug}
+    class procedure SelfTest; static;
+    {$ENDIF}
+  end;
+
+
   EnumUtils<T> = class sealed
   public
     class function ToString(const value : Integer) : string;  reintroduce; static; inline;
   end;
 
+
   StringUtils<T> = class sealed
   public
     class function ToString(const value : T) : string;  reintroduce; static; inline;
@@ -283,6 +306,97 @@
   result := (UpCase(pc^) = HTML_BEGIN[3]);
 end;
 
+{ IntegerUtils }
+
+
+class procedure IntegerUtils.SwapBytes( var one, two : Byte);
+var tmp : Byte;
+begin
+  tmp := one;
+  one := two;
+  two := tmp;
+end;
+
+
+class procedure IntegerUtils.Swap2( const pValue : Pointer);
+var pData : PByteArray absolute pValue;
+begin
+  SwapBytes( pData^[0], pData^[1]);
+end;
+
+
+class procedure IntegerUtils.Swap4( const pValue : Pointer);
+var pData : PByteArray absolute pValue;
+begin
+  SwapBytes( pData^[0], pData^[3]);
+  SwapBytes( pData^[1], pData^[2]);
+end;
+
+
+class procedure IntegerUtils.Swap8( const pValue : Pointer);
+var pData : PByteArray absolute pValue;
+begin
+  SwapBytes( pData^[0], pData^[7]);
+  SwapBytes( pData^[1], pData^[6]);
+  SwapBytes( pData^[2], pData^[5]);
+  SwapBytes( pData^[3], pData^[4]);
+end;
+
+
+class procedure IntegerUtils.SwapByteOrder( const pValue : Pointer; const size : Integer);
+begin
+  case size of
+    2 : Swap2( pValue);
+    4 : Swap4( pValue);
+    8 : Swap8( pValue);
+  else
+    raise EArgumentException.Create('Unexpected size');
+  end;
+end;
+
+
+{ TGuidHelper }
+
+
+function TGuidHelper.SwapByteOrder : TGuid;
+// convert to/from network byte order
+// - https://www.ietf.org/rfc/rfc4122.txt
+// - https://stackoverflow.com/questions/10850075/guid-uuid-compatibility-issue-between-net-and-linux
+// - https://lists.gnu.org/archive/html/bug-parted/2002-01/msg00099.html
+begin
+  result := Self;
+
+  IntegerUtils.SwapByteOrder( @result.D1, SizeOf(result.D1));
+  IntegerUtils.SwapByteOrder( @result.D2, SizeOf(result.D2));
+  IntegerUtils.SwapByteOrder( @result.D3, SizeOf(result.D3));
+  //result.D4 = array of byte -> implicitly correct
+end;
+
+
+{$IFDEF Debug}
+class procedure TGuidHelper.SelfTest;
+var guid   : TGuid;
+    pBytes : PByteArray;
+    i, expected : Integer;
+const TEST_GUID : TGuid = '{00112233-4455-6677-8899-aabbccddeeff}';
+begin
+  // host to network
+  guid := TEST_GUID;
+  guid := guid.SwapByteOrder;
+
+  // validate network order
+  pBytes := @guid;
+  for i := 0 to $F do begin
+    expected := i * $11;
+    ASSERT( pBytes^[i] = expected);
+  end;
+
+  // network to host and final validation
+  guid := guid.SwapByteOrder;
+  ASSERT( IsEqualGuid( guid, TEST_GUID));
+end;
+{$ENDIF}
+
 
 
 {$IFDEF Win64}
@@ -378,4 +492,8 @@
 end;
 
 
+begin
+  {$IFDEF Debug}
+  TGuid.SelfTest;
+  {$ENDIF}
 end.
diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/TestClient.pas
index 040f815..86235eb 100644
--- a/lib/delphi/test/TestClient.pas
+++ b/lib/delphi/test/TestClient.pas
@@ -34,7 +34,7 @@
 interface
 
 uses
-  Windows, SysUtils, Classes, Math, ComObj, ActiveX,
+  Classes, Windows, SysUtils, Math, ActiveX, ComObj,
   {$IFDEF SupportsAsync} System.Threading, {$ENDIF}
   DateUtils,
   Generics.Collections,
@@ -393,6 +393,7 @@
   i32 : Integer;
   i64 : Int64;
   binOut,binIn : TBytes;
+  guidIn, guidOut : TGuid;
   dub : Double;
   o : IXtruct;
   o2 : IXtruct2;
@@ -543,6 +544,16 @@
   i64 := client.testI64(-34359738368);
   Expect( i64 = -34359738368, 'testI64(-34359738368) = ' + IntToStr( i64));
 
+  guidOut := StringToGUID('{00112233-4455-6677-8899-AABBCCDDEEFF}');
+  Console.WriteLine('testUuid('+GUIDToString(guidOut)+')');
+  try
+    guidIn := client.testUuid(guidOut);
+    Expect( IsEqualGUID(guidIn, guidOut), 'testUuid('+GUIDToString(guidOut)+') = '+GUIDToString(guidIn));
+  except
+    on e:TApplicationException do Console.WriteLine('testUuid(): '+e.Message);
+    on e:Exception do Expect( FALSE, 'testUuid(): Unexpected exception "'+e.ClassName+'": '+e.Message);
+  end;
+
   // random binary small
   for testsize := Low(TTestSize) to High(TTestSize) do begin
     binOut := PrepareBinaryData( TRUE, testsize);
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index d7cc026..3ae82a1 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -67,6 +67,7 @@
         function testI64(const thing: Int64): Int64;
         function testDouble(const thing: Double): Double;
         function testBinary(const thing: TBytes): TBytes;
+        function testUuid(const thing: System.TGuid): System.TGuid;
         function testStruct(const thing: IXtruct): IXtruct;
         function testNest(const thing: IXtruct2): IXtruct2;
         function testMap(const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
@@ -150,6 +151,12 @@
   Result := thing;
 end;
 
+function TTestServer.TTestHandlerImpl.testUuid(const thing: System.TGuid): System.TGuid;
+begin
+  Console.WriteLine('testUuid('+GUIDToString(thing)+')');
+  Result := thing;
+end;
+
 function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
 begin
   Console.WriteLine('testEnum(' + EnumUtils<TNumberz>.ToString(Ord(thing)) + ')');
diff --git a/lib/delphi/test/client.dproj b/lib/delphi/test/client.dproj
index c57424d..ae6683d 100644
--- a/lib/delphi/test/client.dproj
+++ b/lib/delphi/test/client.dproj
@@ -1,22 +1,4 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you 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.
--->
-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 		<PropertyGroup>
 			<ProjectGuid>{F262F488-F81C-4B6E-8694-518C54CBB8F3}</ProjectGuid>
 			<MainSource>client.dpr</MainSource>
@@ -142,7 +124,9 @@
 						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="Comments"/>
 					</VersionInfoKeys>
-					<Parameters/>
+					<Parameters>
+						<Parameters Name="RunParams">--protocol=compact  </Parameters>
+					</Parameters>
 				</Delphi.Personality>
 				<Platforms>
 					<Platform value="Win32">True</Platform>
diff --git a/lib/delphi/test/serializer/TestSerializer.Data.pas b/lib/delphi/test/serializer/TestSerializer.Data.pas
index 4b8cc66..269e307 100644
--- a/lib/delphi/test/serializer/TestSerializer.Data.pas
+++ b/lib/delphi/test/serializer/TestSerializer.Data.pas
@@ -23,6 +23,8 @@
 
 uses
   SysUtils,
+  ActiveX,
+  ComObj,
   Thrift.Protocol,
   Thrift.Collections,
   DebugProtoTest;
@@ -193,6 +195,8 @@
   // !!
   result.setZomg_unicode( UnicodeString( us));
 
+  result.Rfc4122_uuid := TGuid.Create('{00112233-4455-6677-8899-aabbccddeeff}');
+
   {$IF cDebugProtoTest_Option_AnsiStr_Binary}
   result.SetBase64('base64');
   {$ELSEIF cDebugProtoTest_Option_COM_Types}
diff --git a/lib/delphi/test/serializer/TestSerializer.Tests.pas b/lib/delphi/test/serializer/TestSerializer.Tests.pas
index 443a22d..6ed1a48 100644
--- a/lib/delphi/test/serializer/TestSerializer.Tests.pas
+++ b/lib/delphi/test/serializer/TestSerializer.Tests.pas
@@ -43,6 +43,7 @@
   System_,
   DebugProtoTest;
 
+{$TYPEINFO ON}
 
 type
   TFactoryPair = record
@@ -208,6 +209,7 @@
   ASSERT( Abs( tested.Double_precision - correct.Double_precision) < 1E-12);
   ASSERT( tested.Some_characters = correct.Some_characters);
   ASSERT( tested.Zomg_unicode = correct.Zomg_unicode);
+  ASSERT( tested.Rfc4122_uuid = correct.Rfc4122_uuid);
   ASSERT( tested.What_who = correct.What_who);
 
   ASSERT( LengthOf(tested.Base64) = LengthOf(correct.Base64));
@@ -303,9 +305,9 @@
 
 
 class function TTestSerializer.UserFriendlyName( const method : TMethod) : string;
+const NAMES : array[TMethod] of string = ('TBytes','Stream');
 begin
-  result := EnumUtils<TMethod>.ToString(Ord(method));
-  result := StringReplace( result, 'mt_', '', [rfReplaceAll]);
+  result := NAMES[method];
 end;
 
 
@@ -342,7 +344,7 @@
     config : IThriftConfiguration;
 begin
   config := TThriftConfigurationImpl.Create;
-  config.MaxMessageSize := 0;   // we don't read anything here
+  //config.MaxMessageSize := 0;   // we don't read anything here
 
   serial := TSerializer.Create( factory.prot, factory.trans, config);
   try
@@ -358,7 +360,7 @@
     config : IThriftConfiguration;
 begin
   config := TThriftConfigurationImpl.Create;
-  config.MaxMessageSize := 0;   // we don't read anything here
+  //config.MaxMessageSize := 0;   // we don't read anything here
 
   serial := TSerializer.Create( factory.prot, factory.trans, config);
   try
diff --git a/lib/delphi/test/server.dproj b/lib/delphi/test/server.dproj
index 9f7e5c6..151f7ee 100644
--- a/lib/delphi/test/server.dproj
+++ b/lib/delphi/test/server.dproj
@@ -1,22 +1,4 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you 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.
--->
-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 		<PropertyGroup>
 			<ProjectGuid>{07CEDA3D-0963-40FE-B3C2-0ED4E24DE067}</ProjectGuid>
 			<MainSource>server.dpr</MainSource>
@@ -140,6 +122,9 @@
 						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="Comments"/>
 					</VersionInfoKeys>
+					<Parameters>
+						<Parameters Name="RunParams">--protocol=compact  </Parameters>
+					</Parameters>
 				</Delphi.Personality>
 				<Platforms>
 					<Platform value="Win32">True</Platform>
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
index 4a38205..bf5a379 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
@@ -36,57 +36,63 @@
     2: optional double             opt_two
     3: optional i16                opt_three
     4: optional string             opt_four
-    5: optional binary             opt_five
+    5: optional uuid               opt_five
     6: optional list<i32>          opt_six
     7: optional set<i64>           opt_seven
     8: optional map<i8,i16>        opt_eight
+	9: optional binary             opt_nine
 
     11: required Distance          req_one
     12: required double            req_two
     13: required i16               req_three
     14: required string            req_four
-    15: required binary            req_five
+    15: required uuid              req_five
     16: required list<i32>         req_six
     17: required set<i64>          req_seven
     18: required map<i8,i16>       req_eight
+    19: required binary            req_nine
     
     21:          Distance          def_one
     22:          double            def_two
     23:          i16               def_three
     24:          string            def_four
-    25:          binary            def_five
+    25:          uuid              def_five
     26:          list<i32>         def_six
     27:          set<i64>          def_seven
     28:          map<i8,i16>       def_eight
-
+	29:          binary            def_nine
+    
     // having default values
     
     31: optional Distance          opt_one_with_value   = Distance.bar
     32: optional double            opt_two_with_value   = 2.22
     33: optional i16               opt_three_with_value = 3
     34: optional string            opt_four_with_value  = "four"
-    35: optional binary            opt_five_with_value  = "five\t"
+    35: optional uuid              opt_five_with_value  = "55555555-5555-5555-5555-000000000000"
     36: optional list<i32>         opt_six_with_value   = [6]
     37: optional set<i64>          opt_seven_with_value = [7]
     38: optional map<i8,i16>       opt_eight_with_value = { 8 : 8 }
-
+	39: optional binary            opt_nine_with_value  = "nine\t"
+    
     41: required Distance          req_one_with_value     = Distance.bar
     42: required double            req_two_with_value     = 2.22
     43: required i16               req_three_with_value = 3
     44: required string            req_four_with_value     = "four"
-    45: required binary            req_five_with_value     = "five"
+    45: required uuid              req_five_with_value  = "55555555-5555-5555-5555-000000000000"
     46: required list<i32>         req_six_with_value     = [6]
     47: required set<i64>          req_seven_with_value = [7]
     48: required map<i8,i16>       req_eight_with_value = { 8 : 8 }
+    49: required binary            req_nine_with_value     = "nine"
     
     51:          Distance          def_one_with_value     = Distance.bar
     52:          double            def_two_with_value     = 2.22
     53:          i16               def_three_with_value = 3
     54:          string            def_four_with_value     = "four"
-    55:          binary            def_five_with_value     = "five"
+    55:          uuid              def_five_with_value  = "55555555-5555-5555-5555-000000000000"
     56:          list<i32>         def_six_with_value     = [6]
     57:          set<i64>          def_seven_with_value = [7]
     58:          map<i8,i16>       def_eight_with_value = { 8 : 8 }
+    59:          binary            def_nine_with_value     = "nine"
     
     90: optional bool              last_of_the_mohicans
 
@@ -124,10 +130,11 @@
     402: optional double             opt_two
     403: optional i16                opt_three
     404: optional string             opt_four
-    405: optional binary             opt_five
+    405: optional uuid               opt_five
     406: optional list<i32>          opt_six
     407: optional set<i64>           opt_seven
     408: optional map<i8,i16>        opt_eight
+    409: optional binary             opt_nine
 }
 
 typedef RaceDetails  RaceDetails2
diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
index afffed5..11b5af4 100644
--- a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
+++ b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs
@@ -81,16 +81,18 @@
             Assert.IsFalse(instance.__isset.opt_six);
             Assert.IsFalse(instance.__isset.opt_seven);
             Assert.IsFalse(instance.__isset.opt_eight);
+            Assert.IsFalse(instance.__isset.opt_nine);
 
             // set all required to null/default
             instance.Req_one = default;
             instance.Req_two = default;
             instance.Req_three = default;
             Assert.IsNotNull(instance.Req_four);
-            Assert.IsNotNull(instance.Req_five);
-            instance.Req_six = default; 
-            instance.Req_seven = default;;
+            instance.Req_five = default;
+            instance.Req_six = default;
+            instance.Req_seven = default;
             instance.Req_eight = default;
+            Assert.IsNotNull(instance.Req_nine);
 
             // leave non-required fields unset again
             Assert.IsFalse(instance.__isset.def_one);
@@ -101,6 +103,7 @@
             Assert.IsFalse(instance.__isset.def_six);
             Assert.IsFalse(instance.__isset.def_seven);
             Assert.IsFalse(instance.__isset.def_eight);
+            Assert.IsFalse(instance.__isset.def_nine);
 
             // these should have IDL defaults set
 
@@ -112,12 +115,13 @@
             Assert.IsTrue(instance.__isset.opt_six_with_value);
             Assert.IsTrue(instance.__isset.opt_seven_with_value);
             Assert.IsTrue(instance.__isset.opt_eight_with_value);
+            Assert.IsTrue(instance.__isset.opt_nine_with_value);
 
             Assert.AreEqual(instance.Req_one_with_value, (Distance)1);
             Assert.AreEqual(instance.Req_two_with_value, 2.22);
             Assert.AreEqual(instance.Req_three_with_value, 3);
             Assert.AreEqual(instance.Req_four_with_value, "four");
-            Assert.AreEqual("five", Encoding.UTF8.GetString(instance.Req_five_with_value!));
+            Assert.AreEqual(new Guid("55555555-5555-5555-5555-000000000000"), instance.Req_five_with_value);
 
             Assert.IsTrue(instance.Req_six_with_value!.Count == 1);
             Assert.AreEqual(instance.Req_six_with_value[0], 6 );
@@ -128,6 +132,8 @@
             Assert.IsTrue(instance.Req_eight_with_value!.Count == 1);
             Assert.IsTrue(instance.Req_eight_with_value[8] == 8);
 
+            Assert.AreEqual("nine", Encoding.UTF8.GetString(instance.Req_nine_with_value!));
+
             Assert.IsTrue(instance.__isset.def_one_with_value);
             Assert.IsTrue(instance.__isset.def_two_with_value);
             Assert.IsTrue(instance.__isset.def_three_with_value);
@@ -136,6 +142,7 @@
             Assert.IsTrue(instance.__isset.def_six_with_value);
             Assert.IsTrue(instance.__isset.def_seven_with_value);
             Assert.IsTrue(instance.__isset.def_eight_with_value);
+            Assert.IsTrue(instance.__isset.def_nine_with_value);
 
             instance.Last_of_the_mohicans = true;
 
@@ -180,6 +187,7 @@
             instance.Opt_six = ModifyValue(instance.Opt_six);
             instance.Opt_seven = ModifyValue(instance.Opt_seven);
             instance.Opt_eight = ModifyValue(instance.Opt_eight);
+            instance.Opt_nine = ModifyValue(instance.Opt_nine);
 
             instance.Req_one = ModifyValue(instance.Req_one);
             instance.Req_two = ModifyValue(instance.Req_two);
@@ -189,6 +197,7 @@
             instance.Req_six = ModifyValue(instance.Req_six);
             instance.Req_seven = ModifyValue(instance.Req_seven);
             instance.Req_eight = ModifyValue(instance.Req_eight);
+            instance.Req_nine = ModifyValue(instance.Req_nine);
 
             instance.Def_one = ModifyValue(instance.Def_one);
             instance.Def_two = ModifyValue(instance.Def_two);
@@ -198,6 +207,7 @@
             instance.Def_six = ModifyValue(instance.Def_six);
             instance.Def_seven = ModifyValue(instance.Def_seven);
             instance.Def_eight = ModifyValue(instance.Def_eight);
+            instance.Def_nine = ModifyValue(instance.Def_nine);
 
             instance.Opt_one_with_value = ModifyValue(instance.Opt_one_with_value);
             instance.Opt_two_with_value = ModifyValue(instance.Opt_two_with_value);
@@ -207,6 +217,7 @@
             instance.Opt_six_with_value = ModifyValue(instance.Opt_six_with_value);
             instance.Opt_seven_with_value = ModifyValue(instance.Opt_seven_with_value);
             instance.Opt_eight_with_value = ModifyValue(instance.Opt_eight_with_value);
+            instance.Opt_nine_with_value = ModifyValue(instance.Opt_nine_with_value);
 
             instance.Req_one_with_value = ModifyValue(instance.Req_one_with_value);
             instance.Req_two_with_value = ModifyValue(instance.Req_two_with_value);
@@ -216,6 +227,7 @@
             instance.Req_six_with_value = ModifyValue(instance.Req_six_with_value);
             instance.Req_seven_with_value = ModifyValue(instance.Req_seven_with_value);
             instance.Req_eight_with_value = ModifyValue(instance.Req_eight_with_value);
+            instance.Req_nine_with_value = ModifyValue(instance.Req_nine_with_value);
 
             instance.Def_one_with_value = ModifyValue(instance.Def_one_with_value);
             instance.Def_two_with_value = ModifyValue(instance.Def_two_with_value);
@@ -225,6 +237,7 @@
             instance.Def_six_with_value = ModifyValue(instance.Def_six_with_value);
             instance.Def_seven_with_value = ModifyValue(instance.Def_seven_with_value);
             instance.Def_eight_with_value = ModifyValue(instance.Def_eight_with_value);
+            instance.Def_nine_with_value = ModifyValue(instance.Def_nine_with_value);
 
             instance.Last_of_the_mohicans = ModifyValue(instance.Last_of_the_mohicans);
 
@@ -435,6 +448,11 @@
             return value + "1";
         }
 
+        private static Guid ModifyValue(Guid value)
+        {
+            return new Guid( ModifyValue(value.ToByteArray()));
+        }
+
         private static double ModifyValue(double value)
         {
             return value + 1.1;
@@ -461,6 +479,7 @@
             Assert.IsFalse(TCollections.Equals(first.Opt_six, second.Opt_six));
             Assert.IsFalse(TCollections.Equals(first.Opt_seven, second.Opt_seven));
             Assert.IsFalse(TCollections.Equals(first.Opt_eight, second.Opt_eight));
+            Assert.IsFalse(TCollections.Equals(first.Opt_nine, second.Opt_nine));
 
             Assert.AreNotEqual(first.Req_one, second.Req_one);
             Assert.AreNotEqual(first.Req_two, second.Req_two);
@@ -470,6 +489,7 @@
             Assert.IsFalse(TCollections.Equals(first.Req_six, second.Req_six));
             Assert.IsFalse(TCollections.Equals(first.Req_seven, second.Req_seven));
             Assert.IsFalse(TCollections.Equals(first.Req_eight, second.Req_eight));
+            Assert.IsFalse(TCollections.Equals(first.Req_nine, second.Req_nine));
 
             Assert.AreNotEqual(first.Def_one, second.Def_one);
             Assert.AreNotEqual(first.Def_two, second.Def_two);
@@ -479,6 +499,7 @@
             Assert.IsFalse(TCollections.Equals(first.Def_six, second.Def_six));
             Assert.IsFalse(TCollections.Equals(first.Def_seven, second.Def_seven));
             Assert.IsFalse(TCollections.Equals(first.Def_eight, second.Def_eight));
+            Assert.IsFalse(TCollections.Equals(first.Def_nine, second.Def_nine));
 
             Assert.AreNotEqual(first.Opt_one_with_value, second.Opt_one_with_value);
             Assert.AreNotEqual(first.Opt_two_with_value, second.Opt_two_with_value);
@@ -488,6 +509,7 @@
             Assert.IsFalse(TCollections.Equals(first.Opt_six_with_value, second.Opt_six_with_value));
             Assert.IsFalse(TCollections.Equals(first.Opt_seven_with_value, second.Opt_seven_with_value));
             Assert.IsFalse(TCollections.Equals(first.Opt_eight_with_value, second.Opt_eight_with_value));
+            Assert.IsFalse(TCollections.Equals(first.Opt_nine_with_value, second.Opt_nine_with_value));
 
             Assert.AreNotEqual(first.Req_one_with_value, second.Req_one_with_value);
             Assert.AreNotEqual(first.Req_two_with_value, second.Req_two_with_value);
@@ -497,6 +519,7 @@
             Assert.IsFalse(TCollections.Equals(first.Req_six_with_value, second.Req_six_with_value));
             Assert.IsFalse(TCollections.Equals(first.Req_seven_with_value, second.Req_seven_with_value));
             Assert.IsFalse(TCollections.Equals(first.Req_eight_with_value, second.Req_eight_with_value));
+            Assert.IsFalse(TCollections.Equals(first.Req_nine_with_value, second.Req_nine_with_value));
 
             Assert.AreNotEqual(first.Def_one_with_value, second.Def_one_with_value);
             Assert.AreNotEqual(first.Def_two_with_value, second.Def_two_with_value);
@@ -506,6 +529,7 @@
             Assert.IsFalse(TCollections.Equals(first.Def_six_with_value, second.Def_six_with_value));
             Assert.IsFalse(TCollections.Equals(first.Def_seven_with_value, second.Def_seven_with_value));
             Assert.IsFalse(TCollections.Equals(first.Def_eight_with_value, second.Def_eight_with_value));
+            Assert.IsFalse(TCollections.Equals(first.Def_nine_with_value, second.Def_nine_with_value));
 
             Assert.AreNotEqual(first.Last_of_the_mohicans, second.Last_of_the_mohicans);
 
@@ -539,6 +563,7 @@
             Assert.IsTrue(TCollections.Equals(first.Opt_six, second.Opt_six));
             Assert.IsTrue(TCollections.Equals(first.Opt_seven, second.Opt_seven));
             Assert.IsTrue(TCollections.Equals(first.Opt_eight, second.Opt_eight));
+            Assert.IsTrue(TCollections.Equals(first.Opt_nine, second.Opt_nine));
 
             Assert.AreEqual(first.Req_one, second.Req_one);
             Assert.AreEqual(first.Req_two, second.Req_two);
@@ -548,6 +573,7 @@
             Assert.IsTrue(TCollections.Equals(first.Req_six, second.Req_six));
             Assert.IsTrue(TCollections.Equals(first.Req_seven, second.Req_seven));
             Assert.IsTrue(TCollections.Equals(first.Req_eight, second.Req_eight));
+            Assert.IsTrue(TCollections.Equals(first.Req_nine, second.Req_nine));
 
             Assert.AreEqual(first.Def_one, second.Def_one);
             Assert.AreEqual(first.Def_two, second.Def_two);
@@ -557,6 +583,7 @@
             Assert.IsTrue(TCollections.Equals(first.Def_six, second.Def_six));
             Assert.IsTrue(TCollections.Equals(first.Def_seven, second.Def_seven));
             Assert.IsTrue(TCollections.Equals(first.Def_eight, second.Def_eight));
+            Assert.IsTrue(TCollections.Equals(first.Def_nine, second.Def_nine));
 
             Assert.AreEqual(first.Opt_one_with_value, second.Opt_one_with_value);
             Assert.AreEqual(first.Opt_two_with_value, second.Opt_two_with_value);
@@ -566,6 +593,7 @@
             Assert.IsTrue(TCollections.Equals(first.Opt_six_with_value, second.Opt_six_with_value));
             Assert.IsTrue(TCollections.Equals(first.Opt_seven_with_value, second.Opt_seven_with_value));
             Assert.IsTrue(TCollections.Equals(first.Opt_eight_with_value, second.Opt_eight_with_value));
+            Assert.IsTrue(TCollections.Equals(first.Opt_nine_with_value, second.Opt_nine_with_value));
 
             Assert.AreEqual(first.Req_one_with_value, second.Req_one_with_value);
             Assert.AreEqual(first.Req_two_with_value, second.Req_two_with_value);
@@ -575,6 +603,7 @@
             Assert.IsTrue(TCollections.Equals(first.Req_six_with_value, second.Req_six_with_value));
             Assert.IsTrue(TCollections.Equals(first.Req_seven_with_value, second.Req_seven_with_value));
             Assert.IsTrue(TCollections.Equals(first.Req_eight_with_value, second.Req_eight_with_value));
+            Assert.IsTrue(TCollections.Equals(first.Req_nine_with_value, second.Req_nine_with_value));
 
             Assert.AreEqual(first.Def_one_with_value, second.Def_one_with_value);
             Assert.AreEqual(first.Def_two_with_value, second.Def_two_with_value);
@@ -584,6 +613,7 @@
             Assert.IsTrue(TCollections.Equals(first.Def_six_with_value, second.Def_six_with_value));
             Assert.IsTrue(TCollections.Equals(first.Def_seven_with_value, second.Def_seven_with_value));
             Assert.IsTrue(TCollections.Equals(first.Def_eight_with_value, second.Def_eight_with_value));
+            Assert.IsTrue(TCollections.Equals(first.Def_nine_with_value, second.Def_nine_with_value));
 
             Assert.AreEqual(first.Last_of_the_mohicans, second.Last_of_the_mohicans);
 
diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
index ebc1717..80eacc2 100644
--- a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
+++ b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs
@@ -48,19 +48,19 @@
             Assert.IsNull(instance.Def_four);
             Assert.IsNull(instance.Opt_four);
 
-            // byte[]
-            Assert.IsTrue(instance.__isset.def_five);
-            Assert.IsTrue(instance.__isset.opt_five);
-            Assert.IsTrue((instance.Req_five == null) || (instance.Req_five.Length == 0));
-            Assert.IsNull(instance.Def_five);
-            Assert.IsNull(instance.Opt_five);
-
             // list<>
             Assert.IsTrue(instance.__isset.def_six);
             Assert.IsTrue(instance.__isset.opt_six);
             Assert.IsNull(instance.Req_six);
             Assert.IsNull(instance.Opt_six);
             Assert.IsNull(instance.Def_six);
+
+            // byte[]
+            Assert.IsTrue(instance.__isset.def_nine);
+            Assert.IsTrue(instance.__isset.opt_nine);
+            Assert.IsTrue((instance.Req_nine == null) || (instance.Req_nine.Length == 0));
+            Assert.IsNull(instance.Def_nine);
+            Assert.IsNull(instance.Opt_nine);
         }
 
         [TestMethod]
@@ -80,27 +80,27 @@
             instance.Def_four = null;
             instance.Opt_four = null;
 
-            // byte[]
-            instance.Req_five = null;
-            instance.Def_five = null;
-            instance.Opt_five = null;
-
             // list<>
             instance.Req_six = null;
             instance.Opt_six = null;
             instance.Def_six = null;
 
+            // byte[]
+            instance.Req_nine = null;
+            instance.Def_nine = null;
+            instance.Opt_nine = null;
+
             // back to normal
             #pragma warning restore CS8625
 
             // test the setup
             CheckInstance(instance);
 
-            // validate proper null checks , any of these throws if not
+            // validate proper null checks, any of these throws if not
             instance.ToString();
             instance.GetHashCode();
 
-            // validate proper null checks , any of these throws if not
+            // validate proper null checks, any of these throws if not
             var copy = instance.DeepCopy();
             CheckInstance(copy);
         }
diff --git a/lib/netstd/Thrift/Protocol/Entities/TType.cs b/lib/netstd/Thrift/Protocol/Entities/TType.cs
index 4e922a7..2f3037b 100644
--- a/lib/netstd/Thrift/Protocol/Entities/TType.cs
+++ b/lib/netstd/Thrift/Protocol/Entities/TType.cs
@@ -32,6 +32,7 @@
         Struct = 12,
         Map = 13,
         Set = 14,
-        List = 15
+        List = 15,
+        Uuid = 16
     }
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
index eee137c..ba2a7ab 100644
--- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
@@ -21,6 +21,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
 using Thrift.Transport;
 
 
@@ -209,6 +210,14 @@
             await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
         }
 
+        public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
+        {
+            cancellationToken.ThrowIfCancellationRequested();
+
+            var bytes = uuid.SwapByteOrder().ToByteArray();
+            await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+        }
+
         public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
         {
             cancellationToken.ThrowIfCancellationRequested();
@@ -401,6 +410,16 @@
             return buf;
         }
 
+        public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
+        {
+            cancellationToken.ThrowIfCancellationRequested();
+
+            Transport.CheckReadBytesAvailable(16);  // = sizeof(uuid)
+            var buf = new byte[16];
+            await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
+            return new Guid(buf).SwapByteOrder();
+        }
+
         public override async ValueTask<string> ReadStringAsync(CancellationToken cancellationToken)
         {
             cancellationToken.ThrowIfCancellationRequested();
@@ -443,6 +462,7 @@
                 case TType.Map: return sizeof(int);  // element count
                 case TType.Set: return sizeof(int);  // element count
                 case TType.List: return sizeof(int);  // element count
+                case TType.Uuid: return 16;  // uuid bytes
                 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
             }
         }
diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
index 6893ad4..b899d3d 100644
--- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
@@ -24,6 +24,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
 using Thrift.Transport;
 
 
@@ -43,8 +44,8 @@
         private const byte NoTypeOverride = 0xFF;
 
         // ReSharper disable once InconsistentNaming
-        private static readonly byte[] TTypeToCompactType = new byte[16];
-        private static readonly TType[] CompactTypeToTType = new TType[13];
+        private static readonly byte[] TTypeToCompactType = new byte[17];
+        private static readonly TType[] CompactTypeToTType = new TType[14];
 
         /// <summary>
         ///     Used to keep track of the last field for the current and previous structs, so we can do the delta stuff.
@@ -86,18 +87,19 @@
         public TCompactProtocol(TTransport trans)
             : base(trans)
         {
-            TTypeToCompactType[(int) TType.Stop] = Types.Stop;
-            TTypeToCompactType[(int) TType.Bool] = Types.BooleanTrue;
-            TTypeToCompactType[(int) TType.Byte] = Types.Byte;
-            TTypeToCompactType[(int) TType.I16] = Types.I16;
-            TTypeToCompactType[(int) TType.I32] = Types.I32;
-            TTypeToCompactType[(int) TType.I64] = Types.I64;
-            TTypeToCompactType[(int) TType.Double] = Types.Double;
-            TTypeToCompactType[(int) TType.String] = Types.Binary;
-            TTypeToCompactType[(int) TType.List] = Types.List;
-            TTypeToCompactType[(int) TType.Set] = Types.Set;
-            TTypeToCompactType[(int) TType.Map] = Types.Map;
-            TTypeToCompactType[(int) TType.Struct] = Types.Struct;
+            TTypeToCompactType[(int)TType.Stop] = Types.Stop;
+            TTypeToCompactType[(int)TType.Bool] = Types.BooleanTrue;
+            TTypeToCompactType[(int)TType.Byte] = Types.Byte;
+            TTypeToCompactType[(int)TType.I16] = Types.I16;
+            TTypeToCompactType[(int)TType.I32] = Types.I32;
+            TTypeToCompactType[(int)TType.I64] = Types.I64;
+            TTypeToCompactType[(int)TType.Double] = Types.Double;
+            TTypeToCompactType[(int)TType.String] = Types.Binary;
+            TTypeToCompactType[(int)TType.List] = Types.List;
+            TTypeToCompactType[(int)TType.Set] = Types.Set;
+            TTypeToCompactType[(int)TType.Map] = Types.Map;
+            TTypeToCompactType[(int)TType.Struct] = Types.Struct;
+            TTypeToCompactType[(int)TType.Uuid] = Types.Uuid;
 
             CompactTypeToTType[Types.Stop] = TType.Stop;
             CompactTypeToTType[Types.BooleanTrue] = TType.Bool;
@@ -112,6 +114,7 @@
             CompactTypeToTType[Types.Set] = TType.Set;
             CompactTypeToTType[Types.Map] = TType.Map;
             CompactTypeToTType[Types.Struct] = TType.Struct;
+            CompactTypeToTType[Types.Uuid] = TType.Uuid;
         }
 
         public void Reset()
@@ -395,6 +398,14 @@
             await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
         }
 
+        public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
+        {
+            cancellationToken.ThrowIfCancellationRequested();
+
+            var bytes = uuid.SwapByteOrder().ToByteArray();
+            await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+        }
+
         public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
         {
             cancellationToken.ThrowIfCancellationRequested();
@@ -665,6 +676,16 @@
             return buf;
         }
 
+        public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
+        {
+            cancellationToken.ThrowIfCancellationRequested();
+
+            Transport.CheckReadBytesAvailable(16);  // = sizeof(uuid)
+            var buf = new byte[16];
+            await Trans.ReadAllAsync(buf, 0, 16, cancellationToken);
+            return new Guid(buf).SwapByteOrder();
+        }
+
         public override async ValueTask<TList> ReadListBeginAsync(CancellationToken cancellationToken)
         {
             cancellationToken.ThrowIfCancellationRequested();
@@ -792,19 +813,20 @@
         {
             switch (type)
             {
-                case TType.Stop:    return 0;
-                case TType.Void:    return 0;
-                case TType.Bool:   return sizeof(byte);
+                case TType.Stop: return 0;
+                case TType.Void: return 0;
+                case TType.Bool: return sizeof(byte);
                 case TType.Double: return 8;  // uses fixedLongToBytes() which always writes 8 bytes
                 case TType.Byte: return sizeof(byte);
-                case TType.I16:     return sizeof(byte);  // zigzag
-                case TType.I32:     return sizeof(byte);  // zigzag
-                case TType.I64:     return sizeof(byte);  // zigzag
+                case TType.I16: return sizeof(byte);  // zigzag
+                case TType.I32: return sizeof(byte);  // zigzag
+                case TType.I64: return sizeof(byte);  // zigzag
                 case TType.String: return sizeof(byte);  // string length
-                case TType.Struct:  return 0;             // empty struct
-                case TType.Map:     return sizeof(byte);  // element count
-                case TType.Set:    return sizeof(byte);  // element count
-                case TType.List:    return sizeof(byte);  // element count
+                case TType.Struct: return 0;             // empty struct
+                case TType.Map: return sizeof(byte);  // element count
+                case TType.Set: return sizeof(byte);  // element count
+                case TType.List: return sizeof(byte);  // element count
+                case TType.Uuid: return 16;  // uuid bytes
                 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
             }
         }
@@ -835,6 +857,7 @@
             public const byte Set = 0x0A;
             public const byte Map = 0x0B;
             public const byte Struct = 0x0C;
+            public const byte Uuid = 0x0D;
         }
     }
 }
diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
index 8799026..c100d86 100644
--- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
@@ -401,6 +401,10 @@
         {
             await WriteJsonBase64Async(bytes, cancellationToken);
         }
+        public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken = default)
+        {
+            await WriteStringAsync(uuid.ToString("D"), cancellationToken);  // no curly braces
+        }
 
         /// <summary>
         ///     Read in a JSON string, unescaping as appropriate.. Skip Reading from the
@@ -817,6 +821,11 @@
             return await ReadJsonBase64Async(cancellationToken);
         }
 
+        public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken = default)
+        {
+            return new Guid( await ReadStringAsync(cancellationToken));
+        }
+
         // Return the minimum number of bytes a type will consume on the wire
         public override int GetMinSerializedSize(TType type)
         {
@@ -835,6 +844,7 @@
                 case TType.Map: return 2;  // empty map
                 case TType.Set: return 2;  // empty set
                 case TType.List: return 2;  // empty list
+                case TType.Uuid: return 36;  // "E236974D-F0B0-4E05-8F29-0B455D41B1A1"
                 default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
             }
         }
diff --git a/lib/netstd/Thrift/Protocol/TProtocol.cs b/lib/netstd/Thrift/Protocol/TProtocol.cs
index cd93833..f2bec60 100644
--- a/lib/netstd/Thrift/Protocol/TProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TProtocol.cs
@@ -148,6 +148,7 @@
         }
 
         public abstract Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken = default);
+        public abstract Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken = default);
 
         public abstract ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken = default);
 
@@ -192,5 +193,7 @@
         }
 
         public abstract ValueTask<byte[]> ReadBinaryAsync(CancellationToken cancellationToken = default);
+
+        public abstract ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken = default);
     }
 }
diff --git a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
index b032e83..1ea9fb9 100644
--- a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
+++ b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
@@ -144,6 +144,11 @@
             await _wrappedProtocol.WriteBinaryAsync(bytes, cancellationToken);
         }
 
+        public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken)
+        {
+            await _wrappedProtocol.WriteUuidAsync(uuid, cancellationToken);
+        }
+
         public override async ValueTask<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
         {
             return await _wrappedProtocol.ReadMessageBeginAsync(cancellationToken);
@@ -244,6 +249,11 @@
             return await _wrappedProtocol.ReadBinaryAsync(cancellationToken);
         }
 
+        public override async ValueTask<Guid> ReadUuidAsync(CancellationToken cancellationToken)
+        {
+            return await _wrappedProtocol.ReadUuidAsync(cancellationToken);
+        }
+
         // Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
         public override int GetMinSerializedSize(TType type)
         {
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs b/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs
new file mode 100644
index 0000000..190ddbb
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you 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.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+
+namespace Thrift.Protocol.Utilities
+{
+    public static class TGuidExtensions
+    {
+        public static Guid SwapByteOrder(this Guid self)
+        {
+            var bytes = self.ToByteArray();
+
+            // already network order on BigEndian machines
+            if (BitConverter.IsLittleEndian)
+            {
+                SwapBytes(ref bytes[0], ref bytes[3]);
+                SwapBytes(ref bytes[1], ref bytes[2]);
+                SwapBytes(ref bytes[4], ref bytes[5]);
+                SwapBytes(ref bytes[6], ref bytes[7]);
+            }
+
+            return new Guid(bytes);
+        }
+
+        private static void SwapBytes(ref byte one, ref byte two)
+        {
+            var tmp = one;
+            one = two;
+            two = tmp;
+        }
+
+        #region SelfTest
+#if DEBUG
+        static private readonly Guid TEST_GUID = new Guid("{00112233-4455-6677-8899-aabbccddeeff}");
+
+        static TGuidExtensions()
+        {
+            SelfTest();
+        }
+
+        private static void SelfTest()
+        {
+            // host to network
+            var guid = TEST_GUID;
+            guid = guid.SwapByteOrder();
+
+            // validate network order
+            var bytes = guid.ToByteArray();
+            for (var i = 0; i < 10; ++i)
+            {
+                var expected = i * 0x11;
+                Debug.Assert( bytes[i] == expected);
+            }
+
+            // network to host and final validation
+            guid = guid.SwapByteOrder();
+            Debug.Assert(guid.Equals(TEST_GUID));
+        }
+
+#endif
+        #endregion
+
+    }
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
index 6cc1302..f8c261a 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// Licensed to the Apache Software Foundation(ASF) under one
 // or more contributor license agreements.See the NOTICE file
 // distributed with this work for additional information
 // regarding copyright ownership.The ASF licenses this file
@@ -56,6 +56,7 @@
             public static readonly byte[] NameMap = { (byte)'m', (byte)'a', (byte)'p' };
             public static readonly byte[] NameList = { (byte)'l', (byte)'s', (byte)'t' };
             public static readonly byte[] NameSet = { (byte)'s', (byte)'e', (byte)'t' };
+            public static readonly byte[] NameUuid = { (byte)'u', (byte)'i', (byte)'d' };
         }
     }
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
index ff49ebe..67c7bc0 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// Licensed to the Apache Software Foundation(ASF) under one
 // or more contributor license agreements.See the NOTICE file
 // distributed with this work for additional information
 // regarding copyright ownership.The ASF licenses this file
@@ -48,6 +48,8 @@
                     return TJSONProtocolConstants.TypeNames.NameSet;
                 case TType.List:
                     return TJSONProtocolConstants.TypeNames.NameList;
+                case TType.Uuid:
+                    return TJSONProtocolConstants.TypeNames.NameUuid;
                 default:
                     throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType");
             }
@@ -102,6 +104,9 @@
                     case (byte) 't':
                         result = TType.Bool;
                         break;
+                    case (byte)'u':
+                        result = TType.Uuid;
+                        break;
                 }
             }
             if (result == TType.Stop)
@@ -173,4 +178,4 @@
             return (byte)((char)val + 'a');
         }
     }
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
index 832e46e..3c8b37a 100644
--- a/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
+++ b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
@@ -55,6 +55,9 @@
                         // Don't try to decode the string, just skip it.
                         await protocol.ReadBinaryAsync(cancellationToken);
                         break;
+                    case TType.Uuid:
+                        await protocol.ReadUuidAsync(cancellationToken);
+                        break;
                     case TType.Struct:
                         await protocol.ReadStructBeginAsync(cancellationToken);
                         while (true)
diff --git a/test/ConstantsDemo.thrift b/test/ConstantsDemo.thrift
index 204e805..e03f053 100644
--- a/test/ConstantsDemo.thrift
+++ b/test/ConstantsDemo.thrift
@@ -65,6 +65,8 @@
 
 const set<i32> GEN_SET = [ 235, 235, 53235 ]
 
+const uuid GEN_UUID = "00000000-4444-CCCC-ffff-0123456789ab"
+
 exception Blah {
   1:  i32 bing }
 
diff --git a/test/DebugProtoTest.thrift b/test/DebugProtoTest.thrift
index 5d0face..3750d8d 100644
--- a/test/DebugProtoTest.thrift
+++ b/test/DebugProtoTest.thrift
@@ -48,6 +48,7 @@
   12: list<i8> byte_list = [1, 2, 3],
   13: list<i16> i16_list = [1,2,3],
   14: list<i64> i64_list = [1,2,3]
+  15: uuid rfc4122_uuid
 }
 
 struct Bonk {
diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift
index 4a1045f..42607cc 100644
--- a/test/ThriftTest.thrift
+++ b/test/ThriftTest.thrift
@@ -112,6 +112,7 @@
   // Do not insert line break as test/go/Makefile.am is removing this line with pattern match
   3: required list<map<set<i32> (python.immutable = ""), map<i32,set<list<map<Insanity,string>(python.immutable = "")> (python.immutable = "")>>>> list_field,
   4: binary binary_field
+  5: uuid uuid_field
 }
 
 union SomeUnion {
@@ -196,6 +197,13 @@
   binary       testBinary(1: binary thing),
 
   /**
+   * Prints 'testUuid("%s")' where '%s' is the uuid given. Note that the uuid byte order should be correct.
+   * @param uuid  thing - the uuid to print
+   * @return uuid  - returns the uuid 'thing'
+   */
+  uuid       testUuid(1: uuid thing),
+
+  /**
    * Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values
    * @param Xtruct thing - the Xtruct to print
    * @return Xtruct - returns the Xtruct 'thing'
diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs
index 29c0d2e..4700de8 100644
--- a/test/netstd/Client/TestClient.cs
+++ b/test/netstd/Client/TestClient.cs
@@ -588,8 +588,28 @@
                 returnCode |= ErrorBaseTypes;
             }
 
+            // testUuid()
+            var uuidOut = new Guid("{00112233-4455-6677-8899-AABBCCDDEEFF}");
+            Console.Write("testUuid({0})", uuidOut);
+            try
+            {
+                var uuidIn = await client.testUuid(uuidOut, MakeTimeoutToken());
+                Console.WriteLine(" = {0}", uuidIn);
+                if (!uuidIn.Equals(uuidOut))
+                {
+                    Console.WriteLine("*** FAILED ***");
+                    returnCode |= ErrorBaseTypes;
+                }
+            }
+            catch (Thrift.TApplicationException ex)
+            {
+                Console.WriteLine("*** FAILED ***");
+                returnCode |= ErrorBaseTypes;
+                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
+            }
+
             // testBinary()
-            foreach(BinaryTestSize binTestCase in Enum.GetValues(typeof(BinaryTestSize)))
+            foreach (BinaryTestSize binTestCase in Enum.GetValues(typeof(BinaryTestSize)))
             {
                 var binOut = PrepareTestData(true, binTestCase);
 
diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj
index 8faad9d..0a78e88 100644
--- a/test/netstd/Server/Server.csproj
+++ b/test/netstd/Server/Server.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <!--
     Licensed to the Apache Software Foundation(ASF) under one
     or more contributor license agreements.See the NOTICE file
diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs
index 86072b0..71a2a30 100644
--- a/test/netstd/Server/TestServer.cs
+++ b/test/netstd/Server/TestServer.cs
@@ -271,6 +271,12 @@
                 return Task.FromResult(thing ?? Array.Empty<byte>());
             }
 
+            public Task<Guid> testUuid(Guid thing, CancellationToken cancellationToken)
+            {
+                logger.Invoke("testUuid({0})", thing.ToString("B"));
+                return Task.FromResult(thing);
+            }
+
             public Task<Xtruct> testStruct(Xtruct? thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing?.String_thing ?? "<null>", thing?.Byte_thing ?? 0, thing?.I32_thing ?? 0, thing?.I64_thing ?? 0);