summaryrefslogtreecommitdiff
path: root/vendor/github.com/bufbuild/protocompile/internal
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bufbuild/protocompile/internal')
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/editions/editions.go420
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/featuresext/cpp_features.protosetbin0 -> 605 bytes
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/featuresext/featuresext.go84
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/featuresext/java_features.protosetbin0 -> 856 bytes
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/message_context.go98
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/messageset/messageset.go62
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/norace.go19
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/options.go71
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/race.go19
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/tags.go336
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/types.go35
-rw-r--r--vendor/github.com/bufbuild/protocompile/internal/util.go244
12 files changed, 1388 insertions, 0 deletions
diff --git a/vendor/github.com/bufbuild/protocompile/internal/editions/editions.go b/vendor/github.com/bufbuild/protocompile/internal/editions/editions.go
new file mode 100644
index 0000000..ee054fa
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/editions/editions.go
@@ -0,0 +1,420 @@
+// 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 editions contains helpers related to resolving features for
+// Protobuf editions. These are lower-level helpers. Higher-level helpers
+// (which use this package under the hood) can be found in the exported
+// protoutil package.
+package editions
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/reflect/protoregistry"
+ "google.golang.org/protobuf/types/descriptorpb"
+ "google.golang.org/protobuf/types/dynamicpb"
+)
+
+const (
+ // MinSupportedEdition is the earliest edition supported by this module.
+ // It should be 2023 (the first edition) for the indefinite future.
+ MinSupportedEdition = descriptorpb.Edition_EDITION_2023
+
+ // MaxSupportedEdition is the most recent edition supported by this module.
+ MaxSupportedEdition = descriptorpb.Edition_EDITION_2023
+)
+
+var (
+ // SupportedEditions is the exhaustive set of editions that protocompile
+ // can support. We don't allow it to compile future/unknown editions, to
+ // make sure we don't generate incorrect descriptors, in the event that
+ // a future edition introduces a change or new feature that requires
+ // new logic in the compiler.
+ SupportedEditions = computeSupportedEditions(MinSupportedEdition, MaxSupportedEdition)
+
+ // FeatureSetDescriptor is the message descriptor for the compiled-in
+ // version (in the descriptorpb package) of the google.protobuf.FeatureSet
+ // message type.
+ FeatureSetDescriptor = (*descriptorpb.FeatureSet)(nil).ProtoReflect().Descriptor()
+ // FeatureSetType is the message type for the compiled-in version (in
+ // the descriptorpb package) of google.protobuf.FeatureSet.
+ FeatureSetType = (*descriptorpb.FeatureSet)(nil).ProtoReflect().Type()
+
+ editionDefaults map[descriptorpb.Edition]*descriptorpb.FeatureSet
+ editionDefaultsInit sync.Once
+)
+
+// HasFeatures is implemented by all options messages and provides a
+// nil-receiver-safe way of accessing the features explicitly configured
+// in those options.
+type HasFeatures interface {
+ GetFeatures() *descriptorpb.FeatureSet
+}
+
+var _ HasFeatures = (*descriptorpb.FileOptions)(nil)
+var _ HasFeatures = (*descriptorpb.MessageOptions)(nil)
+var _ HasFeatures = (*descriptorpb.FieldOptions)(nil)
+var _ HasFeatures = (*descriptorpb.OneofOptions)(nil)
+var _ HasFeatures = (*descriptorpb.ExtensionRangeOptions)(nil)
+var _ HasFeatures = (*descriptorpb.EnumOptions)(nil)
+var _ HasFeatures = (*descriptorpb.EnumValueOptions)(nil)
+var _ HasFeatures = (*descriptorpb.ServiceOptions)(nil)
+var _ HasFeatures = (*descriptorpb.MethodOptions)(nil)
+
+// ResolveFeature resolves a feature for the given descriptor. This simple
+// helper examines the given element and its ancestors, searching for an
+// override. If there is no overridden value, it returns a zero value.
+func ResolveFeature(
+ element protoreflect.Descriptor,
+ fields ...protoreflect.FieldDescriptor,
+) (protoreflect.Value, error) {
+ for {
+ var features *descriptorpb.FeatureSet
+ if withFeatures, ok := element.Options().(HasFeatures); ok {
+ // It should not really be possible for 'ok' to ever be false...
+ features = withFeatures.GetFeatures()
+ }
+
+ // TODO: adaptFeatureSet is only looking at the first field. But if we needed to
+ // support an extension field inside a custom feature, we'd really need
+ // to check all fields. That gets particularly complicated if the traversal
+ // path of fields includes list and map values. Luckily, features are not
+ // supposed to be repeated and not supposed to themselves have extensions.
+ // So this should be fine, at least for now.
+ msgRef, err := adaptFeatureSet(features, fields[0])
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ // Navigate the fields to find the value
+ var val protoreflect.Value
+ for i, field := range fields {
+ if i > 0 {
+ msgRef = val.Message()
+ }
+ if !msgRef.Has(field) {
+ val = protoreflect.Value{}
+ break
+ }
+ val = msgRef.Get(field)
+ }
+ if val.IsValid() {
+ // All fields were set!
+ return val, nil
+ }
+
+ parent := element.Parent()
+ if parent == nil {
+ // We've reached the end of the inheritance chain.
+ return protoreflect.Value{}, nil
+ }
+ element = parent
+ }
+}
+
+// HasEdition should be implemented by values that implement
+// [protoreflect.FileDescriptor], to provide access to the file's
+// edition when its syntax is [protoreflect.Editions].
+type HasEdition interface {
+ // Edition returns the numeric value of a google.protobuf.Edition enum
+ // value that corresponds to the edition of this file. If the file does
+ // not use editions, it should return the enum value that corresponds
+ // to the syntax level, EDITION_PROTO2 or EDITION_PROTO3.
+ Edition() int32
+}
+
+// GetEdition returns the edition for a given element. It returns
+// EDITION_PROTO2 or EDITION_PROTO3 if the element is in a file that
+// uses proto2 or proto3 syntax, respectively. It returns EDITION_UNKNOWN
+// if the syntax of the given element is not recognized or if the edition
+// cannot be ascertained from the element's [protoreflect.FileDescriptor].
+func GetEdition(d protoreflect.Descriptor) descriptorpb.Edition {
+ switch d.ParentFile().Syntax() {
+ case protoreflect.Proto2:
+ return descriptorpb.Edition_EDITION_PROTO2
+ case protoreflect.Proto3:
+ return descriptorpb.Edition_EDITION_PROTO3
+ case protoreflect.Editions:
+ withEdition, ok := d.ParentFile().(HasEdition)
+ if !ok {
+ // The parent file should always be a *result, so we should
+ // never be able to actually get in here. If we somehow did
+ // have another implementation of protoreflect.FileDescriptor,
+ // it doesn't provide a way to get the edition, other than the
+ // potentially expensive step of generating a FileDescriptorProto
+ // and then querying for the edition from that. :/
+ return descriptorpb.Edition_EDITION_UNKNOWN
+ }
+ return descriptorpb.Edition(withEdition.Edition())
+ default:
+ return descriptorpb.Edition_EDITION_UNKNOWN
+ }
+}
+
+// GetEditionDefaults returns the default feature values for the given edition.
+// It returns nil if the given edition is not known.
+//
+// This only populates known features, those that are fields of [*descriptorpb.FeatureSet].
+// It does not populate any extension fields.
+//
+// The returned value must not be mutated as it references shared package state.
+func GetEditionDefaults(edition descriptorpb.Edition) *descriptorpb.FeatureSet {
+ editionDefaultsInit.Do(func() {
+ editionDefaults = make(map[descriptorpb.Edition]*descriptorpb.FeatureSet, len(descriptorpb.Edition_name))
+ // Compute default for all known editions in descriptorpb.
+ for editionInt := range descriptorpb.Edition_name {
+ edition := descriptorpb.Edition(editionInt)
+ defaults := &descriptorpb.FeatureSet{}
+ defaultsRef := defaults.ProtoReflect()
+ fields := defaultsRef.Descriptor().Fields()
+ // Note: we are not computing defaults for extensions. Those are not needed
+ // by anything in the compiler, so we can get away with just computing
+ // defaults for these static, non-extension fields.
+ for i, length := 0, fields.Len(); i < length; i++ {
+ field := fields.Get(i)
+ val, err := GetFeatureDefault(edition, FeatureSetType, field)
+ if err != nil {
+ // should we fail somehow??
+ continue
+ }
+ defaultsRef.Set(field, val)
+ }
+ editionDefaults[edition] = defaults
+ }
+ })
+ return editionDefaults[edition]
+}
+
+// GetFeatureDefault computes the default value for a feature. The given container
+// is the message type that contains the field. This should usually be the descriptor
+// for google.protobuf.FeatureSet, but can be a different message for computing the
+// default value of custom features.
+//
+// Note that this always re-computes the default. For known fields of FeatureSet,
+// it is more efficient to query from the statically computed default messages,
+// like so:
+//
+// editions.GetEditionDefaults(edition).ProtoReflect().Get(feature)
+func GetFeatureDefault(edition descriptorpb.Edition, container protoreflect.MessageType, feature protoreflect.FieldDescriptor) (protoreflect.Value, error) {
+ opts, ok := feature.Options().(*descriptorpb.FieldOptions)
+ if !ok {
+ // this is most likely impossible except for contrived use cases...
+ return protoreflect.Value{}, fmt.Errorf("options is %T instead of *descriptorpb.FieldOptions", feature.Options())
+ }
+ maxEdition := descriptorpb.Edition(-1)
+ var maxVal string
+ for _, def := range opts.EditionDefaults {
+ if def.GetEdition() <= edition && def.GetEdition() > maxEdition {
+ maxEdition = def.GetEdition()
+ maxVal = def.GetValue()
+ }
+ }
+ if maxEdition == -1 {
+ // no matching default found
+ return protoreflect.Value{}, fmt.Errorf("no relevant default for edition %s", edition)
+ }
+ // We use a typed nil so that it won't fall back to the global registry. Features
+ // should not use extensions or google.protobuf.Any, so a nil *Types is fine.
+ unmarshaler := prototext.UnmarshalOptions{Resolver: (*protoregistry.Types)(nil)}
+ // The string value is in the text format: either a field value literal or a
+ // message literal. (Repeated and map features aren't supported, so there's no
+ // array or map literal syntax to worry about.)
+ if feature.Kind() == protoreflect.MessageKind || feature.Kind() == protoreflect.GroupKind {
+ fldVal := container.Zero().NewField(feature)
+ err := unmarshaler.Unmarshal([]byte(maxVal), fldVal.Message().Interface())
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return fldVal, nil
+ }
+ // The value is the textformat for the field. But prototext doesn't provide a way
+ // to unmarshal a single field value. To work around, we unmarshal into an enclosing
+ // message, which means we must prefix the value with the field name.
+ if feature.IsExtension() {
+ maxVal = fmt.Sprintf("[%s]: %s", feature.FullName(), maxVal)
+ } else {
+ maxVal = fmt.Sprintf("%s: %s", feature.Name(), maxVal)
+ }
+ empty := container.New()
+ err := unmarshaler.Unmarshal([]byte(maxVal), empty.Interface())
+ if err != nil {
+ return protoreflect.Value{}, err
+ }
+ return empty.Get(feature), nil
+}
+
+func adaptFeatureSet(msg *descriptorpb.FeatureSet, field protoreflect.FieldDescriptor) (protoreflect.Message, error) {
+ msgRef := msg.ProtoReflect()
+ var actualField protoreflect.FieldDescriptor
+ switch {
+ case field.IsExtension():
+ // Extensions can be used directly with the feature set, even if
+ // field.ContainingMessage() != FeatureSetDescriptor. But only if
+ // the value is either not a message or is a message with the
+ // right descriptor, i.e. val.Descriptor() == field.Message().
+ if actualField = actualDescriptor(msgRef, field); actualField == nil || actualField == field {
+ if msgRef.Has(field) || len(msgRef.GetUnknown()) == 0 {
+ return msgRef, nil
+ }
+ // The field is not present, but the message has unrecognized values. So
+ // let's try to parse the unrecognized bytes, just in case they contain
+ // this extension.
+ temp := &descriptorpb.FeatureSet{}
+ unmarshaler := proto.UnmarshalOptions{
+ AllowPartial: true,
+ Resolver: resolverForExtension{field},
+ }
+ if err := unmarshaler.Unmarshal(msgRef.GetUnknown(), temp); err != nil {
+ return nil, fmt.Errorf("failed to parse unrecognized fields of FeatureSet: %w", err)
+ }
+ return temp.ProtoReflect(), nil
+ }
+ case field.ContainingMessage() == FeatureSetDescriptor:
+ // Known field, not dynamically generated. Can directly use with the feature set.
+ return msgRef, nil
+ default:
+ actualField = FeatureSetDescriptor.Fields().ByNumber(field.Number())
+ }
+
+ // If we get here, we have a dynamic field descriptor or an extension
+ // descriptor whose message type does not match the descriptor of the
+ // stored value. We need to copy its value into a dynamic message,
+ // which requires marshalling/unmarshalling.
+ // We only need to copy over the unrecognized bytes (if any)
+ // and the same field (if present).
+ data := msgRef.GetUnknown()
+ if actualField != nil && msgRef.Has(actualField) {
+ subset := &descriptorpb.FeatureSet{}
+ subset.ProtoReflect().Set(actualField, msgRef.Get(actualField))
+ var err error
+ data, err = proto.MarshalOptions{AllowPartial: true}.MarshalAppend(data, subset)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal FeatureSet field %s to bytes: %w", field.Name(), err)
+ }
+ }
+ if len(data) == 0 {
+ // No relevant data to copy over, so we can just return
+ // a zero value message
+ return dynamicpb.NewMessageType(field.ContainingMessage()).Zero(), nil
+ }
+
+ other := dynamicpb.NewMessage(field.ContainingMessage())
+ // We don't need to use a resolver for this step because we know that
+ // field is not an extension. And features are not allowed to themselves
+ // have extensions.
+ if err := (proto.UnmarshalOptions{AllowPartial: true}).Unmarshal(data, other); err != nil {
+ return nil, fmt.Errorf("failed to marshal FeatureSet field %s to bytes: %w", field.Name(), err)
+ }
+ return other, nil
+}
+
+type resolverForExtension struct {
+ ext protoreflect.ExtensionDescriptor
+}
+
+func (r resolverForExtension) FindMessageByName(_ protoreflect.FullName) (protoreflect.MessageType, error) {
+ return nil, protoregistry.NotFound
+}
+
+func (r resolverForExtension) FindMessageByURL(_ string) (protoreflect.MessageType, error) {
+ return nil, protoregistry.NotFound
+}
+
+func (r resolverForExtension) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
+ if field == r.ext.FullName() {
+ return asExtensionType(r.ext), nil
+ }
+ return nil, protoregistry.NotFound
+}
+
+func (r resolverForExtension) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
+ if message == r.ext.ContainingMessage().FullName() && field == r.ext.Number() {
+ return asExtensionType(r.ext), nil
+ }
+ return nil, protoregistry.NotFound
+}
+
+func asExtensionType(ext protoreflect.ExtensionDescriptor) protoreflect.ExtensionType {
+ if xtd, ok := ext.(protoreflect.ExtensionTypeDescriptor); ok {
+ return xtd.Type()
+ }
+ return dynamicpb.NewExtensionType(ext)
+}
+
+func computeSupportedEditions(minEdition, maxEdition descriptorpb.Edition) map[string]descriptorpb.Edition {
+ supportedEditions := map[string]descriptorpb.Edition{}
+ for editionNum := range descriptorpb.Edition_name {
+ edition := descriptorpb.Edition(editionNum)
+ if edition >= minEdition && edition <= maxEdition {
+ name := strings.TrimPrefix(edition.String(), "EDITION_")
+ supportedEditions[name] = edition
+ }
+ }
+ return supportedEditions
+}
+
+// actualDescriptor returns the actual field descriptor referenced by msg that
+// corresponds to the given ext (i.e. same number). It returns nil if msg has
+// no reference, if the actual descriptor is the same as ext, or if ext is
+// otherwise safe to use as is.
+func actualDescriptor(msg protoreflect.Message, ext protoreflect.ExtensionDescriptor) protoreflect.FieldDescriptor {
+ if !msg.Has(ext) || ext.Message() == nil {
+ // nothing to match; safe as is
+ return nil
+ }
+ val := msg.Get(ext)
+ switch {
+ case ext.IsMap(): // should not actually be possible
+ expectedDescriptor := ext.MapValue().Message()
+ if expectedDescriptor == nil {
+ return nil // nothing to match
+ }
+ // We know msg.Has(field) is true, from above, so there's at least one entry.
+ var matches bool
+ val.Map().Range(func(_ protoreflect.MapKey, val protoreflect.Value) bool {
+ matches = val.Message().Descriptor() == expectedDescriptor
+ return false
+ })
+ if matches {
+ return nil
+ }
+ case ext.IsList():
+ // We know msg.Has(field) is true, from above, so there's at least one entry.
+ if val.List().Get(0).Message().Descriptor() == ext.Message() {
+ return nil
+ }
+ case !ext.IsMap():
+ if val.Message().Descriptor() == ext.Message() {
+ return nil
+ }
+ }
+ // The underlying message descriptors do not match. So we need to return
+ // the actual field descriptor. Sadly, protoreflect.Message provides no way
+ // to query the field descriptor in a message by number. For non-extensions,
+ // one can query the associated message descriptor. But for extensions, we
+ // have to do the slow thing, and range through all fields looking for it.
+ var actualField protoreflect.FieldDescriptor
+ msg.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
+ if fd.Number() == ext.Number() {
+ actualField = fd
+ return false
+ }
+ return true
+ })
+ return actualField
+}
diff --git a/vendor/github.com/bufbuild/protocompile/internal/featuresext/cpp_features.protoset b/vendor/github.com/bufbuild/protocompile/internal/featuresext/cpp_features.protoset
new file mode 100644
index 0000000..106ad8e
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/featuresext/cpp_features.protoset
Binary files differ
diff --git a/vendor/github.com/bufbuild/protocompile/internal/featuresext/featuresext.go b/vendor/github.com/bufbuild/protocompile/internal/featuresext/featuresext.go
new file mode 100644
index 0000000..892524e
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/featuresext/featuresext.go
@@ -0,0 +1,84 @@
+// 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 featuresext provides file descriptors for the
+// "google/protobuf/cpp_features.proto" and "google/protobuf/java_features.proto"
+// standard import files. Unlike the other standard/well-known
+// imports, these files have no standard Go package in their
+// runtime with generated code. So in order to make them available
+// as "standard imports" to compiler users, we must embed these
+// descriptors into a Go package.
+package featuresext
+
+import (
+ _ "embed"
+ "fmt"
+ "sync"
+
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protodesc"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/reflect/protoregistry"
+ "google.golang.org/protobuf/types/descriptorpb"
+)
+
+var (
+ //go:embed cpp_features.protoset
+ cppFeatures []byte
+
+ //go:embed java_features.protoset
+ javaFeatures []byte
+
+ initOnce sync.Once
+ initCppFeatures protoreflect.FileDescriptor
+ initCppErr error
+ initJavaFeatures protoreflect.FileDescriptor
+ initJavaErr error
+)
+
+func initDescriptors() {
+ initOnce.Do(func() {
+ initCppFeatures, initCppErr = buildDescriptor("google/protobuf/cpp_features.proto", cppFeatures)
+ initJavaFeatures, initJavaErr = buildDescriptor("google/protobuf/java_features.proto", javaFeatures)
+ })
+}
+
+func CppFeaturesDescriptor() (protoreflect.FileDescriptor, error) {
+ initDescriptors()
+ return initCppFeatures, initCppErr
+}
+
+func JavaFeaturesDescriptor() (protoreflect.FileDescriptor, error) {
+ initDescriptors()
+ return initJavaFeatures, initJavaErr
+}
+
+func buildDescriptor(name string, data []byte) (protoreflect.FileDescriptor, error) {
+ var files descriptorpb.FileDescriptorSet
+ err := proto.Unmarshal(data, &files)
+ if err != nil {
+ return nil, fmt.Errorf("failed to load descriptor for %q: %w", name, err)
+ }
+ if len(files.File) != 1 {
+ return nil, fmt.Errorf("failed to load descriptor for %q: expected embedded descriptor set to contain exactly one file but it instead has %d", name, len(files.File))
+ }
+ if files.File[0].GetName() != name {
+ return nil, fmt.Errorf("failed to load descriptor for %q: embedded descriptor contains wrong file %q", name, files.File[0].GetName())
+ }
+ descriptor, err := protodesc.NewFile(files.File[0], protoregistry.GlobalFiles)
+ if err != nil {
+ return nil, fmt.Errorf("failed to load descriptor for %q: %w", name, err)
+ }
+ return descriptor, nil
+}
diff --git a/vendor/github.com/bufbuild/protocompile/internal/featuresext/java_features.protoset b/vendor/github.com/bufbuild/protocompile/internal/featuresext/java_features.protoset
new file mode 100644
index 0000000..60de3eb
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/featuresext/java_features.protoset
Binary files differ
diff --git a/vendor/github.com/bufbuild/protocompile/internal/message_context.go b/vendor/github.com/bufbuild/protocompile/internal/message_context.go
new file mode 100644
index 0000000..52acbdf
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/message_context.go
@@ -0,0 +1,98 @@
+// 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 internal
+
+import (
+ "bytes"
+ "fmt"
+
+ "google.golang.org/protobuf/types/descriptorpb"
+
+ "github.com/bufbuild/protocompile/ast"
+)
+
+// ParsedFile wraps an optional AST and required FileDescriptorProto.
+// This is used so types like parser.Result can be passed to this internal package avoiding circular imports.
+// Additionally, it makes it less likely that users might specify one or the other.
+type ParsedFile interface {
+ // AST returns the parsed abstract syntax tree. This returns nil if the
+ // Result was created without an AST.
+ AST() *ast.FileNode
+ // FileDescriptorProto returns the file descriptor proto.
+ FileDescriptorProto() *descriptorpb.FileDescriptorProto
+}
+
+// MessageContext provides information about the location in a descriptor
+// hierarchy, for adding context to warnings and error messages.
+type MessageContext struct {
+ // The relevant file
+ File ParsedFile
+
+ // The type and fully-qualified name of the element within the file.
+ ElementType string
+ ElementName string
+
+ // If the element being processed is an option (or *in* an option)
+ // on the named element above, this will be non-nil.
+ Option *descriptorpb.UninterpretedOption
+ // If the element being processed is inside a message literal in an
+ // option value, this will be non-empty and represent a traversal
+ // to the element in question.
+ OptAggPath string
+}
+
+func (c *MessageContext) String() string {
+ var ctx bytes.Buffer
+ if c.ElementType != "file" {
+ _, _ = fmt.Fprintf(&ctx, "%s %s: ", c.ElementType, c.ElementName)
+ }
+ if c.Option != nil && c.Option.Name != nil {
+ ctx.WriteString("option ")
+ writeOptionName(&ctx, c.Option.Name)
+ if c.File.AST() == nil {
+ // if we have no source position info, try to provide as much context
+ // as possible (if nodes != nil, we don't need this because any errors
+ // will actually have file and line numbers)
+ if c.OptAggPath != "" {
+ _, _ = fmt.Fprintf(&ctx, " at %s", c.OptAggPath)
+ }
+ }
+ ctx.WriteString(": ")
+ }
+ return ctx.String()
+}
+
+func writeOptionName(buf *bytes.Buffer, parts []*descriptorpb.UninterpretedOption_NamePart) {
+ first := true
+ for _, p := range parts {
+ if first {
+ first = false
+ } else {
+ buf.WriteByte('.')
+ }
+ nm := p.GetNamePart()
+ if nm[0] == '.' {
+ // skip leading dot
+ nm = nm[1:]
+ }
+ if p.GetIsExtension() {
+ buf.WriteByte('(')
+ buf.WriteString(nm)
+ buf.WriteByte(')')
+ } else {
+ buf.WriteString(nm)
+ }
+ }
+}
diff --git a/vendor/github.com/bufbuild/protocompile/internal/messageset/messageset.go b/vendor/github.com/bufbuild/protocompile/internal/messageset/messageset.go
new file mode 100644
index 0000000..850a0c6
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/messageset/messageset.go
@@ -0,0 +1,62 @@
+// 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 messageset
+
+import (
+ "math"
+ "sync"
+
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protodesc"
+ "google.golang.org/protobuf/types/descriptorpb"
+)
+
+var (
+ messageSetSupport bool
+ messageSetSupportInit sync.Once
+)
+
+// CanSupportMessageSets returns true if the protobuf-go runtime supports
+// serializing messages with the message set wire format.
+func CanSupportMessageSets() bool {
+ messageSetSupportInit.Do(func() {
+ // We check using the protodesc package, instead of just relying
+ // on protolegacy build tag, in case someone links in a fork of
+ // the protobuf-go runtime that supports legacy proto1 features
+ // or in case the protobuf-go runtime adds another mechanism to
+ // enable or disable it (such as environment variable).
+ _, err := protodesc.NewFile(&descriptorpb.FileDescriptorProto{
+ Name: proto.String("test.proto"),
+ MessageType: []*descriptorpb.DescriptorProto{
+ {
+ Name: proto.String("MessageSet"),
+ Options: &descriptorpb.MessageOptions{
+ MessageSetWireFormat: proto.Bool(true),
+ },
+ ExtensionRange: []*descriptorpb.DescriptorProto_ExtensionRange{
+ {
+ Start: proto.Int32(1),
+ End: proto.Int32(math.MaxInt32),
+ },
+ },
+ },
+ },
+ }, nil)
+ // When message sets are not supported, the above returns an error:
+ // message "MessageSet" is a MessageSet, which is a legacy proto1 feature that is no longer supported
+ messageSetSupport = err == nil
+ })
+ return messageSetSupport
+}
diff --git a/vendor/github.com/bufbuild/protocompile/internal/norace.go b/vendor/github.com/bufbuild/protocompile/internal/norace.go
new file mode 100644
index 0000000..2acf4e4
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/norace.go
@@ -0,0 +1,19 @@
+// 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.
+
+//go:build !race
+
+package internal
+
+const IsRace = false
diff --git a/vendor/github.com/bufbuild/protocompile/internal/options.go b/vendor/github.com/bufbuild/protocompile/internal/options.go
new file mode 100644
index 0000000..4eaa0f6
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/options.go
@@ -0,0 +1,71 @@
+// 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 internal
+
+import (
+ "google.golang.org/protobuf/types/descriptorpb"
+
+ "github.com/bufbuild/protocompile/ast"
+)
+
+type hasOptionNode interface {
+ OptionNode(part *descriptorpb.UninterpretedOption) ast.OptionDeclNode
+ FileNode() ast.FileDeclNode // needed in order to query for NodeInfo
+}
+
+type errorHandler func(span ast.SourceSpan, format string, args ...interface{}) error
+
+func FindFirstOption(res hasOptionNode, handler errorHandler, scope string, opts []*descriptorpb.UninterpretedOption, name string) (int, error) {
+ return findOption(res, handler, scope, opts, name, false, true)
+}
+
+func FindOption(res hasOptionNode, handler errorHandler, scope string, opts []*descriptorpb.UninterpretedOption, name string) (int, error) {
+ return findOption(res, handler, scope, opts, name, true, false)
+}
+
+func findOption(res hasOptionNode, handler errorHandler, scope string, opts []*descriptorpb.UninterpretedOption, name string, exact, first bool) (int, error) {
+ found := -1
+ for i, opt := range opts {
+ if exact && len(opt.Name) != 1 {
+ continue
+ }
+ if opt.Name[0].GetIsExtension() || opt.Name[0].GetNamePart() != name {
+ continue
+ }
+ if first {
+ return i, nil
+ }
+ if found >= 0 {
+ optNode := res.OptionNode(opt)
+ fn := res.FileNode()
+ node := optNode.GetName()
+ nodeInfo := fn.NodeInfo(node)
+ return -1, handler(nodeInfo, "%s: option %s cannot be defined more than once", scope, name)
+ }
+ found = i
+ }
+ return found, nil
+}
+
+func RemoveOption(uo []*descriptorpb.UninterpretedOption, indexToRemove int) []*descriptorpb.UninterpretedOption {
+ switch {
+ case indexToRemove == 0:
+ return uo[1:]
+ case indexToRemove == len(uo)-1:
+ return uo[:len(uo)-1]
+ default:
+ return append(uo[:indexToRemove], uo[indexToRemove+1:]...)
+ }
+}
diff --git a/vendor/github.com/bufbuild/protocompile/internal/race.go b/vendor/github.com/bufbuild/protocompile/internal/race.go
new file mode 100644
index 0000000..e70e414
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/race.go
@@ -0,0 +1,19 @@
+// 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.
+
+//go:build race
+
+package internal
+
+const IsRace = true
diff --git a/vendor/github.com/bufbuild/protocompile/internal/tags.go b/vendor/github.com/bufbuild/protocompile/internal/tags.go
new file mode 100644
index 0000000..179728f
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/tags.go
@@ -0,0 +1,336 @@
+// 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 internal
+
+import "math"
+
+const (
+ // MaxNormalTag is the maximum allowed tag number for a field in a normal message.
+ MaxNormalTag = 536870911 // 2^29 - 1
+
+ // MaxMessageSetTag is the maximum allowed tag number of a field in a message that
+ // uses the message set wire format.
+ MaxMessageSetTag = math.MaxInt32 - 1
+
+ // MaxTag is the maximum allowed tag number. (It is the same as MaxMessageSetTag
+ // since that is the absolute highest allowed.)
+ MaxTag = MaxMessageSetTag
+
+ // SpecialReservedStart is the first tag in a range that is reserved and not
+ // allowed for use in message definitions.
+ SpecialReservedStart = 19000
+ // SpecialReservedEnd is the last tag in a range that is reserved and not
+ // allowed for use in message definitions.
+ SpecialReservedEnd = 19999
+
+ // NB: It would be nice to use constants from generated code instead of
+ // hard-coding these here. But code-gen does not emit these as constants
+ // anywhere. The only places they appear in generated code are struct tags
+ // on fields of the generated descriptor protos.
+
+ // FilePackageTag is the tag number of the package element in a file
+ // descriptor proto.
+ FilePackageTag = 2
+ // FileDependencyTag is the tag number of the dependencies element in a
+ // file descriptor proto.
+ FileDependencyTag = 3
+ // FileMessagesTag is the tag number of the messages element in a file
+ // descriptor proto.
+ FileMessagesTag = 4
+ // FileEnumsTag is the tag number of the enums element in a file descriptor
+ // proto.
+ FileEnumsTag = 5
+ // FileServicesTag is the tag number of the services element in a file
+ // descriptor proto.
+ FileServicesTag = 6
+ // FileExtensionsTag is the tag number of the extensions element in a file
+ // descriptor proto.
+ FileExtensionsTag = 7
+ // FileOptionsTag is the tag number of the options element in a file
+ // descriptor proto.
+ FileOptionsTag = 8
+ // FileOptionsJavaStringCheckUTF8Tag is the tag number of the java_string_check_utf8
+ // field in the FileOptions proto.
+ FileOptionsJavaStringCheckUTF8Tag = 27
+ // FileOptionsFeaturesTag is the tag number of the features field in the
+ // FileOptions proto.
+ FileOptionsFeaturesTag = 50
+ // FileSourceCodeInfoTag is the tag number of the source code info element
+ // in a file descriptor proto.
+ FileSourceCodeInfoTag = 9
+ // FilePublicDependencyTag is the tag number of the public dependency element
+ // in a file descriptor proto.
+ FilePublicDependencyTag = 10
+ // FileWeakDependencyTag is the tag number of the weak dependency element
+ // in a file descriptor proto.
+ FileWeakDependencyTag = 11
+ // FileSyntaxTag is the tag number of the syntax element in a file
+ // descriptor proto.
+ FileSyntaxTag = 12
+ // FileEditionTag is the tag number of the edition element in a file
+ // descriptor proto.
+ FileEditionTag = 14
+ // MessageNameTag is the tag number of the name element in a message
+ // descriptor proto.
+ MessageNameTag = 1
+ // MessageFieldsTag is the tag number of the fields element in a message
+ // descriptor proto.
+ MessageFieldsTag = 2
+ // MessageNestedMessagesTag is the tag number of the nested messages
+ // element in a message descriptor proto.
+ MessageNestedMessagesTag = 3
+ // MessageEnumsTag is the tag number of the enums element in a message
+ // descriptor proto.
+ MessageEnumsTag = 4
+ // MessageExtensionRangesTag is the tag number of the extension ranges
+ // element in a message descriptor proto.
+ MessageExtensionRangesTag = 5
+ // MessageExtensionsTag is the tag number of the extensions element in a
+ // message descriptor proto.
+ MessageExtensionsTag = 6
+ // MessageOptionsTag is the tag number of the options element in a message
+ // descriptor proto.
+ MessageOptionsTag = 7
+ // MessageOptionsFeaturesTag is the tag number of the features field in the
+ // MessageOptions proto.
+ MessageOptionsFeaturesTag = 12
+ // MessageOneofsTag is the tag number of the one-ofs element in a message
+ // descriptor proto.
+ MessageOneofsTag = 8
+ // MessageReservedRangesTag is the tag number of the reserved ranges element
+ // in a message descriptor proto.
+ MessageReservedRangesTag = 9
+ // MessageReservedNamesTag is the tag number of the reserved names element
+ // in a message descriptor proto.
+ MessageReservedNamesTag = 10
+ // ExtensionRangeStartTag is the tag number of the start index in an
+ // extension range proto.
+ ExtensionRangeStartTag = 1
+ // ExtensionRangeEndTag is the tag number of the end index in an
+ // extension range proto.
+ ExtensionRangeEndTag = 2
+ // ExtensionRangeOptionsTag is the tag number of the options element in an
+ // extension range proto.
+ ExtensionRangeOptionsTag = 3
+ // ExtensionRangeOptionsDeclarationTag is the tag number of the declaration
+ // field in the ExtensionRangeOptions proto.
+ ExtensionRangeOptionsDeclarationTag = 2
+ // ExtensionRangeOptionsVerificationTag is the tag number of the verification
+ // field in the ExtensionRangeOptions proto.
+ ExtensionRangeOptionsVerificationTag = 3
+ // ExtensionRangeOptionsDeclarationNumberTag is the tag number of the number
+ // field in the ExtensionRangeOptions.Declaration proto.
+ ExtensionRangeOptionsDeclarationNumberTag = 1
+ // ExtensionRangeOptionsDeclarationFullNameTag is the tag number of the full_name
+ // field in the ExtensionRangeOptions.Declaration proto.
+ ExtensionRangeOptionsDeclarationFullNameTag = 2
+ // ExtensionRangeOptionsDeclarationTypeTag is the tag number of the type
+ // field in the ExtensionRangeOptions.Declaration proto.
+ ExtensionRangeOptionsDeclarationTypeTag = 3
+ // ExtensionRangeOptionsDeclarationReservedTag is the tag number of the reserved
+ // field in the ExtensionRangeOptions.Declaration proto.
+ ExtensionRangeOptionsDeclarationReservedTag = 5
+ // ExtensionRangeOptionsDeclarationRepeatedTag is the tag number of the repeated
+ // field in the ExtensionRangeOptions.Declaration proto.
+ ExtensionRangeOptionsDeclarationRepeatedTag = 6
+ // ExtensionRangeOptionsFeaturesTag is the tag number of the features field in the
+ // ExtensionRangeOptions proto.
+ ExtensionRangeOptionsFeaturesTag = 50
+ // ReservedRangeStartTag is the tag number of the start index in a reserved
+ // range proto. This field number is the same for both "flavors" of reserved
+ // ranges: DescriptorProto.ReservedRange and EnumDescriptorProto.EnumReservedRange.
+ ReservedRangeStartTag = 1
+ // ReservedRangeEndTag is the tag number of the end index in a reserved
+ // range proto. This field number is the same for both "flavors" of reserved
+ // ranges: DescriptorProto.ReservedRange and EnumDescriptorProto.EnumReservedRange.
+ ReservedRangeEndTag = 2
+ // FieldNameTag is the tag number of the name element in a field descriptor
+ // proto.
+ FieldNameTag = 1
+ // FieldExtendeeTag is the tag number of the extendee element in a field
+ // descriptor proto.
+ FieldExtendeeTag = 2
+ // FieldNumberTag is the tag number of the number element in a field
+ // descriptor proto.
+ FieldNumberTag = 3
+ // FieldLabelTag is the tag number of the label element in a field
+ // descriptor proto.
+ FieldLabelTag = 4
+ // FieldTypeTag is the tag number of the type element in a field descriptor
+ // proto.
+ FieldTypeTag = 5
+ // FieldTypeNameTag is the tag number of the type name element in a field
+ // descriptor proto.
+ FieldTypeNameTag = 6
+ // FieldDefaultTag is the tag number of the default value element in a
+ // field descriptor proto.
+ FieldDefaultTag = 7
+ // FieldOptionsTag is the tag number of the options element in a field
+ // descriptor proto.
+ FieldOptionsTag = 8
+ // FieldOptionsCTypeTag is the number of the ctype field in the
+ // FieldOptions proto.
+ FieldOptionsCTypeTag = 1
+ // FieldOptionsPackedTag is the number of the packed field in the
+ // FieldOptions proto.
+ FieldOptionsPackedTag = 2
+ // FieldOptionsLazyTag is the number of the lazy field in the
+ // FieldOptions proto.
+ FieldOptionsLazyTag = 5
+ // FieldOptionsJSTypeTag is the number of the jstype field in the
+ // FieldOptions proto.
+ FieldOptionsJSTypeTag = 6
+ // FieldOptionsUnverifiedLazyTag is the number of the unverified_lazy
+ // field in the FieldOptions proto.
+ FieldOptionsUnverifiedLazyTag = 15
+ // FieldOptionsFeaturesTag is the tag number of the features field in the
+ // FieldOptions proto.
+ FieldOptionsFeaturesTag = 21
+ // FieldOneofIndexTag is the tag number of the oneof index element in a
+ // field descriptor proto.
+ FieldOneofIndexTag = 9
+ // FieldJSONNameTag is the tag number of the JSON name element in a field
+ // descriptor proto.
+ FieldJSONNameTag = 10
+ // FieldProto3OptionalTag is the tag number of the proto3_optional element
+ // in a descriptor proto.
+ FieldProto3OptionalTag = 17
+ // OneofNameTag is the tag number of the name element in a one-of
+ // descriptor proto.
+ OneofNameTag = 1
+ // OneofOptionsTag is the tag number of the options element in a one-of
+ // descriptor proto.
+ OneofOptionsTag = 2
+ // OneofOptionsFeaturesTag is the tag number of the features field in the
+ // OneofOptions proto.
+ OneofOptionsFeaturesTag = 1
+ // EnumNameTag is the tag number of the name element in an enum descriptor
+ // proto.
+ EnumNameTag = 1
+ // EnumValuesTag is the tag number of the values element in an enum
+ // descriptor proto.
+ EnumValuesTag = 2
+ // EnumOptionsTag is the tag number of the options element in an enum
+ // descriptor proto.
+ EnumOptionsTag = 3
+ // EnumOptionsFeaturesTag is the tag number of the features field in the
+ // EnumOptions proto.
+ EnumOptionsFeaturesTag = 7
+ // EnumReservedRangesTag is the tag number of the reserved ranges element in
+ // an enum descriptor proto.
+ EnumReservedRangesTag = 4
+ // EnumReservedNamesTag is the tag number of the reserved names element in
+ // an enum descriptor proto.
+ EnumReservedNamesTag = 5
+ // EnumValNameTag is the tag number of the name element in an enum value
+ // descriptor proto.
+ EnumValNameTag = 1
+ // EnumValNumberTag is the tag number of the number element in an enum
+ // value descriptor proto.
+ EnumValNumberTag = 2
+ // EnumValOptionsTag is the tag number of the options element in an enum
+ // value descriptor proto.
+ EnumValOptionsTag = 3
+ // EnumValOptionsFeaturesTag is the tag number of the features field in the
+ // EnumValueOptions proto.
+ EnumValOptionsFeaturesTag = 2
+ // ServiceNameTag is the tag number of the name element in a service
+ // descriptor proto.
+ ServiceNameTag = 1
+ // ServiceMethodsTag is the tag number of the methods element in a service
+ // descriptor proto.
+ ServiceMethodsTag = 2
+ // ServiceOptionsTag is the tag number of the options element in a service
+ // descriptor proto.
+ ServiceOptionsTag = 3
+ // ServiceOptionsFeaturesTag is the tag number of the features field in the
+ // ServiceOptions proto.
+ ServiceOptionsFeaturesTag = 34
+ // MethodNameTag is the tag number of the name element in a method
+ // descriptor proto.
+ MethodNameTag = 1
+ // MethodInputTag is the tag number of the input type element in a method
+ // descriptor proto.
+ MethodInputTag = 2
+ // MethodOutputTag is the tag number of the output type element in a method
+ // descriptor proto.
+ MethodOutputTag = 3
+ // MethodOptionsTag is the tag number of the options element in a method
+ // descriptor proto.
+ MethodOptionsTag = 4
+ // MethodOptionsFeaturesTag is the tag number of the features field in the
+ // MethodOptions proto.
+ MethodOptionsFeaturesTag = 35
+ // MethodInputStreamTag is the tag number of the input stream flag in a
+ // method descriptor proto.
+ MethodInputStreamTag = 5
+ // MethodOutputStreamTag is the tag number of the output stream flag in a
+ // method descriptor proto.
+ MethodOutputStreamTag = 6
+
+ // UninterpretedOptionsTag is the tag number of the uninterpreted options
+ // element. All *Options messages use the same tag for the field that stores
+ // uninterpreted options.
+ UninterpretedOptionsTag = 999
+
+ // UninterpretedNameTag is the tag number of the name element in an
+ // uninterpreted options proto.
+ UninterpretedNameTag = 2
+ // UninterpretedIdentTag is the tag number of the identifier value in an
+ // uninterpreted options proto.
+ UninterpretedIdentTag = 3
+ // UninterpretedPosIntTag is the tag number of the positive int value in an
+ // uninterpreted options proto.
+ UninterpretedPosIntTag = 4
+ // UninterpretedNegIntTag is the tag number of the negative int value in an
+ // uninterpreted options proto.
+ UninterpretedNegIntTag = 5
+ // UninterpretedDoubleTag is the tag number of the double value in an
+ // uninterpreted options proto.
+ UninterpretedDoubleTag = 6
+ // UninterpretedStringTag is the tag number of the string value in an
+ // uninterpreted options proto.
+ UninterpretedStringTag = 7
+ // UninterpretedAggregateTag is the tag number of the aggregate value in an
+ // uninterpreted options proto.
+ UninterpretedAggregateTag = 8
+ // UninterpretedNameNameTag is the tag number of the name element in an
+ // uninterpreted option name proto.
+ UninterpretedNameNameTag = 1
+
+ // AnyTypeURLTag is the tag number of the type_url field of the Any proto.
+ AnyTypeURLTag = 1
+ // AnyValueTag is the tag number of the value field of the Any proto.
+ AnyValueTag = 2
+
+ // FeatureSetFieldPresenceTag is the tag number of the field_presence field
+ // in the FeatureSet proto.
+ FeatureSetFieldPresenceTag = 1
+ // FeatureSetEnumTypeTag is the tag number of the enum_type field in the
+ // FeatureSet proto.
+ FeatureSetEnumTypeTag = 2
+ // FeatureSetRepeatedFieldEncodingTag is the tag number of the repeated_field_encoding
+ // field in the FeatureSet proto.
+ FeatureSetRepeatedFieldEncodingTag = 3
+ // FeatureSetUTF8ValidationTag is the tag number of the utf8_validation field
+ // in the FeatureSet proto.
+ FeatureSetUTF8ValidationTag = 4
+ // FeatureSetMessageEncodingTag is the tag number of the message_encoding
+ // field in the FeatureSet proto.
+ FeatureSetMessageEncodingTag = 5
+ // FeatureSetJSONFormatTag is the tag number of the json_format field in
+ // the FeatureSet proto.
+ FeatureSetJSONFormatTag = 6
+)
diff --git a/vendor/github.com/bufbuild/protocompile/internal/types.go b/vendor/github.com/bufbuild/protocompile/internal/types.go
new file mode 100644
index 0000000..04090a8
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/types.go
@@ -0,0 +1,35 @@
+// 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 internal
+
+import "google.golang.org/protobuf/types/descriptorpb"
+
+var FieldTypes = map[string]descriptorpb.FieldDescriptorProto_Type{
+ "double": descriptorpb.FieldDescriptorProto_TYPE_DOUBLE,
+ "float": descriptorpb.FieldDescriptorProto_TYPE_FLOAT,
+ "int32": descriptorpb.FieldDescriptorProto_TYPE_INT32,
+ "int64": descriptorpb.FieldDescriptorProto_TYPE_INT64,
+ "uint32": descriptorpb.FieldDescriptorProto_TYPE_UINT32,
+ "uint64": descriptorpb.FieldDescriptorProto_TYPE_UINT64,
+ "sint32": descriptorpb.FieldDescriptorProto_TYPE_SINT32,
+ "sint64": descriptorpb.FieldDescriptorProto_TYPE_SINT64,
+ "fixed32": descriptorpb.FieldDescriptorProto_TYPE_FIXED32,
+ "fixed64": descriptorpb.FieldDescriptorProto_TYPE_FIXED64,
+ "sfixed32": descriptorpb.FieldDescriptorProto_TYPE_SFIXED32,
+ "sfixed64": descriptorpb.FieldDescriptorProto_TYPE_SFIXED64,
+ "bool": descriptorpb.FieldDescriptorProto_TYPE_BOOL,
+ "string": descriptorpb.FieldDescriptorProto_TYPE_STRING,
+ "bytes": descriptorpb.FieldDescriptorProto_TYPE_BYTES,
+}
diff --git a/vendor/github.com/bufbuild/protocompile/internal/util.go b/vendor/github.com/bufbuild/protocompile/internal/util.go
new file mode 100644
index 0000000..569cb3f
--- /dev/null
+++ b/vendor/github.com/bufbuild/protocompile/internal/util.go
@@ -0,0 +1,244 @@
+// 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 internal
+
+import (
+ "bytes"
+ "unicode"
+ "unicode/utf8"
+
+ "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// JSONName returns the default JSON name for a field with the given name.
+// This mirrors the algorithm in protoc:
+//
+// https://github.com/protocolbuffers/protobuf/blob/v21.3/src/google/protobuf/descriptor.cc#L95
+func JSONName(name string) string {
+ var js []rune
+ nextUpper := false
+ for _, r := range name {
+ if r == '_' {
+ nextUpper = true
+ continue
+ }
+ if nextUpper {
+ nextUpper = false
+ js = append(js, unicode.ToUpper(r))
+ } else {
+ js = append(js, r)
+ }
+ }
+ return string(js)
+}
+
+// InitCap returns the given field name, but with the first letter capitalized.
+func InitCap(name string) string {
+ r, sz := utf8.DecodeRuneInString(name)
+ return string(unicode.ToUpper(r)) + name[sz:]
+}
+
+// CreatePrefixList returns a list of package prefixes to search when resolving
+// a symbol name. If the given package is blank, it returns only the empty
+// string. If the given package contains only one token, e.g. "foo", it returns
+// that token and the empty string, e.g. ["foo", ""]. Otherwise, it returns
+// successively shorter prefixes of the package and then the empty string. For
+// example, for a package named "foo.bar.baz" it will return the following list:
+//
+// ["foo.bar.baz", "foo.bar", "foo", ""]
+func CreatePrefixList(pkg string) []string {
+ if pkg == "" {
+ return []string{""}
+ }
+
+ numDots := 0
+ // one pass to pre-allocate the returned slice
+ for i := 0; i < len(pkg); i++ {
+ if pkg[i] == '.' {
+ numDots++
+ }
+ }
+ if numDots == 0 {
+ return []string{pkg, ""}
+ }
+
+ prefixes := make([]string, numDots+2)
+ // second pass to fill in returned slice
+ for i := 0; i < len(pkg); i++ {
+ if pkg[i] == '.' {
+ prefixes[numDots] = pkg[:i]
+ numDots--
+ }
+ }
+ prefixes[0] = pkg
+
+ return prefixes
+}
+
+func WriteEscapedBytes(buf *bytes.Buffer, b []byte) {
+ // This uses the same algorithm as the protoc C++ code for escaping strings.
+ // The protoc C++ code in turn uses the abseil C++ library's CEscape function:
+ // https://github.com/abseil/abseil-cpp/blob/934f613818ffcb26c942dff4a80be9a4031c662c/absl/strings/escaping.cc#L406
+ for _, c := range b {
+ switch c {
+ case '\n':
+ buf.WriteString("\\n")
+ case '\r':
+ buf.WriteString("\\r")
+ case '\t':
+ buf.WriteString("\\t")
+ case '"':
+ buf.WriteString("\\\"")
+ case '\'':
+ buf.WriteString("\\'")
+ case '\\':
+ buf.WriteString("\\\\")
+ default:
+ if c >= 0x20 && c < 0x7f {
+ // simple printable characters
+ buf.WriteByte(c)
+ } else {
+ // use octal escape for all other values
+ buf.WriteRune('\\')
+ buf.WriteByte('0' + ((c >> 6) & 0x7))
+ buf.WriteByte('0' + ((c >> 3) & 0x7))
+ buf.WriteByte('0' + (c & 0x7))
+ }
+ }
+ }
+}
+
+// IsZeroLocation returns true if the given loc is a zero value
+// (which is returned from queries that have no result).
+func IsZeroLocation(loc protoreflect.SourceLocation) bool {
+ return loc.Path == nil &&
+ loc.StartLine == 0 &&
+ loc.StartColumn == 0 &&
+ loc.EndLine == 0 &&
+ loc.EndColumn == 0 &&
+ loc.LeadingDetachedComments == nil &&
+ loc.LeadingComments == "" &&
+ loc.TrailingComments == "" &&
+ loc.Next == 0
+}
+
+// ComputePath computes the source location path for the given descriptor.
+// The boolean value indicates whether the result is valid. If the path
+// cannot be computed for d, the function returns nil, false.
+func ComputePath(d protoreflect.Descriptor) (protoreflect.SourcePath, bool) {
+ _, ok := d.(protoreflect.FileDescriptor)
+ if ok {
+ return nil, true
+ }
+ var path protoreflect.SourcePath
+ for {
+ p := d.Parent()
+ switch d := d.(type) {
+ case protoreflect.FileDescriptor:
+ return reverse(path), true
+ case protoreflect.MessageDescriptor:
+ path = append(path, int32(d.Index()))
+ switch p.(type) {
+ case protoreflect.FileDescriptor:
+ path = append(path, FileMessagesTag)
+ case protoreflect.MessageDescriptor:
+ path = append(path, MessageNestedMessagesTag)
+ default:
+ return nil, false
+ }
+ case protoreflect.FieldDescriptor:
+ path = append(path, int32(d.Index()))
+ switch p.(type) {
+ case protoreflect.FileDescriptor:
+ if d.IsExtension() {
+ path = append(path, FileExtensionsTag)
+ } else {
+ return nil, false
+ }
+ case protoreflect.MessageDescriptor:
+ if d.IsExtension() {
+ path = append(path, MessageExtensionsTag)
+ } else {
+ path = append(path, MessageFieldsTag)
+ }
+ default:
+ return nil, false
+ }
+ case protoreflect.OneofDescriptor:
+ path = append(path, int32(d.Index()))
+ if _, ok := p.(protoreflect.MessageDescriptor); ok {
+ path = append(path, MessageOneofsTag)
+ } else {
+ return nil, false
+ }
+ case protoreflect.EnumDescriptor:
+ path = append(path, int32(d.Index()))
+ switch p.(type) {
+ case protoreflect.FileDescriptor:
+ path = append(path, FileEnumsTag)
+ case protoreflect.MessageDescriptor:
+ path = append(path, MessageEnumsTag)
+ default:
+ return nil, false
+ }
+ case protoreflect.EnumValueDescriptor:
+ path = append(path, int32(d.Index()))
+ if _, ok := p.(protoreflect.EnumDescriptor); ok {
+ path = append(path, EnumValuesTag)
+ } else {
+ return nil, false
+ }
+ case protoreflect.ServiceDescriptor:
+ path = append(path, int32(d.Index()))
+ if _, ok := p.(protoreflect.FileDescriptor); ok {
+ path = append(path, FileServicesTag)
+ } else {
+ return nil, false
+ }
+ case protoreflect.MethodDescriptor:
+ path = append(path, int32(d.Index()))
+ if _, ok := p.(protoreflect.ServiceDescriptor); ok {
+ path = append(path, ServiceMethodsTag)
+ } else {
+ return nil, false
+ }
+ }
+ d = p
+ }
+}
+
+// CanPack returns true if a repeated field of the given kind
+// can use packed encoding.
+func CanPack(k protoreflect.Kind) bool {
+ switch k {
+ case protoreflect.MessageKind, protoreflect.GroupKind, protoreflect.StringKind, protoreflect.BytesKind:
+ return false
+ default:
+ return true
+ }
+}
+
+func ClonePath(path protoreflect.SourcePath) protoreflect.SourcePath {
+ clone := make(protoreflect.SourcePath, len(path))
+ copy(clone, path)
+ return clone
+}
+
+func reverse(p protoreflect.SourcePath) protoreflect.SourcePath {
+ for i, j := 0, len(p)-1; i < j; i, j = i+1, j-1 {
+ p[i], p[j] = p[j], p[i]
+ }
+ return p
+}