blob: be57f532be26462c6b5b868ac7f137d4c96546f8 [file] [log] [blame]
// Copyright 2019 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 legacy
import (
"sync"
"testing"
"google.golang.org/protobuf/reflect/protoreflect"
)
type (
MessageA struct {
A1 *MessageA `protobuf:"bytes,1,req,name=a1"`
A2 *MessageB `protobuf:"bytes,2,req,name=a2"`
A3 Enum `protobuf:"varint,3,opt,name=a3,enum=legacy.Enum"`
}
MessageB struct {
B1 *MessageA `protobuf:"bytes,1,req,name=b1"`
B2 *MessageB `protobuf:"bytes,2,req,name=b2"`
B3 Enum `protobuf:"varint,3,opt,name=b3,enum=legacy.Enum"`
}
Enum int32
)
// TestConcurrentInit tests that concurrent wrapping of multiple legacy types
// results in the exact same descriptor being created.
func TestConcurrentInit(t *testing.T) {
const numParallel = 5
var messageATypes [numParallel]protoreflect.MessageType
var messageBTypes [numParallel]protoreflect.MessageType
var enumDescs [numParallel]protoreflect.EnumDescriptor
// Concurrently load message and enum types.
var wg sync.WaitGroup
for i := 0; i < numParallel; i++ {
i := i
wg.Add(3)
go func() {
defer wg.Done()
messageATypes[i] = Export{}.MessageTypeOf((*MessageA)(nil))
}()
go func() {
defer wg.Done()
messageBTypes[i] = Export{}.MessageTypeOf((*MessageB)(nil))
}()
go func() {
defer wg.Done()
enumDescs[i] = Export{}.EnumDescriptorOf(Enum(0))
}()
}
wg.Wait()
var (
wantMTA = messageATypes[0]
wantMDA = messageATypes[0].Descriptor().Fields().ByNumber(1).Message()
wantMTB = messageBTypes[0]
wantMDB = messageBTypes[0].Descriptor().Fields().ByNumber(2).Message()
wantED = messageATypes[0].Descriptor().Fields().ByNumber(3).Enum()
)
for _, gotMT := range messageATypes[1:] {
if gotMT != wantMTA {
t.Error("MessageType(MessageA) mismatch")
}
if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA {
t.Error("MessageDescriptor(MessageA) mismatch")
}
if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB {
t.Error("MessageDescriptor(MessageB) mismatch")
}
if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED {
t.Error("EnumDescriptor(Enum) mismatch")
}
}
for _, gotMT := range messageBTypes[1:] {
if gotMT != wantMTB {
t.Error("MessageType(MessageB) mismatch")
}
if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA {
t.Error("MessageDescriptor(MessageA) mismatch")
}
if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB {
t.Error("MessageDescriptor(MessageB) mismatch")
}
if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED {
t.Error("EnumDescriptor(Enum) mismatch")
}
}
for _, gotED := range enumDescs[1:] {
if gotED != wantED {
t.Error("EnumType(Enum) mismatch")
}
}
}