| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package descriptor | 5 package descriptor |
| 6 | 6 |
| 7 import "strings" | 7 import ( |
| 8 » "strings" |
| 9 ) |
| 8 | 10 |
| 9 // SplitFullName splits package name and service/type name. | 11 const ( |
| 10 func SplitFullName(fullName string) (pkg string, name string) { | 12 » // NumberFileDescriptorProto_Package is the number of package field |
| 13 » // in FileDescriptorProto message. |
| 14 » NumberFileDescriptorProto_Package = 2 |
| 15 » // NumberFileDescriptorProto_Message is the number of message field |
| 16 » // in FileDescriptorProto message. |
| 17 » NumberFileDescriptorProto_Message = 4 |
| 18 » // NumberFileDescriptorProto_Enum is the number of enum field |
| 19 » // in FileDescriptorProto message. |
| 20 » NumberFileDescriptorProto_Enum = 5 |
| 21 » // NumberFileDescriptorProto_Service is the number of service field |
| 22 » // in FileDescriptorProto message. |
| 23 » NumberFileDescriptorProto_Service = 6 |
| 24 |
| 25 » // NumberServiceDescriptorProto_Method is the number of method field |
| 26 » // in ServiceDescriptorProto message. |
| 27 » NumberServiceDescriptorProto_Method = 2 |
| 28 |
| 29 » // NumberDescriptorProto_Field is the number of field field |
| 30 » // in DescriptorProto message. |
| 31 » NumberDescriptorProto_Field = 2 |
| 32 » // NumberDescriptorProto_NestedType is the number of nested_type field |
| 33 » // in DescriptorProto message. |
| 34 » NumberDescriptorProto_NestedType = 3 |
| 35 » // NumberDescriptorProto_EnumType is the number of enum_type field |
| 36 » // in DescriptorProto message. |
| 37 » NumberDescriptorProto_EnumType = 4 |
| 38 » // NumberDescriptorProto_OneOf is the number of oneof_decl field |
| 39 » // in DescriptorProto message. |
| 40 » NumberDescriptorProto_OneOf = 8 |
| 41 |
| 42 » // NumberEnumDescriptorProto_Value is the number of value field |
| 43 » // in EnumDescriptorProto message. |
| 44 » NumberEnumDescriptorProto_Value = 2 |
| 45 ) |
| 46 |
| 47 // splitFullName splits package name and service/type name. |
| 48 func splitFullName(fullName string) (pkg string, name string) { |
| 11 lastDot := strings.LastIndex(fullName, ".") | 49 lastDot := strings.LastIndex(fullName, ".") |
| 12 if lastDot < 0 { | 50 if lastDot < 0 { |
| 13 name = fullName | 51 name = fullName |
| 14 } else { | 52 } else { |
| 15 pkg = fullName[:lastDot] | 53 pkg = fullName[:lastDot] |
| 16 name = fullName[lastDot+1:] | 54 name = fullName[lastDot+1:] |
| 17 } | 55 } |
| 18 return | 56 return |
| 19 } | 57 } |
| 20 | 58 |
| 21 //////////////////////////////////////////////////////////////////////////////// | 59 //////////////////////////////////////////////////////////////////////////////// |
| 22 // FileDescriptorSet | 60 // FileDescriptorSet |
| 23 | 61 |
| 24 // FindFile searches for a FileDescriptorProto by name. | 62 // FindFile searches for a FileDescriptorProto by name. |
| 25 func (s *FileDescriptorSet) FindFile(name string) *FileDescriptorProto { | 63 func (s *FileDescriptorSet) FindFile(name string) int { |
| 26 » for _, x := range s.GetFile() { | 64 » for i, x := range s.GetFile() { |
| 27 if x.GetName() == name { | 65 if x.GetName() == name { |
| 28 » » » return x | 66 » » » return i |
| 29 } | 67 } |
| 30 } | 68 } |
| 31 » return nil | 69 » return -1 |
| 32 } | 70 } |
| 33 | 71 |
| 34 // FindMessage searches for a message by full name. | 72 // Resolve searches for an object by full name. obj can be one of |
| 35 func (s *FileDescriptorSet) FindMessage(fullName string) *DescriptorProto { | 73 // *ServiceDescriptorProto, |
| 36 » pkg, name := SplitFullName(fullName) | 74 // *MethodDescriptorProto, |
| 75 // *DescriptorProto, |
| 76 // *FieldDescriptorProto, |
| 77 // *DescriptorProto, |
| 78 // *EnumDescriptorProto, |
| 79 // *EnumValueDescriptorProto or |
| 80 // nil |
| 81 // |
| 82 // For path, see comment in SourceCodeInfo message. |
| 83 func (s *FileDescriptorSet) Resolve(fullName string) (file *FileDescriptorProto,
obj interface{}, path []int) { |
| 84 » if fullName == "" { |
| 85 » » return nil, nil, nil |
| 86 » } |
| 87 » pkg, name := splitFullName(fullName) |
| 88 |
| 89 » // Check top-level objects. |
| 37 for _, f := range s.GetFile() { | 90 for _, f := range s.GetFile() { |
| 38 if f.GetPackage() == pkg { | 91 if f.GetPackage() == pkg { |
| 39 » » » if x := f.FindMessage(name); x != nil { | 92 » » » if i := f.FindService(name); i != -1 { |
| 40 » » » » return x | 93 » » » » return f, f.Service[i], []int{NumberFileDescript
orProto_Service, i} |
| 94 » » » } |
| 95 » » » if i := f.FindMessage(name); i != -1 { |
| 96 » » » » return f, f.MessageType[i], []int{NumberFileDesc
riptorProto_Message, i} |
| 97 » » » } |
| 98 » » » if i := f.FindEnum(name); i != -1 { |
| 99 » » » » return f, f.EnumType[i], []int{NumberFileDescrip
torProto_Enum, i} |
| 41 } | 100 } |
| 42 } | 101 } |
| 43 } | 102 } |
| 44 » return nil | 103 |
| 104 » // Recurse. |
| 105 » var parent interface{} |
| 106 » file, parent, path = s.Resolve(pkg) |
| 107 » switch parent := parent.(type) { |
| 108 |
| 109 » case *ServiceDescriptorProto: |
| 110 » » if i := parent.FindMethod(name); i != -1 { |
| 111 » » » return file, parent.Method[i], append(path, NumberServic
eDescriptorProto_Method, i) |
| 112 » » } |
| 113 |
| 114 » case *DescriptorProto: |
| 115 » » if i := parent.FindMessage(name); i != -1 { |
| 116 » » » return file, parent.NestedType[i], append(path, NumberDe
scriptorProto_NestedType, i) |
| 117 » » } |
| 118 » » if i := parent.FindEnum(name); i != -1 { |
| 119 » » » return file, parent.EnumType[i], append(path, NumberDesc
riptorProto_EnumType, i) |
| 120 » » } |
| 121 » » if i := parent.FindField(name); i != -1 { |
| 122 » » » return file, parent.Field[i], append(path, NumberDescrip
torProto_Field, i) |
| 123 » » } |
| 124 » » if i := parent.FindOneOf(name); i != -1 { |
| 125 » » » return file, parent.OneofDecl[i], append(path, NumberDes
criptorProto_OneOf, i) |
| 126 » » } |
| 127 |
| 128 » case *EnumDescriptorProto: |
| 129 » » if i := parent.FindValue(name); i != -1 { |
| 130 » » » return file, parent.Value[i], append(path, NumberEnumDes
criptorProto_Value, i) |
| 131 » » } |
| 132 » } |
| 133 |
| 134 » return nil, nil, nil |
| 45 } | 135 } |
| 46 | 136 |
| 47 // FindEnum searches for a enum by full name. | 137 // FindService searches for a service by full name. |
| 48 func (s *FileDescriptorSet) FindEnum(fullName string) *EnumDescriptorProto { | 138 func (s *FileDescriptorSet) FindService(fullName string) (file *FileDescriptorPr
oto, serviceIndex int) { |
| 49 » pkg, name := SplitFullName(fullName) | 139 » pkg, name := splitFullName(fullName) |
| 50 for _, f := range s.GetFile() { | 140 for _, f := range s.GetFile() { |
| 51 if f.GetPackage() == pkg { | 141 if f.GetPackage() == pkg { |
| 52 » » » if x := f.FindEnum(name); x != nil { | 142 » » » if i := f.FindService(name); i != -1 { |
| 53 » » » » return x | 143 » » » » return f, i |
| 54 } | 144 } |
| 55 } | 145 } |
| 56 } | 146 } |
| 57 » return nil | 147 » return nil, -1 |
| 58 } | |
| 59 | |
| 60 // FindService searches for a service by full name. | |
| 61 func (s *FileDescriptorSet) FindService(fullName string) *ServiceDescriptorProto
{ | |
| 62 » pkg, name := SplitFullName(fullName) | |
| 63 » for _, f := range s.GetFile() { | |
| 64 » » if f.GetPackage() == pkg { | |
| 65 » » » if x := f.FindService(name); x != nil { | |
| 66 » » » » return x | |
| 67 » » » } | |
| 68 » » } | |
| 69 » } | |
| 70 » return nil | |
| 71 } | 148 } |
| 72 | 149 |
| 73 //////////////////////////////////////////////////////////////////////////////// | 150 //////////////////////////////////////////////////////////////////////////////// |
| 74 // FileDescriptorProto | 151 // FileDescriptorProto |
| 75 | 152 |
| 76 // FindService searches for a ServiceDescriptorProto by name. | 153 // FindService searches for a ServiceDescriptorProto by name. |
| 77 func (f *FileDescriptorProto) FindService(name string) *ServiceDescriptorProto { | 154 func (f *FileDescriptorProto) FindService(name string) int { |
| 78 » for _, x := range f.GetService() { | 155 » for i, x := range f.GetService() { |
| 79 if x.GetName() == name { | 156 if x.GetName() == name { |
| 80 » » » return x | 157 » » » return i |
| 81 } | 158 } |
| 82 } | 159 } |
| 83 » return nil | 160 » return -1 |
| 84 } | 161 } |
| 85 | 162 |
| 86 // FindMessage searches for a DescriptorProto by name. | 163 // FindMessage searches for a DescriptorProto by name. |
| 87 func (f *FileDescriptorProto) FindMessage(name string) *DescriptorProto { | 164 func (f *FileDescriptorProto) FindMessage(name string) int { |
| 88 » for _, x := range f.GetMessageType() { | 165 » for i, x := range f.GetMessageType() { |
| 89 if x.GetName() == name { | 166 if x.GetName() == name { |
| 90 » » » return x | 167 » » » return i |
| 91 } | 168 } |
| 92 } | 169 } |
| 93 » return nil | 170 » return -1 |
| 94 } | 171 } |
| 95 | 172 |
| 96 // FindEnum searches for a EnumDescriptorProto by name. | 173 // FindEnum searches for an EnumDescriptorProto by name. |
| 97 func (f *FileDescriptorProto) FindEnum(name string) *EnumDescriptorProto { | 174 func (f *FileDescriptorProto) FindEnum(name string) int { |
| 98 » for _, x := range f.GetEnumType() { | 175 » for i, x := range f.GetEnumType() { |
| 99 if x.GetName() == name { | 176 if x.GetName() == name { |
| 100 » » » return x | 177 » » » return i |
| 101 } | 178 } |
| 102 } | 179 } |
| 103 » return nil | 180 » return -1 |
| 104 } | 181 } |
| 105 | 182 |
| 106 //////////////////////////////////////////////////////////////////////////////// | 183 //////////////////////////////////////////////////////////////////////////////// |
| 107 // ServiceDescriptorProto | 184 // ServiceDescriptorProto |
| 108 | 185 |
| 109 // FindMethod searches for a MethodDescriptorProto by name. | 186 // FindMethod searches for a MethodDescriptorProto by name. |
| 110 func (s *ServiceDescriptorProto) FindMethod(name string) *MethodDescriptorProto
{ | 187 func (s *ServiceDescriptorProto) FindMethod(name string) int { |
| 111 » for _, x := range s.GetMethod() { | 188 » for i, x := range s.GetMethod() { |
| 112 if x.GetName() == name { | 189 if x.GetName() == name { |
| 113 » » » return x | 190 » » » return i |
| 114 } | 191 } |
| 115 } | 192 } |
| 116 » return nil | 193 » return -1 |
| 117 } | 194 } |
| 118 | 195 |
| 119 //////////////////////////////////////////////////////////////////////////////// | 196 //////////////////////////////////////////////////////////////////////////////// |
| 120 // DescriptorProto (a message) | 197 // DescriptorProto (a message) |
| 121 | 198 |
| 122 // FindField searches for a FieldDescriptorProto by name. | 199 // FindField searches for a FieldDescriptorProto by name. |
| 123 func (d *DescriptorProto) FindField(name string) *FieldDescriptorProto { | 200 func (d *DescriptorProto) FindField(name string) int { |
| 124 » for _, x := range d.GetField() { | 201 » for i, x := range d.GetField() { |
| 125 if x.GetName() == name { | 202 if x.GetName() == name { |
| 126 » » » return x | 203 » » » return i |
| 127 } | 204 } |
| 128 } | 205 } |
| 129 » return nil | 206 » return -1 |
| 207 } |
| 208 |
| 209 // FindMessage searches for a nested DescriptorProto by name. |
| 210 func (d *DescriptorProto) FindMessage(name string) int { |
| 211 » for i, x := range d.GetNestedType() { |
| 212 » » if x.GetName() == name { |
| 213 » » » return i |
| 214 » » } |
| 215 » } |
| 216 » return -1 |
| 217 } |
| 218 |
| 219 // FindEnum searches for a nested EnumDescriptorProto by name. |
| 220 func (d *DescriptorProto) FindEnum(name string) int { |
| 221 » for i, x := range d.GetEnumType() { |
| 222 » » if x.GetName() == name { |
| 223 » » » return i |
| 224 » » } |
| 225 » } |
| 226 » return -1 |
| 227 } |
| 228 |
| 229 // FindOneOf searches for a nested OneofDescriptorProto by name. |
| 230 func (d *DescriptorProto) FindOneOf(name string) int { |
| 231 » for i, x := range d.GetOneofDecl() { |
| 232 » » if x.GetName() == name { |
| 233 » » » return i |
| 234 » » } |
| 235 » } |
| 236 » return -1 |
| 130 } | 237 } |
| 131 | 238 |
| 132 //////////////////////////////////////////////////////////////////////////////// | 239 //////////////////////////////////////////////////////////////////////////////// |
| 240 // EnumDescriptorProto |
| 241 |
| 242 // FindValue searches for an EnumValueDescriptorProto by name. |
| 243 func (e *EnumDescriptorProto) FindValue(name string) int { |
| 244 for i, x := range e.GetValue() { |
| 245 if x.GetName() == name { |
| 246 return i |
| 247 } |
| 248 } |
| 249 return -1 |
| 250 } |
| 251 |
| 252 //////////////////////////////////////////////////////////////////////////////// |
| 133 // SourceCodeInfo | 253 // SourceCodeInfo |
| 134 | 254 |
| 135 // FindLocation searches for a location by path. | 255 // FindLocation searches for a location by path. |
| 136 func (s *SourceCodeInfo) FindLocation(path []int) *SourceCodeInfo_Location { | 256 func (s *SourceCodeInfo) FindLocation(path []int) *SourceCodeInfo_Location { |
| 137 Outer: | 257 Outer: |
| 138 » for _, l := range s.Location { | 258 » for _, l := range s.GetLocation() { |
| 139 if len(path) != len(l.Path) { | 259 if len(path) != len(l.Path) { |
| 140 continue | 260 continue |
| 141 } | 261 } |
| 142 for i := range path { | 262 for i := range path { |
| 143 if int32(path[i]) != l.Path[i] { | 263 if int32(path[i]) != l.Path[i] { |
| 144 continue Outer | 264 continue Outer |
| 145 } | 265 } |
| 146 } | 266 } |
| 147 return l | 267 return l |
| 148 } | 268 } |
| 149 return nil | 269 return nil |
| 150 } | 270 } |
| OLD | NEW |