proto: generate Get methods for fields of basic type in proto3

Given proto3 schema:

  message Foo {
    string some_value = 1;
  }

  message Bar {
    Foo foo = 1;
  }

  message Baz {
    Bar bar = 1;
  }

Accessing baz.bar.foo.SomeValue currently requires this code:

        if f := baz.GetBar().GetFoo(); f != nil {
                fmt.Printf("value was %v\n", f.SomeValue)
        }

After the CL, it becomes:

        fmt.Printf("value was %v\n", baz.GetBar().GetFoo().GetSomeValue())

There are downsides to generating more code:
   - all things equal, less code is better
   - larger API surface

The upsides are:
 - consistency with proto2 API (proto2 and proto3 can be mixed. Keeping API consistent is important)
 - easier to explain API - all fields have Get method. No exceptions.
 - reduced user confusion - questions about this come up frequently

testing:
  - added a new test
  - inspected a diff for an arbitrarily chosen schema
PiperOrigin-RevId: 138212965
diff --git a/proto/proto3_test.go b/proto/proto3_test.go
index 462f805..735837f 100644
--- a/proto/proto3_test.go
+++ b/proto/proto3_test.go
@@ -93,6 +93,16 @@
 	}
 }
 
+func TestGettersForBasicTypesExist(t *testing.T) {
+	var m pb.Message
+	if got := m.GetNested().GetBunny(); got != "" {
+		t.Errorf("m.GetNested().GetBunny() = %q, want empty string", got)
+	}
+	if got := m.GetNested().GetCute(); got {
+		t.Errorf("m.GetNested().GetCute() = %t, want false", got)
+	}
+}
+
 func TestProto3SetDefaults(t *testing.T) {
 	in := &pb.Message{
 		Terrain: map[string]*pb.Nested{
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go
index 0e5d2b7..5052076 100644
--- a/protoc-gen-go/generator/generator.go
+++ b/protoc-gen-go/generator/generator.go
@@ -2076,11 +2076,6 @@
 			star = "*"
 		}
 
-		// In proto3, only generate getters for message fields and oneof fields.
-		if message.proto3() && *field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE && !oneof {
-			continue
-		}
-
 		// Only export getter symbols for basic types,
 		// and for messages and enums in the same package.
 		// Groups are not exported.
@@ -2139,7 +2134,11 @@
 			continue
 		}
 		if !oneof {
-			g.P("if m != nil && m." + fname + " != nil {")
+			if message.proto3() {
+				g.P("if m != nil {")
+			} else {
+				g.P("if m != nil && m." + fname + " != nil {")
+			}
 			g.In()
 			g.P("return " + star + "m." + fname)
 			g.Out()