mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-08 19:14:05 +00:00
reflect: add Index method to descriptor
Useful for dealing with SourceCodeInfo location paths, which identify entities by their index. Change-Id: I2034fc06b14c9b29b26e356fad21e106f63fbd14 Reviewed-on: https://go-review.googlesource.com/134115 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
c84688961e
commit
3de06c0868
@ -114,7 +114,7 @@ var listTypesTemplate = template.Must(template.New("").Funcs(template.FuncMap{
|
||||
panic("already initialized")
|
||||
}
|
||||
t.{{$nameMeta}} = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, {{printf "%v" (eq . "EnumValue")}})
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, {{printf "%v" (eq . "EnumValue")}})
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
|
@ -45,6 +45,11 @@ type Descriptor interface {
|
||||
// Support for this functionality is optional and may return (nil, false).
|
||||
Parent() (Descriptor, bool)
|
||||
|
||||
// Index returns the the index of this descriptor within its parent.
|
||||
// It returns 0 if the descriptor does not have a parent or if the parent
|
||||
// is unknown.
|
||||
Index() int
|
||||
|
||||
// Syntax is the protobuf syntax.
|
||||
Syntax() Syntax // e.g., Proto2 or Proto3
|
||||
|
||||
|
@ -27,6 +27,7 @@ var (
|
||||
type placeholderName pref.FullName
|
||||
|
||||
func (t placeholderName) Parent() (pref.Descriptor, bool) { return nil, false }
|
||||
func (t placeholderName) Index() int { return 0 }
|
||||
func (t placeholderName) Syntax() pref.Syntax { return 0 }
|
||||
func (t placeholderName) Name() pref.Name { return pref.FullName(t).Name() }
|
||||
func (t placeholderName) FullName() pref.FullName { return pref.FullName(t) }
|
||||
|
@ -33,7 +33,7 @@ func (p *messagesMeta) lazyInit(parent protoreflect.Descriptor, ts []Message) *m
|
||||
panic("already initialized")
|
||||
}
|
||||
t.messageMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -83,7 +83,7 @@ func (p *fieldsMeta) lazyInit(parent protoreflect.Descriptor, ts []Field) *field
|
||||
panic("already initialized")
|
||||
}
|
||||
t.fieldMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -166,7 +166,7 @@ func (p *oneofsMeta) lazyInit(parent protoreflect.Descriptor, ts []Oneof) *oneof
|
||||
panic("already initialized")
|
||||
}
|
||||
t.oneofMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -212,7 +212,7 @@ func (p *extensionsMeta) lazyInit(parent protoreflect.Descriptor, ts []Extension
|
||||
panic("already initialized")
|
||||
}
|
||||
t.extensionMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -258,7 +258,7 @@ func (p *enumsMeta) lazyInit(parent protoreflect.Descriptor, ts []Enum) *enums {
|
||||
panic("already initialized")
|
||||
}
|
||||
t.enumMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -306,7 +306,7 @@ func (p *enumValuesMeta) lazyInit(parent protoreflect.Descriptor, ts []EnumValue
|
||||
panic("already initialized")
|
||||
}
|
||||
t.enumValueMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, true)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, true)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -370,7 +370,7 @@ func (p *servicesMeta) lazyInit(parent protoreflect.Descriptor, ts []Service) *s
|
||||
panic("already initialized")
|
||||
}
|
||||
t.serviceMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
@ -416,7 +416,7 @@ func (p *methodsMeta) lazyInit(parent protoreflect.Descriptor, ts []Method) *met
|
||||
panic("already initialized")
|
||||
}
|
||||
t.methodMeta = &metas[i]
|
||||
t.inheritedMeta.init(nb, parent, t.Name, false)
|
||||
t.inheritedMeta.init(nb, parent, i, t.Name, false)
|
||||
}
|
||||
p.typs = ts
|
||||
})
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
// inheritedMeta is information inherited from the parent.
|
||||
type inheritedMeta struct {
|
||||
parent pref.Descriptor
|
||||
index int
|
||||
syntax pref.Syntax
|
||||
fullName pref.FullName
|
||||
|
||||
@ -24,7 +25,7 @@ type inheritedMeta struct {
|
||||
opts descriptorOptionsMeta
|
||||
}
|
||||
|
||||
func (m *inheritedMeta) init(nb *nameBuilder, parent pref.Descriptor, name pref.Name, child bool) {
|
||||
func (m *inheritedMeta) init(nb *nameBuilder, parent pref.Descriptor, index int, name pref.Name, child bool) {
|
||||
// Most descriptors are namespaced as a child of their parent.
|
||||
// However, EnumValues are the exception in that they are namespaced
|
||||
// as a sibling of the parent Enum type.
|
||||
@ -34,6 +35,7 @@ func (m *inheritedMeta) init(nb *nameBuilder, parent pref.Descriptor, name pref.
|
||||
}
|
||||
|
||||
m.parent = parent
|
||||
m.index = index
|
||||
m.syntax = parent.Syntax()
|
||||
m.fullName = nb.Append(prefix, name)
|
||||
}
|
||||
@ -58,6 +60,7 @@ func newFile(f *File) fileDesc {
|
||||
return fileDesc{f}
|
||||
}
|
||||
func (t fileDesc) Parent() (pref.Descriptor, bool) { return nil, false }
|
||||
func (t fileDesc) Index() int { return 0 }
|
||||
func (t fileDesc) Syntax() pref.Syntax { return t.f.Syntax }
|
||||
func (t fileDesc) Name() pref.Name { return t.f.Package.Name() }
|
||||
func (t fileDesc) FullName() pref.FullName { return t.f.Package }
|
||||
@ -164,6 +167,7 @@ type messageMeta struct {
|
||||
type messageDesc struct{ m *Message }
|
||||
|
||||
func (t messageDesc) Parent() (pref.Descriptor, bool) { return t.m.parent, true }
|
||||
func (t messageDesc) Index() int { return t.m.index }
|
||||
func (t messageDesc) Syntax() pref.Syntax { return t.m.syntax }
|
||||
func (t messageDesc) Name() pref.Name { return t.m.Name }
|
||||
func (t messageDesc) FullName() pref.FullName { return t.m.fullName }
|
||||
@ -194,6 +198,7 @@ type fieldMeta struct {
|
||||
type fieldDesc struct{ f *Field }
|
||||
|
||||
func (t fieldDesc) Parent() (pref.Descriptor, bool) { return t.f.parent, true }
|
||||
func (t fieldDesc) Index() int { return t.f.index }
|
||||
func (t fieldDesc) Syntax() pref.Syntax { return t.f.syntax }
|
||||
func (t fieldDesc) Name() pref.Name { return t.f.Name }
|
||||
func (t fieldDesc) FullName() pref.FullName { return t.f.fullName }
|
||||
@ -278,6 +283,7 @@ type oneofMeta struct {
|
||||
type oneofDesc struct{ o *Oneof }
|
||||
|
||||
func (t oneofDesc) Parent() (pref.Descriptor, bool) { return t.o.parent, true }
|
||||
func (t oneofDesc) Index() int { return t.o.index }
|
||||
func (t oneofDesc) Syntax() pref.Syntax { return t.o.syntax }
|
||||
func (t oneofDesc) Name() pref.Name { return t.o.Name }
|
||||
func (t oneofDesc) FullName() pref.FullName { return t.o.fullName }
|
||||
@ -301,6 +307,7 @@ type extensionDesc struct{ x *Extension }
|
||||
|
||||
func (t extensionDesc) Parent() (pref.Descriptor, bool) { return t.x.parent, true }
|
||||
func (t extensionDesc) Syntax() pref.Syntax { return t.x.syntax }
|
||||
func (t extensionDesc) Index() int { return t.x.index }
|
||||
func (t extensionDesc) Name() pref.Name { return t.x.Name }
|
||||
func (t extensionDesc) FullName() pref.FullName { return t.x.fullName }
|
||||
func (t extensionDesc) IsPlaceholder() bool { return false }
|
||||
@ -334,6 +341,7 @@ type enumMeta struct {
|
||||
type enumDesc struct{ e *Enum }
|
||||
|
||||
func (t enumDesc) Parent() (pref.Descriptor, bool) { return t.e.parent, true }
|
||||
func (t enumDesc) Index() int { return t.e.index }
|
||||
func (t enumDesc) Syntax() pref.Syntax { return t.e.syntax }
|
||||
func (t enumDesc) Name() pref.Name { return t.e.Name }
|
||||
func (t enumDesc) FullName() pref.FullName { return t.e.fullName }
|
||||
@ -351,6 +359,7 @@ type enumValueMeta struct {
|
||||
type enumValueDesc struct{ v *EnumValue }
|
||||
|
||||
func (t enumValueDesc) Parent() (pref.Descriptor, bool) { return t.v.parent, true }
|
||||
func (t enumValueDesc) Index() int { return t.v.index }
|
||||
func (t enumValueDesc) Syntax() pref.Syntax { return t.v.syntax }
|
||||
func (t enumValueDesc) Name() pref.Name { return t.v.Name }
|
||||
func (t enumValueDesc) FullName() pref.FullName { return t.v.fullName }
|
||||
@ -370,6 +379,7 @@ type serviceMeta struct {
|
||||
type serviceDesc struct{ s *Service }
|
||||
|
||||
func (t serviceDesc) Parent() (pref.Descriptor, bool) { return t.s.parent, true }
|
||||
func (t serviceDesc) Index() int { return t.s.index }
|
||||
func (t serviceDesc) Syntax() pref.Syntax { return t.s.syntax }
|
||||
func (t serviceDesc) Name() pref.Name { return t.s.Name }
|
||||
func (t serviceDesc) FullName() pref.FullName { return t.s.fullName }
|
||||
@ -390,6 +400,7 @@ type methodMeta struct {
|
||||
type methodDesc struct{ m *Method }
|
||||
|
||||
func (t methodDesc) Parent() (pref.Descriptor, bool) { return t.m.parent, true }
|
||||
func (t methodDesc) Index() int { return t.m.index }
|
||||
func (t methodDesc) Syntax() pref.Syntax { return t.m.syntax }
|
||||
func (t methodDesc) Name() pref.Name { return t.m.Name }
|
||||
func (t methodDesc) FullName() pref.FullName { return t.m.fullName }
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
type standaloneMessage struct{ m *StandaloneMessage }
|
||||
|
||||
func (t standaloneMessage) Parent() (pref.Descriptor, bool) { return nil, false }
|
||||
func (t standaloneMessage) Index() int { return 0 }
|
||||
func (t standaloneMessage) Syntax() pref.Syntax { return t.m.Syntax }
|
||||
func (t standaloneMessage) Name() pref.Name { return t.m.FullName.Name() }
|
||||
func (t standaloneMessage) FullName() pref.FullName { return t.m.FullName }
|
||||
@ -35,6 +36,7 @@ func (t standaloneMessage) ProtoInternal(pragma.DoNotImplement) {}
|
||||
type standaloneEnum struct{ e *StandaloneEnum }
|
||||
|
||||
func (t standaloneEnum) Parent() (pref.Descriptor, bool) { return nil, false }
|
||||
func (t standaloneEnum) Index() int { return 0 }
|
||||
func (t standaloneEnum) Syntax() pref.Syntax { return t.e.Syntax }
|
||||
func (t standaloneEnum) Name() pref.Name { return t.e.FullName.Name() }
|
||||
func (t standaloneEnum) FullName() pref.FullName { return t.e.FullName }
|
||||
@ -49,6 +51,7 @@ func (t standaloneEnum) ProtoInternal(pragma.DoNotImplement) {}
|
||||
type standaloneExtension struct{ x *StandaloneExtension }
|
||||
|
||||
func (t standaloneExtension) Parent() (pref.Descriptor, bool) { return nil, false }
|
||||
func (t standaloneExtension) Index() int { return 0 }
|
||||
func (t standaloneExtension) Syntax() pref.Syntax { return t.x.Syntax }
|
||||
func (t standaloneExtension) Name() pref.Name { return t.x.FullName.Name() }
|
||||
func (t standaloneExtension) FullName() pref.FullName { return t.x.FullName }
|
||||
|
@ -336,6 +336,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
type M = map[string]interface{}
|
||||
want := M{
|
||||
"Parent": nil,
|
||||
"Index": 0,
|
||||
"Syntax": pref.Proto2,
|
||||
"Name": pref.Name("test"),
|
||||
"FullName": pref.FullName("test"),
|
||||
@ -346,6 +347,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
"Len": 3,
|
||||
"Get:0": M{
|
||||
"Parent": M{"FullName": pref.FullName("test")},
|
||||
"Index": 0,
|
||||
"Syntax": pref.Proto2,
|
||||
"Name": pref.Name("A"),
|
||||
"FullName": pref.FullName("test.A"),
|
||||
@ -355,6 +357,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
"Len": 2,
|
||||
"ByNumber:1": M{
|
||||
"Parent": M{"FullName": pref.FullName("test.A")},
|
||||
"Index": 0,
|
||||
"Name": pref.Name("key"),
|
||||
"FullName": pref.FullName("test.A.key"),
|
||||
"Number": pref.FieldNumber(1),
|
||||
@ -372,6 +375,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
},
|
||||
"ByNumber:2": M{
|
||||
"Parent": M{"FullName": pref.FullName("test.A")},
|
||||
"Index": 1,
|
||||
"Name": pref.Name("value"),
|
||||
"FullName": pref.FullName("test.A.value"),
|
||||
"Number": pref.FieldNumber(2),
|
||||
@ -397,12 +401,14 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
"Extensions": M{"Len": 0},
|
||||
},
|
||||
"ByName:B": M{
|
||||
"Name": pref.Name("B"),
|
||||
"Name": pref.Name("B"),
|
||||
"Index": 1,
|
||||
"Fields": M{
|
||||
"Len": 6,
|
||||
"ByJSONName:field_one": nil,
|
||||
"ByJSONName:fieldOne": M{
|
||||
"Name": pref.Name("field_one"),
|
||||
"Index": 0,
|
||||
"JSONName": "fieldOne",
|
||||
"Default": "hello",
|
||||
"OneofType": M{"Name": pref.Name("O1"), "IsPlaceholder": false},
|
||||
@ -410,6 +416,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
"ByJSONName:fieldTwo": nil,
|
||||
"ByJSONName:Field2": M{
|
||||
"Name": pref.Name("field_two"),
|
||||
"Index": 1,
|
||||
"JSONName": "Field2",
|
||||
"Default": pref.EnumNumber(1),
|
||||
"OneofType": M{"Name": pref.Name("O2"), "IsPlaceholder": false},
|
||||
@ -444,6 +451,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
"ByName:O0": nil,
|
||||
"ByName:O1": M{
|
||||
"FullName": pref.FullName("test.B.O1"),
|
||||
"Index": 0,
|
||||
"Fields": M{
|
||||
"Len": 1,
|
||||
"Get:0": M{"FullName": pref.FullName("test.B.field_one")},
|
||||
@ -451,6 +459,7 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
},
|
||||
"Get:1": M{
|
||||
"FullName": pref.FullName("test.B.O2"),
|
||||
"Index": 1,
|
||||
"Fields": M{
|
||||
"Len": 2,
|
||||
"ByName:field_two": M{"Name": pref.Name("field_two")},
|
||||
@ -475,7 +484,8 @@ func testFileAccessors(t *testing.T, fd pref.FileDescriptor) {
|
||||
},
|
||||
},
|
||||
"Get:2": M{
|
||||
"Name": pref.Name("C"),
|
||||
"Name": pref.Name("C"),
|
||||
"Index": 2,
|
||||
"Messages": M{
|
||||
"Len": 1,
|
||||
"Get:0": M{"FullName": pref.FullName("test.C.A")},
|
||||
|
Loading…
x
Reference in New Issue
Block a user