diff --git a/Makefile b/Makefile index 959377285..aea221939 100644 --- a/Makefile +++ b/Makefile @@ -153,6 +153,7 @@ wellknownimports: $(PROTOC) $(sort $(wildcard $(PROTOC_DIR)/include/google/proto @mkdir -p wellknownimports/google/protobuf/compiler cp -R $(PROTOC_DIR)/include/google/protobuf/*.proto wellknownimports/google/protobuf cp -R $(PROTOC_DIR)/include/google/protobuf/compiler/*.proto wellknownimports/google/protobuf/compiler + find wellknownimports/google -type f | sed 's|wellknownimports/||' | xargs protoc -I wellknownimports -owellknownimports/wkt.pb internal/testdata/all.protoset: $(PROTOC) $(sort $(wildcard internal/testdata/*.proto)) cd $(@D) && $(PROTOC) --descriptor_set_out=$(@F) --include_imports -I. $(filter-out protoc,$(^F)) diff --git a/experimental/fdp/generator.go b/experimental/fdp/generator.go index ce0d03346..1e3171e9d 100644 --- a/experimental/fdp/generator.go +++ b/experimental/fdp/generator.go @@ -31,9 +31,9 @@ import ( "github.com/bufbuild/protocompile/experimental/source" "github.com/bufbuild/protocompile/experimental/token" "github.com/bufbuild/protocompile/experimental/token/keyword" - "github.com/bufbuild/protocompile/internal" "github.com/bufbuild/protocompile/internal/ext/cmpx" "github.com/bufbuild/protocompile/internal/ext/iterx" + "github.com/bufbuild/protocompile/internal/tags" ) type generator struct { @@ -87,7 +87,7 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { } g.addSourceLocationWithSourcePathElements( file.AST().Package().Span(), - []int32{internal.FilePackageTag}, + []int32{tags.File_Package}, true, ) @@ -106,7 +106,7 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { file.AST().Syntax().Span(), // According to descriptor.proto and protoc behavior, the path is always set to [12] // for both syntax and editions. - []int32{internal.FileSyntaxTag}, + []int32{tags.File_Syntax}, true, ) @@ -127,7 +127,7 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { fdp.Dependency = append(fdp.Dependency, imp.Path()) g.addSourceLocationWithSourcePathElements( imp.Decl.Span(), - []int32{internal.FileDependencyTag, int32(i)}, + []int32{tags.File_Dependency, int32(i)}, true, ) if imp.Public { @@ -137,7 +137,7 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { }) g.addSourceLocationWithSourcePathElements( public.Span(), - []int32{internal.FilePublicDependencyTag, publicDepIndex}, + []int32{tags.File_PublicDependency, publicDepIndex}, false, ) publicDepIndex++ @@ -149,7 +149,7 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { }) g.addSourceLocationWithSourcePathElements( weak.Span(), - []int32{internal.FileWeakDependencyTag, weakDepIndex}, + []int32{tags.File_WeakDependency, weakDepIndex}, false, ) weakDepIndex++ @@ -158,7 +158,7 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { fdp.OptionDependency = append(fdp.OptionDependency, imp.Path()) g.addSourceLocationWithSourcePathElements( imp.Decl.Span(), - []int32{internal.FileOptionDependencyTag, optionDepIndex}, + []int32{tags.File_OptionDependency, optionDepIndex}, true, ) } @@ -173,46 +173,46 @@ func (g *generator) file(file *ir.File, fdp *descriptorpb.FileDescriptorProto) { if ty.IsEnum() { edp := new(descriptorpb.EnumDescriptorProto) fdp.EnumType = append(fdp.EnumType, edp) - g.enum(ty, edp, internal.FileEnumsTag, enumIndex) + g.enum(ty, edp, tags.File_EnumType, enumIndex) enumIndex++ continue } mdp := new(descriptorpb.DescriptorProto) fdp.MessageType = append(fdp.MessageType, mdp) - g.message(ty, mdp, internal.FileMessagesTag, msgIndex) + g.message(ty, mdp, tags.File_MessageType, msgIndex) msgIndex++ } for i, service := range seq.All(file.Services()) { sdp := new(descriptorpb.ServiceDescriptorProto) fdp.Service = append(fdp.Service, sdp) - g.service(service, sdp, internal.FileServicesTag, int32(i)) + g.service(service, sdp, tags.File_Service, int32(i)) } var extnIndex int32 for extend := range seq.Values(file.Extends()) { g.addSourceLocationWithSourcePathElements( extend.AST().Span(), - []int32{internal.FileExtensionsTag}, + []int32{tags.File_Extension}, true, ) for extn := range seq.Values(extend.Extensions()) { fd := new(descriptorpb.FieldDescriptorProto) fdp.Extension = append(fdp.Extension, fd) - g.field(extn, fd, internal.FileExtensionsTag, extnIndex) + g.field(extn, fd, tags.File_Extension, extnIndex) extnIndex++ } } if options := file.Options(); !iterx.Empty(options.Fields()) { for option := range file.AST().Options() { - g.addSourceLocationWithSourcePathElements(option.Span(), []int32{internal.FileOptionsTag}, false) + g.addSourceLocationWithSourcePathElements(option.Span(), []int32{tags.File_Options}, false) } fdp.Options = new(descriptorpb.FileOptions) - g.options(options, fdp.Options, internal.FileOptionsTag) + g.options(options, fdp.Options, tags.File_Options) } if g.sourceCodeInfoExtn != nil && iterx.Empty2(g.sourceCodeInfoExtn.ProtoReflect().Range) { @@ -257,26 +257,26 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc addSourceLocation(messageAST.Span(), true) mdp.Name = addr(ty.Name()) - addSourceLocationWithSourcePathElements(messageAST.Name.Span(), []int32{internal.MessageNameTag}, false) + addSourceLocationWithSourcePathElements(messageAST.Name.Span(), []int32{tags.Message_Name}, false) for i, field := range seq.All(ty.Members()) { fd := new(descriptorpb.FieldDescriptorProto) mdp.Field = append(mdp.Field, fd) - g.field(field, fd, internal.MessageFieldsTag, int32(i)) + g.field(field, fd, tags.Message_Field, int32(i)) } var extnIndex int32 for extend := range seq.Values(ty.Extends()) { addSourceLocationWithSourcePathElements( extend.AST().Span(), - []int32{internal.MessageExtensionsTag}, + []int32{tags.Message_Extension}, true, ) for extn := range seq.Values(extend.Extensions()) { fd := new(descriptorpb.FieldDescriptorProto) mdp.Extension = append(mdp.Extension, fd) - g.field(extn, fd, internal.MessageExtensionsTag, extnIndex) + g.field(extn, fd, tags.Message_Extension, extnIndex) extnIndex++ } } @@ -286,14 +286,14 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if ty.IsEnum() { edp := new(descriptorpb.EnumDescriptorProto) mdp.EnumType = append(mdp.EnumType, edp) - g.enum(ty, edp, internal.MessageEnumsTag, enumIndex) + g.enum(ty, edp, tags.Message_EnumType, enumIndex) enumIndex++ continue } nested := new(descriptorpb.DescriptorProto) mdp.NestedType = append(mdp.NestedType, nested) - g.message(ty, nested, internal.MessageNestedMessagesTag, nestedMsgIndex) + g.message(ty, nested, tags.Message_NestedType, nestedMsgIndex) nestedMsgIndex++ } @@ -307,7 +307,7 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc addSourceLocationWithSourcePathElements( extensions.DeclAST().Span(), - []int32{internal.MessageExtensionRangesTag}, + []int32{tags.Message_ExtensionRange}, true, ) @@ -316,9 +316,9 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if !ty.IsMapEntry() { g.rangeSourceCodeInfo( extensions.AST(), - internal.MessageExtensionRangesTag, - internal.ExtensionRangeStartTag, - internal.ExtensionRangeEndTag, + tags.Message_ExtensionRange, + tags.Message_ExtensionRange_Start, + tags.Message_ExtensionRange_End, int32(i), ) } @@ -326,12 +326,12 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if options := extensions.Options(); !iterx.Empty(options.Fields()) { addSourceLocationWithSourcePathElements( extensions.DeclAST().Options().Span(), - []int32{internal.ExtensionRangeOptionsTag}, + []int32{tags.Message_ExtensionRange_Options}, false, ) er.Options = new(descriptorpb.ExtensionRangeOptions) - g.options(options, er.Options, internal.ExtensionRangeOptionsTag) + g.options(options, er.Options, tags.Message_ExtensionRange_Options) } } @@ -340,7 +340,7 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if !topLevelSourceLocation { addSourceLocationWithSourcePathElements( reserved.DeclAST().Span(), - []int32{internal.MessageReservedRangesTag}, + []int32{tags.Message_ReservedRange}, true, ) topLevelSourceLocation = true @@ -358,9 +358,9 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if !ty.IsMapEntry() { g.rangeSourceCodeInfo( reserved.AST(), - internal.MessageReservedRangesTag, - internal.ReservedRangeStartTag, - internal.ReservedRangeEndTag, + tags.Message_ReservedRange, + tags.Message_ReservedRange_Start, + tags.Message_ReservedRange_End, int32(i), ) } @@ -371,7 +371,7 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if !topLevelSourceLocation { addSourceLocationWithSourcePathElements( name.DeclAST().Span(), - []int32{internal.MessageReservedNamesTag}, + []int32{tags.Message_ReservedName}, true, ) topLevelSourceLocation = true @@ -380,7 +380,7 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc mdp.ReservedName = append(mdp.ReservedName, name.Name()) addSourceLocationWithSourcePathElements( name.AST().Span(), - []int32{internal.MessageReservedNamesTag, int32(i)}, + []int32{tags.Message_ReservedName, int32(i)}, false, ) } @@ -388,7 +388,7 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc for i, oneof := range seq.All(ty.Oneofs()) { odp := new(descriptorpb.OneofDescriptorProto) mdp.OneofDecl = append(mdp.OneofDecl, odp) - g.oneof(oneof, odp, internal.MessageOneofsTag, int32(i)) + g.oneof(oneof, odp, tags.Message_OneofDecl, int32(i)) } if g.currentFile.Syntax() == syntax.Proto3 { @@ -410,11 +410,11 @@ func (g *generator) message(ty ir.Type, mdp *descriptorpb.DescriptorProto, sourc if options := ty.Options(); !iterx.Empty(options.Fields()) { for option := range messageAST.Body.Options() { - addSourceLocationWithSourcePathElements(option.Span(), []int32{internal.MessageOptionsTag}, false) + addSourceLocationWithSourcePathElements(option.Span(), []int32{tags.Message_Options}, false) } mdp.Options = new(descriptorpb.MessageOptions) - g.options(options, mdp.Options, internal.MessageOptionsTag) + g.options(options, mdp.Options, tags.Message_Options) } switch exported, explicit := ty.IsExported(); { @@ -462,10 +462,10 @@ func (g *generator) field(f ir.Member, fdp *descriptorpb.FieldDescriptorProto, s } fdp.Name = addr(f.Name()) - addSourceLocationWithSourcePathElements(fieldAST.Name.Span(), []int32{internal.FieldNameTag}, false) + addSourceLocationWithSourcePathElements(fieldAST.Name.Span(), []int32{tags.Field_Name}, false) fdp.Number = addr(f.Number()) - addSourceLocationWithSourcePathElements(fieldAST.Tag.Span(), []int32{internal.FieldNumberTag}, false) + addSourceLocationWithSourcePathElements(fieldAST.Tag.Span(), []int32{tags.Field_Number}, false) switch f.Presence() { case presence.Explicit, presence.Implicit, presence.Shared: @@ -482,16 +482,16 @@ func (g *generator) field(f ir.Member, fdp *descriptorpb.FieldDescriptorProto, s for prefix := range fieldAST.Type.Prefixes() { addSourceLocationWithSourcePathElements( prefix.PrefixToken().Span(), - []int32{internal.FieldLabelTag}, + []int32{tags.Field_Label}, false, ) } - fieldTypeSourcePathElement := internal.FieldTypeNameTag + fieldTypeSourcePathElement := tags.Field_TypeName if ty := f.Element(); !ty.IsZero() { if kind := ty.Predeclared().FDPType(); kind != 0 { fdp.Type = kind.Enum() - fieldTypeSourcePathElement = internal.FieldTypeTag + fieldTypeSourcePathElement = tags.Field_Type } else { fdp.TypeName = addr(string(ty.FullName().ToAbsolute())) switch { @@ -514,7 +514,7 @@ func (g *generator) field(f ir.Member, fdp *descriptorpb.FieldDescriptorProto, s fdp.Extendee = addr(string(f.Container().FullName().ToAbsolute())) addSourceLocationWithSourcePathElements( f.Extend().AST().Name().Span(), - []int32{internal.FieldExtendeeTag}, + []int32{tags.Field_Extendee}, false, ) } @@ -526,12 +526,12 @@ func (g *generator) field(f ir.Member, fdp *descriptorpb.FieldDescriptorProto, s if options := f.Options(); !iterx.Empty(options.Fields()) { addSourceLocationWithSourcePathElements( fieldAST.Options.Span(), - []int32{internal.FieldOptionsTag}, + []int32{tags.Field_Options}, false, ) fdp.Options = new(descriptorpb.FieldOptions) - g.options(options, fdp.Options, internal.FieldOptionsTag) + g.options(options, fdp.Options, tags.Field_Options) } // If this field is part of a map entry type, we need to grab all the explicitly set @@ -596,19 +596,19 @@ func (g *generator) oneof(o ir.Oneof, odp *descriptorpb.OneofDescriptorProto, so g.addSourceLocation(oneofAST.Span(), true) odp.Name = addr(o.Name()) - reset := g.path.with(internal.OneofNameTag) + reset := g.path.with(tags.Oneof_Name) g.addSourceLocation(oneofAST.Name.Span(), false) reset() if options := o.Options(); !iterx.Empty(options.Fields()) { for option := range oneofAST.Body.Options() { - reset := g.path.with(internal.OneofOptionsTag) + reset := g.path.with(tags.Oneof_Options) g.addSourceLocation(option.Span(), false) reset() } odp.Options = new(descriptorpb.OneofOptions) - g.options(options, odp.Options, internal.OneofOptionsTag) + g.options(options, odp.Options, tags.Oneof_Options) } } @@ -620,20 +620,20 @@ func (g *generator) enum(ty ir.Type, edp *descriptorpb.EnumDescriptorProto, sour g.addSourceLocation(enumAST.Span(), true) edp.Name = addr(ty.Name()) - reset := g.path.with(internal.EnumNameTag) + reset := g.path.with(tags.Enum_Name) g.addSourceLocation(enumAST.Name.Span(), false) reset() for i, enumValue := range seq.All(ty.Members()) { evd := new(descriptorpb.EnumValueDescriptorProto) edp.Value = append(edp.Value, evd) - g.enumValue(enumValue, evd, internal.EnumValuesTag, int32(i)) + g.enumValue(enumValue, evd, tags.Enum_Value, int32(i)) } var topLevelSourceLocation bool for i, reserved := range seq.All(ty.ReservedRanges()) { if !topLevelSourceLocation { - reset := g.path.with(internal.EnumReservedRangesTag) + reset := g.path.with(tags.Enum_ReservedRange) g.addSourceLocation(reserved.DeclAST().Span(), true) reset() topLevelSourceLocation = true @@ -648,9 +648,9 @@ func (g *generator) enum(ty ir.Type, edp *descriptorpb.EnumDescriptorProto, sour g.rangeSourceCodeInfo( reserved.AST(), - internal.EnumReservedRangesTag, - internal.ReservedRangeStartTag, - internal.ReservedRangeEndTag, + tags.Enum_ReservedRange, + tags.Enum_ReservedRange_Start, + tags.Enum_ReservedRange_End, int32(i), ) } @@ -658,27 +658,27 @@ func (g *generator) enum(ty ir.Type, edp *descriptorpb.EnumDescriptorProto, sour topLevelSourceLocation = false for i, name := range seq.All(ty.ReservedNames()) { if !topLevelSourceLocation { - reset := g.path.with(internal.EnumReservedNamesTag) + reset := g.path.with(tags.Enum_ReservedName) g.addSourceLocation(name.DeclAST().Span(), true) reset() topLevelSourceLocation = true } edp.ReservedName = append(edp.ReservedName, name.Name()) - reset := g.path.with(internal.EnumReservedNamesTag, int32(i)) + reset := g.path.with(tags.Enum_ReservedName, int32(i)) g.addSourceLocation(name.AST().Span(), false) reset() } if options := ty.Options(); !iterx.Empty(options.Fields()) { for option := range enumAST.Body.Options() { - reset := g.path.with(internal.EnumOptionsTag) + reset := g.path.with(tags.Enum_Options) g.addSourceLocation(option.Span(), false) reset() } edp.Options = new(descriptorpb.EnumOptions) - g.options(options, edp.Options, internal.EnumOptionsTag) + g.options(options, edp.Options, tags.Enum_Options) } switch exported, explicit := ty.IsExported(); { @@ -700,22 +700,22 @@ func (g *generator) enumValue(f ir.Member, evdp *descriptorpb.EnumValueDescripto g.addSourceLocation(enumValueAST.Span(), true) evdp.Name = addr(f.Name()) - reset := g.path.with(internal.EnumValNameTag) + reset := g.path.with(tags.EnumValue_Name) g.addSourceLocation(enumValueAST.Name.Span(), false) reset() evdp.Number = addr(f.Number()) - reset = g.path.with(internal.EnumValNumberTag) + reset = g.path.with(tags.EnumValue_Number) g.addSourceLocation(enumValueAST.Tag.Span(), false) reset() if options := f.Options(); !iterx.Empty(options.Fields()) { - reset := g.path.with(internal.EnumValOptionsTag) + reset := g.path.with(tags.EnumValue_Options) g.addSourceLocation(enumValueAST.Options.Span(), false) reset() evdp.Options = new(descriptorpb.EnumValueOptions) - g.options(options, evdp.Options, internal.EnumValOptionsTag) + g.options(options, evdp.Options, tags.EnumValue_Options) } } @@ -727,24 +727,24 @@ func (g *generator) service(s ir.Service, sdp *descriptorpb.ServiceDescriptorPro g.addSourceLocation(serviceAST.Span(), true) sdp.Name = addr(s.Name()) - reset := g.path.with(internal.ServiceNameTag) + reset := g.path.with(tags.Service_Name) g.addSourceLocation(serviceAST.Name.Span(), false) reset() for i, method := range seq.All(s.Methods()) { mdp := new(descriptorpb.MethodDescriptorProto) sdp.Method = append(sdp.Method, mdp) - g.method(method, mdp, internal.ServiceMethodsTag, int32(i)) + g.method(method, mdp, tags.Service_Method, int32(i)) } if options := s.Options(); !iterx.Empty(options.Fields()) { sdp.Options = new(descriptorpb.ServiceOptions) for option := range serviceAST.Body.Options() { - reset := g.path.with(internal.ServiceOptionsTag) + reset := g.path.with(tags.Service_Options) g.addSourceLocation(option.Span(), false) reset() } - g.options(options, sdp.Options, internal.ServiceOptionsTag) + g.options(options, sdp.Options, tags.Service_Options) } } @@ -756,7 +756,7 @@ func (g *generator) method(m ir.Method, mdp *descriptorpb.MethodDescriptorProto, g.addSourceLocation(methodAST.Span(), true) mdp.Name = addr(m.Name()) - reset := g.path.with(internal.MethodNameTag) + reset := g.path.with(tags.Method_Name) g.addSourceLocation(methodAST.Name.Span(), false) reset() @@ -769,11 +769,11 @@ func (g *generator) method(m ir.Method, mdp *descriptorpb.MethodDescriptorProto, // Methods only have a single input, see [descriptorpb.MethodDescriptorProto]. inputAST := methodAST.Signature.Inputs().At(0) if prefixed := inputAST.AsPrefixed(); !prefixed.IsZero() { - reset := g.path.with(internal.MethodInputStreamTag) + reset := g.path.with(tags.Method_ClientStreaming) g.addSourceLocation(prefixed.PrefixToken().Span(), false) reset() } - reset = g.path.with(internal.MethodInputTag) + reset = g.path.with(tags.Method_InputType) g.addSourceLocation(inputAST.RemovePrefixes().Span(), false) reset() @@ -786,11 +786,11 @@ func (g *generator) method(m ir.Method, mdp *descriptorpb.MethodDescriptorProto, // Methods only have a single output, see [descriptorpb.MethodDescriptorProto]. outputAST := methodAST.Signature.Outputs().At(0) if prefixed := outputAST.AsPrefixed(); !prefixed.IsZero() { - reset := g.path.with(internal.MethodOutputStreamTag) + reset := g.path.with(tags.Method_ServerStreaming) g.addSourceLocation(prefixed.PrefixToken().Span(), false) reset() } - reset = g.path.with(internal.MethodOutputTag) + reset = g.path.with(tags.Method_OutputType) g.addSourceLocation(outputAST.RemovePrefixes().Span(), false) reset() @@ -798,9 +798,9 @@ func (g *generator) method(m ir.Method, mdp *descriptorpb.MethodDescriptorProto, if options := m.Options(); !methodAST.Body.IsZero() { mdp.Options = new(descriptorpb.MethodOptions) for option := range methodAST.Body.Options() { - g.addSourceLocationWithSourcePathElements(option.Span(), []int32{internal.MethodOptionsTag}, false) + g.addSourceLocationWithSourcePathElements(option.Span(), []int32{tags.Method_Options}, false) } - g.options(options, mdp.Options, internal.MethodOptionsTag) + g.options(options, mdp.Options, tags.Method_Options) } } diff --git a/experimental/ir/ir_member.go b/experimental/ir/ir_member.go index a32cb181f..d2852b4f3 100644 --- a/experimental/ir/ir_member.go +++ b/experimental/ir/ir_member.go @@ -25,6 +25,7 @@ import ( "github.com/bufbuild/protocompile/experimental/seq" "github.com/bufbuild/protocompile/internal/arena" "github.com/bufbuild/protocompile/internal/intern" + "github.com/bufbuild/protocompile/internal/tags" ) //go:generate go run github.com/bufbuild/protocompile/internal/enum option_target.yaml @@ -121,7 +122,7 @@ func (m Member) IsPacked() bool { feature := m.FeatureSet().Lookup(builtins.FeaturePacked).Value() value, _ := feature.AsInt() - return value == 1 // google.protobuf.FeatureSet.PACKED + return value == tags.FeatureSet_RepeatedFieldEncoding_Packed } // IsUnicode returns whether this is a string-typed message field that must @@ -133,7 +134,7 @@ func (m Member) IsUnicode() bool { builtins := m.Context().builtins() utf8Feature, _ := m.FeatureSet().Lookup(builtins.FeatureUTF8).Value().AsInt() - return utf8Feature == 2 // FeatureSet.VERIFY + return utf8Feature == tags.FeatureSet_Utf8Validation_Verify } // AsTagRange wraps this member in a TagRange. @@ -172,9 +173,9 @@ func (m Member) TypeAST() ast.TypeAny { if !ty.MapField().IsZero() { k, v := ty.AST().Type().RemovePrefixes().AsGeneric().AsMap() switch m.Number() { - case 1: + case tags.MapEntry_Key: return k - case 2: + case tags.MapEntry_Value: return v } } diff --git a/experimental/ir/ir_type.go b/experimental/ir/ir_type.go index ada802e6c..556069035 100644 --- a/experimental/ir/ir_type.go +++ b/experimental/ir/ir_type.go @@ -17,7 +17,6 @@ package ir import ( "fmt" "iter" - "math" "github.com/bufbuild/protocompile/experimental/ast" "github.com/bufbuild/protocompile/experimental/ast/predeclared" @@ -30,6 +29,7 @@ import ( "github.com/bufbuild/protocompile/internal/ext/iterx" "github.com/bufbuild/protocompile/internal/intern" "github.com/bufbuild/protocompile/internal/interval" + "github.com/bufbuild/protocompile/internal/tags" ) // TagRange is a range of tag numbers in a [Type]. @@ -182,7 +182,7 @@ func (t Type) IsClosedEnum() bool { builtins := t.Context().builtins() n, _ := t.FeatureSet().Lookup(builtins.FeatureEnum).Value().AsInt() - return n == 2 // FeatureSet.CLOSED + return n == tags.FeatureSet_EnumType_Closed } // IsPackable returns whether this type can be the element of a packed repeated @@ -222,11 +222,13 @@ func (t Type) IsExported() (exported, explicit bool) { if key := t.Context().builtins().FeatureVisibility; !key.IsZero() { feature := t.FeatureSet().Lookup(key) switch v, _ := feature.Value().AsInt(); v { - case 0, 1: // DEFAULT_SYMBOL_VISIBILITY_UNKNOWN, EXPORT_ALL + case tags.FeatureSet_DefaultSymbolVisibility_Unknown, + tags.FeatureSet_DefaultSymbolVisibility_ExportAll: return true, false - case 2: // EXPORT_TOP_LEVEL + case tags.FeatureSet_DefaultSymbolVisibility_ExportTopLevel: return t.Parent().IsZero(), false - case 3, 4: // LOCAL_ALL, STRICT + case tags.FeatureSet_DefaultSymbolVisibility_LocalAll, + tags.FeatureSet_DefaultSymbolVisibility_Strict: return false, false } } @@ -529,11 +531,11 @@ func (t Type) AbsoluteRange() (start, end int32) { } switch { case t.IsEnum(): - return math.MinInt32, math.MaxInt32 + return tags.EnumMin, tags.EnumMax case t.IsMessageSet(): - return 1, messageSetNumberMax + return tags.MessageSetMin, tags.MessageSetMax default: - return 1, fieldNumberMax + return tags.FieldMin, tags.FieldMax } } diff --git a/experimental/ir/lower_deprecated.go b/experimental/ir/lower_deprecated.go index 9e945a29c..cde4265b1 100644 --- a/experimental/ir/lower_deprecated.go +++ b/experimental/ir/lower_deprecated.go @@ -16,7 +16,7 @@ package ir import ( "github.com/bufbuild/protocompile/experimental/report" - "github.com/bufbuild/protocompile/experimental/report/tags" + "github.com/bufbuild/protocompile/experimental/report/rtags" "github.com/bufbuild/protocompile/experimental/seq" "github.com/bufbuild/protocompile/experimental/source" ) @@ -129,6 +129,6 @@ func (e errDeprecated) Diagnose(d *report.Diagnostic) { report.Message("`%s` is deprecated", e.name), report.Snippet(e.ref), report.Snippetf(e.cause, "deprecated here"), - report.Tag(tags.Deprecated), + report.Tag(rtags.Deprecated), ) } diff --git a/experimental/ir/lower_eval.go b/experimental/ir/lower_eval.go index e3dac9ea1..de5ed8256 100644 --- a/experimental/ir/lower_eval.go +++ b/experimental/ir/lower_eval.go @@ -33,20 +33,10 @@ import ( "github.com/bufbuild/protocompile/internal/ext/iterx" "github.com/bufbuild/protocompile/internal/ext/slicesx" "github.com/bufbuild/protocompile/internal/ext/stringsx" + "github.com/bufbuild/protocompile/internal/tags" ) const ( - fieldNumberBits = 29 - fieldNumberMax = 1< hi { @@ -936,14 +926,14 @@ func (e *evaluator) checkIntBounds(args evalArgs, signed bool, bits int, neg boo } } - if bits == fieldNumberBits { + if bits == tags.FieldBits { if v == 0 { err() return 0, false } // Check that this is not one of the special reserved numbers. - if v >= firstReserved && v <= lastReserved { + if v >= tags.FirstReserved && v <= tags.LastReserved { err() return rawValueBits(v), false } @@ -997,11 +987,11 @@ func (e *evaluator) evalPath(args evalArgs, expr ast.Path, neg ast.ExprPrefixed) if ok { switch args.memberNumber { case enumNumber: - return enumNumberMax, ok + return tags.EnumMax, ok case fieldNumber: - return fieldNumberMax, ok + return tags.FieldMax, ok case messageSetNumber: - return messageSetNumberMax, ok + return tags.MessageSetMax, ok } } else { e.Errorf("`max` outside of range end").Apply( @@ -1278,8 +1268,8 @@ func (e errLiteralRange) Diagnose(d *report.Diagnostic) { hi = lo - 1 } else { hi = (uint64(1) << e.bits) - 1 - if e.bits == messageSetNumberBits { - hi = messageSetNumberMax + if e.bits == tags.MessageSetBits { + hi = tags.MessageSetMax } } @@ -1309,7 +1299,7 @@ func (e errLiteralRange) Diagnose(d *report.Diagnostic) { return prefix + strconv.FormatUint(v, base) } - if e.bits == fieldNumberBits { + if e.bits == tags.FieldBits { d.Apply( report.Message("%s out of range", taxa.FieldNumber), report.Snippet(e.expr), @@ -1318,8 +1308,8 @@ func (e errLiteralRange) Diagnose(d *report.Diagnostic) { taxa.FieldNumber, itoa(1), itoa(hi), - itoa(uint64(firstReserved)), - itoa(uint64(lastReserved))), + itoa(tags.FirstReserved), + itoa(tags.LastReserved)), ) } else { d.Apply( diff --git a/experimental/ir/lower_json.go b/experimental/ir/lower_json.go index cefcb048c..96e631577 100644 --- a/experimental/ir/lower_json.go +++ b/experimental/ir/lower_json.go @@ -23,6 +23,7 @@ import ( "github.com/bufbuild/protocompile/internal" "github.com/bufbuild/protocompile/internal/cases" "github.com/bufbuild/protocompile/internal/intern" + "github.com/bufbuild/protocompile/internal/tags" ) func populateJSONNames(file *File, r *report.Report) { @@ -33,7 +34,7 @@ func populateJSONNames(file *File, r *report.Report) { clear(names) jsonFormat, _ := ty.FeatureSet().Lookup(builtins.FeatureJSON).Value().AsInt() - strict := jsonFormat == 1 + strict := jsonFormat == tags.FeatureSet_JsonFormat_Allow // First, populate the default names, and check for collisions among // them. diff --git a/experimental/ir/lower_maps.go b/experimental/ir/lower_maps.go index e7e3c9ae6..761dea99f 100644 --- a/experimental/ir/lower_maps.go +++ b/experimental/ir/lower_maps.go @@ -23,6 +23,7 @@ import ( "github.com/bufbuild/protocompile/experimental/report" "github.com/bufbuild/protocompile/experimental/seq" pcinternal "github.com/bufbuild/protocompile/internal" + "github.com/bufbuild/protocompile/internal/tags" ) // generateMapEntries generates map entry types for all map-typed fields. @@ -100,8 +101,8 @@ func generateMapEntries(file *File, r *report.Report) { ty.Raw().extnsStart++ } - makeField("key", 1) - makeField("value", 2) + makeField("key", tags.MapEntry_Key) + makeField("value", tags.MapEntry_Value) // Update the field to be a repeated field of the given type. field.Raw().elem = ty.toRef(file) diff --git a/experimental/ir/lower_resolve.go b/experimental/ir/lower_resolve.go index 4c90d6fac..998258bd4 100644 --- a/experimental/ir/lower_resolve.go +++ b/experimental/ir/lower_resolve.go @@ -24,12 +24,13 @@ import ( "github.com/bufbuild/protocompile/experimental/internal/taxa" "github.com/bufbuild/protocompile/experimental/ir/presence" "github.com/bufbuild/protocompile/experimental/report" - "github.com/bufbuild/protocompile/experimental/report/tags" + "github.com/bufbuild/protocompile/experimental/report/rtags" "github.com/bufbuild/protocompile/experimental/seq" "github.com/bufbuild/protocompile/experimental/source" "github.com/bufbuild/protocompile/experimental/token" "github.com/bufbuild/protocompile/experimental/token/keyword" "github.com/bufbuild/protocompile/internal/ext/iterx" + "github.com/bufbuild/protocompile/internal/tags" ) // resolveNames resolves all of the names that need resolving in a file. @@ -149,7 +150,7 @@ func resolveFieldType(field Member, r *report.Report) { ) } - if !field.Container().MapField().IsZero() && field.Number() == 1 { + if !field.Container().MapField().IsZero() && field.Number() == tags.MapEntry_Key { // Legalize that the key type must be comparable. ty := sym.AsType() if !ty.Predeclared().IsMapKey() { @@ -320,7 +321,7 @@ func (r symbolRef) resolve() Symbol { func (r symbolRef) diagnoseLookup(sym Symbol, expectedName FullName) *report.Diagnostic { if sym.IsZero() { return r.Errorf("cannot find `%s` in this scope", r.name).Apply( - report.Tag(tags.UnknownSymbol), + report.Tag(rtags.UnknownSymbol), report.Snippetf(r.span, "not found in this scope"), report.Helpf("the full name of this scope is `%s`", r.scope), ) @@ -337,7 +338,7 @@ func (r symbolRef) diagnoseLookup(sym Symbol, expectedName FullName) *report.Dia case expectedName != "": // Complain if we found the "wrong" type. return r.Errorf("cannot find `%s` in this scope", r.name).Apply( - report.Tag(tags.UnknownSymbol), + report.Tag(rtags.UnknownSymbol), report.Snippetf(r.span, "not found in this scope"), report.Snippetf(sym.Definition(), "found possibly related symbol `%s`", sym.FullName()), diff --git a/experimental/ir/lower_validate.go b/experimental/ir/lower_validate.go index 38b4aa06b..f16807c8e 100644 --- a/experimental/ir/lower_validate.go +++ b/experimental/ir/lower_validate.go @@ -31,7 +31,7 @@ import ( "github.com/bufbuild/protocompile/experimental/internal/taxa" "github.com/bufbuild/protocompile/experimental/ir/presence" "github.com/bufbuild/protocompile/experimental/report" - "github.com/bufbuild/protocompile/experimental/report/tags" + "github.com/bufbuild/protocompile/experimental/report/rtags" "github.com/bufbuild/protocompile/experimental/seq" "github.com/bufbuild/protocompile/experimental/source" "github.com/bufbuild/protocompile/experimental/token" @@ -41,6 +41,7 @@ import ( "github.com/bufbuild/protocompile/internal/ext/mapsx" "github.com/bufbuild/protocompile/internal/ext/slicesx" "github.com/bufbuild/protocompile/internal/intern" + "github.com/bufbuild/protocompile/internal/tags" ) var asciiIdent = regexp.MustCompile(`^[a-zA-Z_][0-9a-zA-Z_]*$`) @@ -58,7 +59,7 @@ func diagnoseUnusedImports(f *File, r *report.Report) { Start: 0, End: imp.Decl.Span().Len(), }), report.Helpf("no symbols from this file are referenced"), - report.Tag(tags.UnusedImport), + report.Tag(rtags.UnusedImport), ) } } @@ -220,10 +221,10 @@ func validateFileOptions(f *File, r *report.Report) { } optimize := f.Options().Field(builtins.OptimizeFor) - if v, _ := optimize.AsInt(); v != 3 { // google.protobuf.FileOptions.LITE_RUNTIME + if v, _ := optimize.AsInt(); v != tags.FileOptions_OptimizeMode_LiteRuntime { for imp := range seq.Values(f.Imports()) { impOptimize := imp.Options().Field(builtins.OptimizeFor) - if v, _ := impOptimize.AsInt(); v == 3 { // google.protobuf.FileOptions.LITE_RUNTIME + if v, _ := impOptimize.AsInt(); v == tags.FileOptions_OptimizeMode_LiteRuntime { r.Errorf("`LITE_RUNTIME` file imported in non-`LITE_RUNTIME` file").Apply( report.Snippet(imp.Decl.ImportPath()), report.Snippetf(optimize.ValueAST(), "optimization level set here"), @@ -236,7 +237,7 @@ func validateFileOptions(f *File, r *report.Report) { } defaultPresence := f.FeatureSet().Lookup(builtins.FeaturePresence).Value() - if v, _ := defaultPresence.AsInt(); v == 3 { // google.protobuf.FeatureSet.LEGACY_REQUIRED + if v, _ := defaultPresence.AsInt(); v == tags.FeatureSet_FieldPresence_LegacyRequired { r.Errorf("cannot set `LEGACY_REQUIRED` at the file level").Apply( report.Snippet(defaultPresence.ValueAST()), ) @@ -738,8 +739,8 @@ func validatePresence(m Member, r *report.Report) { } switch v, _ := feature.Value().AsInt(); v { - case 1: // EXPLICIT - case 2: // IMPLICIT + case tags.FeatureSet_FieldPresence_Explicit: + case tags.FeatureSet_FieldPresence_Implicit: if m.Element().IsMessage() { r.Error(errTypeConstraint{ want: taxa.MessageType, @@ -754,7 +755,7 @@ func validatePresence(m Member, r *report.Report) { report.Helpf("all message-typed fields explicit presence"), ) } - case 3: // LEGACY_REQUIRED + case tags.FeatureSet_FieldPresence_LegacyRequired: r.Warnf("required fields are deprecated").Apply( report.Snippet(feature.Value().ValueAST()), report.Helpf( @@ -851,7 +852,7 @@ func validateLazy(m Member, r *report.Report) { group := m.FeatureSet().Lookup(builtins.FeatureGroup) groupValue, _ := group.Value().AsInt() - if groupValue == 2 { // FeatureSet.DELIMITED + if groupValue == tags.FeatureSet_MessageEncoding_Delimited { d := r.SoftErrorf(set, "expected length-prefixed field").Apply( report.Snippet(m.AST()), report.Snippetf(lazy.KeyAST(), "`%s` set here", lazy.Field().Name()), @@ -904,11 +905,11 @@ func validateCType(m Member, r *report.Report) { var want string switch ctypeValue { - case 0: // FieldOptions.STRING + case tags.FieldOptions_CType_String: want = "STRING" - case 1: // FieldOptions.CORD + case tags.FieldOptions_CType_Cord: want = "CORD" - case 2: // FieldOptions.STRING_PIECE + case tags.FieldOptions_CType_StringPiece: want = "VIEW" } @@ -941,7 +942,7 @@ func validateCType(m Member, r *report.Report) { d.Apply(report.Helpf("this becomes a hard error in %s", syntax.Edition2023.Name())) } - case m.IsExtension() && ctypeValue == 1: // google.protobuf.FieldOptions.CORD + case m.IsExtension() && ctypeValue == tags.FieldOptions_CType_Cord: d := r.SoftErrorf(is2023, "cannot use `CORD` on an extension field").Apply( report.Snippet(m.AST()), report.Snippetf(ctype.ValueAST(), "`CORD` set here"), @@ -1094,14 +1095,16 @@ func validateVisibility(ty Type, r *report.Report) { } feature := ty.FeatureSet().Lookup(key) value, _ := feature.Value().AsInt() - strict := value == 4 // STRICT + strict := value == tags.FeatureSet_DefaultSymbolVisibility_Strict var impliedExport bool switch value { - case 0, 1: // DEFAULT_SYMBOL_VISIBILITY_UNKNOWN, EXPORT_ALL + case tags.FeatureSet_DefaultSymbolVisibility_Unknown, + tags.FeatureSet_DefaultSymbolVisibility_ExportAll: impliedExport = true - case 2: // EXPORT_TOP_LEVEL + case tags.FeatureSet_DefaultSymbolVisibility_ExportTopLevel: impliedExport = ty.Parent().IsZero() - case 3, 4: // LOCAL_ALL, STRICT + case tags.FeatureSet_DefaultSymbolVisibility_LocalAll, + tags.FeatureSet_DefaultSymbolVisibility_Strict: impliedExport = false } @@ -1239,7 +1242,7 @@ func validateNamingStyle(f *File, r *report.Report) { isStyle2024 := func(featureSet FeatureSet) bool { feature := featureSet.Lookup(key) value, _ := feature.Value().AsInt() - return value == 1 // STYLE2024 + return value == tags.FeatureSet_EnforceNamingStyle_2024 } // Validate package name (file-level scope). diff --git a/experimental/report/tags/tags.go b/experimental/report/rtags/rtags.go similarity index 98% rename from experimental/report/tags/tags.go rename to experimental/report/rtags/rtags.go index 1bc8ec9bc..cdb9769a2 100644 --- a/experimental/report/tags/tags.go +++ b/experimental/report/rtags/rtags.go @@ -13,7 +13,7 @@ // limitations under the License. // Package tags defines publicly-exposed diagnostic tag constants for use with [report.Tag]. -package tags +package rtags import _ "github.com/bufbuild/protocompile/experimental/report" // Imported for package documentation. diff --git a/internal/ext/stringsx/stringsx.go b/internal/ext/stringsx/stringsx.go index e709b4659..257bf80f1 100644 --- a/internal/ext/stringsx/stringsx.go +++ b/internal/ext/stringsx/stringsx.go @@ -142,6 +142,21 @@ func CutLast(s, sep string) (before, after string, found bool) { return "", s, false } +// CutOverlap finds the largest string that is both a suffix of a and a prefix +// of b, and returns it and the pieces around it. +// +// This function's runtime is O(len(a)*len(b)). +func CutOverlap(a, b string) (before, middle, after string) { + n := 0 + for i := 0; i <= min(len(a), len(b)); i++ { + if a[len(a)-i:] == b[:i] { + n = i + } + } + + return a[:len(a)-n], a[len(a)-n:], b[n:] +} + // PartitionKey returns an iterator of the largest substrings of s such that // key(r) for each rune in each substring is the same value. // diff --git a/internal/tags.go b/internal/tags.go deleted file mode 100644 index 48a56f555..000000000 --- a/internal/tags.go +++ /dev/null @@ -1,339 +0,0 @@ -// Copyright 2020-2025 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 - // FileOptionDependencyTag is the tag number of the option dependency element - // in a file descriptor proto. - FileOptionDependencyTag = 15 - // 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/internal/tags/gen/main.go b/internal/tags/gen/main.go new file mode 100644 index 000000000..292c27e42 --- /dev/null +++ b/internal/tags/gen/main.go @@ -0,0 +1,148 @@ +// Copyright 2020-2025 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 main + +import ( + "bytes" + "errors" + "fmt" + "go/format" + "iter" + "os" + "runtime/debug" + "strings" + + "github.com/bufbuild/protocompile/internal/cases" + "github.com/bufbuild/protocompile/internal/ext/flagx" + "github.com/bufbuild/protocompile/internal/ext/stringsx" + "github.com/bufbuild/protocompile/wellknownimports" + "google.golang.org/protobuf/reflect/protoreflect" +) + +// convertPath converts a fully-qualified Protobuf path from descriptor.proto +// into a nice variable name. +func convertPath(name protoreflect.FullName) string { + path := string(name) + path = strings.TrimPrefix(path, "google.protobuf.") + + buf := new(strings.Builder) + prev := "" + for c := range strings.SplitSeq(path, ".") { + if c == "VisibilityFeature" { + continue + } + + if c == "DescriptorProto" { + c = "Message" + } + c, _ = strings.CutSuffix(c, "DescriptorProto") + c = cases.Pascal.Convert(c) + if _, _, c2 := stringsx.CutOverlap(prev, c); c2 != "" { + c = c2 + } + + if buf.Len() > 0 { + buf.WriteByte('_') + } + buf.WriteString(c) + prev = c + } + + return buf.String() +} + +func walk[D protoreflect.Descriptor](d protoreflect.FileDescriptor) iter.Seq[D] { + return func(y func(D) bool) { + yield := func(d protoreflect.Descriptor) bool { + v, ok := d.(D) + return !ok || y(v) + } + + var rec func(protoreflect.Descriptor) bool + rec = func(d protoreflect.Descriptor) bool { + switch d := d.(type) { + case protoreflect.FileDescriptor: + return yield(d) && each(d.Enums(), rec) && each(d.Messages(), rec) + case protoreflect.MessageDescriptor: + return yield(d) && each(d.Enums(), rec) && + each(d.Fields(), yield) && + each(d.Messages(), rec) + case protoreflect.EnumDescriptor: + return yield(d) && each(d.Values(), rec) + default: + return yield(d) + } + } + + rec(d) + } +} + +func each[T protoreflect.Descriptor, L interface { + Len() int + Get(int) T +}](l L, yield func(protoreflect.Descriptor) bool) bool { + for i := range l.Len() { + if !yield(l.Get(i)) { + return false + } + } + return true +} + +func main() { + flagx.Main(func() error { + files := wellknownimports.Files() + descpb, _ := files.FindFileByPath("google/protobuf/descriptor.proto") + anypb, _ := files.FindFileByPath("google/protobuf/any.proto") + + info, ok := debug.ReadBuildInfo() + if !ok { + return errors.New("debug: could not read build info") + } + + out := new(bytes.Buffer) + fmt.Fprintf(out, "// Code generated by %s. DO NOT EDIT.\n\n", info.Path) + fmt.Fprintf(out, "package %s\n\n", os.Getenv("GOPACKAGE")) + + fmt.Fprintf(out, "const (\n") + for field := range walk[protoreflect.FieldDescriptor](descpb) { + fmt.Fprintf(out, "// Field number for %v.\n", field.FullName()) + fmt.Fprintf(out, "\t%s = %v\n\n", convertPath(field.FullName()), field.Number()) + } + for field := range walk[protoreflect.FieldDescriptor](anypb) { + fmt.Fprintf(out, "// Field number for %v.\n", field.FullName()) + fmt.Fprintf(out, "\t%s = %v\n\n", convertPath(field.FullName()), field.Number()) + } + fmt.Fprintf(out, ")\n\n") + + fmt.Fprintf(out, "const (\n") + for value := range walk[protoreflect.EnumValueDescriptor](descpb) { + fmt.Fprintf(out, "// Enum value for %v.\n", value.FullName()) + + // Use nice, enum-relative names. + name := value.Parent().FullName() + "." + protoreflect.FullName(value.Name()) + fmt.Fprintf(out, "\t%s = %v\n\n", convertPath(name), value.Number()) + } + fmt.Fprintf(out, ")\n\n") + + src, err := format.Source(out.Bytes()) + if err != nil { + return err + } + + return os.WriteFile("generated.go", src, 0666) //nolint:gosec + }) +} diff --git a/internal/tags/generated.go b/internal/tags/generated.go new file mode 100644 index 000000000..c98f90b81 --- /dev/null +++ b/internal/tags/generated.go @@ -0,0 +1,834 @@ +// Copyright 2020-2025 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. + +// Code generated by github.com/bufbuild/protocompile/internal/tags/gen. DO NOT EDIT. + +package tags + +const ( + // Field number for google.protobuf.FileDescriptorSet.file. + FileDescriptorSet_File = 1 + + // Field number for google.protobuf.FileDescriptorProto.name. + File_Name = 1 + + // Field number for google.protobuf.FileDescriptorProto.package. + File_Package = 2 + + // Field number for google.protobuf.FileDescriptorProto.dependency. + File_Dependency = 3 + + // Field number for google.protobuf.FileDescriptorProto.public_dependency. + File_PublicDependency = 10 + + // Field number for google.protobuf.FileDescriptorProto.weak_dependency. + File_WeakDependency = 11 + + // Field number for google.protobuf.FileDescriptorProto.option_dependency. + File_OptionDependency = 15 + + // Field number for google.protobuf.FileDescriptorProto.message_type. + File_MessageType = 4 + + // Field number for google.protobuf.FileDescriptorProto.enum_type. + File_EnumType = 5 + + // Field number for google.protobuf.FileDescriptorProto.service. + File_Service = 6 + + // Field number for google.protobuf.FileDescriptorProto.extension. + File_Extension = 7 + + // Field number for google.protobuf.FileDescriptorProto.options. + File_Options = 8 + + // Field number for google.protobuf.FileDescriptorProto.source_code_info. + File_SourceCodeInfo = 9 + + // Field number for google.protobuf.FileDescriptorProto.syntax. + File_Syntax = 12 + + // Field number for google.protobuf.FileDescriptorProto.edition. + File_Edition = 14 + + // Field number for google.protobuf.DescriptorProto.name. + Message_Name = 1 + + // Field number for google.protobuf.DescriptorProto.field. + Message_Field = 2 + + // Field number for google.protobuf.DescriptorProto.extension. + Message_Extension = 6 + + // Field number for google.protobuf.DescriptorProto.nested_type. + Message_NestedType = 3 + + // Field number for google.protobuf.DescriptorProto.enum_type. + Message_EnumType = 4 + + // Field number for google.protobuf.DescriptorProto.extension_range. + Message_ExtensionRange = 5 + + // Field number for google.protobuf.DescriptorProto.oneof_decl. + Message_OneofDecl = 8 + + // Field number for google.protobuf.DescriptorProto.options. + Message_Options = 7 + + // Field number for google.protobuf.DescriptorProto.reserved_range. + Message_ReservedRange = 9 + + // Field number for google.protobuf.DescriptorProto.reserved_name. + Message_ReservedName = 10 + + // Field number for google.protobuf.DescriptorProto.visibility. + Message_Visibility = 11 + + // Field number for google.protobuf.DescriptorProto.ExtensionRange.start. + Message_ExtensionRange_Start = 1 + + // Field number for google.protobuf.DescriptorProto.ExtensionRange.end. + Message_ExtensionRange_End = 2 + + // Field number for google.protobuf.DescriptorProto.ExtensionRange.options. + Message_ExtensionRange_Options = 3 + + // Field number for google.protobuf.DescriptorProto.ReservedRange.start. + Message_ReservedRange_Start = 1 + + // Field number for google.protobuf.DescriptorProto.ReservedRange.end. + Message_ReservedRange_End = 2 + + // Field number for google.protobuf.ExtensionRangeOptions.uninterpreted_option. + ExtensionRangeOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.ExtensionRangeOptions.declaration. + ExtensionRangeOptions_Declaration = 2 + + // Field number for google.protobuf.ExtensionRangeOptions.features. + ExtensionRangeOptions_Features = 50 + + // Field number for google.protobuf.ExtensionRangeOptions.verification. + ExtensionRangeOptions_Verification = 3 + + // Field number for google.protobuf.ExtensionRangeOptions.Declaration.number. + ExtensionRangeOptions_Declaration_Number = 1 + + // Field number for google.protobuf.ExtensionRangeOptions.Declaration.full_name. + ExtensionRangeOptions_Declaration_FullName = 2 + + // Field number for google.protobuf.ExtensionRangeOptions.Declaration.type. + ExtensionRangeOptions_Declaration_Type = 3 + + // Field number for google.protobuf.ExtensionRangeOptions.Declaration.reserved. + ExtensionRangeOptions_Declaration_Reserved = 5 + + // Field number for google.protobuf.ExtensionRangeOptions.Declaration.repeated. + ExtensionRangeOptions_Declaration_Repeated = 6 + + // Field number for google.protobuf.FieldDescriptorProto.name. + Field_Name = 1 + + // Field number for google.protobuf.FieldDescriptorProto.number. + Field_Number = 3 + + // Field number for google.protobuf.FieldDescriptorProto.label. + Field_Label = 4 + + // Field number for google.protobuf.FieldDescriptorProto.type. + Field_Type = 5 + + // Field number for google.protobuf.FieldDescriptorProto.type_name. + Field_TypeName = 6 + + // Field number for google.protobuf.FieldDescriptorProto.extendee. + Field_Extendee = 2 + + // Field number for google.protobuf.FieldDescriptorProto.default_value. + Field_DefaultValue = 7 + + // Field number for google.protobuf.FieldDescriptorProto.oneof_index. + Field_OneofIndex = 9 + + // Field number for google.protobuf.FieldDescriptorProto.json_name. + Field_JsonName = 10 + + // Field number for google.protobuf.FieldDescriptorProto.options. + Field_Options = 8 + + // Field number for google.protobuf.FieldDescriptorProto.proto3_optional. + Field_Proto3Optional = 17 + + // Field number for google.protobuf.OneofDescriptorProto.name. + Oneof_Name = 1 + + // Field number for google.protobuf.OneofDescriptorProto.options. + Oneof_Options = 2 + + // Field number for google.protobuf.EnumDescriptorProto.name. + Enum_Name = 1 + + // Field number for google.protobuf.EnumDescriptorProto.value. + Enum_Value = 2 + + // Field number for google.protobuf.EnumDescriptorProto.options. + Enum_Options = 3 + + // Field number for google.protobuf.EnumDescriptorProto.reserved_range. + Enum_ReservedRange = 4 + + // Field number for google.protobuf.EnumDescriptorProto.reserved_name. + Enum_ReservedName = 5 + + // Field number for google.protobuf.EnumDescriptorProto.visibility. + Enum_Visibility = 6 + + // Field number for google.protobuf.EnumDescriptorProto.EnumReservedRange.start. + Enum_ReservedRange_Start = 1 + + // Field number for google.protobuf.EnumDescriptorProto.EnumReservedRange.end. + Enum_ReservedRange_End = 2 + + // Field number for google.protobuf.EnumValueDescriptorProto.name. + EnumValue_Name = 1 + + // Field number for google.protobuf.EnumValueDescriptorProto.number. + EnumValue_Number = 2 + + // Field number for google.protobuf.EnumValueDescriptorProto.options. + EnumValue_Options = 3 + + // Field number for google.protobuf.ServiceDescriptorProto.name. + Service_Name = 1 + + // Field number for google.protobuf.ServiceDescriptorProto.method. + Service_Method = 2 + + // Field number for google.protobuf.ServiceDescriptorProto.options. + Service_Options = 3 + + // Field number for google.protobuf.MethodDescriptorProto.name. + Method_Name = 1 + + // Field number for google.protobuf.MethodDescriptorProto.input_type. + Method_InputType = 2 + + // Field number for google.protobuf.MethodDescriptorProto.output_type. + Method_OutputType = 3 + + // Field number for google.protobuf.MethodDescriptorProto.options. + Method_Options = 4 + + // Field number for google.protobuf.MethodDescriptorProto.client_streaming. + Method_ClientStreaming = 5 + + // Field number for google.protobuf.MethodDescriptorProto.server_streaming. + Method_ServerStreaming = 6 + + // Field number for google.protobuf.FileOptions.java_package. + FileOptions_JavaPackage = 1 + + // Field number for google.protobuf.FileOptions.java_outer_classname. + FileOptions_JavaOuterClassname = 8 + + // Field number for google.protobuf.FileOptions.java_multiple_files. + FileOptions_JavaMultipleFiles = 10 + + // Field number for google.protobuf.FileOptions.java_generate_equals_and_hash. + FileOptions_JavaGenerateEqualsAndHash = 20 + + // Field number for google.protobuf.FileOptions.java_string_check_utf8. + FileOptions_JavaStringCheckUtf8 = 27 + + // Field number for google.protobuf.FileOptions.optimize_for. + FileOptions_OptimizeFor = 9 + + // Field number for google.protobuf.FileOptions.go_package. + FileOptions_GoPackage = 11 + + // Field number for google.protobuf.FileOptions.cc_generic_services. + FileOptions_CcGenericServices = 16 + + // Field number for google.protobuf.FileOptions.java_generic_services. + FileOptions_JavaGenericServices = 17 + + // Field number for google.protobuf.FileOptions.py_generic_services. + FileOptions_PyGenericServices = 18 + + // Field number for google.protobuf.FileOptions.deprecated. + FileOptions_Deprecated = 23 + + // Field number for google.protobuf.FileOptions.cc_enable_arenas. + FileOptions_CcEnableArenas = 31 + + // Field number for google.protobuf.FileOptions.objc_class_prefix. + FileOptions_ObjcClassPrefix = 36 + + // Field number for google.protobuf.FileOptions.csharp_namespace. + FileOptions_CsharpNamespace = 37 + + // Field number for google.protobuf.FileOptions.swift_prefix. + FileOptions_SwiftPrefix = 39 + + // Field number for google.protobuf.FileOptions.php_class_prefix. + FileOptions_PhpClassPrefix = 40 + + // Field number for google.protobuf.FileOptions.php_namespace. + FileOptions_PhpNamespace = 41 + + // Field number for google.protobuf.FileOptions.php_metadata_namespace. + FileOptions_PhpMetadataNamespace = 44 + + // Field number for google.protobuf.FileOptions.ruby_package. + FileOptions_RubyPackage = 45 + + // Field number for google.protobuf.FileOptions.features. + FileOptions_Features = 50 + + // Field number for google.protobuf.FileOptions.uninterpreted_option. + FileOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.MessageOptions.message_set_wire_format. + MessageOptions_MessageSetWireFormat = 1 + + // Field number for google.protobuf.MessageOptions.no_standard_descriptor_accessor. + MessageOptions_NoStandardDescriptorAccessor = 2 + + // Field number for google.protobuf.MessageOptions.deprecated. + MessageOptions_Deprecated = 3 + + // Field number for google.protobuf.MessageOptions.map_entry. + MessageOptions_MapEntry = 7 + + // Field number for google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts. + MessageOptions_DeprecatedLegacyJsonFieldConflicts = 11 + + // Field number for google.protobuf.MessageOptions.features. + MessageOptions_Features = 12 + + // Field number for google.protobuf.MessageOptions.uninterpreted_option. + MessageOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.FieldOptions.ctype. + FieldOptions_Ctype = 1 + + // Field number for google.protobuf.FieldOptions.packed. + FieldOptions_Packed = 2 + + // Field number for google.protobuf.FieldOptions.jstype. + FieldOptions_Jstype = 6 + + // Field number for google.protobuf.FieldOptions.lazy. + FieldOptions_Lazy = 5 + + // Field number for google.protobuf.FieldOptions.unverified_lazy. + FieldOptions_UnverifiedLazy = 15 + + // Field number for google.protobuf.FieldOptions.deprecated. + FieldOptions_Deprecated = 3 + + // Field number for google.protobuf.FieldOptions.weak. + FieldOptions_Weak = 10 + + // Field number for google.protobuf.FieldOptions.debug_redact. + FieldOptions_DebugRedact = 16 + + // Field number for google.protobuf.FieldOptions.retention. + FieldOptions_Retention = 17 + + // Field number for google.protobuf.FieldOptions.targets. + FieldOptions_Targets = 19 + + // Field number for google.protobuf.FieldOptions.edition_defaults. + FieldOptions_EditionDefaults = 20 + + // Field number for google.protobuf.FieldOptions.features. + FieldOptions_Features = 21 + + // Field number for google.protobuf.FieldOptions.feature_support. + FieldOptions_FeatureSupport = 22 + + // Field number for google.protobuf.FieldOptions.uninterpreted_option. + FieldOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.FieldOptions.EditionDefault.edition. + FieldOptions_EditionDefault_Edition = 3 + + // Field number for google.protobuf.FieldOptions.EditionDefault.value. + FieldOptions_EditionDefault_Value = 2 + + // Field number for google.protobuf.FieldOptions.FeatureSupport.edition_introduced. + FieldOptions_FeatureSupport_EditionIntroduced = 1 + + // Field number for google.protobuf.FieldOptions.FeatureSupport.edition_deprecated. + FieldOptions_FeatureSupport_EditionDeprecated = 2 + + // Field number for google.protobuf.FieldOptions.FeatureSupport.deprecation_warning. + FieldOptions_FeatureSupport_DeprecationWarning = 3 + + // Field number for google.protobuf.FieldOptions.FeatureSupport.edition_removed. + FieldOptions_FeatureSupport_EditionRemoved = 4 + + // Field number for google.protobuf.OneofOptions.features. + OneofOptions_Features = 1 + + // Field number for google.protobuf.OneofOptions.uninterpreted_option. + OneofOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.EnumOptions.allow_alias. + EnumOptions_AllowAlias = 2 + + // Field number for google.protobuf.EnumOptions.deprecated. + EnumOptions_Deprecated = 3 + + // Field number for google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts. + EnumOptions_DeprecatedLegacyJsonFieldConflicts = 6 + + // Field number for google.protobuf.EnumOptions.features. + EnumOptions_Features = 7 + + // Field number for google.protobuf.EnumOptions.uninterpreted_option. + EnumOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.EnumValueOptions.deprecated. + EnumValueOptions_Deprecated = 1 + + // Field number for google.protobuf.EnumValueOptions.features. + EnumValueOptions_Features = 2 + + // Field number for google.protobuf.EnumValueOptions.debug_redact. + EnumValueOptions_DebugRedact = 3 + + // Field number for google.protobuf.EnumValueOptions.feature_support. + EnumValueOptions_FeatureSupport = 4 + + // Field number for google.protobuf.EnumValueOptions.uninterpreted_option. + EnumValueOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.ServiceOptions.features. + ServiceOptions_Features = 34 + + // Field number for google.protobuf.ServiceOptions.deprecated. + ServiceOptions_Deprecated = 33 + + // Field number for google.protobuf.ServiceOptions.uninterpreted_option. + ServiceOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.MethodOptions.deprecated. + MethodOptions_Deprecated = 33 + + // Field number for google.protobuf.MethodOptions.idempotency_level. + MethodOptions_IdempotencyLevel = 34 + + // Field number for google.protobuf.MethodOptions.features. + MethodOptions_Features = 35 + + // Field number for google.protobuf.MethodOptions.uninterpreted_option. + MethodOptions_UninterpretedOption = 999 + + // Field number for google.protobuf.UninterpretedOption.name. + UninterpretedOption_Name = 2 + + // Field number for google.protobuf.UninterpretedOption.identifier_value. + UninterpretedOption_IdentifierValue = 3 + + // Field number for google.protobuf.UninterpretedOption.positive_int_value. + UninterpretedOption_PositiveIntValue = 4 + + // Field number for google.protobuf.UninterpretedOption.negative_int_value. + UninterpretedOption_NegativeIntValue = 5 + + // Field number for google.protobuf.UninterpretedOption.double_value. + UninterpretedOption_DoubleValue = 6 + + // Field number for google.protobuf.UninterpretedOption.string_value. + UninterpretedOption_StringValue = 7 + + // Field number for google.protobuf.UninterpretedOption.aggregate_value. + UninterpretedOption_AggregateValue = 8 + + // Field number for google.protobuf.UninterpretedOption.NamePart.name_part. + UninterpretedOption_NamePart_NamePart = 1 + + // Field number for google.protobuf.UninterpretedOption.NamePart.is_extension. + UninterpretedOption_NamePart_IsExtension = 2 + + // Field number for google.protobuf.FeatureSet.field_presence. + FeatureSet_FieldPresence = 1 + + // Field number for google.protobuf.FeatureSet.enum_type. + FeatureSet_EnumType = 2 + + // Field number for google.protobuf.FeatureSet.repeated_field_encoding. + FeatureSet_RepeatedFieldEncoding = 3 + + // Field number for google.protobuf.FeatureSet.utf8_validation. + FeatureSet_Utf8Validation = 4 + + // Field number for google.protobuf.FeatureSet.message_encoding. + FeatureSet_MessageEncoding = 5 + + // Field number for google.protobuf.FeatureSet.json_format. + FeatureSet_JsonFormat = 6 + + // Field number for google.protobuf.FeatureSet.enforce_naming_style. + FeatureSet_EnforceNamingStyle = 7 + + // Field number for google.protobuf.FeatureSet.default_symbol_visibility. + FeatureSet_DefaultSymbolVisibility = 8 + + // Field number for google.protobuf.FeatureSetDefaults.defaults. + FeatureSetDefaults_Defaults = 1 + + // Field number for google.protobuf.FeatureSetDefaults.minimum_edition. + FeatureSetDefaults_MinimumEdition = 4 + + // Field number for google.protobuf.FeatureSetDefaults.maximum_edition. + FeatureSetDefaults_MaximumEdition = 5 + + // Field number for google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition. + FeatureSetDefaults_FeatureSetEditionDefault_Edition = 3 + + // Field number for google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features. + FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures = 4 + + // Field number for google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features. + FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures = 5 + + // Field number for google.protobuf.SourceCodeInfo.location. + SourceCodeInfo_Location = 1 + + // Field number for google.protobuf.SourceCodeInfo.Location.path. + SourceCodeInfo_Location_Path = 1 + + // Field number for google.protobuf.SourceCodeInfo.Location.span. + SourceCodeInfo_Location_Span = 2 + + // Field number for google.protobuf.SourceCodeInfo.Location.leading_comments. + SourceCodeInfo_Location_LeadingComments = 3 + + // Field number for google.protobuf.SourceCodeInfo.Location.trailing_comments. + SourceCodeInfo_Location_TrailingComments = 4 + + // Field number for google.protobuf.SourceCodeInfo.Location.leading_detached_comments. + SourceCodeInfo_Location_LeadingDetachedComments = 6 + + // Field number for google.protobuf.GeneratedCodeInfo.annotation. + GeneratedCodeInfo_Annotation = 1 + + // Field number for google.protobuf.GeneratedCodeInfo.Annotation.path. + GeneratedCodeInfo_Annotation_Path = 1 + + // Field number for google.protobuf.GeneratedCodeInfo.Annotation.source_file. + GeneratedCodeInfo_Annotation_SourceFile = 2 + + // Field number for google.protobuf.GeneratedCodeInfo.Annotation.begin. + GeneratedCodeInfo_Annotation_Begin = 3 + + // Field number for google.protobuf.GeneratedCodeInfo.Annotation.end. + GeneratedCodeInfo_Annotation_End = 4 + + // Field number for google.protobuf.GeneratedCodeInfo.Annotation.semantic. + GeneratedCodeInfo_Annotation_Semantic = 5 + + // Field number for google.protobuf.Any.type_url. + Any_TypeUrl = 1 + + // Field number for google.protobuf.Any.value. + Any_Value = 2 +) + +const ( + // Enum value for google.protobuf.EDITION_UNKNOWN. + Edition_Unknown = 0 + + // Enum value for google.protobuf.EDITION_LEGACY. + Edition_Legacy = 900 + + // Enum value for google.protobuf.EDITION_PROTO2. + Edition_Proto2 = 998 + + // Enum value for google.protobuf.EDITION_PROTO3. + Edition_Proto3 = 999 + + // Enum value for google.protobuf.EDITION_2023. + Edition_2023 = 1000 + + // Enum value for google.protobuf.EDITION_2024. + Edition_2024 = 1001 + + // Enum value for google.protobuf.EDITION_UNSTABLE. + Edition_Unstable = 9999 + + // Enum value for google.protobuf.EDITION_1_TEST_ONLY. + Edition_1TestOnly = 1 + + // Enum value for google.protobuf.EDITION_2_TEST_ONLY. + Edition_2TestOnly = 2 + + // Enum value for google.protobuf.EDITION_99997_TEST_ONLY. + Edition_99997TestOnly = 99997 + + // Enum value for google.protobuf.EDITION_99998_TEST_ONLY. + Edition_99998TestOnly = 99998 + + // Enum value for google.protobuf.EDITION_99999_TEST_ONLY. + Edition_99999TestOnly = 99999 + + // Enum value for google.protobuf.EDITION_MAX. + Edition_Max = 2147483647 + + // Enum value for google.protobuf.VISIBILITY_UNSET. + SymbolVisibility_Unset = 0 + + // Enum value for google.protobuf.VISIBILITY_LOCAL. + SymbolVisibility_Local = 1 + + // Enum value for google.protobuf.VISIBILITY_EXPORT. + SymbolVisibility_Export = 2 + + // Enum value for google.protobuf.ExtensionRangeOptions.DECLARATION. + ExtensionRangeOptions_VerificationState_Declaration = 0 + + // Enum value for google.protobuf.ExtensionRangeOptions.UNVERIFIED. + ExtensionRangeOptions_VerificationState_Unverified = 1 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_DOUBLE. + Field_Type_Double = 1 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_FLOAT. + Field_Type_Float = 2 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_INT64. + Field_Type_Int64 = 3 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_UINT64. + Field_Type_Uint64 = 4 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_INT32. + Field_Type_Int32 = 5 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_FIXED64. + Field_Type_Fixed64 = 6 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_FIXED32. + Field_Type_Fixed32 = 7 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_BOOL. + Field_Type_Bool = 8 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_STRING. + Field_Type_String = 9 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_GROUP. + Field_Type_Group = 10 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_MESSAGE. + Field_Type_Message = 11 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_BYTES. + Field_Type_Bytes = 12 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_UINT32. + Field_Type_Uint32 = 13 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_ENUM. + Field_Type_Enum = 14 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_SFIXED32. + Field_Type_Sfixed32 = 15 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_SFIXED64. + Field_Type_Sfixed64 = 16 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_SINT32. + Field_Type_Sint32 = 17 + + // Enum value for google.protobuf.FieldDescriptorProto.TYPE_SINT64. + Field_Type_Sint64 = 18 + + // Enum value for google.protobuf.FieldDescriptorProto.LABEL_OPTIONAL. + Field_Label_Optional = 1 + + // Enum value for google.protobuf.FieldDescriptorProto.LABEL_REPEATED. + Field_Label_Repeated = 3 + + // Enum value for google.protobuf.FieldDescriptorProto.LABEL_REQUIRED. + Field_Label_Required = 2 + + // Enum value for google.protobuf.FileOptions.SPEED. + FileOptions_OptimizeMode_Speed = 1 + + // Enum value for google.protobuf.FileOptions.CODE_SIZE. + FileOptions_OptimizeMode_CodeSize = 2 + + // Enum value for google.protobuf.FileOptions.LITE_RUNTIME. + FileOptions_OptimizeMode_LiteRuntime = 3 + + // Enum value for google.protobuf.FieldOptions.STRING. + FieldOptions_CType_String = 0 + + // Enum value for google.protobuf.FieldOptions.CORD. + FieldOptions_CType_Cord = 1 + + // Enum value for google.protobuf.FieldOptions.STRING_PIECE. + FieldOptions_CType_StringPiece = 2 + + // Enum value for google.protobuf.FieldOptions.JS_NORMAL. + FieldOptions_JsType_JsNormal = 0 + + // Enum value for google.protobuf.FieldOptions.JS_STRING. + FieldOptions_JsType_JsString = 1 + + // Enum value for google.protobuf.FieldOptions.JS_NUMBER. + FieldOptions_JsType_JsNumber = 2 + + // Enum value for google.protobuf.FieldOptions.RETENTION_UNKNOWN. + FieldOptions_OptionRetention_Unknown = 0 + + // Enum value for google.protobuf.FieldOptions.RETENTION_RUNTIME. + FieldOptions_OptionRetention_Runtime = 1 + + // Enum value for google.protobuf.FieldOptions.RETENTION_SOURCE. + FieldOptions_OptionRetention_Source = 2 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_UNKNOWN. + FieldOptions_OptionTargetType_Unknown = 0 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_FILE. + FieldOptions_OptionTargetType_File = 1 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_EXTENSION_RANGE. + FieldOptions_OptionTargetType_ExtensionRange = 2 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_MESSAGE. + FieldOptions_OptionTargetType_Message = 3 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_FIELD. + FieldOptions_OptionTargetType_Field = 4 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_ONEOF. + FieldOptions_OptionTargetType_Oneof = 5 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_ENUM. + FieldOptions_OptionTargetType_Enum = 6 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_ENUM_ENTRY. + FieldOptions_OptionTargetType_EnumEntry = 7 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_SERVICE. + FieldOptions_OptionTargetType_Service = 8 + + // Enum value for google.protobuf.FieldOptions.TARGET_TYPE_METHOD. + FieldOptions_OptionTargetType_Method = 9 + + // Enum value for google.protobuf.MethodOptions.IDEMPOTENCY_UNKNOWN. + MethodOptions_IdempotencyLevel_IdempotencyUnknown = 0 + + // Enum value for google.protobuf.MethodOptions.NO_SIDE_EFFECTS. + MethodOptions_IdempotencyLevel_NoSideEffects = 1 + + // Enum value for google.protobuf.MethodOptions.IDEMPOTENT. + MethodOptions_IdempotencyLevel_Idempotent = 2 + + // Enum value for google.protobuf.FeatureSet.FIELD_PRESENCE_UNKNOWN. + FeatureSet_FieldPresence_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.EXPLICIT. + FeatureSet_FieldPresence_Explicit = 1 + + // Enum value for google.protobuf.FeatureSet.IMPLICIT. + FeatureSet_FieldPresence_Implicit = 2 + + // Enum value for google.protobuf.FeatureSet.LEGACY_REQUIRED. + FeatureSet_FieldPresence_LegacyRequired = 3 + + // Enum value for google.protobuf.FeatureSet.ENUM_TYPE_UNKNOWN. + FeatureSet_EnumType_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.OPEN. + FeatureSet_EnumType_Open = 1 + + // Enum value for google.protobuf.FeatureSet.CLOSED. + FeatureSet_EnumType_Closed = 2 + + // Enum value for google.protobuf.FeatureSet.REPEATED_FIELD_ENCODING_UNKNOWN. + FeatureSet_RepeatedFieldEncoding_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.PACKED. + FeatureSet_RepeatedFieldEncoding_Packed = 1 + + // Enum value for google.protobuf.FeatureSet.EXPANDED. + FeatureSet_RepeatedFieldEncoding_Expanded = 2 + + // Enum value for google.protobuf.FeatureSet.UTF8_VALIDATION_UNKNOWN. + FeatureSet_Utf8Validation_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.VERIFY. + FeatureSet_Utf8Validation_Verify = 2 + + // Enum value for google.protobuf.FeatureSet.NONE. + FeatureSet_Utf8Validation_None = 3 + + // Enum value for google.protobuf.FeatureSet.MESSAGE_ENCODING_UNKNOWN. + FeatureSet_MessageEncoding_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.LENGTH_PREFIXED. + FeatureSet_MessageEncoding_LengthPrefixed = 1 + + // Enum value for google.protobuf.FeatureSet.DELIMITED. + FeatureSet_MessageEncoding_Delimited = 2 + + // Enum value for google.protobuf.FeatureSet.JSON_FORMAT_UNKNOWN. + FeatureSet_JsonFormat_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.ALLOW. + FeatureSet_JsonFormat_Allow = 1 + + // Enum value for google.protobuf.FeatureSet.LEGACY_BEST_EFFORT. + FeatureSet_JsonFormat_LegacyBestEffort = 2 + + // Enum value for google.protobuf.FeatureSet.ENFORCE_NAMING_STYLE_UNKNOWN. + FeatureSet_EnforceNamingStyle_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.STYLE2024. + FeatureSet_EnforceNamingStyle_2024 = 1 + + // Enum value for google.protobuf.FeatureSet.STYLE_LEGACY. + FeatureSet_EnforceNamingStyle_Legacy = 2 + + // Enum value for google.protobuf.FeatureSet.VisibilityFeature.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN. + FeatureSet_DefaultSymbolVisibility_Unknown = 0 + + // Enum value for google.protobuf.FeatureSet.VisibilityFeature.EXPORT_ALL. + FeatureSet_DefaultSymbolVisibility_ExportAll = 1 + + // Enum value for google.protobuf.FeatureSet.VisibilityFeature.EXPORT_TOP_LEVEL. + FeatureSet_DefaultSymbolVisibility_ExportTopLevel = 2 + + // Enum value for google.protobuf.FeatureSet.VisibilityFeature.LOCAL_ALL. + FeatureSet_DefaultSymbolVisibility_LocalAll = 3 + + // Enum value for google.protobuf.FeatureSet.VisibilityFeature.STRICT. + FeatureSet_DefaultSymbolVisibility_Strict = 4 + + // Enum value for google.protobuf.GeneratedCodeInfo.Annotation.NONE. + GeneratedCodeInfo_Annotation_Semantic_None = 0 + + // Enum value for google.protobuf.GeneratedCodeInfo.Annotation.SET. + GeneratedCodeInfo_Annotation_Semantic_Set = 1 + + // Enum value for google.protobuf.GeneratedCodeInfo.Annotation.ALIAS. + GeneratedCodeInfo_Annotation_Semantic_Alias = 2 +) diff --git a/internal/tags/tags.go b/internal/tags/tags.go new file mode 100644 index 000000000..ff41b1c4f --- /dev/null +++ b/internal/tags/tags.go @@ -0,0 +1,46 @@ +// Copyright 2020-2025 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 tag contains all of the numeric field and enum value tag numbers +// from descriptor.proto. +package tags + +//go:generate go run ./gen + +// Field numbers for synthetic map entry messages. +// +//nolint:revive,stylecheck +const ( + MapEntry_Key = 1 + MapEntry_Value = 2 +) + +const ( + FieldBits = 29 + FieldMin = 1 + FieldMax = 1<= descriptorpb.Edition_EDITION_2024 { // We don't support edition 2024 yet, but we went ahead and mimic'ed this check // from protoc, which currently has experimental support for 2024. - span := r.findOptionSpan(fd, internal.FieldOptionsCTypeTag) + span := r.findOptionSpan(fd, tags.FieldOptions_Ctype) if err := handler.HandleErrorf(span, "ctype option cannot be used as of edition 2024; use features.string_type instead"); err != nil { return err } @@ -147,10 +148,10 @@ func (r *result) validateField(fld protoreflect.FieldDescriptor, handler *report var span ast.SourceSpan var optionName string if fd.proto.Options.GetLazy() { - span = r.findOptionSpan(fd, internal.FieldOptionsLazyTag) + span = r.findOptionSpan(fd, tags.FieldOptions_Lazy) optionName = "lazy" } else { - span = r.findOptionSpan(fd, internal.FieldOptionsUnverifiedLazyTag) + span = r.findOptionSpan(fd, tags.FieldOptions_UnverifiedLazy) optionName = "unverified_lazy" } var suffix string @@ -171,7 +172,7 @@ func (r *result) validateField(fld protoreflect.FieldDescriptor, handler *report protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: // allowed only for 64-bit integer types default: - span := r.findOptionSpan(fd, internal.FieldOptionsJSTypeTag) + span := r.findOptionSpan(fd, tags.FieldOptions_Jstype) err := handler.HandleErrorf(span, "only 64-bit integer fields (int64, uint64, sint64, fixed64, and sfixed64) can specify a jstype other than JS_NORMAL") if err != nil { return err @@ -218,13 +219,13 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) return err } } - } else if fd.Number() > internal.MaxNormalTag { + } else if fd.Number() > tags.FieldMax { // In validateBasic() we just made sure these were within bounds for any message. But // now that things are linked, we can check if the extendee is messageset wire format // and, if not, enforce tighter limit. file := r.FileNode() info := file.NodeInfo(r.FieldNode(fd.proto).FieldTag()) - err := handler.HandleErrorf(info, "tag number %d is higher than max allowed tag number (%d)", fd.Number(), internal.MaxNormalTag) + err := handler.HandleErrorf(info, "tag number %d is higher than max allowed tag number (%d)", fd.Number(), tags.FieldMax) if err != nil { return err } @@ -266,7 +267,7 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) file := r.FileNode() info := file.NodeInfo(r.FieldNode(fd.proto).FieldTag()) span, _ := findExtensionRangeOptionSpan(msg.ParentFile(), msg, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(j), internal.ExtensionRangeOptionsDeclarationReservedTag) + tags.ExtensionRangeOptions_Declaration, int32(j), tags.ExtensionRangeOptions_Declaration_Reserved) err := handler.HandleErrorf(info, "cannot use field number %d for an extension because it is reserved in declaration at %v", fd.Number(), span.Start()) if err != nil { @@ -278,7 +279,7 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) file := r.FileNode() info := file.NodeInfo(r.FieldNode(fd.proto).FieldName()) span, _ := findExtensionRangeOptionSpan(msg.ParentFile(), msg, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(j), internal.ExtensionRangeOptionsDeclarationFullNameTag) + tags.ExtensionRangeOptions_Declaration, int32(j), tags.ExtensionRangeOptions_Declaration_FullName) err := handler.HandleErrorf(info, "expected extension with number %d to be named %s, not %s, per declaration at %v", fd.Number(), strings.TrimPrefix(extDecl.GetFullName(), "."), fd.FullName(), span.Start()) if err != nil { @@ -289,7 +290,7 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) file := r.FileNode() info := file.NodeInfo(r.FieldNode(fd.proto).FieldType()) span, _ := findExtensionRangeOptionSpan(msg.ParentFile(), msg, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(j), internal.ExtensionRangeOptionsDeclarationTypeTag) + tags.ExtensionRangeOptions_Declaration, int32(j), tags.ExtensionRangeOptions_Declaration_Type) err := handler.HandleErrorf(info, "expected extension with number %d to have type %s, not %s, per declaration at %v", fd.Number(), strings.TrimPrefix(extDecl.GetType(), "."), getTypeName(fd), span.Start()) if err != nil { @@ -304,7 +305,7 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) file := r.FileNode() info := file.NodeInfo(r.FieldNode(fd.proto).FieldLabel()) span, _ := findExtensionRangeOptionSpan(msg.ParentFile(), msg, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(j), internal.ExtensionRangeOptionsDeclarationRepeatedTag) + tags.ExtensionRangeOptions_Declaration, int32(j), tags.ExtensionRangeOptions_Declaration_Repeated) err := handler.HandleErrorf(info, "expected extension with number %d to be %s, not %s, per declaration at %v", fd.Number(), expected, actual, span.Start()) if err != nil { @@ -317,7 +318,7 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) file := r.FileNode() info := file.NodeInfo(r.FieldNode(fd.proto).FieldTag()) span, _ := findExtensionRangeOptionSpan(fd.ParentFile(), msg, i, extRange, - internal.ExtensionRangeOptionsVerificationTag) + tags.ExtensionRangeOptions_Verification) err := handler.HandleErrorf(info, "expected extension with number %d to be declared in type %s, but no declaration found at %v", fd.Number(), fd.ContainingMessage().FullName(), span.Start()) if err != nil { @@ -331,7 +332,7 @@ func (r *result) validateExtension(fd *fldDescriptor, handler *reporter.Handler) func (r *result) validatePacked(fd *fldDescriptor, handler *reporter.Handler) error { if fd.proto.Options != nil && fd.proto.Options.Packed != nil && isEditions(r) { - span := r.findOptionSpan(fd, internal.FieldOptionsPackedTag) + span := r.findOptionSpan(fd, tags.FieldOptions_Packed) err := handler.HandleErrorf(span, "packed option cannot be used with editions; use features.repeated_field_encoding=PACKED instead") if err != nil { return err @@ -377,22 +378,22 @@ func (r *result) validateFieldFeatures(fld *fldDescriptor, handler *reporter.Han if features.FieldPresence != nil { switch { case fld.proto.OneofIndex != nil: - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetFieldPresenceTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_FieldPresence) if err := handler.HandleErrorf(span, "oneof fields may not specify field presence"); err != nil { return err } case fld.Cardinality() == protoreflect.Repeated: - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetFieldPresenceTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_FieldPresence) if err := handler.HandleErrorf(span, "repeated fields may not specify field presence"); err != nil { return err } case fld.IsExtension(): - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetFieldPresenceTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_FieldPresence) if err := handler.HandleErrorf(span, "extension fields may not specify field presence"); err != nil { return err } case fld.Message() != nil && features.GetFieldPresence() == descriptorpb.FeatureSet_IMPLICIT: - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetFieldPresenceTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_FieldPresence) if err := handler.HandleErrorf(span, "message fields may not specify implicit presence"); err != nil { return err } @@ -400,12 +401,12 @@ func (r *result) validateFieldFeatures(fld *fldDescriptor, handler *reporter.Han } if features.RepeatedFieldEncoding != nil { if fld.Cardinality() != protoreflect.Repeated { - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetRepeatedFieldEncodingTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_RepeatedFieldEncoding) if err := handler.HandleErrorf(span, "only repeated fields may specify repeated field encoding"); err != nil { return err } } else if !internal.CanPack(fld.Kind()) && features.GetRepeatedFieldEncoding() == descriptorpb.FeatureSet_PACKED { - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetRepeatedFieldEncodingTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_RepeatedFieldEncoding) if err := handler.HandleErrorf(span, "only repeated primitive fields may specify packed encoding"); err != nil { return err } @@ -417,7 +418,7 @@ func (r *result) validateFieldFeatures(fld *fldDescriptor, handler *reporter.Han (isMap && fld.MapKey().Kind() != protoreflect.StringKind && fld.MapValue().Kind() != protoreflect.StringKind) { - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetUTF8ValidationTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_Utf8Validation) if err := handler.HandleErrorf(span, "only string fields may specify UTF8 validation"); err != nil { return err } @@ -425,7 +426,7 @@ func (r *result) validateFieldFeatures(fld *fldDescriptor, handler *reporter.Han } if features.MessageEncoding != nil { if fld.Message() == nil || fld.IsMap() { - span := r.findOptionSpan(fld, internal.FieldOptionsFeaturesTag, internal.FeatureSetMessageEncodingTag) + span := r.findOptionSpan(fld, tags.FieldOptions_Features, tags.FeatureSet_MessageEncoding) if err := handler.HandleErrorf(span, "only message fields may specify message encoding"); err != nil { return err } @@ -580,9 +581,9 @@ func (r *result) validateExtensionDeclarations(md *msgDescriptor, handler *repor // DECLARATION. It's an error for declarations to be present but the // verification field explicitly set to something other than that. if opts.Verification != nil && opts.GetVerification() != descriptorpb.ExtensionRangeOptions_DECLARATION { - span, ok := findExtensionRangeOptionSpan(r, md, i, extRange, internal.ExtensionRangeOptionsVerificationTag) + span, ok := findExtensionRangeOptionSpan(r, md, i, extRange, tags.ExtensionRangeOptions_Verification) if !ok { - span, _ = findExtensionRangeOptionSpan(r, md, i, extRange, internal.ExtensionRangeOptionsDeclarationTag, 0) + span, _ = findExtensionRangeOptionSpan(r, md, i, extRange, tags.ExtensionRangeOptions_Declaration, 0) } if err := handler.HandleErrorf(span, "extension range cannot have declarations and have verification of %s", opts.GetVerification()); err != nil { return err @@ -591,13 +592,13 @@ func (r *result) validateExtensionDeclarations(md *msgDescriptor, handler *repor declsByTag := map[int32]ast.SourcePos{} for i, extDecl := range extRange.GetOptions().GetDeclaration() { if extDecl.Number == nil { - span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, internal.ExtensionRangeOptionsDeclarationTag, int32(i)) + span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, tags.ExtensionRangeOptions_Declaration, int32(i)) if err := handler.HandleErrorf(span, "extension declaration is missing required field number"); err != nil { return err } } else { extensionNumberSpan, _ := findExtensionRangeOptionSpan(r, md, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(i), internal.ExtensionRangeOptionsDeclarationNumberTag) + tags.ExtensionRangeOptions_Declaration, int32(i), tags.ExtensionRangeOptions_Declaration_Number) if extDecl.GetNumber() < extRange.GetStart() || extDecl.GetNumber() >= extRange.GetEnd() { // Number is out of range. // See if one of the other ranges on the same extends statement includes the number, @@ -642,14 +643,14 @@ func (r *result) validateExtensionDeclarations(md *msgDescriptor, handler *repor } if extDecl.FullName == nil && !extDecl.GetReserved() { - span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, internal.ExtensionRangeOptionsDeclarationTag, int32(i)) + span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, tags.ExtensionRangeOptions_Declaration, int32(i)) if err := handler.HandleErrorf(span, "extension declaration that is not marked reserved must have a full_name"); err != nil { return err } } else if extDecl.FullName != nil { var extensionFullName protoreflect.FullName extensionNameSpan, _ := findExtensionRangeOptionSpan(r, md, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(i), internal.ExtensionRangeOptionsDeclarationFullNameTag) + tags.ExtensionRangeOptions_Declaration, int32(i), tags.ExtensionRangeOptions_Declaration_FullName) if !strings.HasPrefix(extDecl.GetFullName(), ".") { if err := handler.HandleErrorf(extensionNameSpan, "extension declaration full name %q should start with a leading dot (.)", extDecl.GetFullName()); err != nil { return err @@ -669,7 +670,7 @@ func (r *result) validateExtensionDeclarations(md *msgDescriptor, handler *repor } if extDecl.Type == nil && !extDecl.GetReserved() { - span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, internal.ExtensionRangeOptionsDeclarationTag, int32(i)) + span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, tags.ExtensionRangeOptions_Declaration, int32(i)) if err := handler.HandleErrorf(span, "extension declaration that is not marked reserved must have a type"); err != nil { return err } @@ -677,14 +678,14 @@ func (r *result) validateExtensionDeclarations(md *msgDescriptor, handler *repor if strings.HasPrefix(extDecl.GetType(), ".") { if !protoreflect.FullName(extDecl.GetType()[1:]).IsValid() { span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(i), internal.ExtensionRangeOptionsDeclarationTypeTag) + tags.ExtensionRangeOptions_Declaration, int32(i), tags.ExtensionRangeOptions_Declaration_Type) if err := handler.HandleErrorf(span, "extension declaration type %q is not a valid qualified name", extDecl.GetType()); err != nil { return err } } } else if !isBuiltinTypeName(extDecl.GetType()) { span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(i), internal.ExtensionRangeOptionsDeclarationTypeTag) + tags.ExtensionRangeOptions_Declaration, int32(i), tags.ExtensionRangeOptions_Declaration_Type) if err := handler.HandleErrorf(span, "extension declaration type %q must be a builtin type or start with a leading dot (.)", extDecl.GetType()); err != nil { return err } @@ -694,12 +695,12 @@ func (r *result) validateExtensionDeclarations(md *msgDescriptor, handler *repor if extDecl.GetReserved() && (extDecl.FullName == nil) != (extDecl.Type == nil) { var fieldTag int32 if extDecl.FullName != nil { - fieldTag = internal.ExtensionRangeOptionsDeclarationFullNameTag + fieldTag = tags.ExtensionRangeOptions_Declaration_FullName } else { - fieldTag = internal.ExtensionRangeOptionsDeclarationTypeTag + fieldTag = tags.ExtensionRangeOptions_Declaration_Type } span, _ := findExtensionRangeOptionSpan(r, md, i, extRange, - internal.ExtensionRangeOptionsDeclarationTag, int32(i), fieldTag) + tags.ExtensionRangeOptions_Declaration, int32(i), fieldTag) if err := handler.HandleErrorf(span, "extension declarations that are reserved should specify both full_name and type or neither"); err != nil { return err } @@ -789,9 +790,9 @@ func findExtensionRangeOptionSpan( } //nolint:gocritic // intentionally assigning to different slice variables - extRangePath := append(msgPath, internal.MessageExtensionRangesTag, int32(extRangeIndex)) - optsPath := append(extRangePath, internal.ExtensionRangeOptionsTag) //nolint:gocritic - fullPath := append(optsPath, path...) //nolint:gocritic + extRangePath := append(msgPath, tags.Message_ExtensionRange, int32(extRangeIndex)) + optsPath := append(extRangePath, tags.Message_ExtensionRange_Options) //nolint:gocritic + fullPath := append(optsPath, path...) //nolint:gocritic srcLoc := srcLocs.ByPath(fullPath) if srcLoc.Path != nil { // found it diff --git a/options/options.go b/options/options.go index 24958f5ab..63a61c186 100644 --- a/options/options.go +++ b/options/options.go @@ -43,6 +43,7 @@ import ( "github.com/bufbuild/protocompile/ast" "github.com/bufbuild/protocompile/internal" "github.com/bufbuild/protocompile/internal/messageset" + "github.com/bufbuild/protocompile/internal/tags" "github.com/bufbuild/protocompile/linker" "github.com/bufbuild/protocompile/parser" "github.com/bufbuild/protocompile/reporter" @@ -412,7 +413,7 @@ func (interp *interpreter) interpretFieldPseudoOptions(fqn string, fld *descript } // attribute source code info if on, ok := optNode.(*ast.OptionNode); ok { - interp.index[on] = &sourceinfo.OptionSourceInfo{Path: []int32{-1, internal.FieldJSONNameTag}} + interp.index[on] = &sourceinfo.OptionSourceInfo{Path: []int32{-1, tags.Field_JsonName}} } uo = internal.RemoveOption(uo, index) if strings.HasPrefix(jsonName, "[") && strings.HasSuffix(jsonName, "]") { @@ -428,7 +429,7 @@ func (interp *interpreter) interpretFieldPseudoOptions(fqn string, fld *descript // attribute source code info optNode := interp.file.OptionNode(uo[index]) if on, ok := optNode.(*ast.OptionNode); ok { - interp.index[on] = &sourceinfo.OptionSourceInfo{Path: []int32{-1, internal.FieldDefaultTag}} + interp.index[on] = &sourceinfo.OptionSourceInfo{Path: []int32{-1, tags.Field_DefaultValue}} } uo = internal.RemoveOption(uo, index) } @@ -2071,15 +2072,15 @@ func (interp *interpreter) messageLiteralValue( hadError = true continue } - typeURLDescriptor := fmd.Fields().ByNumber(internal.AnyTypeURLTag) + typeURLDescriptor := fmd.Fields().ByNumber(tags.Any_TypeUrl) var err error switch { case typeURLDescriptor == nil: - err = fmt.Errorf("message schema is missing type_url field (number %d)", internal.AnyTypeURLTag) + err = fmt.Errorf("message schema is missing type_url field (number %d)", tags.Any_TypeUrl) case typeURLDescriptor.IsList(): - err = fmt.Errorf("message schema has type_url field (number %d) that is a list but should be singular", internal.AnyTypeURLTag) + err = fmt.Errorf("message schema has type_url field (number %d) that is a list but should be singular", tags.Any_TypeUrl) case typeURLDescriptor.Kind() != protoreflect.StringKind: - err = fmt.Errorf("message schema has type_url field (number %d) that is %s but should be string", internal.AnyTypeURLTag, typeURLDescriptor.Kind()) + err = fmt.Errorf("message schema has type_url field (number %d) that is %s but should be string", tags.Any_TypeUrl, typeURLDescriptor.Kind()) } if err != nil { err := interp.handleErrorf(interp.nodeInfo(fieldNode.Name), "%v%w", mc, err) @@ -2089,14 +2090,14 @@ func (interp *interpreter) messageLiteralValue( hadError = true continue } - valueDescriptor := fmd.Fields().ByNumber(internal.AnyValueTag) + valueDescriptor := fmd.Fields().ByNumber(tags.Any_Value) switch { case valueDescriptor == nil: - err = fmt.Errorf("message schema is missing value field (number %d)", internal.AnyValueTag) + err = fmt.Errorf("message schema is missing value field (number %d)", tags.Any_Value) case valueDescriptor.IsList(): - err = fmt.Errorf("message schema has value field (number %d) that is a list but should be singular", internal.AnyValueTag) + err = fmt.Errorf("message schema has value field (number %d) that is a list but should be singular", tags.Any_Value) case valueDescriptor.Kind() != protoreflect.BytesKind: - err = fmt.Errorf("message schema has value field (number %d) that is %s but should be bytes", internal.AnyValueTag, valueDescriptor.Kind()) + err = fmt.Errorf("message schema has value field (number %d) that is %s but should be bytes", tags.Any_Value, valueDescriptor.Kind()) } if err != nil { err := interp.handleErrorf(interp.nodeInfo(fieldNode.Name), "%v%w", mc, err) @@ -2144,7 +2145,7 @@ func (interp *interpreter) messageLiteralValue( continue } // parse the message value - msgVal, valueSrcInfo, err := interp.messageLiteralValue(targetType, mc, anyFields, dynamicpb.NewMessage(anyMd), append(pathPrefix, internal.AnyValueTag)) + msgVal, valueSrcInfo, err := interp.messageLiteralValue(targetType, mc, anyFields, dynamicpb.NewMessage(anyMd), append(pathPrefix, tags.Any_Value)) if err != nil { return protoreflect.Value{}, sourceinfo.OptionSourceInfo{}, err } else if !msgVal.IsValid() { diff --git a/options/source_retention_options.go b/options/source_retention_options.go index b811c5b19..312e76e7d 100644 --- a/options/source_retention_options.go +++ b/options/source_retention_options.go @@ -21,7 +21,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" - "github.com/bufbuild/protocompile/internal" + "github.com/bufbuild/protocompile/internal/tags" ) // StripSourceRetentionOptionsFromFile returns a file descriptor proto that omits any @@ -40,7 +40,7 @@ func StripSourceRetentionOptionsFromFile(file *descriptorpb.FileDescriptorProto) removedPaths = &sourcePathTrie{} } var dirty bool - optionsPath := path.push(internal.FileOptionsTag) + optionsPath := path.push(tags.File_Options) newOpts, err := stripSourceRetentionOptions(file.GetOptions(), optionsPath, removedPaths) if err != nil { return nil, err @@ -48,7 +48,7 @@ func StripSourceRetentionOptionsFromFile(file *descriptorpb.FileDescriptorProto) if newOpts != file.GetOptions() { dirty = true } - msgsPath := path.push(internal.FileMessagesTag) + msgsPath := path.push(tags.File_MessageType) newMsgs, changed, err := stripOptionsFromAll(file.GetMessageType(), stripSourceRetentionOptionsFromMessage, msgsPath, removedPaths) if err != nil { return nil, err @@ -56,7 +56,7 @@ func StripSourceRetentionOptionsFromFile(file *descriptorpb.FileDescriptorProto) if changed { dirty = true } - enumsPath := path.push(internal.FileEnumsTag) + enumsPath := path.push(tags.File_EnumType) newEnums, changed, err := stripOptionsFromAll(file.GetEnumType(), stripSourceRetentionOptionsFromEnum, enumsPath, removedPaths) if err != nil { return nil, err @@ -64,7 +64,7 @@ func StripSourceRetentionOptionsFromFile(file *descriptorpb.FileDescriptorProto) if changed { dirty = true } - extsPath := path.push(internal.FileExtensionsTag) + extsPath := path.push(tags.File_Extension) newExts, changed, err := stripOptionsFromAll(file.GetExtension(), stripSourceRetentionOptionsFromField, extsPath, removedPaths) if err != nil { return nil, err @@ -72,7 +72,7 @@ func StripSourceRetentionOptionsFromFile(file *descriptorpb.FileDescriptorProto) if changed { dirty = true } - svcsPath := path.push(internal.FileServicesTag) + svcsPath := path.push(tags.File_Service) newSvcs, changed, err := stripOptionsFromAll(file.GetService(), stripSourceRetentionOptionsFromService, svcsPath, removedPaths) if err != nil { return nil, err @@ -217,7 +217,7 @@ func stripSourceRetentionOptionsFromMessage( removedPaths *sourcePathTrie, ) (*descriptorpb.DescriptorProto, error) { var dirty bool - optionsPath := path.push(internal.MessageOptionsTag) + optionsPath := path.push(tags.Message_Options) newOpts, err := stripSourceRetentionOptions(msg.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -225,7 +225,7 @@ func stripSourceRetentionOptionsFromMessage( if newOpts != msg.Options { dirty = true } - fieldsPath := path.push(internal.MessageFieldsTag) + fieldsPath := path.push(tags.Message_Field) newFields, changed, err := stripOptionsFromAll(msg.Field, stripSourceRetentionOptionsFromField, fieldsPath, removedPaths) if err != nil { return nil, err @@ -233,7 +233,7 @@ func stripSourceRetentionOptionsFromMessage( if changed { dirty = true } - oneofsPath := path.push(internal.MessageOneofsTag) + oneofsPath := path.push(tags.Message_OneofDecl) newOneofs, changed, err := stripOptionsFromAll(msg.OneofDecl, stripSourceRetentionOptionsFromOneof, oneofsPath, removedPaths) if err != nil { return nil, err @@ -241,7 +241,7 @@ func stripSourceRetentionOptionsFromMessage( if changed { dirty = true } - extRangesPath := path.push(internal.MessageExtensionRangesTag) + extRangesPath := path.push(tags.Message_ExtensionRange) newExtRanges, changed, err := stripOptionsFromAll(msg.ExtensionRange, stripSourceRetentionOptionsFromExtensionRange, extRangesPath, removedPaths) if err != nil { return nil, err @@ -249,7 +249,7 @@ func stripSourceRetentionOptionsFromMessage( if changed { dirty = true } - msgsPath := path.push(internal.MessageNestedMessagesTag) + msgsPath := path.push(tags.Message_NestedType) newMsgs, changed, err := stripOptionsFromAll(msg.NestedType, stripSourceRetentionOptionsFromMessage, msgsPath, removedPaths) if err != nil { return nil, err @@ -257,7 +257,7 @@ func stripSourceRetentionOptionsFromMessage( if changed { dirty = true } - enumsPath := path.push(internal.MessageEnumsTag) + enumsPath := path.push(tags.Message_EnumType) newEnums, changed, err := stripOptionsFromAll(msg.EnumType, stripSourceRetentionOptionsFromEnum, enumsPath, removedPaths) if err != nil { return nil, err @@ -265,7 +265,7 @@ func stripSourceRetentionOptionsFromMessage( if changed { dirty = true } - extsPath := path.push(internal.MessageExtensionsTag) + extsPath := path.push(tags.Message_Extension) newExts, changed, err := stripOptionsFromAll(msg.Extension, stripSourceRetentionOptionsFromField, extsPath, removedPaths) if err != nil { return nil, err @@ -297,7 +297,7 @@ func stripSourceRetentionOptionsFromField( path sourcePath, removedPaths *sourcePathTrie, ) (*descriptorpb.FieldDescriptorProto, error) { - optionsPath := path.push(internal.FieldOptionsTag) + optionsPath := path.push(tags.Field_Options) newOpts, err := stripSourceRetentionOptions(field.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -318,7 +318,7 @@ func stripSourceRetentionOptionsFromOneof( path sourcePath, removedPaths *sourcePathTrie, ) (*descriptorpb.OneofDescriptorProto, error) { - optionsPath := path.push(internal.OneofOptionsTag) + optionsPath := path.push(tags.Oneof_Options) newOpts, err := stripSourceRetentionOptions(oneof.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -339,7 +339,7 @@ func stripSourceRetentionOptionsFromExtensionRange( path sourcePath, removedPaths *sourcePathTrie, ) (*descriptorpb.DescriptorProto_ExtensionRange, error) { - optionsPath := path.push(internal.ExtensionRangeOptionsTag) + optionsPath := path.push(tags.Message_ExtensionRange_Options) newOpts, err := stripSourceRetentionOptions(extRange.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -361,7 +361,7 @@ func stripSourceRetentionOptionsFromEnum( removedPaths *sourcePathTrie, ) (*descriptorpb.EnumDescriptorProto, error) { var dirty bool - optionsPath := path.push(internal.EnumOptionsTag) + optionsPath := path.push(tags.Enum_Options) newOpts, err := stripSourceRetentionOptions(enum.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -369,7 +369,7 @@ func stripSourceRetentionOptionsFromEnum( if newOpts != enum.Options { dirty = true } - valsPath := path.push(internal.EnumValuesTag) + valsPath := path.push(tags.Enum_Value) newVals, changed, err := stripOptionsFromAll(enum.Value, stripSourceRetentionOptionsFromEnumValue, valsPath, removedPaths) if err != nil { return nil, err @@ -396,7 +396,7 @@ func stripSourceRetentionOptionsFromEnumValue( path sourcePath, removedPaths *sourcePathTrie, ) (*descriptorpb.EnumValueDescriptorProto, error) { - optionsPath := path.push(internal.EnumValOptionsTag) + optionsPath := path.push(tags.EnumValue_Options) newOpts, err := stripSourceRetentionOptions(enumVal.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -418,7 +418,7 @@ func stripSourceRetentionOptionsFromService( removedPaths *sourcePathTrie, ) (*descriptorpb.ServiceDescriptorProto, error) { var dirty bool - optionsPath := path.push(internal.ServiceOptionsTag) + optionsPath := path.push(tags.Service_Options) newOpts, err := stripSourceRetentionOptions(svc.Options, optionsPath, removedPaths) if err != nil { return nil, err @@ -426,7 +426,7 @@ func stripSourceRetentionOptionsFromService( if newOpts != svc.Options { dirty = true } - methodsPath := path.push(internal.ServiceMethodsTag) + methodsPath := path.push(tags.Service_Method) newMethods, changed, err := stripOptionsFromAll(svc.Method, stripSourceRetentionOptionsFromMethod, methodsPath, removedPaths) if err != nil { return nil, err @@ -453,7 +453,7 @@ func stripSourceRetentionOptionsFromMethod( path sourcePath, removedPaths *sourcePathTrie, ) (*descriptorpb.MethodDescriptorProto, error) { - optionsPath := path.push(internal.MethodOptionsTag) + optionsPath := path.push(tags.Method_Options) newOpts, err := stripSourceRetentionOptions(method.Options, optionsPath, removedPaths) if err != nil { return nil, err diff --git a/options/source_retention_options_test.go b/options/source_retention_options_test.go index ae4142168..5d556a611 100644 --- a/options/source_retention_options_test.go +++ b/options/source_retention_options_test.go @@ -28,7 +28,7 @@ import ( "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/dynamicpb" - "github.com/bufbuild/protocompile/internal" + "github.com/bufbuild/protocompile/internal/tags" ) func TestStripSourceOnlyOptions(t *testing.T) { @@ -427,24 +427,24 @@ func TestStripSourceOnlyOptionsFromFile(t *testing.T) { }, SourceCodeInfo: &descriptorpb.SourceCodeInfo{ Location: combineAll( - allLocations(internal.FileOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageFieldsTag, 0, internal.FieldOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageFieldsTag, 1, internal.FieldOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageOneofsTag, 0, internal.OneofOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageExtensionRangesTag, 0, internal.ExtensionRangeOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageNestedMessagesTag, 0, internal.MessageOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageNestedMessagesTag, 0, internal.MessageFieldsTag, 0, internal.FieldOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageEnumsTag, 0, internal.EnumOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageEnumsTag, 0, internal.EnumValuesTag, 0, internal.EnumValOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageEnumsTag, 0, internal.EnumValuesTag, 1, internal.EnumValOptionsTag), - allLocations(internal.FileMessagesTag, 0, internal.MessageExtensionsTag, 0, internal.FieldOptionsTag), - allLocations(internal.FileEnumsTag, 0, internal.EnumOptionsTag), - allLocations(internal.FileEnumsTag, 0, internal.EnumValuesTag, 0, internal.EnumValOptionsTag), - allLocations(internal.FileEnumsTag, 0, internal.EnumValuesTag, 1, internal.EnumValOptionsTag), - allLocations(internal.FileExtensionsTag, 0, internal.FieldOptionsTag), - allLocations(internal.FileServicesTag, 0, internal.ServiceOptionsTag), - allLocations(internal.FileServicesTag, 0, internal.ServiceMethodsTag, 0, internal.MethodOptionsTag), + allLocations(tags.File_Options), + allLocations(tags.File_MessageType, 0, tags.Message_Options), + allLocations(tags.File_MessageType, 0, tags.Message_Field, 0, tags.Field_Options), + allLocations(tags.File_MessageType, 0, tags.Message_Field, 1, tags.Field_Options), + allLocations(tags.File_MessageType, 0, tags.Message_OneofDecl, 0, tags.Oneof_Options), + allLocations(tags.File_MessageType, 0, tags.Message_ExtensionRange, 0, tags.Message_ExtensionRange_Options), + allLocations(tags.File_MessageType, 0, tags.Message_NestedType, 0, tags.Message_Options), + allLocations(tags.File_MessageType, 0, tags.Message_NestedType, 0, tags.Message_Field, 0, tags.Field_Options), + allLocations(tags.File_MessageType, 0, tags.Message_EnumType, 0, tags.Enum_Options), + allLocations(tags.File_MessageType, 0, tags.Message_EnumType, 0, tags.Enum_Value, 0, tags.EnumValue_Options), + allLocations(tags.File_MessageType, 0, tags.Message_EnumType, 0, tags.Enum_Value, 1, tags.EnumValue_Options), + allLocations(tags.File_MessageType, 0, tags.Message_Extension, 0, tags.Field_Options), + allLocations(tags.File_EnumType, 0, tags.Enum_Options), + allLocations(tags.File_EnumType, 0, tags.Enum_Value, 0, tags.EnumValue_Options), + allLocations(tags.File_EnumType, 0, tags.Enum_Value, 1, tags.EnumValue_Options), + allLocations(tags.File_Extension, 0, tags.Field_Options), + allLocations(tags.File_Service, 0, tags.Service_Options), + allLocations(tags.File_Service, 0, tags.Service_Method, 0, tags.Method_Options), ), }, } @@ -580,24 +580,24 @@ func TestStripSourceOnlyOptionsFromFile(t *testing.T) { }, SourceCodeInfo: &descriptorpb.SourceCodeInfo{ Location: combineAll( - strippedLocations(internal.FileOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageFieldsTag, 0, internal.FieldOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageFieldsTag, 1, internal.FieldOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageOneofsTag, 0, internal.OneofOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageExtensionRangesTag, 0, internal.ExtensionRangeOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageNestedMessagesTag, 0, internal.MessageOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageNestedMessagesTag, 0, internal.MessageFieldsTag, 0, internal.FieldOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageEnumsTag, 0, internal.EnumOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageEnumsTag, 0, internal.EnumValuesTag, 0, internal.EnumValOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageEnumsTag, 0, internal.EnumValuesTag, 1, internal.EnumValOptionsTag), - strippedLocations(internal.FileMessagesTag, 0, internal.MessageExtensionsTag, 0, internal.FieldOptionsTag), - strippedLocations(internal.FileEnumsTag, 0, internal.EnumOptionsTag), - strippedLocations(internal.FileEnumsTag, 0, internal.EnumValuesTag, 0, internal.EnumValOptionsTag), - strippedLocations(internal.FileEnumsTag, 0, internal.EnumValuesTag, 1, internal.EnumValOptionsTag), - strippedLocations(internal.FileExtensionsTag, 0, internal.FieldOptionsTag), - strippedLocations(internal.FileServicesTag, 0, internal.ServiceOptionsTag), - strippedLocations(internal.FileServicesTag, 0, internal.ServiceMethodsTag, 0, internal.MethodOptionsTag), + strippedLocations(tags.File_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_Field, 0, tags.Field_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_Field, 1, tags.Field_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_OneofDecl, 0, tags.Oneof_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_ExtensionRange, 0, tags.Message_ExtensionRange_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_NestedType, 0, tags.Message_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_NestedType, 0, tags.Message_Field, 0, tags.Field_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_EnumType, 0, tags.Enum_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_EnumType, 0, tags.Enum_Value, 0, tags.EnumValue_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_EnumType, 0, tags.Enum_Value, 1, tags.EnumValue_Options), + strippedLocations(tags.File_MessageType, 0, tags.Message_Extension, 0, tags.Field_Options), + strippedLocations(tags.File_EnumType, 0, tags.Enum_Options), + strippedLocations(tags.File_EnumType, 0, tags.Enum_Value, 0, tags.EnumValue_Options), + strippedLocations(tags.File_EnumType, 0, tags.Enum_Value, 1, tags.EnumValue_Options), + strippedLocations(tags.File_Extension, 0, tags.Field_Options), + strippedLocations(tags.File_Service, 0, tags.Service_Options), + strippedLocations(tags.File_Service, 0, tags.Service_Method, 0, tags.Method_Options), ), }, } diff --git a/parser/result.go b/parser/result.go index 8ad6993bc..24a558784 100644 --- a/parser/result.go +++ b/parser/result.go @@ -29,6 +29,7 @@ import ( "github.com/bufbuild/protocompile/ast" "github.com/bufbuild/protocompile/internal" "github.com/bufbuild/protocompile/internal/editions" + "github.com/bufbuild/protocompile/internal/tags" "github.com/bufbuild/protocompile/reporter" ) @@ -277,13 +278,13 @@ func (r *result) addExtensions(ext *ast.ExtendNode, flds *[]*descriptorpb.FieldD case *ast.FieldNode: count++ // use higher limit since we don't know yet whether extendee is messageset wire format - fd := r.asFieldDescriptor(decl, internal.MaxTag, syntax, handler) + fd := r.asFieldDescriptor(decl, tags.MessageSetMax, syntax, handler) fd.Extendee = proto.String(extendee) *flds = append(*flds, fd) case *ast.GroupNode: count++ // ditto: use higher limit right now - fd, md := r.asGroupDescriptors(decl, syntax, internal.MaxTag, handler, depth+1) + fd, md := r.asGroupDescriptors(decl, syntax, tags.MessageSetMax, handler, depth+1) fd.Extendee = proto.String(extendee) *flds = append(*flds, fd) *msgs = append(*msgs, md) @@ -596,7 +597,7 @@ func (r *result) addMessageBody(msgd *descriptorpb.DescriptorProto, body *ast.Me // now that we have options, we can see if this uses messageset wire format, which // impacts how we validate tag numbers in any fields in the message - maxTag := int32(internal.MaxNormalTag) + maxTag := int32(tags.FieldMax) messageSetOpt, err := r.isMessageSetWireFormat("message "+msgd.GetName(), msgd, handler) if err != nil { return @@ -606,7 +607,7 @@ func (r *result) addMessageBody(msgd *descriptorpb.DescriptorProto, body *ast.Me nodeInfo := r.file.NodeInfo(node) _ = handler.HandleErrorf(nodeInfo, "messages with message-set wire format are not allowed with proto3 syntax") } - maxTag = internal.MaxTag // higher limit for messageset wire format + maxTag = tags.MessageSetMax // higher limit for messageset wire format } rsvdNames := map[string]ast.SourcePos{} @@ -774,8 +775,8 @@ func (r *result) checkTag(n ast.Node, v uint64, maxTag int32) error { return reporter.Errorf(r.file.NodeInfo(n), "tag number %d must be greater than zero", v) case v > uint64(maxTag): return reporter.Errorf(r.file.NodeInfo(n), "tag number %d is higher than max allowed tag number (%d)", v, maxTag) - case v >= internal.SpecialReservedStart && v <= internal.SpecialReservedEnd: - return reporter.Errorf(r.file.NodeInfo(n), "tag number %d is in disallowed reserved range %d-%d", v, internal.SpecialReservedStart, internal.SpecialReservedEnd) + case v >= tags.FirstReserved && v <= tags.LastReserved: + return reporter.Errorf(r.file.NodeInfo(n), "tag number %d is in disallowed reserved range %d-%d", v, tags.FirstReserved, tags.LastReserved) default: return nil } diff --git a/sourceinfo/source_code_info.go b/sourceinfo/source_code_info.go index 320aaa5d5..7712cb439 100644 --- a/sourceinfo/source_code_info.go +++ b/sourceinfo/source_code_info.go @@ -29,6 +29,7 @@ import ( "github.com/bufbuild/protocompile/ast" "github.com/bufbuild/protocompile/internal" + "github.com/bufbuild/protocompile/internal/tags" ) // OptionIndex is a mapping of AST nodes that define options to corresponding @@ -146,13 +147,13 @@ func generateSourceInfoForFile(opts OptionIndex, sci *sourceCodeInfo, file *ast. sci.newLocWithoutComments(file, nil) if file.Syntax != nil { - sci.newLocWithComments(file.Syntax, append(path, internal.FileSyntaxTag)) + sci.newLocWithComments(file.Syntax, append(path, tags.File_Syntax)) } if file.Edition != nil { // Despite editions having its own field, protoc behavior sets the path in source code - // info as [internal.FileSyntaxTag] and this is vaguely outlined in descriptor.proto + // info as [tag.File_Syntax] and this is vaguely outlined in descriptor.proto // https://github.com/protocolbuffers/protobuf/blob/22e1e6bd90aa8dc35f8cc28b5d7fc03858060f0b/src/google/protobuf/descriptor.proto#L137-L144 - sci.newLocWithComments(file.Edition, append(path, internal.FileSyntaxTag)) + sci.newLocWithComments(file.Edition, append(path, tags.File_Syntax)) } var depIndex, pubDepIndex, weakDepIndex, optIndex, msgIndex, enumIndex, extendIndex, svcIndex int32 @@ -160,32 +161,32 @@ func generateSourceInfoForFile(opts OptionIndex, sci *sourceCodeInfo, file *ast. for _, child := range file.Decls { switch child := child.(type) { case *ast.ImportNode: - sci.newLocWithComments(child, append(path, internal.FileDependencyTag, depIndex)) + sci.newLocWithComments(child, append(path, tags.File_Dependency, depIndex)) depIndex++ if child.Public != nil { - sci.newLoc(child.Public, append(path, internal.FilePublicDependencyTag, pubDepIndex)) + sci.newLoc(child.Public, append(path, tags.File_PublicDependency, pubDepIndex)) pubDepIndex++ } else if child.Weak != nil { - sci.newLoc(child.Weak, append(path, internal.FileWeakDependencyTag, weakDepIndex)) + sci.newLoc(child.Weak, append(path, tags.File_WeakDependency, weakDepIndex)) weakDepIndex++ } case *ast.PackageNode: - sci.newLocWithComments(child, append(path, internal.FilePackageTag)) + sci.newLocWithComments(child, append(path, tags.File_Package)) case *ast.OptionNode: - generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, internal.FileOptionsTag)) + generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, tags.File_Options)) case *ast.MessageNode: - generateSourceCodeInfoForMessage(opts, sci, child, nil, append(path, internal.FileMessagesTag, msgIndex)) + generateSourceCodeInfoForMessage(opts, sci, child, nil, append(path, tags.File_MessageType, msgIndex)) msgIndex++ case *ast.EnumNode: - generateSourceCodeInfoForEnum(opts, sci, child, append(path, internal.FileEnumsTag, enumIndex)) + generateSourceCodeInfoForEnum(opts, sci, child, append(path, tags.File_EnumType, enumIndex)) enumIndex++ case *ast.ExtendNode: - extsPath := append(path, internal.FileExtensionsTag) //nolint:gocritic // intentionally creating new slice var + extsPath := append(path, tags.File_Extension) //nolint:gocritic // intentionally creating new slice var // we clone the path here so that append can't mutate extsPath, since they may share storage - msgsPath := append(internal.ClonePath(path), internal.FileMessagesTag) + msgsPath := append(internal.ClonePath(path), tags.File_MessageType) generateSourceCodeInfoForExtensions(opts, sci, child, &extendIndex, &msgIndex, extsPath, msgsPath) case *ast.ServiceNode: - generateSourceCodeInfoForService(opts, sci, child, append(path, internal.FileServicesTag, svcIndex)) + generateSourceCodeInfoForService(opts, sci, child, append(path, tags.File_Service, svcIndex)) svcIndex++ } } @@ -211,32 +212,32 @@ func generateSourceCodeInfoForOption(opts OptionIndex, sci *sourceCodeInfo, n *a // it's an uninterpreted option optPath := path - optPath = append(optPath, internal.UninterpretedOptionsTag, *uninterpIndex) + optPath = append(optPath, tags.UninterpretedOption, *uninterpIndex) *uninterpIndex++ sci.newLoc(n, optPath) var valTag int32 switch n.Val.(type) { case ast.IdentValueNode: - valTag = internal.UninterpretedIdentTag + valTag = tags.UninterpretedOption_IdentifierValue case *ast.NegativeIntLiteralNode: - valTag = internal.UninterpretedNegIntTag + valTag = tags.UninterpretedOption_NegativeIntValue case ast.IntValueNode: - valTag = internal.UninterpretedPosIntTag + valTag = tags.UninterpretedOption_PositiveIntValue case ast.FloatValueNode: - valTag = internal.UninterpretedDoubleTag + valTag = tags.UninterpretedOption_DoubleValue case ast.StringValueNode: - valTag = internal.UninterpretedStringTag + valTag = tags.UninterpretedOption_StringValue case *ast.MessageLiteralNode: - valTag = internal.UninterpretedAggregateTag + valTag = tags.UninterpretedOption_AggregateValue } if valTag != 0 { sci.newLoc(n.Val, append(optPath, valTag)) } for j, nn := range n.Name.Parts { optNmPath := optPath - optNmPath = append(optNmPath, internal.UninterpretedNameTag, int32(j)) + optNmPath = append(optNmPath, tags.UninterpretedOption_Name, int32(j)) sci.newLoc(nn, optNmPath) - sci.newLoc(nn.Name, append(optNmPath, internal.UninterpretedNameNameTag)) + sci.newLoc(nn.Name, append(optNmPath, tags.UninterpretedOption_NamePart_NamePart)) } } @@ -273,12 +274,12 @@ func generateSourceInfoForOptionChildren(sci *sourceCodeInfo, n ast.ValueNode, p } fullPath := combinePathsForOption(pathPrefix, fieldInfo.Path) locationNode := ast.Node(fieldNode) - if fieldNode.Name.IsAnyTypeReference() && fullPath[len(fullPath)-1] == internal.AnyValueTag { + if fieldNode.Name.IsAnyTypeReference() && fullPath[len(fullPath)-1] == tags.Any_Value { // This is a special expanded Any. So also insert a location // for the type URL field. typeURLPath := make([]int32, len(fullPath)) copy(typeURLPath, fullPath) - typeURLPath[len(typeURLPath)-1] = internal.AnyTypeURLTag + typeURLPath[len(typeURLPath)-1] = tags.Any_TypeUrl sci.newLoc(fieldNode.Name, fullPath) // And create the next location so it's just the value, // not the full field definition. @@ -327,11 +328,11 @@ func generateSourceCodeInfoForMessage(opts OptionIndex, sci *sourceCodeInfo, n a } sci.newBlockLocWithComments(n, openBrace, path) - sci.newLoc(n.MessageName(), append(path, internal.MessageNameTag)) + sci.newLoc(n.MessageName(), append(path, tags.Message_Name)) // matching protoc, which emits the corresponding field type name (for group fields) // right after the source location for the group message name if fieldPath != nil { - sci.newLoc(n.MessageName(), append(fieldPath, internal.FieldTypeNameTag)) + sci.newLoc(n.MessageName(), append(fieldPath, tags.Field_TypeName)) } var optIndex, fieldIndex, oneofIndex, extendIndex, nestedMsgIndex int32 @@ -339,47 +340,47 @@ func generateSourceCodeInfoForMessage(opts OptionIndex, sci *sourceCodeInfo, n a for _, child := range decls { switch child := child.(type) { case *ast.OptionNode: - generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, internal.MessageOptionsTag)) + generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, tags.Message_Options)) case *ast.FieldNode: - generateSourceCodeInfoForField(opts, sci, child, append(path, internal.MessageFieldsTag, fieldIndex)) + generateSourceCodeInfoForField(opts, sci, child, append(path, tags.Message_Field, fieldIndex)) fieldIndex++ case *ast.GroupNode: - fldPath := append(path, internal.MessageFieldsTag, fieldIndex) //nolint:gocritic // intentionally creating new slice var + fldPath := append(path, tags.Message_Field, fieldIndex) //nolint:gocritic // intentionally creating new slice var generateSourceCodeInfoForField(opts, sci, child, fldPath) fieldIndex++ // we clone the path here so that append can't mutate fldPath, since they may share storage - msgPath := append(internal.ClonePath(path), internal.MessageNestedMessagesTag, nestedMsgIndex) + msgPath := append(internal.ClonePath(path), tags.Message_NestedType, nestedMsgIndex) generateSourceCodeInfoForMessage(opts, sci, child.AsMessage(), fldPath, msgPath) nestedMsgIndex++ case *ast.MapFieldNode: - generateSourceCodeInfoForField(opts, sci, child, append(path, internal.MessageFieldsTag, fieldIndex)) + generateSourceCodeInfoForField(opts, sci, child, append(path, tags.Message_Field, fieldIndex)) fieldIndex++ nestedMsgIndex++ case *ast.OneofNode: - fldsPath := append(path, internal.MessageFieldsTag) //nolint:gocritic // intentionally creating new slice var + fldsPath := append(path, tags.Message_Field) //nolint:gocritic // intentionally creating new slice var // we clone the path here and below so that append ops can't mutate // fldPath or msgsPath, since they may otherwise share storage - msgsPath := append(internal.ClonePath(path), internal.MessageNestedMessagesTag) - ooPath := append(internal.ClonePath(path), internal.MessageOneofsTag, oneofIndex) + msgsPath := append(internal.ClonePath(path), tags.Message_NestedType) + ooPath := append(internal.ClonePath(path), tags.Message_OneofDecl, oneofIndex) generateSourceCodeInfoForOneof(opts, sci, child, &fieldIndex, &nestedMsgIndex, fldsPath, msgsPath, ooPath) oneofIndex++ case *ast.MessageNode: - generateSourceCodeInfoForMessage(opts, sci, child, nil, append(path, internal.MessageNestedMessagesTag, nestedMsgIndex)) + generateSourceCodeInfoForMessage(opts, sci, child, nil, append(path, tags.Message_NestedType, nestedMsgIndex)) nestedMsgIndex++ case *ast.EnumNode: - generateSourceCodeInfoForEnum(opts, sci, child, append(path, internal.MessageEnumsTag, nestedEnumIndex)) + generateSourceCodeInfoForEnum(opts, sci, child, append(path, tags.Message_EnumType, nestedEnumIndex)) nestedEnumIndex++ case *ast.ExtendNode: - extsPath := append(path, internal.MessageExtensionsTag) //nolint:gocritic // intentionally creating new slice var + extsPath := append(path, tags.Message_Extension) //nolint:gocritic // intentionally creating new slice var // we clone the path here so that append can't mutate extsPath, since they may share storage - msgsPath := append(internal.ClonePath(path), internal.MessageNestedMessagesTag) + msgsPath := append(internal.ClonePath(path), tags.Message_NestedType) generateSourceCodeInfoForExtensions(opts, sci, child, &extendIndex, &nestedMsgIndex, extsPath, msgsPath) case *ast.ExtensionRangeNode: - generateSourceCodeInfoForExtensionRanges(opts, sci, child, &extRangeIndex, append(path, internal.MessageExtensionRangesTag)) + generateSourceCodeInfoForExtensionRanges(opts, sci, child, &extRangeIndex, append(path, tags.Message_ExtensionRange)) case *ast.ReservedNode: if len(child.Names) > 0 { resPath := path - resPath = append(resPath, internal.MessageReservedNamesTag) + resPath = append(resPath, tags.Message_ReservedName) sci.newLocWithComments(child, resPath) for _, rn := range child.Names { sci.newLoc(rn, append(resPath, reservedNameIndex)) @@ -389,7 +390,7 @@ func generateSourceCodeInfoForMessage(opts OptionIndex, sci *sourceCodeInfo, n a // For editions, reserved names are identifiers. if len(child.Identifiers) > 0 { resPath := path - resPath = append(resPath, internal.MessageReservedNamesTag) + resPath = append(resPath, tags.Message_ReservedName) sci.newLocWithComments(child, resPath) for _, rn := range child.Identifiers { sci.newLoc(rn, append(resPath, reservedNameIndex)) @@ -398,7 +399,7 @@ func generateSourceCodeInfoForMessage(opts OptionIndex, sci *sourceCodeInfo, n a } if len(child.Ranges) > 0 { resPath := path - resPath = append(resPath, internal.MessageReservedRangesTag) + resPath = append(resPath, tags.Message_ReservedRange) sci.newLocWithComments(child, resPath) for _, rr := range child.Ranges { generateSourceCodeInfoForReservedRange(sci, rr, append(resPath, reservedRangeIndex)) @@ -411,20 +412,20 @@ func generateSourceCodeInfoForMessage(opts OptionIndex, sci *sourceCodeInfo, n a func generateSourceCodeInfoForEnum(opts OptionIndex, sci *sourceCodeInfo, n *ast.EnumNode, path []int32) { sci.newBlockLocWithComments(n, n.OpenBrace, path) - sci.newLoc(n.Name, append(path, internal.EnumNameTag)) + sci.newLoc(n.Name, append(path, tags.Enum_Name)) var optIndex, valIndex, reservedNameIndex, reservedRangeIndex int32 for _, child := range n.Decls { switch child := child.(type) { case *ast.OptionNode: - generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, internal.EnumOptionsTag)) + generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, tags.Enum_Options)) case *ast.EnumValueNode: - generateSourceCodeInfoForEnumValue(opts, sci, child, append(path, internal.EnumValuesTag, valIndex)) + generateSourceCodeInfoForEnumValue(opts, sci, child, append(path, tags.Enum_Value, valIndex)) valIndex++ case *ast.ReservedNode: if len(child.Names) > 0 { resPath := path - resPath = append(resPath, internal.EnumReservedNamesTag) + resPath = append(resPath, tags.Enum_ReservedName) sci.newLocWithComments(child, resPath) for _, rn := range child.Names { sci.newLoc(rn, append(resPath, reservedNameIndex)) @@ -433,7 +434,7 @@ func generateSourceCodeInfoForEnum(opts OptionIndex, sci *sourceCodeInfo, n *ast } if len(child.Ranges) > 0 { resPath := path - resPath = append(resPath, internal.EnumReservedRangesTag) + resPath = append(resPath, tags.Enum_ReservedRange) sci.newLocWithComments(child, resPath) for _, rr := range child.Ranges { generateSourceCodeInfoForReservedRange(sci, rr, append(resPath, reservedRangeIndex)) @@ -446,13 +447,13 @@ func generateSourceCodeInfoForEnum(opts OptionIndex, sci *sourceCodeInfo, n *ast func generateSourceCodeInfoForEnumValue(opts OptionIndex, sci *sourceCodeInfo, n *ast.EnumValueNode, path []int32) { sci.newLocWithComments(n, path) - sci.newLoc(n.Name, append(path, internal.EnumValNameTag)) - sci.newLoc(n.Number, append(path, internal.EnumValNumberTag)) + sci.newLoc(n.Name, append(path, tags.EnumValue_Name)) + sci.newLoc(n.Number, append(path, tags.EnumValue_Number)) // enum value options if n.Options != nil { optsPath := path - optsPath = append(optsPath, internal.EnumValOptionsTag) + optsPath = append(optsPath, tags.EnumValue_Options) sci.newLoc(n.Options, optsPath) var optIndex int32 for _, opt := range n.Options.GetElements() { @@ -463,14 +464,14 @@ func generateSourceCodeInfoForEnumValue(opts OptionIndex, sci *sourceCodeInfo, n func generateSourceCodeInfoForReservedRange(sci *sourceCodeInfo, n *ast.RangeNode, path []int32) { sci.newLoc(n, path) - sci.newLoc(n.StartVal, append(path, internal.ReservedRangeStartTag)) + sci.newLoc(n.StartVal, append(path, tags.Message_ReservedRange_Start)) switch { case n.EndVal != nil: - sci.newLoc(n.EndVal, append(path, internal.ReservedRangeEndTag)) + sci.newLoc(n.EndVal, append(path, tags.Message_ReservedRange_End)) case n.Max != nil: - sci.newLoc(n.Max, append(path, internal.ReservedRangeEndTag)) + sci.newLoc(n.Max, append(path, tags.Message_ReservedRange_End)) default: - sci.newLoc(n.StartVal, append(path, internal.ReservedRangeEndTag)) + sci.newLoc(n.StartVal, append(path, tags.Message_ReservedRange_End)) } } @@ -494,13 +495,13 @@ func generateSourceCodeInfoForExtensions(opts OptionIndex, sci *sourceCodeInfo, func generateSourceCodeInfoForOneof(opts OptionIndex, sci *sourceCodeInfo, n *ast.OneofNode, fieldIndex, nestedMsgIndex *int32, fieldPath, nestedMsgPath, oneofPath []int32) { sci.newBlockLocWithComments(n, n.OpenBrace, oneofPath) - sci.newLoc(n.Name, append(oneofPath, internal.OneofNameTag)) + sci.newLoc(n.Name, append(oneofPath, tags.Oneof_Name)) var optIndex int32 for _, child := range n.Decls { switch child := child.(type) { case *ast.OptionNode: - generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(oneofPath, internal.OneofOptionsTag)) + generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(oneofPath, tags.Oneof_Options)) case *ast.FieldNode: generateSourceCodeInfoForField(opts, sci, child, append(fieldPath, *fieldIndex)) *fieldIndex++ @@ -525,40 +526,40 @@ func generateSourceCodeInfoForField(opts OptionIndex, sci *sourceCodeInfo, n ast // comments will appear on group message sci.newLocWithoutComments(n, path) if n.FieldExtendee() != nil { - sci.newLoc(n.FieldExtendee(), append(path, internal.FieldExtendeeTag)) + sci.newLoc(n.FieldExtendee(), append(path, tags.Field_Extendee)) } if n.FieldLabel() != nil { // no comments here either (label is first token for group, so we want // to leave the comments to be associated with the group message instead) - sci.newLocWithoutComments(n.FieldLabel(), append(path, internal.FieldLabelTag)) + sci.newLocWithoutComments(n.FieldLabel(), append(path, tags.Field_Label)) } - sci.newLoc(n.FieldType(), append(path, internal.FieldTypeTag)) + sci.newLoc(n.FieldType(), append(path, tags.Field_Type)) // let the name comments be attributed to the group name - sci.newLocWithoutComments(n.FieldName(), append(path, internal.FieldNameTag)) + sci.newLocWithoutComments(n.FieldName(), append(path, tags.Field_Name)) } else { sci.newLocWithComments(n, path) if n.FieldExtendee() != nil { - sci.newLoc(n.FieldExtendee(), append(path, internal.FieldExtendeeTag)) + sci.newLoc(n.FieldExtendee(), append(path, tags.Field_Extendee)) } if n.FieldLabel() != nil { - sci.newLoc(n.FieldLabel(), append(path, internal.FieldLabelTag)) + sci.newLoc(n.FieldLabel(), append(path, tags.Field_Label)) } - var tag int32 + var t int32 if _, isScalar := internal.FieldTypes[fieldType]; isScalar { - tag = internal.FieldTypeTag + t = tags.Field_Type } else { // this is a message or an enum, so attribute type location // to the type name field - tag = internal.FieldTypeNameTag + t = tags.Field_TypeName } - sci.newLoc(n.FieldType(), append(path, tag)) - sci.newLoc(n.FieldName(), append(path, internal.FieldNameTag)) + sci.newLoc(n.FieldType(), append(path, t)) + sci.newLoc(n.FieldName(), append(path, tags.Field_Name)) } - sci.newLoc(n.FieldTag(), append(path, internal.FieldNumberTag)) + sci.newLoc(n.FieldTag(), append(path, tags.Field_Number)) if n.GetOptions() != nil { optsPath := path - optsPath = append(optsPath, internal.FieldOptionsTag) + optsPath = append(optsPath, tags.Field_Options) sci.newLoc(n.GetOptions(), optsPath) var optIndex int32 for _, opt := range n.GetOptions().GetElements() { @@ -574,14 +575,14 @@ func generateSourceCodeInfoForExtensionRanges(opts OptionIndex, sci *sourceCodeI path := append(path, *extRangeIndex) *extRangeIndex++ sci.newLoc(child, path) - sci.newLoc(child.StartVal, append(path, internal.ExtensionRangeStartTag)) + sci.newLoc(child.StartVal, append(path, tags.Message_ExtensionRange_Start)) switch { case child.EndVal != nil: - sci.newLoc(child.EndVal, append(path, internal.ExtensionRangeEndTag)) + sci.newLoc(child.EndVal, append(path, tags.Message_ExtensionRange_End)) case child.Max != nil: - sci.newLoc(child.Max, append(path, internal.ExtensionRangeEndTag)) + sci.newLoc(child.Max, append(path, tags.Message_ExtensionRange_End)) default: - sci.newLoc(child.StartVal, append(path, internal.ExtensionRangeEndTag)) + sci.newLoc(child.StartVal, append(path, tags.Message_ExtensionRange_End)) } } // options for all ranges go after the start+end values @@ -590,7 +591,7 @@ func generateSourceCodeInfoForExtensionRanges(opts OptionIndex, sci *sourceCodeI startExtRangeIndex++ if n.Options != nil { optsPath := path - optsPath = append(optsPath, internal.ExtensionRangeOptionsTag) + optsPath = append(optsPath, tags.Message_ExtensionRange_Options) sci.newLoc(n.Options, optsPath) var optIndex int32 for _, opt := range n.Options.GetElements() { @@ -602,14 +603,14 @@ func generateSourceCodeInfoForExtensionRanges(opts OptionIndex, sci *sourceCodeI func generateSourceCodeInfoForService(opts OptionIndex, sci *sourceCodeInfo, n *ast.ServiceNode, path []int32) { sci.newBlockLocWithComments(n, n.OpenBrace, path) - sci.newLoc(n.Name, append(path, internal.ServiceNameTag)) + sci.newLoc(n.Name, append(path, tags.Service_Name)) var optIndex, rpcIndex int32 for _, child := range n.Decls { switch child := child.(type) { case *ast.OptionNode: - generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, internal.ServiceOptionsTag)) + generateSourceCodeInfoForOption(opts, sci, child, false, &optIndex, append(path, tags.Service_Options)) case *ast.RPCNode: - generateSourceCodeInfoForMethod(opts, sci, child, append(path, internal.ServiceMethodsTag, rpcIndex)) + generateSourceCodeInfoForMethod(opts, sci, child, append(path, tags.Service_Method, rpcIndex)) rpcIndex++ } } @@ -621,18 +622,18 @@ func generateSourceCodeInfoForMethod(opts OptionIndex, sci *sourceCodeInfo, n *a } else { sci.newLocWithComments(n, path) } - sci.newLoc(n.Name, append(path, internal.MethodNameTag)) + sci.newLoc(n.Name, append(path, tags.Method_Name)) if n.Input.Stream != nil { - sci.newLoc(n.Input.Stream, append(path, internal.MethodInputStreamTag)) + sci.newLoc(n.Input.Stream, append(path, tags.Method_ClientStreaming)) } - sci.newLoc(n.Input.MessageType, append(path, internal.MethodInputTag)) + sci.newLoc(n.Input.MessageType, append(path, tags.Method_InputType)) if n.Output.Stream != nil { - sci.newLoc(n.Output.Stream, append(path, internal.MethodOutputStreamTag)) + sci.newLoc(n.Output.Stream, append(path, tags.Method_ServerStreaming)) } - sci.newLoc(n.Output.MessageType, append(path, internal.MethodOutputTag)) + sci.newLoc(n.Output.MessageType, append(path, tags.Method_OutputType)) optsPath := path - optsPath = append(optsPath, internal.MethodOptionsTag) + optsPath = append(optsPath, tags.Method_Options) var optIndex int32 for _, decl := range n.Decls { if opt, ok := decl.(*ast.OptionNode); ok { diff --git a/walk/walk.go b/walk/walk.go index 5c8d261f1..6c6b7fc85 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -39,7 +39,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" - "github.com/bufbuild/protocompile/internal" + "github.com/bufbuild/protocompile/internal/tags" ) // Descriptors walks all descriptors in the given file using a depth-first @@ -267,7 +267,7 @@ func (w *protoWalker) walkDescriptorProtos(file *descriptorpb.FileDescriptorProt var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.FileMessagesTag, int32(i)) + p = append(p, tags.File_MessageType, int32(i)) } if err := w.walkDescriptorProto(prefix, p, msg); err != nil { return err @@ -277,7 +277,7 @@ func (w *protoWalker) walkDescriptorProtos(file *descriptorpb.FileDescriptorProt var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.FileEnumsTag, int32(i)) + p = append(p, tags.File_EnumType, int32(i)) } if err := w.walkEnumDescriptorProto(prefix, p, en); err != nil { return err @@ -287,7 +287,7 @@ func (w *protoWalker) walkDescriptorProtos(file *descriptorpb.FileDescriptorProt var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.FileExtensionsTag, int32(i)) + p = append(p, tags.File_Extension, int32(i)) } fqn := prefix + ext.GetName() if err := w.enter(protoreflect.FullName(fqn), p, ext); err != nil { @@ -303,7 +303,7 @@ func (w *protoWalker) walkDescriptorProtos(file *descriptorpb.FileDescriptorProt var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.FileServicesTag, int32(i)) + p = append(p, tags.File_Service, int32(i)) } fqn := prefix + svc.GetName() if err := w.enter(protoreflect.FullName(fqn), p, svc); err != nil { @@ -313,7 +313,7 @@ func (w *protoWalker) walkDescriptorProtos(file *descriptorpb.FileDescriptorProt var mp protoreflect.SourcePath if w.usePath { mp = p - mp = append(mp, internal.ServiceMethodsTag, int32(j)) + mp = append(mp, tags.Service_Method, int32(j)) } mtdFqn := fqn + "." + mtd.GetName() if err := w.enter(protoreflect.FullName(mtdFqn), mp, mtd); err != nil { @@ -344,7 +344,7 @@ func (w *protoWalker) walkDescriptorProto(prefix string, path protoreflect.Sourc var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.MessageFieldsTag, int32(i)) + p = append(p, tags.Message_Field, int32(i)) } fqn := prefix + fld.GetName() if err := w.enter(protoreflect.FullName(fqn), p, fld); err != nil { @@ -360,7 +360,7 @@ func (w *protoWalker) walkDescriptorProto(prefix string, path protoreflect.Sourc var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.MessageOneofsTag, int32(i)) + p = append(p, tags.Message_OneofDecl, int32(i)) } fqn := prefix + oo.GetName() if err := w.enter(protoreflect.FullName(fqn), p, oo); err != nil { @@ -376,7 +376,7 @@ func (w *protoWalker) walkDescriptorProto(prefix string, path protoreflect.Sourc var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.MessageNestedMessagesTag, int32(i)) + p = append(p, tags.Message_NestedType, int32(i)) } if err := w.walkDescriptorProto(prefix, p, nested); err != nil { return err @@ -386,7 +386,7 @@ func (w *protoWalker) walkDescriptorProto(prefix string, path protoreflect.Sourc var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.MessageEnumsTag, int32(i)) + p = append(p, tags.Message_EnumType, int32(i)) } if err := w.walkEnumDescriptorProto(prefix, p, en); err != nil { return err @@ -396,7 +396,7 @@ func (w *protoWalker) walkDescriptorProto(prefix string, path protoreflect.Sourc var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.MessageExtensionsTag, int32(i)) + p = append(p, tags.Message_Extension, int32(i)) } fqn := prefix + ext.GetName() if err := w.enter(protoreflect.FullName(fqn), p, ext); err != nil { @@ -425,7 +425,7 @@ func (w *protoWalker) walkEnumDescriptorProto(prefix string, path protoreflect.S var p protoreflect.SourcePath if w.usePath { p = path - p = append(p, internal.EnumValuesTag, int32(i)) + p = append(p, tags.Enum_Value, int32(i)) } fqn := prefix + val.GetName() if err := w.enter(protoreflect.FullName(fqn), p, val); err != nil { diff --git a/wellknownimports/wellknownimports.go b/wellknownimports/wellknownimports.go index 3ac8331f2..93808fa8d 100644 --- a/wellknownimports/wellknownimports.go +++ b/wellknownimports/wellknownimports.go @@ -20,6 +20,12 @@ import ( "embed" "io" "io/fs" + "sync" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/descriptorpb" "github.com/bufbuild/protocompile" ) @@ -57,3 +63,27 @@ func WithStandardImports(resolver protocompile.Resolver) protocompile.Resolver { }, } } + +var ( + //go:embed wkt.pb + encoded []byte + registry = sync.OnceValue(func() *protoregistry.Files { + fds := new(descriptorpb.FileDescriptorSet) + if err := proto.Unmarshal(encoded, fds); err != nil { + panic(err) + } + + reg, err := protodesc.NewFiles(fds) + if err != nil { + panic(err) + } + + return reg + }) +) + +// Files returns reflection information for the WKTs included with protocompile, +// which are not the ones bundled with protoreflect. +func Files() *protoregistry.Files { + return registry() +} diff --git a/wellknownimports/wkt.pb b/wellknownimports/wkt.pb new file mode 100644 index 000000000..f3d490781 Binary files /dev/null and b/wellknownimports/wkt.pb differ