blob: fda4ee99161f9c675b49318f80e883711734ee44 [file] [log] [blame] [edit]
// Copyright 2020-2024 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bufprotosource
import (
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
)
type message struct {
namedDescriptor
optionExtensionDescriptor
fields []Field
extensions []Field
nestedMessages []Message
nestedEnums []Enum
oneofs []Oneof
reservedMessageRanges []MessageRange
reservedNames []ReservedName
extensionRanges []ExtensionRange
parent Message
isMapEntry bool
messageSetWireFormat bool
noStandardDescriptorAccessor bool
deprecatedLegacyJSONFieldConflicts bool
deprecated bool
messageSetWireFormatPath []int32
noStandardDescriptorAccessorPath []int32
}
func newMessage(
namedDescriptor namedDescriptor,
optionExtensionDescriptor optionExtensionDescriptor,
parent Message,
isMapEntry bool,
messageSetWireFormat bool,
noStandardDescriptorAccessor bool,
deprecatedLegacyJSONFieldConflicts bool,
deprecated bool,
messageSetWireFormatPath []int32,
noStandardDescriptorAccessorPath []int32,
) *message {
return &message{
namedDescriptor: namedDescriptor,
optionExtensionDescriptor: optionExtensionDescriptor,
parent: parent,
isMapEntry: isMapEntry,
messageSetWireFormat: messageSetWireFormat,
noStandardDescriptorAccessor: noStandardDescriptorAccessor,
deprecatedLegacyJSONFieldConflicts: deprecatedLegacyJSONFieldConflicts,
deprecated: deprecated,
messageSetWireFormatPath: messageSetWireFormatPath,
noStandardDescriptorAccessorPath: noStandardDescriptorAccessorPath,
}
}
func (m *message) Fields() []Field {
return m.fields
}
func (m *message) Extensions() []Field {
return m.extensions
}
func (m *message) Messages() []Message {
return m.nestedMessages
}
func (m *message) Enums() []Enum {
return m.nestedEnums
}
func (m *message) Oneofs() []Oneof {
return m.oneofs
}
func (m *message) ReservedMessageRanges() []MessageRange {
return m.reservedMessageRanges
}
func (m *message) ReservedTagRanges() []TagRange {
tagRanges := make([]TagRange, len(m.reservedMessageRanges))
for i, reservedMessageRange := range m.reservedMessageRanges {
tagRanges[i] = reservedMessageRange
}
return tagRanges
}
func (m *message) ReservedNames() []ReservedName {
return m.reservedNames
}
func (m *message) ExtensionRanges() []ExtensionRange {
return m.extensionRanges
}
func (m *message) ExtensionMessageRanges() []MessageRange {
extMsgRanges := make([]MessageRange, len(m.extensionRanges))
for i, extensionRange := range m.extensionRanges {
extMsgRanges[i] = extensionRange
}
return extMsgRanges
}
func (m *message) Parent() Message {
return m.parent
}
func (m *message) IsMapEntry() bool {
return m.isMapEntry
}
func (m *message) MessageSetWireFormat() bool {
return m.messageSetWireFormat
}
func (m *message) NoStandardDescriptorAccessor() bool {
return m.noStandardDescriptorAccessor
}
func (m *message) DeprecatedLegacyJSONFieldConflicts() bool {
return m.deprecatedLegacyJSONFieldConflicts
}
func (m *message) Deprecated() bool {
return m.deprecated
}
func (m *message) MessageSetWireFormatLocation() Location {
return m.getLocation(m.messageSetWireFormatPath)
}
func (m *message) NoStandardDescriptorAccessorLocation() Location {
return m.getLocation(m.noStandardDescriptorAccessorPath)
}
func (m *message) Location() Location {
loc := m.namedDescriptor.Location()
if loc == nil {
return m.maybeMapEntryLocation()
}
return loc
}
func (m *message) NameLocation() Location {
loc := m.namedDescriptor.NameLocation()
if loc == nil {
return m.maybeMapEntryLocation()
}
return loc
}
func (m *message) maybeMapEntryLocation() Location {
parent, _ := m.parent.(*message)
if !m.isMapEntry || parent == nil || m.namedDescriptor.locationStore.isEmpty() {
// not a map entry
return nil
}
// Synthetic map messages come from the type of the corresponding
// map field. So report that location.
if field := parent.findMapField(m.FullName()); field != nil {
return field.TypeNameLocation()
}
return nil
}
func (m *message) findMapField(entryName string) Field {
for _, field := range m.fields {
if field.Type() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE &&
field.Label() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED &&
field.TypeName() == entryName {
return field
}
}
return nil
}
func (m *message) addField(field Field) {
m.fields = append(m.fields, field)
}
func (m *message) addExtension(extension Field) {
m.extensions = append(m.extensions, extension)
}
func (m *message) addNestedMessage(nestedMessage Message) {
m.nestedMessages = append(m.nestedMessages, nestedMessage)
}
func (m *message) addNestedEnum(nestedEnum Enum) {
m.nestedEnums = append(m.nestedEnums, nestedEnum)
}
func (m *message) addOneof(oneof Oneof) {
m.oneofs = append(m.oneofs, oneof)
}
func (m *message) addReservedMessageRange(reservedMessageRange MessageRange) {
m.reservedMessageRanges = append(m.reservedMessageRanges, reservedMessageRange)
}
func (m *message) addReservedName(reservedName ReservedName) {
m.reservedNames = append(m.reservedNames, reservedName)
}
func (m *message) addExtensionRange(extensionRange ExtensionRange) {
m.extensionRanges = append(m.extensionRanges, extensionRange)
}
func (m *message) AsDescriptor() (protoreflect.MessageDescriptor, error) {
return asDescriptor[protoreflect.MessageDescriptor](&m.descriptor, m.FullName(), "a message")
}