mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-04 02:38:50 +00:00
internal/filedesc: avoid deep-copying the options
The protoreflect.Descriptor.Options method is currently documented as returning a reference to the options, where the user must not mutate the returned message. This changes internal/filedesc to avoid returning a copy of the options by caching the first unmarshal. See golang/protobuf#877 Change-Id: I15701d33fbda7535b21b2add72628b02992c373f Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185197 Reviewed-by: Benny Siegert <bsiegert@gmail.com>
This commit is contained in:
parent
93fd968b71
commit
8a4c3d18b1
@ -6,6 +6,7 @@ package filedesc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/protobuf/internal/descopts"
|
"google.golang.org/protobuf/internal/descopts"
|
||||||
"google.golang.org/protobuf/internal/encoding/wire"
|
"google.golang.org/protobuf/internal/encoding/wire"
|
||||||
@ -675,14 +676,18 @@ func (db *DescBuilder) optionsUnmarshaler(p pref.ProtoMessage, b []byte) func()
|
|||||||
if b == nil {
|
if b == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
var opts pref.ProtoMessage
|
||||||
|
var once sync.Once
|
||||||
return func() pref.ProtoMessage {
|
return func() pref.ProtoMessage {
|
||||||
p := reflect.New(reflect.TypeOf(p).Elem()).Interface().(pref.ProtoMessage)
|
once.Do(func() {
|
||||||
if err := (proto.UnmarshalOptions{
|
opts = reflect.New(reflect.TypeOf(p).Elem()).Interface().(pref.ProtoMessage)
|
||||||
AllowPartial: true,
|
if err := (proto.UnmarshalOptions{
|
||||||
Resolver: db.TypeResolver,
|
AllowPartial: true,
|
||||||
}).Unmarshal(b, p); err != nil {
|
Resolver: db.TypeResolver,
|
||||||
panic(err)
|
}).Unmarshal(b, opts); err != nil {
|
||||||
}
|
panic(err)
|
||||||
return p
|
}
|
||||||
|
})
|
||||||
|
return opts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,6 @@ type Descriptor interface {
|
|||||||
// For FileDescriptor, the Path and Package are also valid.
|
// For FileDescriptor, the Path and Package are also valid.
|
||||||
IsPlaceholder() bool
|
IsPlaceholder() bool
|
||||||
|
|
||||||
// TODO: Decide memory ownership of Options.
|
|
||||||
|
|
||||||
// Options returns the descriptor options. The caller must not modify
|
// Options returns the descriptor options. The caller must not modify
|
||||||
// the returned value.
|
// the returned value.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user