compiler/protogen, internal/strs, internal/impl: expose enum Go name derivation

In order to migrate v1 to wrap v2, we need a way to reproduce
the awful enum "names" that v1 used, which was the concatenation of
the proto package with the Go identifier used for the enum.

To support this:
* Move the camel case logic from compiler/protogen to internal/strs
* Add a small stub in internal/impl to expose this functionality

Change-Id: I8ff31daa9ae541e5788dc04d2e89eae1574877e4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/191637
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/strs/strings_test.go b/internal/strs/strings_test.go
index 2c4c2ad..0bb894a 100644
--- a/internal/strs/strings_test.go
+++ b/internal/strs/strings_test.go
@@ -9,6 +9,61 @@
 	"testing"
 )
 
+func TestGoCamelCase(t *testing.T) {
+	tests := []struct {
+		in, want string
+	}{
+		{"", ""},
+		{"one", "One"},
+		{"one_two", "OneTwo"},
+		{"_my_field_name_2", "XMyFieldName_2"},
+		{"Something_Capped", "Something_Capped"},
+		{"my_Name", "My_Name"},
+		{"OneTwo", "OneTwo"},
+		{"_", "X"},
+		{"_a_", "XA_"},
+		{"one.two", "OneTwo"},
+		{"one.Two", "One_Two"},
+		{"one_two.three_four", "OneTwoThreeFour"},
+		{"one_two.Three_four", "OneTwo_ThreeFour"},
+		{"_one._two", "XOne_XTwo"},
+		{"SCREAMING_SNAKE_CASE", "SCREAMING_SNAKE_CASE"},
+		{"double__underscore", "Double_Underscore"},
+		{"camelCase", "CamelCase"},
+		{"go2proto", "Go2Proto"},
+		{"世界", "世界"},
+		{"x世界", "X世界"},
+		{"foo_bar世界", "FooBar世界"},
+	}
+	for _, tc := range tests {
+		if got := GoCamelCase(tc.in); got != tc.want {
+			t.Errorf("GoCamelCase(%q) = %q, want %q", tc.in, got, tc.want)
+		}
+	}
+}
+
+func TestGoSanitized(t *testing.T) {
+	tests := []struct {
+		in, want string
+	}{
+		{"", "_"},
+		{"boo", "boo"},
+		{"Boo", "Boo"},
+		{"ßoo", "ßoo"},
+		{"default", "_default"},
+		{"hello", "hello"},
+		{"hello-world!!", "hello_world__"},
+		{"hello-\xde\xad\xbe\xef\x00", "hello_____"},
+		{"hello 世界", "hello_世界"},
+		{"世界", "世界"},
+	}
+	for _, tc := range tests {
+		if got := GoSanitized(tc.in); got != tc.want {
+			t.Errorf("GoSanitized(%q) = %q, want %q", tc.in, got, tc.want)
+		}
+	}
+}
+
 func TestName(t *testing.T) {
 	tests := []struct {
 		in                string