compiler/protogen: avoid suggesting faulty go_package option

In some situations, the full Go package path cannot be determined,
in which case, we should avoid suggesting a go_package option
that is incorrect.

As a heuristic, check whether the proposed path contains at least
a dot before a slash to determine whether it is a full path or not,
which is a simple way to determine whether the first segment is a
top-level domain.

This avoids printing unhelpful warnings like:
	WARNING: Missing 'go_package' option in "foo/bar.proto", please specify:
		option go_package = ".;foo_package";
	A future release of protoc-gen-go will require this be specified.
	See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
and instead prints a warning like:
	WARNING: Missing 'go_package' option in "foo/bar.proto",
	please specify it with the full Go package path as
	a future release of protoc-gen-go will require this be specified.
	See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.

We rely on the documentation on the developer website to provide
better guidance.

Change-Id: I38fc4c676d0314ba6d7ad8d5f390fb9e237f2bb1
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/232338
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/compiler/protogen/protogen.go b/compiler/protogen/protogen.go
index e3b9e7f..482e846 100644
--- a/compiler/protogen/protogen.go
+++ b/compiler/protogen/protogen.go
@@ -341,11 +341,21 @@
 				"\n", fdesc.GetName(), goPkgOpt)
 		case packageName == "" && importPath == "":
 			// No Go package information provided.
-			warn("Missing 'go_package' option in %q, please specify:\n"+
-				"\toption go_package = %q;\n"+
-				"A future release of protoc-gen-go will require this be specified.\n"+
-				"See "+goPackageDocURL+" for more information.\n"+
-				"\n", fdesc.GetName(), goPkgOpt)
+			dotIdx := strings.Index(goPkgOpt, ".")   // heuristic for top-level domain
+			slashIdx := strings.Index(goPkgOpt, "/") // heuristic for multi-segment path
+			if isFull := 0 <= dotIdx && dotIdx <= slashIdx; isFull {
+				warn("Missing 'go_package' option in %q, please specify:\n"+
+					"\toption go_package = %q;\n"+
+					"A future release of protoc-gen-go will require this be specified.\n"+
+					"See "+goPackageDocURL+" for more information.\n"+
+					"\n", fdesc.GetName(), goPkgOpt)
+			} else {
+				warn("Missing 'go_package' option in %q,\n"+
+					"please specify it with the full Go package path as\n"+
+					"a future release of protoc-gen-go will require this be specified.\n"+
+					"See "+goPackageDocURL+" for more information.\n"+
+					"\n", fdesc.GetName())
+			}
 		}
 	}