protogen: use full path for generated file variable name
Use the full path (including the extension) for the generation of
the per-file variable name. Several reasons for this:
* The current logic is buggy in the case where pathType == pathTypeImport
since the prefix variable will be mangled with the Go import path.
* The extension is technically part of the path.
Thus, "path/to/foo.proto" and "path/to/foo.protodevel" are two
distinctly different imports.
* Style-wise, it subjectively looks better. Rather than being a mixture
of camelCase and snake_case, it is all snake_case for the common case:
before: ProtoFile_google_protobuf_any
after: File_google_protobuf_any_proto
* Since the extension is almost always ".proto", this results in a
suffix of "_proto", which provides an additional layer of protection
against possible name conflicts. The previous approach could possibly
have a conflict between "Foo.proto" and a message named ProtoFile
with a sub-message called Foo.
Also, use the per-file variable name for the raw descriptor variables
instead of the hashed version.
Change-Id: Ic91e326b7593e5985cee6ececc60539c27fe32fe
Reviewed-on: https://go-review.googlesource.com/c/164379
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/protogen/names.go b/protogen/names.go
index a1bddf7..5cf953c 100644
--- a/protogen/names.go
+++ b/protogen/names.go
@@ -48,12 +48,11 @@
// cleanPackageName converts a string to a valid Go package name.
func cleanPackageName(name string) GoPackageName {
- return GoPackageName(cleanGoName(name, false))
+ return GoPackageName(cleanGoName(name))
}
// cleanGoName converts a string to a valid Go identifier.
-// If mustExport, then the returned identifier is exported if not already.
-func cleanGoName(s string, mustExport bool) string {
+func cleanGoName(s string) string {
// Sanitize the input to the set of valid characters,
// which must be '_' or be in the Unicode L or N categories.
s = strings.Map(func(r rune) rune {
@@ -62,21 +61,10 @@
}
return '_'
}, s)
- r, n := utf8.DecodeRuneInString(s)
-
- // Export the identifier by either uppercasing the first character or by
- // prepending 'X' (to ensure name starts in the Unicode Lu category).
- if mustExport {
- // If possible, uppercase the first character. However, not all
- // characters in the Unicode L category have an Lu equivalent.
- if unicode.IsUpper(unicode.ToUpper(r)) {
- return string(unicode.ToUpper(r)) + s[n:]
- }
- return "X" + s
- }
// Prepend '_' in the event of a Go keyword conflict or if
// the identifier is invalid (does not start in the Unicode L category).
+ r, _ := utf8.DecodeRuneInString(s)
if token.Lookup(s).IsKeyword() || !unicode.IsLetter(r) {
return "_" + s
}
diff --git a/protogen/names_test.go b/protogen/names_test.go
index 7bb5e9b..6f03cc9 100644
--- a/protogen/names_test.go
+++ b/protogen/names_test.go
@@ -41,25 +41,22 @@
func TestCleanGoName(t *testing.T) {
tests := []struct {
- in, want, wantExported string
+ in, want string
}{
- {"", "_", "X"},
- {"boo", "boo", "Boo"},
- {"Boo", "Boo", "Boo"},
- {"ßoo", "ßoo", "Xßoo"},
- {"default", "_default", "Default"},
- {"hello", "hello", "Hello"},
- {"hello-world!!", "hello_world__", "Hello_world__"},
- {"hello-\xde\xad\xbe\xef\x00", "hello_____", "Hello_____"},
- {"hello 世界", "hello_世界", "Hello_世界"},
- {"世界", "世界", "X世界"},
+ {"", "_"},
+ {"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 := cleanGoName(tc.in, false); got != tc.want {
- t.Errorf("cleanGoName(%q, false) = %q, want %q", tc.in, got, tc.want)
- }
- if got := cleanGoName(tc.in, true); got != tc.wantExported {
- t.Errorf("cleanGoName(%q, true) = %q, want %q", tc.in, got, tc.wantExported)
+ if got := cleanGoName(tc.in); got != tc.want {
+ t.Errorf("cleanGoName(%q) = %q, want %q", tc.in, got, tc.want)
}
}
}
diff --git a/protogen/protogen.go b/protogen/protogen.go
index 758a20f..3e49719 100644
--- a/protogen/protogen.go
+++ b/protogen/protogen.go
@@ -435,7 +435,7 @@
}
}
f.GoDescriptorIdent = GoIdent{
- GoName: "ProtoFile_" + cleanGoName(prefix, false),
+ GoName: "File_" + cleanGoName(p.GetName()),
GoImportPath: f.GoImportPath,
}
f.GeneratedFilenamePrefix = prefix