| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- // Copyright 2018 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 protoapi contains the set of types referenced by generated messages.
- //
- // WARNING: This package should only ever be imported by generated messages.
- // The compatibility agreement covers nothing except for functionality needed
- // to keep existing generated messages operational.
- package protoapi
- import (
- "fmt"
- "sync"
- "github.com/golang/protobuf/v2/reflect/protoreflect"
- )
- // TODO: How to handle Registration during the v1 to v2 switchover?
- type (
- Message interface {
- Reset()
- String() string
- ProtoMessage()
- }
- ExtensionRange struct {
- Start, End int32 // both inclusive
- }
- ExtensionDesc struct {
- // Type is the descriptor type for the extension field using the v2 API.
- // If populated, the information in this field takes precedence over
- // all other fields in ExtensionDesc.
- Type protoreflect.ExtensionType
- // ExtendedType is a typed nil-pointer to the parent message type that
- // is being extended. It is possible for this to be unpopulated in v2
- // since the message may no longer implement the v1 Message interface.
- //
- // Deprecated: Use Type.ExtendedType instead.
- ExtendedType Message
- // ExtensionType is zero value of the extension type.
- //
- // For historical reasons, reflect.TypeOf(ExtensionType) and Type.GoType
- // may not be identical:
- // * for scalars (except []byte), where ExtensionType uses *T,
- // while Type.GoType uses T.
- // * for repeated fields, where ExtensionType uses []T,
- // while Type.GoType uses *[]T.
- //
- // Deprecated: Use Type.GoType instead.
- ExtensionType interface{}
- // Field is the field number of the extension.
- //
- // Deprecated: Use Type.Number instead.
- Field int32 // field number
- // Name is the fully qualified name of extension.
- //
- // Deprecated: Use Type.FullName instead.
- Name string
- // Tag is the protobuf struct tag used in the v1 API.
- //
- // Deprecated: Do not use.
- Tag string
- // Filename is the proto filename in which the extension is defined.
- //
- // Deprecated: Use Type.Parent to ascend to the top-most parent and use
- // protoreflect.FileDescriptor.Path.
- Filename string
- }
- ExtensionFields extensionFields
- ExtensionField extensionField
- XXX_InternalExtensions extensionSyncMap
- )
- // ExtensionFieldsOf returns an ExtensionFields abstraction over various
- // internal representations of extension fields.
- func ExtensionFieldsOf(p interface{}) ExtensionFields {
- switch p := p.(type) {
- case *map[int32]ExtensionField:
- return (*extensionMap)(p)
- case *XXX_InternalExtensions:
- return (*extensionSyncMap)(p)
- default:
- panic(fmt.Sprintf("invalid extension fields type: %T", p))
- }
- }
- type extensionFields interface {
- Len() int
- Has(protoreflect.FieldNumber) bool
- Get(protoreflect.FieldNumber) ExtensionField
- Set(protoreflect.FieldNumber, ExtensionField)
- Clear(protoreflect.FieldNumber)
- Range(f func(protoreflect.FieldNumber, ExtensionField) bool)
- // HasInit and Locker are used by v1 GetExtension to provide
- // an artificial degree of concurrent safety.
- HasInit() bool
- sync.Locker
- }
- type extensionField struct {
- // When an extension is stored in a message using SetExtension
- // only desc and value are set. When the message is marshaled
- // Raw will be set to the encoded form of the message.
- //
- // When a message is unmarshaled and contains extensions, each
- // extension will have only Raw set. When such an extension is
- // accessed using GetExtension (or GetExtensions) desc and value
- // will be set.
- Desc *ExtensionDesc // TODO: switch to protoreflect.ExtensionType
- // Value is a concrete value for the extension field. Let the type of
- // Desc.ExtensionType be the "API type" and the type of Value be the
- // "storage type". The API type and storage type are the same except:
- // * for scalars (except []byte), where the API type uses *T,
- // while the storage type uses T.
- // * for repeated fields, where the API type uses []T,
- // while the storage type uses *[]T.
- //
- // The reason for the divergence is so that the storage type more naturally
- // matches what is expected of when retrieving the values through the
- // protobuf reflection APIs.
- //
- // The Value may only be populated if Desc is also populated.
- Value interface{} // TODO: switch to protoreflect.Value
- // Raw is the raw encoded bytes for the extension field.
- // It is possible for Raw to be populated irrespective of whether the
- // other fields are populated.
- Raw []byte // TODO: switch to protoreflect.RawFields
- }
- type extensionSyncMap struct {
- p *struct {
- mu sync.Mutex
- m extensionMap
- }
- }
- func (m extensionSyncMap) Len() int {
- if m.p == nil {
- return 0
- }
- return m.p.m.Len()
- }
- func (m extensionSyncMap) Has(n protoreflect.FieldNumber) bool {
- if m.p == nil {
- return false
- }
- return m.p.m.Has(n)
- }
- func (m extensionSyncMap) Get(n protoreflect.FieldNumber) ExtensionField {
- if m.p == nil {
- return ExtensionField{}
- }
- return m.p.m.Get(n)
- }
- func (m *extensionSyncMap) Set(n protoreflect.FieldNumber, x ExtensionField) {
- if m.p == nil {
- m.p = new(struct {
- mu sync.Mutex
- m extensionMap
- })
- }
- m.p.m.Set(n, x)
- }
- func (m extensionSyncMap) Clear(n protoreflect.FieldNumber) {
- if m.p == nil {
- return
- }
- m.p.m.Clear(n)
- }
- func (m extensionSyncMap) Range(f func(protoreflect.FieldNumber, ExtensionField) bool) {
- if m.p == nil {
- return
- }
- m.p.m.Range(f)
- }
- func (m extensionSyncMap) HasInit() bool {
- return m.p != nil
- }
- func (m extensionSyncMap) Lock() {
- m.p.mu.Lock()
- }
- func (m extensionSyncMap) Unlock() {
- m.p.mu.Unlock()
- }
- type extensionMap map[int32]ExtensionField
- func (m extensionMap) Len() int {
- return len(m)
- }
- func (m extensionMap) Has(n protoreflect.FieldNumber) bool {
- _, ok := m[int32(n)]
- return ok
- }
- func (m extensionMap) Get(n protoreflect.FieldNumber) ExtensionField {
- return m[int32(n)]
- }
- func (m *extensionMap) Set(n protoreflect.FieldNumber, x ExtensionField) {
- if *m == nil {
- *m = make(map[int32]ExtensionField)
- }
- (*m)[int32(n)] = x
- }
- func (m *extensionMap) Clear(n protoreflect.FieldNumber) {
- delete(*m, int32(n))
- }
- func (m extensionMap) Range(f func(protoreflect.FieldNumber, ExtensionField) bool) {
- for n, x := range m {
- if !f(protoreflect.FieldNumber(n), x) {
- return
- }
- }
- }
- var globalLock sync.Mutex
- func (m extensionMap) HasInit() bool {
- return m != nil
- }
- func (m extensionMap) Lock() {
- if !m.HasInit() {
- panic("cannot lock an uninitialized map")
- }
- globalLock.Lock()
- }
- func (m extensionMap) Unlock() {
- globalLock.Unlock()
- }
|