THRIFT-3174: Modify initialism code in Go compiler to check first word
Client: Go
Patch: Paul Magrath <paul@paulmagrath.com>

This closes #509
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index a59224d..1584e91 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -302,6 +302,7 @@
   std::set<std::string> commonInitialisms;
 
   std::string camelcase(const std::string& value) const;
+  void fix_common_initialism(std::string& value, int i) const;
   std::string publicize(const std::string& value, bool is_args_or_result = false) const;
   std::string privatize(const std::string& value) const;
   std::string new_prefix(const std::string& value) const;
@@ -419,25 +420,34 @@
 std::string t_go_generator::camelcase(const std::string& value) const {
   std::string value2(value);
   std::setlocale(LC_ALL, "C"); // set locale to classic
+  
+  // Fix common initialism in first word
+  fix_common_initialism(value2, 0);
 
-  // as long as we are changing things, let's change _ followed by lowercase to capital and fix
-  // common initialisms
+  // as long as we are changing things, let's change _ followed by lowercase to 
+  // capital and fix common initialisms
   for (std::string::size_type i = 1; i < value2.size() - 1; ++i) {
     if (value2[i] == '_') {
       if (islower(value2[i + 1])) {
         value2.replace(i, 2, 1, toupper(value2[i + 1]));
       }
-      std::string word = value2.substr(i, value2.find('_', i));
-      std::transform(word.begin(), word.end(), word.begin(), ::toupper);
-      if (commonInitialisms.find(word) != commonInitialisms.end()) {
-        value2.replace(i, word.length(), word);
-      }
+      fix_common_initialism(value2, i);
     }
   }
 
   return value2;
 }
 
+// Checks to see if the word starting at i in value contains a common initialism
+// and if so replaces it with the upper case version of the word.
+void t_go_generator::fix_common_initialism(std::string& value, int i) const {
+  std::string word = value.substr(i, value.find('_', i));
+  std::transform(word.begin(), word.end(), word.begin(), ::toupper);
+  if (commonInitialisms.find(word) != commonInitialisms.end()) {
+    value.replace(i, word.length(), word);
+  }
+}
+
 std::string t_go_generator::publicize(const std::string& value, bool is_args_or_result) const {
   if (value.size() <= 0) {
     return value;
diff --git a/lib/go/test/InitialismsTest.thrift b/lib/go/test/InitialismsTest.thrift
index 68b6350..ad86ac1 100644
--- a/lib/go/test/InitialismsTest.thrift
+++ b/lib/go/test/InitialismsTest.thrift
@@ -20,4 +20,5 @@
 struct InitialismsTest {
     1: string user_id,
     2: string server_url,
+    3: string id, 
 }
diff --git a/lib/go/test/tests/initialisms_test.go b/lib/go/test/tests/initialisms_test.go
index 1d13b97..40923d2 100644
--- a/lib/go/test/tests/initialisms_test.go
+++ b/lib/go/test/tests/initialisms_test.go
@@ -36,4 +36,8 @@
 	if !ok {
 		t.Error("ServerURL attribute is missing!")
 	}
+	_, ok = st.FieldByName("ID")
+	if !ok {
+		t.Error("ID attribute is missing!")
+	}
 }