THRIFT-5652 IDL uuid literals can be improved
Compiler (general)
Patch: Jens Geyer

This closes #2714
diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc
index a07f429..485ec00 100644
--- a/compiler/cpp/src/thrift/main.cc
+++ b/compiler/cpp/src/thrift/main.cc
@@ -742,7 +742,7 @@
       if (value->get_type() != t_const_value::CV_STRING) {
         throw "type error: const \"" + name + "\" was declared as uuid";
       }
-      value->get_uuid(); // validates constant
+      value->set_uuid(value->get_uuid()); // validates constant
       break;
     case t_base_type::TYPE_BOOL:
       if (value->get_type() != t_const_value::CV_INTEGER) {
diff --git a/compiler/cpp/src/thrift/parse/t_const_value.h b/compiler/cpp/src/thrift/parse/t_const_value.h
index 452a90c..382422e 100644
--- a/compiler/cpp/src/thrift/parse/t_const_value.h
+++ b/compiler/cpp/src/thrift/parse/t_const_value.h
@@ -92,8 +92,9 @@
   }
 
   std::string get_uuid() const {
-    validate_uuid(stringVal_);
-    return stringVal_;
+    std::string tmp = stringVal_;
+    validate_uuid(tmp);
+    return tmp;
   }
 
   void set_double(double val) {
@@ -210,13 +211,18 @@
   t_enum* enum_;
 
   t_const_value_type valType_;
-  
-  void validate_uuid(std::string uuid) const {
-    bool valid = (uuid.length() == 36);
+
+  void validate_uuid(std::string & uuid) const {
     const std::string HEXCHARS = std::string("0123456789ABCDEFabcdef");
 
+    // we also allow for usual "Windows GUID" format "{01234567-9012-4567-9012-456789012345}"
+    if ((uuid.length() == 38) && ('{' == uuid[0]) && ('}' == uuid[37])) {
+      uuid = uuid.substr(1, 36);
+    }
+
     // canonical format "01234567-9012-4567-9012-456789012345" expected
-    for( size_t i = 0; valid && (i < uuid.length()); ++i) {
+    bool valid = (uuid.length() == 36);
+    for (size_t i = 0; valid && (i < uuid.length()); ++i) {
       switch(i) {
         case 8:
         case 13:
@@ -224,14 +230,14 @@
         case 23:
           if(uuid[i] != '-') {
             valid = false;
-          }			  
+          }
           break;
         default:
           if(HEXCHARS.find(uuid[i]) == std::string::npos) {
             valid = false;
-          }			  
+          }
           break;
-      }        
+      }
     }
 
     if( ! valid) {
diff --git a/test/ConstantsDemo.thrift b/test/ConstantsDemo.thrift
index e03f053..2245657 100644
--- a/test/ConstantsDemo.thrift
+++ b/test/ConstantsDemo.thrift
@@ -22,8 +22,9 @@
 namespace haxe constantsDemo
 
 struct thing {
-  1: i32 hello,
-  2: i32 goodbye
+  1: i32  hello,
+  2: i32  goodbye
+  3: uuid id
 }
 
 enum enumconstants {
@@ -52,6 +53,10 @@
 const double e10 = 1e10   // fails with 0.9.3 and earlier
 const double e11 = -1e10  
 
+// uuids are accepted with or without curly braces
+const uuid GEN_UUID =  '00000000-4444-CCCC-ffff-0123456789ab'
+const uuid GEN_GUID = '{00112233-4455-6677-8899-aaBBccDDeeFF}'
+
 const map<i32,i32> GEN_MAP = { 35532 : 233, 43523 : 853 }
 const list<i32> GEN_LIST = [ 235235, 23598352, 3253523 ]
 
@@ -59,13 +64,13 @@
 
 const map<string,i32> GEN_MAP2 = { "hello" : 233, "lkj98d" : 853, 'lkjsdf' : 098325 }
 
-const thing GEN_THING = { 'hello' : 325, 'goodbye' : 325352 }
+const thing GEN_THING = { 'hello' : 325, 'goodbye' : 325352, 'id' : '{00112233-4455-6677-8899-aaBBccDDeeFF}' }
 
-const map<i32,thing> GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352 } }
+const map<i32,thing> GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352, 'id' : '00000000-4444-CCCC-ffff-0123456789ab' } }
 
 const set<i32> GEN_SET = [ 235, 235, 53235 ]
 
-const uuid GEN_UUID = "00000000-4444-CCCC-ffff-0123456789ab"
+const set<uuid> GUID_SET = [ '{00112233-4455-6677-8899-aaBBccDDeeFF}', '00000000-4444-CCCC-ffff-0123456789ab' ]
 
 exception Blah {
   1:  i32 bing }