internal/impl: enable fully lazy extensions (over Size and Marshal)

Extensions will be kept in wire format over proto.Size and proto.Marshal.

This change is a significant performance optimization for jobs that read and
write Protobuf messages of the same type, but do not need to process extensions.

This change is based on work by Patrik Nyblom.

Note that the proto.Size semantics for lazy messages might be surprising;
see https://protobuf.dev/reference/go/size/ for details.

We have been running this change for about two weeks in Google,
all known breakages have already been addressed with CL 579995.

related to golang/protobuf#1609

Change-Id: I16be78d15304d775bb30e76356a1a61d61300b43
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/580015
Reviewed-by: Lasse Folger <lassefolger@google.com>
Auto-Submit: Michael Stapelberg <stapelberg@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Michael Stapelberg 2024-05-15 10:47:18 +02:00 committed by Gopher Robot
parent 15d7b138c5
commit 0e932930c8
11 changed files with 2026 additions and 1 deletions

View File

@ -68,7 +68,7 @@ func (mi *MessageInfo) isInitExtensions(ext *map[int32]ExtensionField) error {
}
for _, x := range *ext {
ei := getExtensionFieldInfo(x.Type())
if ei.funcs.isInit == nil {
if ei.funcs.isInit == nil || x.isUnexpandedLazy() {
continue
}
v := x.Value()

View File

@ -99,6 +99,28 @@ func (f *ExtensionField) canLazy(xt protoreflect.ExtensionType) bool {
return false
}
// isUnexpandedLazy returns true if the ExensionField is lazy and not
// yet expanded, which means it's present and already checked for
// initialized required fields.
func (f *ExtensionField) isUnexpandedLazy() bool {
return f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0
}
// lazyBuffer retrieves the buffer for a lazy extension if it's not yet expanded.
//
// The returned buffer has to be kept over whatever operation we're planning,
// as re-retrieving it will fail after the message is lazily decoded.
func (f *ExtensionField) lazyBuffer() []byte {
// This function might be in the critical path, so check the atomic without
// taking a look first, then only take the lock if needed.
if !f.isUnexpandedLazy() {
return nil
}
f.lazy.mu.Lock()
defer f.lazy.mu.Unlock()
return f.lazy.b
}
func (f *ExtensionField) lazyInit() {
f.lazy.mu.Lock()
defer f.lazy.mu.Unlock()

View File

@ -26,6 +26,15 @@ func sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int)
}
num, _ := protowire.DecodeTag(xi.wiretag)
size += messageset.SizeField(num)
if fullyLazyExtensions(opts) {
// Don't expand the extension, instead use the buffer to calculate size
if lb := x.lazyBuffer(); lb != nil {
// We got hold of the buffer, so it's still lazy.
// Don't count the tag size in the extension buffer, it's already added.
size += protowire.SizeTag(messageset.FieldMessage) + len(lb) - xi.tagsize
continue
}
}
size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts)
}
@ -85,6 +94,19 @@ func marshalMessageSetField(mi *MessageInfo, b []byte, x ExtensionField, opts ma
xi := getExtensionFieldInfo(x.Type())
num, _ := protowire.DecodeTag(xi.wiretag)
b = messageset.AppendFieldStart(b, num)
if fullyLazyExtensions(opts) {
// Don't expand the extension if it's still in wire format, instead use the buffer content.
if lb := x.lazyBuffer(); lb != nil {
// The tag inside the lazy buffer is a different tag (the extension
// number), but what we need here is the tag for FieldMessage:
b = protowire.AppendVarint(b, protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType))
b = append(b, lb[xi.tagsize:]...)
b = messageset.AppendFieldEnd(b)
return b, nil
}
}
b, err := xi.funcs.marshal(b, x.Value(), protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType), opts)
if err != nil {
return b, err

View File

@ -149,6 +149,14 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
return b, nil
}
// fullyLazyExtensions returns true if we should attempt to keep extensions lazy over size and marshal.
func fullyLazyExtensions(opts marshalOptions) bool {
// When deterministic marshaling is requested, force an unmarshal for lazy
// extensions to produce a deterministic result, instead of passing through
// bytes lazily that may or may not match what Go Protobuf would produce.
return opts.flags&piface.MarshalDeterministic == 0
}
func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
if ext == nil {
return 0
@ -158,6 +166,14 @@ func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marsha
if xi.funcs.size == nil {
continue
}
if fullyLazyExtensions(opts) {
// Don't expand the extension, instead use the buffer to calculate size
if lb := x.lazyBuffer(); lb != nil {
// We got hold of the buffer, so it's still lazy.
n += len(lb)
continue
}
}
n += xi.funcs.size(x.Value(), xi.tagsize, opts)
}
return n
@ -176,6 +192,13 @@ func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField,
var err error
for _, x := range *ext {
xi := getExtensionFieldInfo(x.Type())
if fullyLazyExtensions(opts) {
// Don't expand the extension if it's still in wire format, instead use the buffer content.
if lb := x.lazyBuffer(); lb != nil {
b = append(b, lb...)
continue
}
}
b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
}
return b, err
@ -191,6 +214,13 @@ func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField,
for _, k := range keys {
x := (*ext)[int32(k)]
xi := getExtensionFieldInfo(x.Type())
if fullyLazyExtensions(opts) {
// Don't expand the extension if it's still in wire format, instead use the buffer content.
if lb := x.lazyBuffer(); lb != nil {
b = append(b, lb...)
continue
}
}
b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
if err != nil {
return b, err

View File

@ -0,0 +1,88 @@
// 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 impl_test
import (
"testing"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/testing/protopack"
lazytestpb "google.golang.org/protobuf/internal/testprotos/lazy"
)
// Constructs a message encoded in denormalized (non-minimal) wire format, but
// using two levels of nesting: A top-level message with a child message which
// in turn has a grandchild message.
func denormalizedTwoLevel(t *testing.T) ([]byte, *lazytestpb.Top, error) {
// Construct a message with denormalized (non-minimal) wire format:
// 1. Encode a top-level message with submessage B (ext) + C (field)
// 2. Replace the encoding of submessage C (field) with
// another instance of submessage B (ext)
//
// This modification of the wire format is spec'd in Protobuf:
// https://github.com/protocolbuffers/protobuf/issues/9257
grandchild := &lazytestpb.Sub{}
proto.SetExtension(grandchild, lazytestpb.E_Ext_B, &lazytestpb.Ext{
SomeFlag: proto.Bool(true),
})
expectedMessage := &lazytestpb.Top{
Child: &lazytestpb.Sub{
Grandchild: grandchild,
},
A: proto.Uint32(2342),
}
fullMessage := protopack.Message{
protopack.Tag{1, protopack.VarintType}, protopack.Varint(2342),
// Child
protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
// Grandchild
protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
// The first occurrence of B matches expectedMessage:
protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
}),
// This second duplicative occurrence of B is spec'd in Protobuf:
// https://github.com/protocolbuffers/protobuf/issues/9257
protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
}),
}),
}),
}.Marshal()
return fullMessage, expectedMessage, nil
}
func TestNoInvalidWireFormatWithDeterministicLazy(t *testing.T) {
fullMessage, _, err := denormalizedTwoLevel(t)
if err != nil {
t.Fatal(err)
}
top := &lazytestpb.Top{}
if err := proto.Unmarshal(fullMessage, top); err != nil {
t.Fatal(err)
}
// Requesting deterministic marshaling should result in unmarshaling (and
// thereby normalizing the non-minimal encoding) when sizing.
//
// If the deterministic flag is dropped (like before cl/624951104), the size
// cache is populated with the non-minimal size. The Marshal call below
// lazily unmarshals (due to the Deterministic flag), which includes
// normalization, and will then report a size mismatch error (instead of
// producing invalid wire format).
proto.MarshalOptions{Deterministic: true}.Size(top)
_, err = proto.MarshalOptions{
Deterministic: true,
UseCachedSize: true,
}.Marshal(top)
if err != nil {
t.Fatal(err)
}
}

