mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2024-12-26 21:24:22 +00:00
eb7b468655
For golang/protobuf#1657 Change-Id: I7b2b0c30506706015ce278e6054439c9ad9ef727 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/634815 TryBot-Bypass: Michael Stapelberg <stapelberg@google.com> Reviewed-by: Joseph Tsai <joetsai@digital-static.net> Reviewed-by: Damien Neil <dneil@google.com>
899 lines
31 KiB
Go
899 lines
31 KiB
Go
// Copyright 2024 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package name_clash_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"google.golang.org/protobuf/compiler/protogen"
|
|
"google.golang.org/protobuf/internal/genid"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/reflect/protodesc"
|
|
descpb "google.golang.org/protobuf/types/descriptorpb"
|
|
"google.golang.org/protobuf/types/gofeaturespb"
|
|
"google.golang.org/protobuf/types/pluginpb"
|
|
|
|
hpb "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/nameclash/test_name_clash_hybrid"
|
|
opb "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/nameclash/test_name_clash_opaque"
|
|
pb "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/nameclash/test_name_clash_open"
|
|
)
|
|
|
|
// TestOpenMangling tests the backwards compatible mangling of fields
|
|
// who clashes with the getters. The expected behavior, which is
|
|
// somewhat surprising, is documented in the proto
|
|
// test_name_clash_open.proto itself.
|
|
func TestOpenMangling(t *testing.T) {
|
|
m1 := &pb.M1{
|
|
Foo: proto.Int32(1),
|
|
GetFoo_: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}
|
|
if m1.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m1.GetFoo(), m1)
|
|
}
|
|
if m1.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m1.GetGetFoo_(), m1)
|
|
}
|
|
if m1.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m1.GetGetGetFoo(), m1)
|
|
}
|
|
m2 := &pb.M2{
|
|
Foo: proto.Int32(1),
|
|
GetFoo_: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}
|
|
if m2.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m2.GetFoo(), m2)
|
|
}
|
|
if m2.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m2.GetGetFoo_(), m2)
|
|
}
|
|
if m2.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m2.GetGetGetFoo(), m2)
|
|
}
|
|
m3 := &pb.M3{
|
|
Foo_: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo_: proto.Int32(3),
|
|
}
|
|
if m3.GetFoo_() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m3.GetFoo_(), m3)
|
|
}
|
|
if m3.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m3.GetGetFoo(), m3)
|
|
}
|
|
if m3.GetGetGetFoo_() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m3.GetGetGetFoo_(), m3)
|
|
}
|
|
|
|
m4 := &pb.M4{
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo_: &pb.M4_GetGetGetFoo{GetGetGetFoo: 3},
|
|
Foo_: proto.Int32(1),
|
|
}
|
|
if m4.GetFoo_() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m4.GetFoo_(), m4)
|
|
}
|
|
if m4.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m4.GetGetFoo(), m4)
|
|
}
|
|
if m4.GetGetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m4.GetGetGetGetFoo(), m4)
|
|
}
|
|
|
|
m5 := &pb.M5{
|
|
GetFoo: proto.Int32(2),
|
|
GetGetGetFoo: &pb.M5_GetGetFoo_{GetGetFoo_: 3},
|
|
Foo_: proto.Int32(1),
|
|
}
|
|
if m5.GetFoo_() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m5.GetFoo_(), m5)
|
|
}
|
|
if m5.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m5.GetGetFoo(), m5)
|
|
}
|
|
if m5.GetGetGetFoo_() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m5.GetGetGetFoo_(), m5)
|
|
}
|
|
|
|
m6 := &pb.M6{
|
|
GetGetFoo: &pb.M6_GetGetGetFoo{GetGetGetFoo: 3},
|
|
GetFoo_: proto.Int32(2),
|
|
Foo: proto.Int32(1),
|
|
}
|
|
if m6.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m6.GetFoo(), m6)
|
|
}
|
|
if m6.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m6.GetGetFoo_(), m6)
|
|
}
|
|
if m6.GetGetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_get_foo' has unexpected value %v for %T (expected 3)", m6.GetGetGetGetFoo(), m6)
|
|
}
|
|
|
|
m7 := &pb.M7{
|
|
GetGetFoo: &pb.M7_GetFoo_{GetFoo_: 3},
|
|
Foo: proto.Int32(1),
|
|
}
|
|
if m7.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m7.GetFoo(), m7)
|
|
}
|
|
if m7.GetGetFoo_() != 3 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m7.GetGetFoo_(), m7)
|
|
}
|
|
m7.GetGetFoo = &pb.M7_Bar{Bar: true}
|
|
if !m7.GetBar() {
|
|
t.Errorf("Proto field 'bar' has unexpected value %v for %T (expected 3)", m7.GetBar(), m7)
|
|
}
|
|
|
|
m8 := &pb.M8{
|
|
GetGetGetFoo_: &pb.M8_GetGetFoo{GetGetFoo: 3},
|
|
GetFoo_: proto.Int32(2),
|
|
Foo: proto.Int32(1),
|
|
}
|
|
if m8.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m8.GetFoo(), m8)
|
|
}
|
|
if m8.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m8.GetGetFoo_(), m8)
|
|
}
|
|
if m8.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m8.GetGetGetFoo(), m8)
|
|
}
|
|
|
|
m9 := &pb.M9{
|
|
GetGetGetFoo_: &pb.M9_GetGetFoo{GetGetFoo: 3},
|
|
Foo: proto.Int32(1),
|
|
}
|
|
if m9.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m9.GetFoo(), m9)
|
|
}
|
|
if m9.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m9.GetGetGetFoo(), m9)
|
|
}
|
|
m9.GetGetGetFoo_ = &pb.M9_GetFoo_{GetFoo_: 2}
|
|
if m9.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m9.GetGetFoo_(), m9)
|
|
}
|
|
|
|
}
|
|
|
|
// TestHybridMangling tests the backwards compatible mangling as well
|
|
// as new style mangling of fields who clashes with the getters. The
|
|
// expected behavior, which is somewhat surprising, is documented in
|
|
// the proto test_name_clash_hybrid.proto itself.
|
|
func TestHybridMangling(t *testing.T) {
|
|
m1 := hpb.M1_builder{
|
|
Foo: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}.Build()
|
|
if m1.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m1.GetFoo(), m1)
|
|
}
|
|
if m1.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m1.GetFoo(), m1)
|
|
}
|
|
if m1.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m1.GetGetFoo_(), m1)
|
|
}
|
|
if m1.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m1.GetGetFoo_(), m1)
|
|
}
|
|
if m1.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m1.GetGetGetFoo(), m1)
|
|
}
|
|
checkNameConsistency(t, m1)
|
|
m2 := hpb.M2_builder{
|
|
Foo: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}.Build()
|
|
if m2.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m2.GetFoo(), m2)
|
|
}
|
|
if m2.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m2.GetFoo(), m2)
|
|
}
|
|
if m2.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m2.GetGetFoo_(), m2)
|
|
}
|
|
if m2.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m2.GetGetFoo_(), m2)
|
|
}
|
|
if m2.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m2.GetGetGetFoo(), m2)
|
|
}
|
|
checkNameConsistency(t, m2)
|
|
m3 := hpb.M3_builder{
|
|
Foo: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}.Build()
|
|
if m3.GetFoo_() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m3.GetFoo_(), m3)
|
|
}
|
|
if m3.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m3.GetFoo_(), m3)
|
|
}
|
|
if m3.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m3.GetGetFoo(), m3)
|
|
}
|
|
if m3.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m3.GetGetFoo(), m3)
|
|
}
|
|
if m3.GetGetGetFoo_() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m3.GetGetGetFoo_(), m3)
|
|
}
|
|
checkNameConsistency(t, m3)
|
|
|
|
m4 := hpb.M4_builder{
|
|
GetFoo: proto.Int32(2),
|
|
GetGetGetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m4.GetFoo_() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m4.GetFoo_(), m4)
|
|
}
|
|
if m4.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m4.Get_Foo(), m4)
|
|
}
|
|
if m4.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m4.GetGetFoo(), m4)
|
|
}
|
|
if m4.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m4.Get_GetFoo(), m4)
|
|
}
|
|
if m4.GetGetGetFoo_().(*hpb.M4_GetGetGetFoo).GetGetGetFoo != 3 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 3)", m4.GetGetGetFoo_(), m4)
|
|
}
|
|
if !m4.HasGetGetFoo() {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected true)", m4.HasGetGetFoo(), m4)
|
|
}
|
|
if m4.GetGetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_get_foo' has unexpected value %v for %T (expected 3)", m4.GetGetGetGetFoo(), m4)
|
|
}
|
|
checkNameConsistency(t, m4)
|
|
|
|
m5 := hpb.M5_builder{
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m5.GetFoo_() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m5.GetFoo_(), m5)
|
|
}
|
|
if m5.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m5.Get_Foo(), m4)
|
|
}
|
|
if m5.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m5.GetGetFoo(), m5)
|
|
}
|
|
if m5.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m5.Get_GetFoo(), m4)
|
|
}
|
|
if m5.GetGetGetFoo_() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m5.GetGetGetFoo_(), m5)
|
|
}
|
|
if m5.Get_GetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m5.Get_GetGetFoo(), m5)
|
|
}
|
|
checkNameConsistency(t, m5)
|
|
|
|
m6 := hpb.M6_builder{
|
|
GetGetGetFoo: proto.Int32(3),
|
|
GetFoo: proto.Int32(2),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m6.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m6.GetFoo(), m6)
|
|
}
|
|
if m6.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m6.Get_Foo(), m6)
|
|
}
|
|
if m6.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m6.GetGetFoo_(), m6)
|
|
}
|
|
if m6.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m6.Get_GetFoo(), m6)
|
|
}
|
|
if m6.GetGetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_get_foo' has unexpected value %v for %T (expected 3)", m6.GetGetGetGetFoo(), m6)
|
|
}
|
|
checkNameConsistency(t, m6)
|
|
|
|
m7 := hpb.M7_builder{
|
|
GetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m7.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m7.GetFoo(), m7)
|
|
}
|
|
if m7.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m7.Get_Foo(), m7)
|
|
}
|
|
if m7.GetGetFoo_() != 3 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 3)", m7.GetGetFoo_(), m7)
|
|
}
|
|
if m7.Get_GetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 3)", m7.Get_GetFoo(), m7)
|
|
}
|
|
m7.SetBar(true)
|
|
if !m7.GetBar() {
|
|
t.Errorf("Proto field 'bar' has unexpected value %v for %T (expected 3)", m7.GetBar(), m7)
|
|
}
|
|
checkNameConsistency(t, m7)
|
|
|
|
m8 := hpb.M8_builder{
|
|
GetGetFoo: proto.Int32(3),
|
|
GetFoo: proto.Int32(2),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m8.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m8.GetFoo(), m8)
|
|
}
|
|
if m8.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m8.Get_Foo(), m8)
|
|
}
|
|
if m8.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m8.GetGetFoo_(), m8)
|
|
}
|
|
if m8.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m8.Get_GetFoo(), m8)
|
|
}
|
|
if m8.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m8.GetGetGetFoo(), m8)
|
|
}
|
|
checkNameConsistency(t, m8)
|
|
|
|
m9 := hpb.M9_builder{
|
|
GetGetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m9.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m9.GetFoo(), m9)
|
|
}
|
|
if m9.Get_Foo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m9.Get_Foo(), m9)
|
|
}
|
|
if m9.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m9.GetGetGetFoo(), m9)
|
|
}
|
|
if m9.Get_GetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m9.Get_GetGetFoo(), m9)
|
|
}
|
|
m9.Set_GetFoo(2)
|
|
if m9.GetGetFoo_() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m9.GetGetFoo_(), m9)
|
|
}
|
|
if m9.Get_GetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m9.Get_GetFoo(), m9)
|
|
}
|
|
checkNameConsistency(t, m9)
|
|
m10 := hpb.M10_builder{
|
|
Foo: proto.Int32(1),
|
|
SetFoo: proto.Int32(2),
|
|
}.Build()
|
|
m10.Set_Foo(47)
|
|
if m10.Get_Foo() != 47 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 47)", m10.Get_Foo(), m10)
|
|
}
|
|
m10.SetSetFoo(11)
|
|
if m10.GetSetFoo() != 11 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 11)", m10.GetSetFoo(), m10)
|
|
}
|
|
checkNameConsistency(t, m10)
|
|
m11 := hpb.M11_builder{
|
|
Foo: proto.Int32(1),
|
|
SetSetFoo: proto.Int32(2),
|
|
}.Build()
|
|
m11.Set_Foo(47)
|
|
if m11.Get_Foo() != 47 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 47)", m11.Get_Foo(), m11)
|
|
}
|
|
m11.SetSetSetFoo(11)
|
|
if m11.GetSetSetFoo() != 11 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 11)", m11.GetSetSetFoo(), m11)
|
|
}
|
|
checkNameConsistency(t, m11)
|
|
m12 := hpb.M12_builder{
|
|
Foo: proto.Int32(1),
|
|
SetFoo: proto.Int32(2),
|
|
}.Build()
|
|
m12.Set_Foo(47)
|
|
if m12.Get_Foo() != 47 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 47)", m12.Get_Foo(), m12)
|
|
}
|
|
m12.Set_SetFoo(11)
|
|
if m12.Get_SetFoo() != 11 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 11)", m12.Get_SetFoo(), m12)
|
|
}
|
|
checkNameConsistency(t, m12)
|
|
m13 := hpb.M13_builder{
|
|
Foo: proto.Int32(1),
|
|
HasFoo: proto.Int32(2),
|
|
}.Build()
|
|
if !m13.Has_Foo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m13.Has_Foo(), m13)
|
|
}
|
|
if !m13.HasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m13.HasHasFoo(), m13)
|
|
}
|
|
checkNameConsistency(t, m13)
|
|
m14 := hpb.M14_builder{
|
|
Foo: proto.Int32(1),
|
|
HasHasFoo: proto.Int32(2),
|
|
}.Build()
|
|
if !m14.Has_Foo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m14.Has_Foo(), m14)
|
|
}
|
|
if !m14.Has_HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m14.Has_HasFoo(), m14)
|
|
}
|
|
if !m14.HasHasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m14.HasHasHasFoo(), m14)
|
|
}
|
|
checkNameConsistency(t, m14)
|
|
m15 := hpb.M15_builder{
|
|
Foo: proto.Int32(1),
|
|
HasFoo: proto.Int32(2),
|
|
}.Build()
|
|
if !m15.Has_Foo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m15.Has_Foo(), m15)
|
|
}
|
|
if !m15.Has_HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m15.Has_HasFoo(), m15)
|
|
}
|
|
if !m15.HasHasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m15.HasHasHasFoo(), m15)
|
|
}
|
|
checkNameConsistency(t, m15)
|
|
m16 := hpb.M16_builder{
|
|
Foo: proto.Int32(1),
|
|
ClearFoo: proto.Int32(2),
|
|
}.Build()
|
|
m16.Clear_Foo()
|
|
if m16.Has_Foo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m16.Has_Foo(), m16)
|
|
}
|
|
m16.ClearClearFoo()
|
|
if m16.HasClearFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m16.HasClearFoo(), m16)
|
|
}
|
|
checkNameConsistency(t, m16)
|
|
m17 := hpb.M17_builder{
|
|
Foo: proto.Int32(1),
|
|
ClearClearFoo: proto.Int32(2),
|
|
}.Build()
|
|
m17.Clear_Foo()
|
|
if m17.Has_Foo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m17.Has_Foo(), m17)
|
|
}
|
|
m17.ClearClearClearFoo()
|
|
if m17.HasClearClearFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m17.HasClearClearFoo(), m17)
|
|
}
|
|
checkNameConsistency(t, m17)
|
|
m18 := hpb.M18_builder{
|
|
Foo: proto.Int32(1),
|
|
ClearFoo: proto.Int32(2),
|
|
}.Build()
|
|
m18.Clear_Foo()
|
|
if m18.Has_Foo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m18.Has_Foo(), m18)
|
|
}
|
|
m18.Clear_ClearFoo()
|
|
if m18.Has_ClearFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m18.Has_ClearFoo(), m18)
|
|
}
|
|
checkNameConsistency(t, m18)
|
|
m19 := hpb.M19_builder{
|
|
Foo: proto.Int32(1),
|
|
WhichFoo: proto.Int32(2),
|
|
}.Build()
|
|
if m19.WhichWhichWhichFoo() != hpb.M19_WhichFoo_case {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected M19_ClearFoo_case)", m19.WhichWhichWhichFoo(), m19)
|
|
}
|
|
checkNameConsistency(t, m19)
|
|
m20 := hpb.M20_builder{
|
|
Foo: proto.Int32(1),
|
|
WhichWhichFoo: proto.Int32(2),
|
|
}.Build()
|
|
if m20.Which_WhichFoo() != hpb.M20_WhichWhichFoo_case {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected M20_WhichWhichFoo_case)", m20.Which_WhichFoo(), m20)
|
|
}
|
|
checkNameConsistency(t, m20)
|
|
|
|
}
|
|
|
|
// TestOpaqueMangling tests the backwards compatible mangling as well
|
|
// as new style mangling of fields who clashes with the getters. The
|
|
// expected behavior, which is somewhat surprising, is documented in
|
|
// the proto test_name_clash_opaque.proto itself.
|
|
func TestOpaqueMangling(t *testing.T) {
|
|
m1 := opb.M1_builder{
|
|
Foo: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}.Build()
|
|
if m1.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m1.GetFoo(), m1)
|
|
}
|
|
if m1.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m1.GetGetFoo(), m1)
|
|
}
|
|
if m1.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m1.GetGetGetFoo(), m1)
|
|
}
|
|
checkNameConsistency(t, m1)
|
|
m2 := opb.M2_builder{
|
|
Foo: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}.Build()
|
|
if m2.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m2.GetFoo(), m2)
|
|
}
|
|
if m2.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m2.GetGetFoo(), m2)
|
|
}
|
|
if m2.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m2.GetGetGetFoo(), m2)
|
|
}
|
|
checkNameConsistency(t, m2)
|
|
m3 := opb.M3_builder{
|
|
Foo: proto.Int32(1),
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
}.Build()
|
|
if m3.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m3.GetFoo(), m3)
|
|
}
|
|
if m3.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m3.GetGetFoo(), m3)
|
|
}
|
|
if m3.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m3.GetGetGetFoo(), m3)
|
|
}
|
|
checkNameConsistency(t, m3)
|
|
|
|
m4 := opb.M4_builder{
|
|
GetFoo: proto.Int32(2),
|
|
GetGetGetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m4.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m4.GetFoo(), m4)
|
|
}
|
|
if m4.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m4.GetGetFoo(), m4)
|
|
}
|
|
if !m4.HasGetGetFoo() {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected true)", m4.HasGetGetFoo(), m4)
|
|
}
|
|
if m4.GetGetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_get_foo' has unexpected value %v for %T (expected 3)", m4.GetGetGetGetFoo(), m4)
|
|
}
|
|
checkNameConsistency(t, m4)
|
|
|
|
m5 := opb.M5_builder{
|
|
GetFoo: proto.Int32(2),
|
|
GetGetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m5.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m5.GetFoo(), m5)
|
|
}
|
|
if m5.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m5.GetGetFoo(), m5)
|
|
}
|
|
if m5.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m5.GetGetGetFoo(), m5)
|
|
}
|
|
checkNameConsistency(t, m5)
|
|
|
|
m6 := opb.M6_builder{
|
|
GetGetGetFoo: proto.Int32(3),
|
|
GetFoo: proto.Int32(2),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m6.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m6.GetFoo(), m6)
|
|
}
|
|
if m6.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m6.GetGetFoo(), m6)
|
|
}
|
|
if m6.GetGetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_get_foo' has unexpected value %v for %T (expected 3)", m6.GetGetGetGetFoo(), m6)
|
|
}
|
|
checkNameConsistency(t, m6)
|
|
|
|
m7 := opb.M7_builder{
|
|
GetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m7.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m7.GetFoo(), m7)
|
|
}
|
|
if m7.GetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 3)", m7.GetGetFoo(), m7)
|
|
}
|
|
m7.SetBar(true)
|
|
if !m7.GetBar() {
|
|
t.Errorf("Proto field 'bar' has unexpected value %v for %T (expected true)", m7.GetBar(), m7)
|
|
}
|
|
checkNameConsistency(t, m7)
|
|
|
|
m8 := opb.M8_builder{
|
|
GetGetFoo: proto.Int32(3),
|
|
GetFoo: proto.Int32(2),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m8.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m8.GetFoo(), m8)
|
|
}
|
|
if m8.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m8.GetGetFoo(), m8)
|
|
}
|
|
if m8.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m8.GetGetGetFoo(), m8)
|
|
}
|
|
checkNameConsistency(t, m8)
|
|
|
|
m9 := opb.M9_builder{
|
|
GetGetFoo: proto.Int32(3),
|
|
Foo: proto.Int32(1),
|
|
}.Build()
|
|
if m9.GetFoo() != 1 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 1)", m9.GetFoo(), m9)
|
|
}
|
|
if m9.GetGetGetFoo() != 3 {
|
|
t.Errorf("Proto field 'get_get_foo' has unexpected value %v for %T (expected 3)", m9.GetGetGetFoo(), m9)
|
|
}
|
|
m9.SetGetFoo(2)
|
|
if m9.GetGetFoo() != 2 {
|
|
t.Errorf("Proto field 'get_foo' has unexpected value %v for %T (expected 2)", m9.GetGetFoo(), m9)
|
|
}
|
|
checkNameConsistency(t, m9)
|
|
m10 := opb.M10_builder{
|
|
Foo: proto.Int32(1),
|
|
SetFoo: proto.Int32(2),
|
|
}.Build()
|
|
m10.SetFoo(48)
|
|
if m10.GetFoo() != 48 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 48)", m10.GetFoo(), m10)
|
|
}
|
|
m10.SetSetFoo(11)
|
|
if m10.GetSetFoo() != 11 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 11)", m10.GetSetFoo(), m10)
|
|
}
|
|
checkNameConsistency(t, m10)
|
|
m11 := opb.M11_builder{
|
|
Foo: proto.Int32(1),
|
|
SetSetFoo: proto.Int32(2),
|
|
}.Build()
|
|
m11.SetFoo(48)
|
|
if m11.GetFoo() != 48 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 48)", m11.GetFoo(), m11)
|
|
}
|
|
m11.SetSetSetFoo(11)
|
|
if m11.GetSetSetFoo() != 11 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 11)", m11.GetSetSetFoo(), m11)
|
|
}
|
|
checkNameConsistency(t, m11)
|
|
m12 := opb.M12_builder{
|
|
Foo: proto.Int32(1),
|
|
SetFoo: proto.Int32(2),
|
|
}.Build()
|
|
m12.SetFoo(48)
|
|
if m12.GetFoo() != 48 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 48)", m12.GetFoo(), m12)
|
|
}
|
|
m12.SetSetFoo(12)
|
|
if m12.GetSetFoo() != 12 {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected 12)", m12.GetSetFoo(), m12)
|
|
}
|
|
checkNameConsistency(t, m12)
|
|
m13 := opb.M13_builder{
|
|
Foo: proto.Int32(1),
|
|
HasFoo: proto.Int32(2),
|
|
}.Build()
|
|
if !m13.HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m13.HasFoo(), m13)
|
|
}
|
|
if !m13.HasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m13.HasHasFoo(), m13)
|
|
}
|
|
checkNameConsistency(t, m13)
|
|
m14 := opb.M14_builder{
|
|
Foo: proto.Int32(1),
|
|
HasHasFoo: proto.Int32(2),
|
|
}.Build()
|
|
if !m14.HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m14.HasFoo(), m14)
|
|
}
|
|
if !m14.HasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m14.HasHasFoo(), m14)
|
|
}
|
|
if !m14.HasHasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m14.HasHasHasFoo(), m14)
|
|
}
|
|
checkNameConsistency(t, m14)
|
|
m15 := opb.M15_builder{
|
|
Foo: proto.Int32(1),
|
|
HasFoo: proto.Int32(2),
|
|
}.Build()
|
|
if !m15.HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m15.HasFoo(), m15)
|
|
}
|
|
if !m15.HasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m15.HasHasFoo(), m15)
|
|
}
|
|
if !m15.HasHasHasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected true)", m15.HasHasHasFoo(), m15)
|
|
}
|
|
checkNameConsistency(t, m15)
|
|
m16 := opb.M16_builder{
|
|
Foo: proto.Int32(1),
|
|
ClearFoo: proto.Int32(2),
|
|
}.Build()
|
|
m16.SetFoo(4711)
|
|
m16.ClearFoo()
|
|
if m16.HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m16.HasFoo(), m16)
|
|
}
|
|
m16.ClearClearFoo()
|
|
if m16.HasClearFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m16.HasClearFoo(), m16)
|
|
}
|
|
checkNameConsistency(t, m16)
|
|
m17 := opb.M17_builder{
|
|
Foo: proto.Int32(1),
|
|
ClearClearFoo: proto.Int32(2),
|
|
}.Build()
|
|
m17.SetFoo(4711)
|
|
m17.ClearFoo()
|
|
if m17.HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m17.HasFoo(), m17)
|
|
}
|
|
m17.ClearClearClearFoo()
|
|
if m17.HasClearClearFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m17.HasClearClearFoo(), m17)
|
|
}
|
|
checkNameConsistency(t, m17)
|
|
m18 := opb.M18_builder{
|
|
Foo: proto.Int32(1),
|
|
ClearFoo: proto.Int32(2),
|
|
}.Build()
|
|
m18.SetFoo(4711)
|
|
m18.ClearFoo()
|
|
if m18.HasFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m18.HasFoo(), m18)
|
|
}
|
|
m18.SetClearFoo(13)
|
|
m18.ClearClearFoo()
|
|
if m18.HasClearFoo() {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected false)", m18.HasClearFoo(), m18)
|
|
}
|
|
checkNameConsistency(t, m18)
|
|
m19 := opb.M19_builder{
|
|
Foo: proto.Int32(1),
|
|
WhichFoo: proto.Int32(2),
|
|
}.Build()
|
|
if m19.WhichWhichWhichFoo() != opb.M19_WhichFoo_case {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected M19_ClearFoo_case)", m19.WhichWhichWhichFoo(), m19)
|
|
}
|
|
checkNameConsistency(t, m19)
|
|
m20 := opb.M20_builder{
|
|
Foo: proto.Int32(1),
|
|
WhichWhichFoo: proto.Int32(2),
|
|
}.Build()
|
|
if m20.WhichWhichFoo() != opb.M20_WhichWhichFoo_case {
|
|
t.Errorf("Proto field 'foo' has unexpected value %v for %T (expected M20_WhichWhichFoo_case)", m20.WhichWhichFoo(), m20)
|
|
}
|
|
checkNameConsistency(t, m20)
|
|
|
|
}
|
|
|
|
func protogenFor(t *testing.T, m proto.Message) *protogen.Message {
|
|
t.Helper()
|
|
|
|
md := m.ProtoReflect().Descriptor()
|
|
|
|
// Construct a Protobuf plugin code generation request based on the
|
|
// transitive closure of dependencies of message m.
|
|
req := &pluginpb.CodeGeneratorRequest{
|
|
ProtoFile: []*descpb.FileDescriptorProto{
|
|
protodesc.ToFileDescriptorProto(descpb.File_google_protobuf_descriptor_proto),
|
|
protodesc.ToFileDescriptorProto(gofeaturespb.File_google_protobuf_go_features_proto),
|
|
protodesc.ToFileDescriptorProto(md.ParentFile()),
|
|
},
|
|
}
|
|
plugin, err := protogen.Options{}.New(req)
|
|
if err != nil {
|
|
t.Fatalf("protogen.Options.New: %v", err)
|
|
}
|
|
if got, want := len(plugin.Files), len(req.ProtoFile); got != want {
|
|
t.Fatalf("protogen returned %d plugin.Files entries, expected %d", got, want)
|
|
}
|
|
file := plugin.Files[len(plugin.Files)-1]
|
|
for _, msg := range file.Messages {
|
|
if msg.Desc.FullName() != md.FullName() {
|
|
continue
|
|
}
|
|
return msg
|
|
}
|
|
t.Fatalf("BUG: message %q not found in protogen response", md.FullName())
|
|
return nil
|
|
}
|
|
|
|
// checkNameConsistency will go through the fields (deliberately avoiding
|
|
// protoreflect; querying protogen instead), and for each field check that one
|
|
// of the two naming schemes is used consistently, so that if you find
|
|
// e.g. Has_Foo, the setter will be Set_Foo and not SetFoo. It also checks that
|
|
// at least one of the naming schemes apply.
|
|
func checkNameConsistency(t *testing.T, m proto.Message) {
|
|
t.Helper()
|
|
// It's wrong to use Go reflection on a Message, but in this
|
|
// case, we're specifically looking at the implementation
|
|
typ := reflect.TypeOf(m)
|
|
// The info we need for one field
|
|
type fi struct {
|
|
name string
|
|
prefixes []string
|
|
}
|
|
// The method prefixes for different kinds of fields
|
|
repeatedPrefixes := []string{"Get", "Set"}
|
|
oneofPrefixes := []string{"Has", "Clear", "Which"}
|
|
optionalPrefixes := []string{"Get", "Set", "Has", "Clear"}
|
|
|
|
fields := []fi{}
|
|
msg := protogenFor(t, m)
|
|
for _, f := range msg.Fields {
|
|
prefixes := optionalPrefixes
|
|
if f.Desc.Cardinality() == genid.Field_CARDINALITY_REPEATED_enum_value {
|
|
prefixes = repeatedPrefixes
|
|
}
|
|
fields = append(fields, fi{name: f.GoName, prefixes: prefixes})
|
|
}
|
|
for _, o := range msg.Oneofs {
|
|
fields = append(fields, fi{name: o.GoName, prefixes: oneofPrefixes})
|
|
}
|
|
if len(fields) == 0 {
|
|
t.Errorf("Message %v checked for consistency has no fields to check", reflect.TypeOf(m))
|
|
}
|
|
// Check method names for all fields
|
|
for _, f := range fields {
|
|
// Remove trailing underscores added by old name mangling algorithm
|
|
for f.name[len(f.name)-1] == '_' {
|
|
f.name = f.name[:len(f.name)-1]
|
|
}
|
|
// Check consistency of either "underscored" methods or "non underscored"
|
|
found := ""
|
|
for _, infix := range []string{"_", ""} {
|
|
for _, prefix := range f.prefixes {
|
|
if m, ok := typ.MethodByName(prefix + infix + f.name); ok {
|
|
found = m.Name
|
|
break
|
|
}
|
|
}
|
|
if found != "" {
|
|
for _, prefix := range f.prefixes {
|
|
if _, ok := typ.MethodByName(prefix + infix + f.name); !ok {
|
|
t.Errorf("Field %s has inconsistent method names - found %s, but not %s", f.name, found, prefix+infix+f.name)
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
// If we found neither, something is wrong
|
|
if found == "" {
|
|
t.Errorf("Field %s has neither plain nor underscored methods.", f.name)
|
|
}
|
|
|
|
}
|
|
}
|