View File

@ -5,13 +5,21 @@
package impl_test
import (
"reflect"
"sync"
"testing"
"unsafe"
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/impl"
"google.golang.org/protobuf/internal/protobuild"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/testing/protocmp"
lazytestpb "google.golang.org/protobuf/internal/testprotos/lazy"
"google.golang.org/protobuf/internal/testprotos/messageset/messagesetpb"
testpb "google.golang.org/protobuf/internal/testprotos/test"
)
@ -50,3 +58,564 @@ func TestLazyExtensions(t *testing.T) {
}
checkLazy("after unmarshal", m, flags.LazyUnmarshalExtensions)
}
func TestMessageSetLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
h := &lazytestpb.Holder{Data: &messagesetpb.MessageSet{}}
ext := &lazytestpb.Rabbit{Name: proto.String("Judy")}
proto.SetExtension(h.GetData(), lazytestpb.E_Rabbit_MessageSetExtension, ext)
nh := roundtrip(t, h).(*lazytestpb.Holder)
if extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
proto.Size(nh)
if extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field) {
t.Errorf("Extension unexpectedly initialized after Size")
}
proto.Marshal(nh)
if extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field) {
t.Errorf("Extension unexpectedly initialized after Marshal")
}
if !proto.HasExtension(nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension) {
t.Fatalf("Can't get extension")
}
if extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field) {
t.Errorf("Extension unexpectedly initialized after Has")
}
nh = roundtrip(t, nh).(*lazytestpb.Holder)
if extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field) {
t.Errorf("Extension unexpectedly initialized after Has")
}
if diff := cmp.Diff(h, nh, protocmp.Transform()); diff != "" {
t.Errorf("Got %+v, want %+v, diff:\n%s", nh, h, diff)
}
if got, want := extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Diff")
}
int := proto.GetExtension(nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension).(*lazytestpb.Rabbit)
if int.GetName() != "Judy" {
t.Errorf("Extension value \"Judy\" not retained, got: %v", int.GetName())
}
if got, want := extensionIsInitialized(t, nh.GetData(), lazytestpb.E_Rabbit_MessageSetExtension.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
}
var (
// Trees are fully lazy
treeTemplate = &lazytestpb.Tree{
Eucalyptus: proto.Bool(true),
}
spGH = lazytestpb.FlyingFoxSpecies_GREY_HEADED
spP = lazytestpb.FlyingFoxSpecies_SPECTACLED
spLE = lazytestpb.FlyingFoxSpecies_LARGE_EARED
spBB = lazytestpb.FlyingFoxSpecies_BARE_BACKED
spF = lazytestpb.PipistrelleSpecies_FOREST
spR = lazytestpb.PipistrelleSpecies_RUSTY
)
func TestExtensionLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
tree := proto.Clone(treeTemplate)
proto.SetExtension(tree, lazytestpb.E_Bat, &lazytestpb.FlyingFox{Species: &spGH})
proto.SetExtension(tree, lazytestpb.E_BatPup, &lazytestpb.FlyingFox{Species: &spP})
nt := roundtrip(t, tree).(*lazytestpb.Tree)
if extensionIsInitialized(t, nt, lazytestpb.E_Bat.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
proto.Size(nt)
if extensionIsInitialized(t, nt, lazytestpb.E_Bat.Field) {
t.Errorf("Extension unexpectedly initialized after Size")
}
gb, err := proto.Marshal(nt)
if err != nil {
t.Fatalf("proto.Marshal(%+v) failed: %v", nt, err)
}
if extensionIsInitialized(t, nt, lazytestpb.E_Bat.Field) {
t.Errorf("Extension unexpectedly initialized after Marshal")
}
fox := proto.GetExtension(nt, lazytestpb.E_Bat).(*lazytestpb.FlyingFox)
if got, want := fox.GetSpecies(), spGH; want != got {
t.Errorf("Extension's Speices field not retained, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, nt, lazytestpb.E_Bat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
if extensionIsInitialized(t, nt, lazytestpb.E_BatPup.Field) {
t.Errorf("Extension unexpectedly initialized after Get")
}
foxPup := proto.GetExtension(nt, lazytestpb.E_BatPup).(*lazytestpb.FlyingFox)
if got, want := foxPup.GetSpecies(), spP; want != got {
t.Errorf("Extension's Speices field not retained, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, nt, lazytestpb.E_Bat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
if got, want := extensionIsInitialized(t, nt, lazytestpb.E_BatPup.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
rt := &lazytestpb.Tree{}
if err := proto.Unmarshal(gb, rt); err != nil {
t.Fatalf("Can't unmarshal pb.Tree: %v", err)
}
if diff := cmp.Diff(tree, rt, protocmp.Transform()); diff != "" {
t.Errorf("Got %+v, want %+v, diff:\n%s", rt, tree, diff)
}
if got, want := extensionIsInitialized(t, rt, lazytestpb.E_Bat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Diff")
}
nt = roundtrip(t, tree).(*lazytestpb.Tree)
proto.ClearExtension(nt, lazytestpb.E_Bat)
proto.ClearExtension(nt, lazytestpb.E_BatPup)
if proto.HasExtension(nt, lazytestpb.E_Bat) {
t.Fatalf("Extension not cleared in (%+v)", nt)
}
if proto.HasExtension(nt, lazytestpb.E_BatPup) {
t.Fatalf("Extension not cleared in (%+v)", nt)
}
}
func TestExtensionNestedScopeLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
tree := proto.Clone(treeTemplate)
proto.SetExtension(tree, lazytestpb.E_BatNest_Bat, &lazytestpb.FlyingFox{Species: &spGH})
nt := roundtrip(t, tree).(*lazytestpb.Tree)
if extensionIsInitialized(t, nt, lazytestpb.E_BatNest_Bat.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
proto.Size(nt)
if extensionIsInitialized(t, nt, lazytestpb.E_BatNest_Bat.Field) {
t.Errorf("Extension unexpectedly initialized after Size")
}
gb, err := proto.Marshal(nt)
if err != nil {
t.Fatalf("proto.Marshal(%+v) failed: %v", nt, err)
}
if extensionIsInitialized(t, nt, lazytestpb.E_BatNest_Bat.Field) {
t.Errorf("Extension unexpectedly initialized after Marshal")
}
fox := proto.GetExtension(nt, lazytestpb.E_BatNest_Bat).(*lazytestpb.FlyingFox)
if got, want := fox.GetSpecies(), spGH; want != got {
t.Errorf("Extension's Speices field not retained, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, nt, lazytestpb.E_BatNest_Bat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
rt := &lazytestpb.Tree{}
if err := proto.Unmarshal(gb, rt); err != nil {
t.Fatalf("Can't unmarshal pb.Tree: %v", err)
}
if diff := cmp.Diff(tree, rt, protocmp.Transform()); diff != "" {
t.Errorf("Got %+v, want %+v, diff:\n%s", rt, tree, diff)
}
if got, want := extensionIsInitialized(t, rt, lazytestpb.E_BatNest_Bat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Diff")
}
}
func TestExtensionRepeatedMessageLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
posse := []*lazytestpb.FlyingFox{
{Species: &spLE},
{Species: &spBB},
}
m := proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_BatPosse, posse)
if got, want := proto.HasExtension(m, lazytestpb.E_BatPosse), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr := roundtrip(t, m).(*lazytestpb.Tree)
if extensionIsInitialized(t, mr, lazytestpb.E_BatPosse.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
mrr := roundtrip(t, mr).(*lazytestpb.Tree)
if got, want := proto.HasExtension(mrr, lazytestpb.E_BatPosse), true; got != want {
t.Errorf("Extension is not present after setting: got %v, want %v", got, want)
}
if extensionIsInitialized(t, mrr, lazytestpb.E_BatPosse.Field) {
t.Errorf("Extension unexpectedly initialized after Has")
}
mrr = roundtrip(t, mr).(*lazytestpb.Tree)
foxPosse := proto.GetExtension(mrr, lazytestpb.E_BatPosse).([]*lazytestpb.FlyingFox)
if got, want := foxPosse[0].GetSpecies(), spLE; got != want {
t.Errorf("Extension's Speices field, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_BatPosse.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
// Set to empty slice instead
m = proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_BatPosse, []*lazytestpb.FlyingFox{})
if got, want := proto.HasExtension(m, lazytestpb.E_BatPosse), false; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr = roundtrip(t, m).(*lazytestpb.Tree)
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_BatPosse.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_BatPosse), false; got != want {
t.Errorf("Extension is not present after setting: got %v, want %v", got, want)
}
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_BatPosse.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Has")
}
mrr = roundtrip(t, mr).(*lazytestpb.Tree)
if got, want := proto.HasExtension(mrr, lazytestpb.E_BatPosse), false; got != want {
t.Errorf("Extension is not present after setting: got %v, want %v", got, want)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_BatPosse.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Has")
}
foxPosse = proto.GetExtension(mrr, lazytestpb.E_BatPosse).([]*lazytestpb.FlyingFox)
if got, want := len(foxPosse), 0; got != want {
t.Errorf("Extension field length, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_BatPosse.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
}
func TestExtensionIntegerLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
var iBat uint32 = 4711
m := proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_IntegerBat, iBat)
if got, want := proto.HasExtension(m, lazytestpb.E_IntegerBat), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr := roundtrip(t, m).(*lazytestpb.Tree)
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_IntegerBat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_IntegerBat), true; got != want {
t.Errorf("Extension is not present after setting: got %v, want %v", got, want)
}
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_IntegerBat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Has")
}
mr = roundtrip(t, m).(*lazytestpb.Tree)
if got, want := proto.GetExtension(mr, lazytestpb.E_IntegerBat).(uint32), iBat; got != want {
t.Errorf("Extension's integer field, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_IntegerBat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
}
func TestExtensionBinaryLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
m := proto.Clone(treeTemplate)
bBat := []byte("I'm a bat")
proto.SetExtension(m, lazytestpb.E_BinaryBat, bBat)
if got, want := proto.HasExtension(m, lazytestpb.E_BinaryBat), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr := roundtrip(t, m).(*lazytestpb.Tree)
// A binary extension is never kept lazy
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_BinaryBat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_BinaryBat), true; got != want {
t.Errorf("Extension present after roundtrip: got %v, want %v", got, want)
}
m = proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_BinaryBat, []byte{})
// An empty binary is also a binary
if got, want := proto.HasExtension(m, lazytestpb.E_BinaryBat), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr = roundtrip(t, m).(*lazytestpb.Tree)
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_BinaryBat.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_BinaryBat), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
}
func TestExtensionGroupLazy(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
// Group: should behave like message
pip := &lazytestpb.Pipistrelle{Species: &spF}
pips := []*lazytestpb.Pipistrelles{
{Species: &spF},
{Species: &spR},
}
m := proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_Pipistrelle, pip)
if got, want := proto.HasExtension(m, lazytestpb.E_Pipistrelle), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr := roundtrip(t, m).(*lazytestpb.Tree)
if extensionIsInitialized(t, mr, lazytestpb.E_Pipistrelle.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_Pipistrelle), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
if extensionIsInitialized(t, mr, lazytestpb.E_Pipistrelle.Field) {
t.Errorf("Extension unexpectedly initialized after Has")
}
mrr := roundtrip(t, mr).(*lazytestpb.Tree)
if extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelle.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
mrr = roundtrip(t, mr).(*lazytestpb.Tree)
if extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelle.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
pipistrelle := proto.GetExtension(mrr, lazytestpb.E_Pipistrelle).(*lazytestpb.Pipistrelle)
if got, want := pipistrelle.GetSpecies(), spF; got != want {
t.Errorf("Extension's Speices field, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelle.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
// Group slice, behaves like message slice
m = proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_Pipistrelles, pips)
if got, want := proto.HasExtension(m, lazytestpb.E_Pipistrelles), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
mr = roundtrip(t, m).(*lazytestpb.Tree)
if extensionIsInitialized(t, mr, lazytestpb.E_Pipistrelles.Field) {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_Pipistrelles), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
if extensionIsInitialized(t, mr, lazytestpb.E_Pipistrelles.Field) {
t.Errorf("Extension unexpectedly initialized after Has")
}
mr = roundtrip(t, m).(*lazytestpb.Tree)
mrr = roundtrip(t, mr).(*lazytestpb.Tree)
if got, want := proto.HasExtension(mrr, lazytestpb.E_Pipistrelles), true; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
if extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelles.Field) {
t.Errorf("Extension unexpectedly initialized after Has")
}
mrr = roundtrip(t, mr).(*lazytestpb.Tree)
pipistrelles := proto.GetExtension(mrr, lazytestpb.E_Pipistrelles).([]*lazytestpb.Pipistrelles)
if got, want := pipistrelles[1].GetSpecies(), spR; got != want {
t.Errorf("Extension's Speices field, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelles.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
// Setting an empty group slice has no effect
m = proto.Clone(treeTemplate)
proto.SetExtension(m, lazytestpb.E_Pipistrelles, []*lazytestpb.Pipistrelles{})
if got, want := proto.HasExtension(m, lazytestpb.E_Pipistrelles), false; got != want {
t.Errorf("Extension present after setting empty: got %v, want %v", got, want)
}
mr = roundtrip(t, m).(*lazytestpb.Tree)
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_Pipistrelles.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Unmarshal")
}
if got, want := proto.HasExtension(mr, lazytestpb.E_Pipistrelles), false; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
if got, want := extensionIsInitialized(t, mr, lazytestpb.E_Pipistrelles.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Has")
}
mrr = roundtrip(t, mr).(*lazytestpb.Tree)
if got, want := proto.HasExtension(mrr, lazytestpb.E_Pipistrelles), false; got != want {
t.Errorf("Extension present after setting: got %v, want %v", got, want)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelles.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Has")
}
noPipistrelles := proto.GetExtension(mrr, lazytestpb.E_Pipistrelles).([]*lazytestpb.Pipistrelles)
if got, want := len(noPipistrelles), 0; got != want {
t.Errorf("Extension's field length, want: %v, got: %v", want, got)
}
if got, want := extensionIsInitialized(t, mrr, lazytestpb.E_Pipistrelles.Field), true; got != want {
t.Errorf("Extension unexpectedly initialized after Get")
}
}
func TestMarshalMessageSetLazyRace(t *testing.T) {
if !flags.LazyUnmarshalExtensions {
t.Skip("lazy extension unmarshaling disabled; not built with the protolegacy tag")
}
h := &lazytestpb.Holder{Data: &messagesetpb.MessageSet{}}
ext := &lazytestpb.Rabbit{Name: proto.String("Judy")}
proto.SetExtension(h.GetData(), lazytestpb.E_Rabbit_MessageSetExtension, ext)
b, err := proto.Marshal(h)
if err != nil {
t.Fatalf("Could not marshal message: %v", err)
}
if err := proto.Unmarshal(b, h); err != nil {
t.Fatalf("Could not unmarshal message: %v", err)
}
// after Unmarshal, the extension is in undecoded form.
// GetExtension will decode it lazily. Make sure this does
// not race against Marshal.
// The following pattern is similar to x/sync/errgroup,
// but we want to avoid adding that dependencies just for a test.
var (
wg sync.WaitGroup
errOnce sync.Once
groupErr error
)
for n := 30; n > 0; n-- {
wg.Add(2)
go func() {
defer wg.Done()
if err := func() error {
b, err := proto.Marshal(h)
if err == nil {
return proto.Unmarshal(b, &lazytestpb.Rabbit{})
}
return err
}(); err != nil {
errOnce.Do(func() { groupErr = err })
}
}()
go func() {
defer wg.Done()
if err := func() error {
if !proto.HasExtension(h.GetData(), lazytestpb.E_Rabbit_MessageSetExtension) {
return errors.New("proto: missing extension")
}
return nil
}(); err != nil {
errOnce.Do(func() { groupErr = err })
}
}()
}
wg.Wait()
if groupErr != nil {
t.Fatal(groupErr)
}
}
// Utility functions for the test cases
// Some functions from pointer_unsafe.go
type pointer struct{ p unsafe.Pointer }
func (p pointer) Apply(f uintptr) pointer {
return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
}
func pointerOfIface(v interface{}) pointer {
type ifaceHeader struct {
Type unsafe.Pointer
Data unsafe.Pointer
}
return pointer{p: (*ifaceHeader)(unsafe.Pointer(&v)).Data}
}
func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
return reflect.NewAt(t, p.p)
}
// Highly implementation dependent - uses unsafe pointers to figure
// out if the lazyExtensionValue is initialized.
func extensionIsInitialized(t *testing.T, data interface{}, fieldNo int32) bool {
ext, ok := reflect.TypeOf(data).Elem().FieldByName("extensionFields")
if !ok {
t.Fatalf("Failed to retrieve offset of field \"extensionFields\".")
}
lazy, ok := reflect.TypeOf((*impl.ExtensionField)(nil)).Elem().FieldByName("lazy")
if !ok {
t.Fatalf("Failed to retrieve offset of field \"lazy\".")
}
pi := pointerOfIface(data)
m, ok := pi.Apply(ext.Offset).AsValueOf(reflect.TypeOf((map[int32]impl.ExtensionField)(nil))).Interface().(*map[int32]impl.ExtensionField)
if !ok {
t.Fatalf("Extension map has unexpected type.")
}
f := (*m)[fieldNo]
// Here we rely on atomicOnce being the first field in the 'lazy' struct.
app, ok := pointerOfIface(&f).Apply(lazy.Offset).AsValueOf(reflect.TypeOf((*uint32)(nil))).Interface().(**uint32)
if !ok {
t.Fatalf("Field atomicOnce does not seem to be the first field, or has changed type.")
}
if *app == nil {
return true // lazy ptr is nil
}
return **app > 0
}
func roundtrip(t *testing.T, m proto.Message) proto.Message {
t.Helper()
n := m.ProtoReflect().Type().New().Interface()
b, err := proto.Marshal(m)
if err != nil {
t.Fatalf("proto.Marshal(%+v) failed: %v", m, err)
}
if err := proto.Unmarshal(b, n); err != nil {
t.Fatalf("proto.Unmarshal failed: %v", err)
}
return n
}

View File

@ -255,6 +255,10 @@ func (m *extensionMap) Has(xd protoreflect.ExtensionTypeDescriptor) (ok bool) {
if !ok {
return false
}
if x.isUnexpandedLazy() {
// Avoid calling x.Value(), which triggers a lazy unmarshal.
return true
}
switch {
case xd.IsList():
return x.Value().List().Len() > 0

View File

@ -0,0 +1,322 @@
// 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.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: internal/testprotos/lazy/lazy_extension_normalized_wire_test.proto
package lazy
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
type Sub struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
extensionFields protoimpl.ExtensionFields
C *uint32 `protobuf:"varint,3,opt,name=c" json:"c,omitempty"`
Grandchild *Sub `protobuf:"bytes,4,opt,name=grandchild" json:"grandchild,omitempty"`
}
func (x *Sub) Reset() {
*x = Sub{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Sub) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Sub) ProtoMessage() {}
func (x *Sub) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Sub.ProtoReflect.Descriptor instead.
func (*Sub) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescGZIP(), []int{0}
}
func (x *Sub) GetC() uint32 {
if x != nil && x.C != nil {
return *x.C
}
return 0
}
func (x *Sub) GetGrandchild() *Sub {
if x != nil {
return x.Grandchild
}
return nil
}
type Top struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
A *uint32 `protobuf:"varint,1,opt,name=a" json:"a,omitempty"`
Child *Sub `protobuf:"bytes,2,opt,name=child" json:"child,omitempty"`
}
func (x *Top) Reset() {
*x = Top{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Top) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Top) ProtoMessage() {}
func (x *Top) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Top.ProtoReflect.Descriptor instead.
func (*Top) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescGZIP(), []int{1}
}
func (x *Top) GetA() uint32 {
if x != nil && x.A != nil {
return *x.A
}
return 0
}
func (x *Top) GetChild() *Sub {
if x != nil {
return x.Child
}
return nil
}
type Ext struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SomeFlag *bool `protobuf:"varint,1,opt,name=some_flag,json=someFlag" json:"some_flag,omitempty"`
}
func (x *Ext) Reset() {
*x = Ext{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Ext) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Ext) ProtoMessage() {}
func (x *Ext) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Ext.ProtoReflect.Descriptor instead.
func (*Ext) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescGZIP(), []int{2}
}
func (x *Ext) GetSomeFlag() bool {
if x != nil && x.SomeFlag != nil {
return *x.SomeFlag
}
return false
}
var file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*Sub)(nil),
ExtensionType: (*Ext)(nil),
Field: 2,
Name: "lazy_extension_normalized_wire_test.Ext.b",
Tag: "bytes,2,opt,name=b",
Filename: "internal/testprotos/lazy/lazy_extension_normalized_wire_test.proto",
},
}
// Extension fields to Sub.
var (
// optional lazy_extension_normalized_wire_test.Ext b = 2;
E_Ext_B = &file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_extTypes[0]
)
var File_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto protoreflect.FileDescriptor
var file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDesc = []byte{
0x0a, 0x42, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6c, 0x61, 0x7a, 0x79, 0x2f, 0x6c, 0x61, 0x7a, 0x79, 0x5f,
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
0x69, 0x7a, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x23, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f,
0x77, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x22, 0x63, 0x0a, 0x03, 0x53, 0x75, 0x62,
0x12, 0x0c, 0x0a, 0x01, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x01, 0x63, 0x12, 0x48,
0x0a, 0x0a, 0x67, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x77,
0x69, 0x72, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x75, 0x62, 0x52, 0x0a, 0x67, 0x72,
0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x53,
0x0a, 0x03, 0x54, 0x6f, 0x70, 0x12, 0x0c, 0x0a, 0x01, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x01, 0x61, 0x12, 0x3e, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x77,
0x69, 0x72, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x75, 0x62, 0x52, 0x05, 0x63, 0x68,
0x69, 0x6c, 0x64, 0x22, 0x84, 0x01, 0x0a, 0x03, 0x45, 0x78, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73,
0x6f, 0x6d, 0x65, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
0x73, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x32, 0x60, 0x0a, 0x01, 0x62, 0x12, 0x28, 0x2e,
0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e,
0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x74,
0x65, 0x73, 0x74, 0x2e, 0x53, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e,
0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x74,
0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x52, 0x01, 0x62, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6c, 0x61, 0x7a,
0x79,
}
var (
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescOnce sync.Once
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescData = file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDesc
)
func file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescGZIP() []byte {
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescOnce.Do(func() {
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescData)
})
return file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDescData
}
var file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_goTypes = []interface{}{
(*Sub)(nil), // 0: lazy_extension_normalized_wire_test.Sub
(*Top)(nil), // 1: lazy_extension_normalized_wire_test.Top
(*Ext)(nil), // 2: lazy_extension_normalized_wire_test.Ext
}
var file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_depIdxs = []int32{
0, // 0: lazy_extension_normalized_wire_test.Sub.grandchild:type_name -> lazy_extension_normalized_wire_test.Sub
0, // 1: lazy_extension_normalized_wire_test.Top.child:type_name -> lazy_extension_normalized_wire_test.Sub
0, // 2: lazy_extension_normalized_wire_test.Ext.b:extendee -> lazy_extension_normalized_wire_test.Sub
2, // 3: lazy_extension_normalized_wire_test.Ext.b:type_name -> lazy_extension_normalized_wire_test.Ext
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
3, // [3:4] is the sub-list for extension type_name
2, // [2:3] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_init() }
func file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_init() {
if File_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Sub); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
case 3:
return &v.extensionFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Top); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Ext); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 1,
NumServices: 0,
},
GoTypes: file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_goTypes,
DependencyIndexes: file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_depIdxs,
MessageInfos: file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_msgTypes,
ExtensionInfos: file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_extTypes,
}.Build()
File_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto = out.File
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_rawDesc = nil
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_goTypes = nil
file_internal_testprotos_lazy_lazy_extension_normalized_wire_test_proto_depIdxs = nil
}

View File

@ -0,0 +1,28 @@
// 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.
syntax = "proto2";
package lazy_extension_normalized_wire_test;
option go_package = "google.golang.org/protobuf/internal/testprotos/lazy";
message Sub {
extensions 2 [verification = UNVERIFIED];
optional uint32 c = 3;
optional Sub grandchild = 4;
}
message Top {
optional uint32 a = 1;
optional Sub child = 2;
}
message Ext {
extend Sub {
optional Ext b = 2;
}
optional bool some_flag = 1;
}

View File

@ -0,0 +1,860 @@
// 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.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: internal/testprotos/lazy/lazy_extension_test.proto
package lazy
import (
messagesetpb "google.golang.org/protobuf/internal/testprotos/messageset/messagesetpb"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
type FlyingFoxSpecies int32
const (
FlyingFoxSpecies_FLYING_FOX_UNDEFINED FlyingFoxSpecies = 0
FlyingFoxSpecies_GREY_HEADED FlyingFoxSpecies = 1
FlyingFoxSpecies_BLACK FlyingFoxSpecies = 2
FlyingFoxSpecies_SPECTACLED FlyingFoxSpecies = 3
FlyingFoxSpecies_LARGE_EARED FlyingFoxSpecies = 4
FlyingFoxSpecies_DUSKY FlyingFoxSpecies = 5
FlyingFoxSpecies_TORRESIAN FlyingFoxSpecies = 6
FlyingFoxSpecies_BARE_BACKED FlyingFoxSpecies = 7
)
// Enum value maps for FlyingFoxSpecies.
var (
FlyingFoxSpecies_name = map[int32]string{
0: "FLYING_FOX_UNDEFINED",
1: "GREY_HEADED",
2: "BLACK",
3: "SPECTACLED",
4: "LARGE_EARED",
5: "DUSKY",
6: "TORRESIAN",
7: "BARE_BACKED",
}
FlyingFoxSpecies_value = map[string]int32{
"FLYING_FOX_UNDEFINED": 0,
"GREY_HEADED": 1,
"BLACK": 2,
"SPECTACLED": 3,
"LARGE_EARED": 4,
"DUSKY": 5,
"TORRESIAN": 6,
"BARE_BACKED": 7,
}
)
func (x FlyingFoxSpecies) Enum() *FlyingFoxSpecies {
p := new(FlyingFoxSpecies)
*p = x
return p
}
func (x FlyingFoxSpecies) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (FlyingFoxSpecies) Descriptor() protoreflect.EnumDescriptor {
return file_internal_testprotos_lazy_lazy_extension_test_proto_enumTypes[0].Descriptor()
}
func (FlyingFoxSpecies) Type() protoreflect.EnumType {
return &file_internal_testprotos_lazy_lazy_extension_test_proto_enumTypes[0]
}
func (x FlyingFoxSpecies) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Do not use.
func (x *FlyingFoxSpecies) UnmarshalJSON(b []byte) error {
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
*x = FlyingFoxSpecies(num)
return nil
}
// Deprecated: Use FlyingFoxSpecies.Descriptor instead.
func (FlyingFoxSpecies) EnumDescriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{0}
}
type PipistrelleSpecies int32
const (
PipistrelleSpecies_PIPISTRELLE_UNDEFINED PipistrelleSpecies = 0
PipistrelleSpecies_FOREST PipistrelleSpecies = 1
PipistrelleSpecies_INDIAN PipistrelleSpecies = 2
PipistrelleSpecies_EGYPTIAN PipistrelleSpecies = 3
PipistrelleSpecies_RUSTY PipistrelleSpecies = 4
PipistrelleSpecies_LEAST PipistrelleSpecies = 5
)
// Enum value maps for PipistrelleSpecies.
var (
PipistrelleSpecies_name = map[int32]string{
0: "PIPISTRELLE_UNDEFINED",
1: "FOREST",
2: "INDIAN",
3: "EGYPTIAN",
4: "RUSTY",
5: "LEAST",
}
PipistrelleSpecies_value = map[string]int32{
"PIPISTRELLE_UNDEFINED": 0,
"FOREST": 1,
"INDIAN": 2,
"EGYPTIAN": 3,
"RUSTY": 4,
"LEAST": 5,
}
)
func (x PipistrelleSpecies) Enum() *PipistrelleSpecies {
p := new(PipistrelleSpecies)
*p = x
return p
}
func (x PipistrelleSpecies) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (PipistrelleSpecies) Descriptor() protoreflect.EnumDescriptor {
return file_internal_testprotos_lazy_lazy_extension_test_proto_enumTypes[1].Descriptor()
}
func (PipistrelleSpecies) Type() protoreflect.EnumType {
return &file_internal_testprotos_lazy_lazy_extension_test_proto_enumTypes[1]
}
func (x PipistrelleSpecies) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Do not use.
func (x *PipistrelleSpecies) UnmarshalJSON(b []byte) error {
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
*x = PipistrelleSpecies(num)
return nil
}
// Deprecated: Use PipistrelleSpecies.Descriptor instead.
func (PipistrelleSpecies) EnumDescriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{1}
}
// This message contains a message set.
type Holder struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Data *messagesetpb.MessageSet `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
}
func (x *Holder) Reset() {
*x = Holder{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Holder) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Holder) ProtoMessage() {}
func (x *Holder) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Holder.ProtoReflect.Descriptor instead.
func (*Holder) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{0}
}
func (x *Holder) GetData() *messagesetpb.MessageSet {
if x != nil {
return x.Data
}
return nil
}
// This message may be inserted into a message set.
type Rabbit struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}
func (x *Rabbit) Reset() {
*x = Rabbit{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Rabbit) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Rabbit) ProtoMessage() {}
func (x *Rabbit) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Rabbit.ProtoReflect.Descriptor instead.
func (*Rabbit) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{1}
}
func (x *Rabbit) GetName() string {
if x != nil && x.Name != nil {
return *x.Name
}
return ""
}
type FlyingFox struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Species *FlyingFoxSpecies `protobuf:"varint,1,opt,name=species,enum=lazy_extension_test.FlyingFoxSpecies" json:"species,omitempty"`
}
func (x *FlyingFox) Reset() {
*x = FlyingFox{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FlyingFox) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FlyingFox) ProtoMessage() {}
func (x *FlyingFox) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FlyingFox.ProtoReflect.Descriptor instead.
func (*FlyingFox) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{2}
}
func (x *FlyingFox) GetSpecies() FlyingFoxSpecies {
if x != nil && x.Species != nil {
return *x.Species
}
return FlyingFoxSpecies_FLYING_FOX_UNDEFINED
}
type Tree struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
extensionFields protoimpl.ExtensionFields
Eucalyptus *bool `protobuf:"varint,1,opt,name=eucalyptus" json:"eucalyptus,omitempty"`
}
func (x *Tree) Reset() {
*x = Tree{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Tree) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Tree) ProtoMessage() {}
func (x *Tree) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Tree.ProtoReflect.Descriptor instead.
func (*Tree) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{3}
}
func (x *Tree) GetEucalyptus() bool {
if x != nil && x.Eucalyptus != nil {
return *x.Eucalyptus
}
return false
}
type Pipistrelle struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Species *PipistrelleSpecies `protobuf:"varint,1,opt,name=species,enum=lazy_extension_test.PipistrelleSpecies" json:"species,omitempty"`
}
func (x *Pipistrelle) Reset() {
*x = Pipistrelle{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Pipistrelle) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Pipistrelle) ProtoMessage() {}
func (x *Pipistrelle) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Pipistrelle.ProtoReflect.Descriptor instead.
func (*Pipistrelle) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{4}
}
func (x *Pipistrelle) GetSpecies() PipistrelleSpecies {
if x != nil && x.Species != nil {
return *x.Species
}
return PipistrelleSpecies_PIPISTRELLE_UNDEFINED
}
type Pipistrelles struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Species *PipistrelleSpecies `protobuf:"varint,1,opt,name=species,enum=lazy_extension_test.PipistrelleSpecies" json:"species,omitempty"`
}
func (x *Pipistrelles) Reset() {
*x = Pipistrelles{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Pipistrelles) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Pipistrelles) ProtoMessage() {}
func (x *Pipistrelles) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Pipistrelles.ProtoReflect.Descriptor instead.
func (*Pipistrelles) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{5}
}
func (x *Pipistrelles) GetSpecies() PipistrelleSpecies {
if x != nil && x.Species != nil {
return *x.Species
}
return PipistrelleSpecies_PIPISTRELLE_UNDEFINED
}
// And the ugly version that is not encouraged
type BatNest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *BatNest) Reset() {
*x = BatNest{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BatNest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BatNest) ProtoMessage() {}
func (x *BatNest) ProtoReflect() protoreflect.Message {
mi := &file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BatNest.ProtoReflect.Descriptor instead.
func (*BatNest) Descriptor() ([]byte, []int) {
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP(), []int{6}
}
var file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*Tree)(nil),
ExtensionType: (*FlyingFox)(nil),
Field: 345570595,
Name: "lazy_extension_test.bat",
Tag: "bytes,345570595,opt,name=bat",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: (*FlyingFox)(nil),
Field: 345570596,
Name: "lazy_extension_test.bat_pup",
Tag: "bytes,345570596,opt,name=bat_pup",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: ([]*FlyingFox)(nil),
Field: 345570597,
Name: "lazy_extension_test.bat_posse",
Tag: "bytes,345570597,rep,name=bat_posse",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: ([]byte)(nil),
Field: 345570598,
Name: "lazy_extension_test.binary_bat",
Tag: "bytes,345570598,opt,name=binary_bat",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: (*uint32)(nil),
Field: 345570599,
Name: "lazy_extension_test.integer_bat",
Tag: "varint,345570599,opt,name=integer_bat",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: (*Pipistrelle)(nil),
Field: 345570600,
Name: "lazy_extension_test.pipistrelle",
Tag: "group,345570600,opt,name=Pipistrelle",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: ([]*Pipistrelles)(nil),
Field: 345570601,
Name: "lazy_extension_test.pipistrelles",
Tag: "group,345570601,rep,name=Pipistrelles",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*messagesetpb.MessageSet)(nil),
ExtensionType: (*Rabbit)(nil),
Field: 345570595,
Name: "lazy_extension_test.Rabbit.message_set_extension",
Tag: "bytes,345570595,opt,name=message_set_extension",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
{
ExtendedType: (*Tree)(nil),
ExtensionType: (*FlyingFox)(nil),
Field: 345570602,
Name: "lazy_extension_test.BatNest.bat",
Tag: "bytes,345570602,opt,name=bat",
Filename: "internal/testprotos/lazy/lazy_extension_test.proto",
},
}
// Extension fields to Tree.
var (
// optional lazy_extension_test.FlyingFox bat = 345570595;
E_Bat = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[0]
// optional lazy_extension_test.FlyingFox bat_pup = 345570596;
E_BatPup = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[1]
// repeated lazy_extension_test.FlyingFox bat_posse = 345570597;
E_BatPosse = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[2]
// optional bytes binary_bat = 345570598;
E_BinaryBat = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[3]
// optional uint32 integer_bat = 345570599;
E_IntegerBat = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[4]
// optional lazy_extension_test.Pipistrelle pipistrelle = 345570600;
E_Pipistrelle = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[5]
// repeated lazy_extension_test.Pipistrelles pipistrelles = 345570601;
E_Pipistrelles = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[6]
// optional lazy_extension_test.FlyingFox bat = 345570602;
E_BatNest_Bat = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[8]
)
// Extension fields to messagesetpb.MessageSet.
var (
// optional lazy_extension_test.Rabbit message_set_extension = 345570595;
E_Rabbit_MessageSetExtension = &file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes[7]
)
var File_internal_testprotos_lazy_lazy_extension_test_proto protoreflect.FileDescriptor
var file_internal_testprotos_lazy_lazy_extension_test_proto_rawDesc = []byte{
0x0a, 0x32, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6c, 0x61, 0x7a, 0x79, 0x2f, 0x6c, 0x61, 0x7a, 0x79, 0x5f,
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x65, 0x74, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x73, 0x65, 0x74, 0x70, 0x62, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73,
0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x42, 0x0a, 0x06, 0x48, 0x6f, 0x6c, 0x64,
0x65, 0x72, 0x12, 0x38, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x65, 0x74, 0x2e, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x97, 0x01, 0x0a,
0x06, 0x52, 0x61, 0x62, 0x62, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0x79, 0x0a, 0x15, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x65, 0x74, 0x2e,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x18, 0xa3, 0xfa, 0xe3, 0xa4, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65,
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x61, 0x62, 0x62, 0x69,
0x74, 0x52, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x45, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x09, 0x46, 0x6c, 0x79, 0x69, 0x6e, 0x67,
0x46, 0x6f, 0x78, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65,
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x6c, 0x79, 0x69, 0x6e,
0x67, 0x46, 0x6f, 0x78, 0x53, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x52, 0x07, 0x73, 0x70, 0x65,
0x63, 0x69, 0x65, 0x73, 0x22, 0x31, 0x0a, 0x04, 0x54, 0x72, 0x65, 0x65, 0x12, 0x1e, 0x0a, 0x0a,
0x65, 0x75, 0x63, 0x61, 0x6c, 0x79, 0x70, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0a, 0x65, 0x75, 0x63, 0x61, 0x6c, 0x79, 0x70, 0x74, 0x75, 0x73, 0x2a, 0x09, 0x08, 0x90,
0x4e, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x50, 0x0a, 0x0b, 0x50, 0x69, 0x70, 0x69, 0x73,
0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x69,
0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73,
0x52, 0x07, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0c, 0x50, 0x69, 0x70,
0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x70, 0x65,
0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x6c, 0x61, 0x7a,
0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74,
0x2e, 0x50, 0x69, 0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63,
0x69, 0x65, 0x73, 0x52, 0x07, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x22, 0x5a, 0x0a, 0x07,
0x42, 0x61, 0x74, 0x4e, 0x65, 0x73, 0x74, 0x32, 0x4f, 0x0a, 0x03, 0x62, 0x61, 0x74, 0x12, 0x19,
0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xaa, 0xfa, 0xe3, 0xa4, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x6c, 0x79, 0x69, 0x6e, 0x67,
0x46, 0x6f, 0x78, 0x52, 0x03, 0x62, 0x61, 0x74, 0x2a, 0x94, 0x01, 0x0a, 0x10, 0x46, 0x6c, 0x79,
0x69, 0x6e, 0x67, 0x46, 0x6f, 0x78, 0x53, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a,
0x14, 0x46, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x4f, 0x58, 0x5f, 0x55, 0x4e, 0x44, 0x45,
0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x52, 0x45, 0x59, 0x5f,
0x48, 0x45, 0x41, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x4c, 0x41, 0x43,
0x4b, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x50, 0x45, 0x43, 0x54, 0x41, 0x43, 0x4c, 0x45,
0x44, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x41, 0x52, 0x47, 0x45, 0x5f, 0x45, 0x41, 0x52,
0x45, 0x44, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x55, 0x53, 0x4b, 0x59, 0x10, 0x05, 0x12,
0x0d, 0x0a, 0x09, 0x54, 0x4f, 0x52, 0x52, 0x45, 0x53, 0x49, 0x41, 0x4e, 0x10, 0x06, 0x12, 0x0f,
0x0a, 0x0b, 0x42, 0x41, 0x52, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x07, 0x2a,
0x6b, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x53, 0x70,
0x65, 0x63, 0x69, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x49, 0x50, 0x49, 0x53, 0x54, 0x52,
0x45, 0x4c, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00,
0x12, 0x0a, 0x0a, 0x06, 0x46, 0x4f, 0x52, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06,
0x49, 0x4e, 0x44, 0x49, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x47, 0x59, 0x50,
0x54, 0x49, 0x41, 0x4e, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x55, 0x53, 0x54, 0x59, 0x10,
0x04, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x45, 0x41, 0x53, 0x54, 0x10, 0x05, 0x3a, 0x4f, 0x0a, 0x03,
0x62, 0x61, 0x74, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xa3,
0xfa, 0xe3, 0xa4, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f,
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x46,
0x6c, 0x79, 0x69, 0x6e, 0x67, 0x46, 0x6f, 0x78, 0x52, 0x03, 0x62, 0x61, 0x74, 0x3a, 0x56, 0x0a,
0x07, 0x62, 0x61, 0x74, 0x5f, 0x70, 0x75, 0x70, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f,
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54,
0x72, 0x65, 0x65, 0x18, 0xa4, 0xfa, 0xe3, 0xa4, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74,
0x65, 0x73, 0x74, 0x2e, 0x46, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x46, 0x6f, 0x78, 0x52, 0x06, 0x62,
0x61, 0x74, 0x50, 0x75, 0x70, 0x3a, 0x5a, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x5f, 0x70, 0x6f, 0x73,
0x73, 0x65, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xa5, 0xfa,
0xe3, 0xa4, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x6c,
0x79, 0x69, 0x6e, 0x67, 0x46, 0x6f, 0x78, 0x52, 0x08, 0x62, 0x61, 0x74, 0x50, 0x6f, 0x73, 0x73,
0x65, 0x3a, 0x3c, 0x0a, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x62, 0x61, 0x74, 0x12,
0x19, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xa6, 0xfa, 0xe3, 0xa4, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x42, 0x61, 0x74, 0x3a,
0x3e, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x74, 0x12, 0x19,
0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xa7, 0xfa, 0xe3, 0xa4, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x42, 0x61, 0x74, 0x3a,
0x61, 0x0a, 0x0b, 0x70, 0x69, 0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x12, 0x19,
0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xa8, 0xfa, 0xe3, 0xa4, 0x01, 0x20,
0x01, 0x28, 0x0a, 0x32, 0x20, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x69, 0x70, 0x69, 0x73, 0x74,
0x72, 0x65, 0x6c, 0x6c, 0x65, 0x52, 0x0b, 0x70, 0x69, 0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c,
0x6c, 0x65, 0x3a, 0x64, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c,
0x65, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x18, 0xa9, 0xfa,
0xe3, 0xa4, 0x01, 0x20, 0x03, 0x28, 0x0a, 0x32, 0x21, 0x2e, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x65,
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x69,
0x70, 0x69, 0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x69,
0x73, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6c, 0x61, 0x7a, 0x79,
}
var (
file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescOnce sync.Once
file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescData = file_internal_testprotos_lazy_lazy_extension_test_proto_rawDesc
)
func file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescGZIP() []byte {
file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescOnce.Do(func() {
file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescData)
})
return file_internal_testprotos_lazy_lazy_extension_test_proto_rawDescData
}
var file_internal_testprotos_lazy_lazy_extension_test_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_internal_testprotos_lazy_lazy_extension_test_proto_goTypes = []interface{}{
(FlyingFoxSpecies)(0), // 0: lazy_extension_test.FlyingFoxSpecies
(PipistrelleSpecies)(0), // 1: lazy_extension_test.PipistrelleSpecies
(*Holder)(nil), // 2: lazy_extension_test.Holder
(*Rabbit)(nil), // 3: lazy_extension_test.Rabbit
(*FlyingFox)(nil), // 4: lazy_extension_test.FlyingFox
(*Tree)(nil), // 5: lazy_extension_test.Tree
(*Pipistrelle)(nil), // 6: lazy_extension_test.Pipistrelle
(*Pipistrelles)(nil), // 7: lazy_extension_test.Pipistrelles
(*BatNest)(nil), // 8: lazy_extension_test.BatNest
(*messagesetpb.MessageSet)(nil), // 9: goproto.proto.messageset.MessageSet
}
var file_internal_testprotos_lazy_lazy_extension_test_proto_depIdxs = []int32{
9, // 0: lazy_extension_test.Holder.data:type_name -> goproto.proto.messageset.MessageSet
0, // 1: lazy_extension_test.FlyingFox.species:type_name -> lazy_extension_test.FlyingFoxSpecies
1, // 2: lazy_extension_test.Pipistrelle.species:type_name -> lazy_extension_test.PipistrelleSpecies
1, // 3: lazy_extension_test.Pipistrelles.species:type_name -> lazy_extension_test.PipistrelleSpecies
5, // 4: lazy_extension_test.bat:extendee -> lazy_extension_test.Tree
5, // 5: lazy_extension_test.bat_pup:extendee -> lazy_extension_test.Tree
5, // 6: lazy_extension_test.bat_posse:extendee -> lazy_extension_test.Tree
5, // 7: lazy_extension_test.binary_bat:extendee -> lazy_extension_test.Tree
5, // 8: lazy_extension_test.integer_bat:extendee -> lazy_extension_test.Tree
5, // 9: lazy_extension_test.pipistrelle:extendee -> lazy_extension_test.Tree
5, // 10: lazy_extension_test.pipistrelles:extendee -> lazy_extension_test.Tree
9, // 11: lazy_extension_test.Rabbit.message_set_extension:extendee -> goproto.proto.messageset.MessageSet
5, // 12: lazy_extension_test.BatNest.bat:extendee -> lazy_extension_test.Tree
4, // 13: lazy_extension_test.bat:type_name -> lazy_extension_test.FlyingFox
4, // 14: lazy_extension_test.bat_pup:type_name -> lazy_extension_test.FlyingFox
4, // 15: lazy_extension_test.bat_posse:type_name -> lazy_extension_test.FlyingFox
6, // 16: lazy_extension_test.pipistrelle:type_name -> lazy_extension_test.Pipistrelle
7, // 17: lazy_extension_test.pipistrelles:type_name -> lazy_extension_test.Pipistrelles
3, // 18: lazy_extension_test.Rabbit.message_set_extension:type_name -> lazy_extension_test.Rabbit
4, // 19: lazy_extension_test.BatNest.bat:type_name -> lazy_extension_test.FlyingFox
20, // [20:20] is the sub-list for method output_type
20, // [20:20] is the sub-list for method input_type
13, // [13:20] is the sub-list for extension type_name
4, // [4:13] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_internal_testprotos_lazy_lazy_extension_test_proto_init() }
func file_internal_testprotos_lazy_lazy_extension_test_proto_init() {
if File_internal_testprotos_lazy_lazy_extension_test_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Holder); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Rabbit); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FlyingFox); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Tree); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
case 3:
return &v.extensionFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Pipistrelle); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Pipistrelles); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BatNest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_internal_testprotos_lazy_lazy_extension_test_proto_rawDesc,
NumEnums: 2,
NumMessages: 7,
NumExtensions: 9,
NumServices: 0,
},
GoTypes: file_internal_testprotos_lazy_lazy_extension_test_proto_goTypes,
DependencyIndexes: file_internal_testprotos_lazy_lazy_extension_test_proto_depIdxs,
EnumInfos: file_internal_testprotos_lazy_lazy_extension_test_proto_enumTypes,
MessageInfos: file_internal_testprotos_lazy_lazy_extension_test_proto_msgTypes,
ExtensionInfos: file_internal_testprotos_lazy_lazy_extension_test_proto_extTypes,
}.Build()
File_internal_testprotos_lazy_lazy_extension_test_proto = out.File
file_internal_testprotos_lazy_lazy_extension_test_proto_rawDesc = nil
file_internal_testprotos_lazy_lazy_extension_test_proto_goTypes = nil
file_internal_testprotos_lazy_lazy_extension_test_proto_depIdxs = nil
}

View File

@ -0,0 +1,80 @@
// 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.
syntax = "proto2";
package lazy_extension_test;
import "internal/testprotos/messageset/messagesetpb/message_set.proto";
option go_package = "google.golang.org/protobuf/internal/testprotos/lazy";
// This message contains a message set.
message Holder {
optional goproto.proto.messageset.MessageSet data = 1;
}
// This message may be inserted into a message set.
message Rabbit {
extend goproto.proto.messageset.MessageSet {
optional Rabbit message_set_extension = 345570595;
}
optional string name = 1;
}
enum FlyingFoxSpecies {
FLYING_FOX_UNDEFINED = 0;
GREY_HEADED = 1;
BLACK = 2;
SPECTACLED = 3;
LARGE_EARED = 4;
DUSKY = 5;
TORRESIAN = 6;
BARE_BACKED = 7;
}
enum PipistrelleSpecies {
PIPISTRELLE_UNDEFINED = 0;
FOREST = 1;
INDIAN = 2;
EGYPTIAN = 3;
RUSTY = 4;
LEAST = 5;
}
message FlyingFox {
optional FlyingFoxSpecies species = 1;
}
message Tree {
optional bool eucalyptus = 1;
extensions 10000 to max;
}
extend Tree {
optional FlyingFox bat = 345570595;
}
extend Tree {
optional FlyingFox bat_pup = 345570596;
}
extend Tree {
repeated FlyingFox bat_posse = 345570597;
optional bytes binary_bat = 345570598;
optional uint32 integer_bat = 345570599;
optional group Pipistrelle = 345570600 {
optional PipistrelleSpecies species = 1;
}
repeated group Pipistrelles = 345570601 {
optional PipistrelleSpecies species = 1;
}
}
// And the ugly version that is not encouraged
message BatNest {
extend Tree {
optional FlyingFox bat = 345570602;
}
}