diff options
author | appilon <apilon@hashicorp.com> | 2019-02-27 16:43:31 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-27 16:43:31 -0500 |
commit | 844b5a68d8af4791755b8f0ad293cc99f5959183 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/golang/protobuf/proto/properties.go | |
parent | 303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff) | |
parent | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff) | |
download | terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip |
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/golang/protobuf/proto/properties.go')
-rw-r--r-- | vendor/github.com/golang/protobuf/proto/properties.go | 544 |
1 files changed, 544 insertions, 0 deletions
diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go new file mode 100644 index 0000000..50b99b8 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/properties.go | |||
@@ -0,0 +1,544 @@ | |||
1 | // Go support for Protocol Buffers - Google's data interchange format | ||
2 | // | ||
3 | // Copyright 2010 The Go Authors. All rights reserved. | ||
4 | // https://github.com/golang/protobuf | ||
5 | // | ||
6 | // Redistribution and use in source and binary forms, with or without | ||
7 | // modification, are permitted provided that the following conditions are | ||
8 | // met: | ||
9 | // | ||
10 | // * Redistributions of source code must retain the above copyright | ||
11 | // notice, this list of conditions and the following disclaimer. | ||
12 | // * Redistributions in binary form must reproduce the above | ||
13 | // copyright notice, this list of conditions and the following disclaimer | ||
14 | // in the documentation and/or other materials provided with the | ||
15 | // distribution. | ||
16 | // * Neither the name of Google Inc. nor the names of its | ||
17 | // contributors may be used to endorse or promote products derived from | ||
18 | // this software without specific prior written permission. | ||
19 | // | ||
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | package proto | ||
33 | |||
34 | /* | ||
35 | * Routines for encoding data into the wire format for protocol buffers. | ||
36 | */ | ||
37 | |||
38 | import ( | ||
39 | "fmt" | ||
40 | "log" | ||
41 | "os" | ||
42 | "reflect" | ||
43 | "sort" | ||
44 | "strconv" | ||
45 | "strings" | ||
46 | "sync" | ||
47 | ) | ||
48 | |||
49 | const debug bool = false | ||
50 | |||
51 | // Constants that identify the encoding of a value on the wire. | ||
52 | const ( | ||
53 | WireVarint = 0 | ||
54 | WireFixed64 = 1 | ||
55 | WireBytes = 2 | ||
56 | WireStartGroup = 3 | ||
57 | WireEndGroup = 4 | ||
58 | WireFixed32 = 5 | ||
59 | ) | ||
60 | |||
61 | // tagMap is an optimization over map[int]int for typical protocol buffer | ||
62 | // use-cases. Encoded protocol buffers are often in tag order with small tag | ||
63 | // numbers. | ||
64 | type tagMap struct { | ||
65 | fastTags []int | ||
66 | slowTags map[int]int | ||
67 | } | ||
68 | |||
69 | // tagMapFastLimit is the upper bound on the tag number that will be stored in | ||
70 | // the tagMap slice rather than its map. | ||
71 | const tagMapFastLimit = 1024 | ||
72 | |||
73 | func (p *tagMap) get(t int) (int, bool) { | ||
74 | if t > 0 && t < tagMapFastLimit { | ||
75 | if t >= len(p.fastTags) { | ||
76 | return 0, false | ||
77 | } | ||
78 | fi := p.fastTags[t] | ||
79 | return fi, fi >= 0 | ||
80 | } | ||
81 | fi, ok := p.slowTags[t] | ||
82 | return fi, ok | ||
83 | } | ||
84 | |||
85 | func (p *tagMap) put(t int, fi int) { | ||
86 | if t > 0 && t < tagMapFastLimit { | ||
87 | for len(p.fastTags) < t+1 { | ||
88 | p.fastTags = append(p.fastTags, -1) | ||
89 | } | ||
90 | p.fastTags[t] = fi | ||
91 | return | ||
92 | } | ||
93 | if p.slowTags == nil { | ||
94 | p.slowTags = make(map[int]int) | ||
95 | } | ||
96 | p.slowTags[t] = fi | ||
97 | } | ||
98 | |||
99 | // StructProperties represents properties for all the fields of a struct. | ||
100 | // decoderTags and decoderOrigNames should only be used by the decoder. | ||
101 | type StructProperties struct { | ||
102 | Prop []*Properties // properties for each field | ||
103 | reqCount int // required count | ||
104 | decoderTags tagMap // map from proto tag to struct field number | ||
105 | decoderOrigNames map[string]int // map from original name to struct field number | ||
106 | order []int // list of struct field numbers in tag order | ||
107 | |||
108 | // OneofTypes contains information about the oneof fields in this message. | ||
109 | // It is keyed by the original name of a field. | ||
110 | OneofTypes map[string]*OneofProperties | ||
111 | } | ||
112 | |||
113 | // OneofProperties represents information about a specific field in a oneof. | ||
114 | type OneofProperties struct { | ||
115 | Type reflect.Type // pointer to generated struct type for this oneof field | ||
116 | Field int // struct field number of the containing oneof in the message | ||
117 | Prop *Properties | ||
118 | } | ||
119 | |||
120 | // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. | ||
121 | // See encode.go, (*Buffer).enc_struct. | ||
122 | |||
123 | func (sp *StructProperties) Len() int { return len(sp.order) } | ||
124 | func (sp *StructProperties) Less(i, j int) bool { | ||
125 | return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag | ||
126 | } | ||
127 | func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } | ||
128 | |||
129 | // Properties represents the protocol-specific behavior of a single struct field. | ||
130 | type Properties struct { | ||
131 | Name string // name of the field, for error messages | ||
132 | OrigName string // original name before protocol compiler (always set) | ||
133 | JSONName string // name to use for JSON; determined by protoc | ||
134 | Wire string | ||
135 | WireType int | ||
136 | Tag int | ||
137 | Required bool | ||
138 | Optional bool | ||
139 | Repeated bool | ||
140 | Packed bool // relevant for repeated primitives only | ||
141 | Enum string // set for enum types only | ||
142 | proto3 bool // whether this is known to be a proto3 field | ||
143 | oneof bool // whether this is a oneof field | ||
144 | |||
145 | Default string // default value | ||
146 | HasDefault bool // whether an explicit default was provided | ||
147 | |||
148 | stype reflect.Type // set for struct types only | ||
149 | sprop *StructProperties // set for struct types only | ||
150 | |||
151 | mtype reflect.Type // set for map types only | ||
152 | MapKeyProp *Properties // set for map types only | ||
153 | MapValProp *Properties // set for map types only | ||
154 | } | ||
155 | |||
156 | // String formats the properties in the protobuf struct field tag style. | ||
157 | func (p *Properties) String() string { | ||
158 | s := p.Wire | ||
159 | s += "," | ||
160 | s += strconv.Itoa(p.Tag) | ||
161 | if p.Required { | ||
162 | s += ",req" | ||
163 | } | ||
164 | if p.Optional { | ||
165 | s += ",opt" | ||
166 | } | ||
167 | if p.Repeated { | ||
168 | s += ",rep" | ||
169 | } | ||
170 | if p.Packed { | ||
171 | s += ",packed" | ||
172 | } | ||
173 | s += ",name=" + p.OrigName | ||
174 | if p.JSONName != p.OrigName { | ||
175 | s += ",json=" + p.JSONName | ||
176 | } | ||
177 | if p.proto3 { | ||
178 | s += ",proto3" | ||
179 | } | ||
180 | if p.oneof { | ||
181 | s += ",oneof" | ||
182 | } | ||
183 | if len(p.Enum) > 0 { | ||
184 | s += ",enum=" + p.Enum | ||
185 | } | ||
186 | if p.HasDefault { | ||
187 | s += ",def=" + p.Default | ||
188 | } | ||
189 | return s | ||
190 | } | ||
191 | |||
192 | // Parse populates p by parsing a string in the protobuf struct field tag style. | ||
193 | func (p *Properties) Parse(s string) { | ||
194 | // "bytes,49,opt,name=foo,def=hello!" | ||
195 | fields := strings.Split(s, ",") // breaks def=, but handled below. | ||
196 | if len(fields) < 2 { | ||
197 | fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) | ||
198 | return | ||
199 | } | ||
200 | |||
201 | p.Wire = fields[0] | ||
202 | switch p.Wire { | ||
203 | case "varint": | ||
204 | p.WireType = WireVarint | ||
205 | case "fixed32": | ||
206 | p.WireType = WireFixed32 | ||
207 | case "fixed64": | ||
208 | p.WireType = WireFixed64 | ||
209 | case "zigzag32": | ||
210 | p.WireType = WireVarint | ||
211 | case "zigzag64": | ||
212 | p.WireType = WireVarint | ||
213 | case "bytes", "group": | ||
214 | p.WireType = WireBytes | ||
215 | // no numeric converter for non-numeric types | ||
216 | default: | ||
217 | fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) | ||
218 | return | ||
219 | } | ||
220 | |||
221 | var err error | ||
222 | p.Tag, err = strconv.Atoi(fields[1]) | ||
223 | if err != nil { | ||
224 | return | ||
225 | } | ||
226 | |||
227 | outer: | ||
228 | for i := 2; i < len(fields); i++ { | ||
229 | f := fields[i] | ||
230 | switch { | ||
231 | case f == "req": | ||
232 | p.Required = true | ||
233 | case f == "opt": | ||
234 | p.Optional = true | ||
235 | case f == "rep": | ||
236 | p.Repeated = true | ||
237 | case f == "packed": | ||
238 | p.Packed = true | ||
239 | case strings.HasPrefix(f, "name="): | ||
240 | p.OrigName = f[5:] | ||
241 | case strings.HasPrefix(f, "json="): | ||
242 | p.JSONName = f[5:] | ||
243 | case strings.HasPrefix(f, "enum="): | ||
244 | p.Enum = f[5:] | ||
245 | case f == "proto3": | ||
246 | p.proto3 = true | ||
247 | case f == "oneof": | ||
248 | p.oneof = true | ||
249 | case strings.HasPrefix(f, "def="): | ||
250 | p.HasDefault = true | ||
251 | p.Default = f[4:] // rest of string | ||
252 | if i+1 < len(fields) { | ||
253 | // Commas aren't escaped, and def is always last. | ||
254 | p.Default += "," + strings.Join(fields[i+1:], ",") | ||
255 | break outer | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() | ||
262 | |||
263 | // setFieldProps initializes the field properties for submessages and maps. | ||
264 | func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { | ||
265 | switch t1 := typ; t1.Kind() { | ||
266 | case reflect.Ptr: | ||
267 | if t1.Elem().Kind() == reflect.Struct { | ||
268 | p.stype = t1.Elem() | ||
269 | } | ||
270 | |||
271 | case reflect.Slice: | ||
272 | if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct { | ||
273 | p.stype = t2.Elem() | ||
274 | } | ||
275 | |||
276 | case reflect.Map: | ||
277 | p.mtype = t1 | ||
278 | p.MapKeyProp = &Properties{} | ||
279 | p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) | ||
280 | p.MapValProp = &Properties{} | ||
281 | vtype := p.mtype.Elem() | ||
282 | if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { | ||
283 | // The value type is not a message (*T) or bytes ([]byte), | ||
284 | // so we need encoders for the pointer to this type. | ||
285 | vtype = reflect.PtrTo(vtype) | ||
286 | } | ||
287 | p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) | ||
288 | } | ||
289 | |||
290 | if p.stype != nil { | ||
291 | if lockGetProp { | ||
292 | p.sprop = GetProperties(p.stype) | ||
293 | } else { | ||
294 | p.sprop = getPropertiesLocked(p.stype) | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | |||
299 | var ( | ||
300 | marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() | ||
301 | ) | ||
302 | |||
303 | // Init populates the properties from a protocol buffer struct tag. | ||
304 | func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { | ||
305 | p.init(typ, name, tag, f, true) | ||
306 | } | ||
307 | |||
308 | func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { | ||
309 | // "bytes,49,opt,def=hello!" | ||
310 | p.Name = name | ||
311 | p.OrigName = name | ||
312 | if tag == "" { | ||
313 | return | ||
314 | } | ||
315 | p.Parse(tag) | ||
316 | p.setFieldProps(typ, f, lockGetProp) | ||
317 | } | ||
318 | |||
319 | var ( | ||
320 | propertiesMu sync.RWMutex | ||
321 | propertiesMap = make(map[reflect.Type]*StructProperties) | ||
322 | ) | ||
323 | |||
324 | // GetProperties returns the list of properties for the type represented by t. | ||
325 | // t must represent a generated struct type of a protocol message. | ||
326 | func GetProperties(t reflect.Type) *StructProperties { | ||
327 | if t.Kind() != reflect.Struct { | ||
328 | panic("proto: type must have kind struct") | ||
329 | } | ||
330 | |||
331 | // Most calls to GetProperties in a long-running program will be | ||
332 | // retrieving details for types we have seen before. | ||
333 | propertiesMu.RLock() | ||
334 | sprop, ok := propertiesMap[t] | ||
335 | propertiesMu.RUnlock() | ||
336 | if ok { | ||
337 | if collectStats { | ||
338 | stats.Chit++ | ||
339 | } | ||
340 | return sprop | ||
341 | } | ||
342 | |||
343 | propertiesMu.Lock() | ||
344 | sprop = getPropertiesLocked(t) | ||
345 | propertiesMu.Unlock() | ||
346 | return sprop | ||
347 | } | ||
348 | |||
349 | // getPropertiesLocked requires that propertiesMu is held. | ||
350 | func getPropertiesLocked(t reflect.Type) *StructProperties { | ||
351 | if prop, ok := propertiesMap[t]; ok { | ||
352 | if collectStats { | ||
353 | stats.Chit++ | ||
354 | } | ||
355 | return prop | ||
356 | } | ||
357 | if collectStats { | ||
358 | stats.Cmiss++ | ||
359 | } | ||
360 | |||
361 | prop := new(StructProperties) | ||
362 | // in case of recursive protos, fill this in now. | ||
363 | propertiesMap[t] = prop | ||
364 | |||
365 | // build properties | ||
366 | prop.Prop = make([]*Properties, t.NumField()) | ||
367 | prop.order = make([]int, t.NumField()) | ||
368 | |||
369 | for i := 0; i < t.NumField(); i++ { | ||
370 | f := t.Field(i) | ||
371 | p := new(Properties) | ||
372 | name := f.Name | ||
373 | p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) | ||
374 | |||
375 | oneof := f.Tag.Get("protobuf_oneof") // special case | ||
376 | if oneof != "" { | ||
377 | // Oneof fields don't use the traditional protobuf tag. | ||
378 | p.OrigName = oneof | ||
379 | } | ||
380 | prop.Prop[i] = p | ||
381 | prop.order[i] = i | ||
382 | if debug { | ||
383 | print(i, " ", f.Name, " ", t.String(), " ") | ||
384 | if p.Tag > 0 { | ||
385 | print(p.String()) | ||
386 | } | ||
387 | print("\n") | ||
388 | } | ||
389 | } | ||
390 | |||
391 | // Re-order prop.order. | ||
392 | sort.Sort(prop) | ||
393 | |||
394 | type oneofMessage interface { | ||
395 | XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) | ||
396 | } | ||
397 | if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { | ||
398 | var oots []interface{} | ||
399 | _, _, _, oots = om.XXX_OneofFuncs() | ||
400 | |||
401 | // Interpret oneof metadata. | ||
402 | prop.OneofTypes = make(map[string]*OneofProperties) | ||
403 | for _, oot := range oots { | ||
404 | oop := &OneofProperties{ | ||
405 | Type: reflect.ValueOf(oot).Type(), // *T | ||
406 | Prop: new(Properties), | ||
407 | } | ||
408 | sft := oop.Type.Elem().Field(0) | ||
409 | oop.Prop.Name = sft.Name | ||
410 | oop.Prop.Parse(sft.Tag.Get("protobuf")) | ||
411 | // There will be exactly one interface field that | ||
412 | // this new value is assignable to. | ||
413 | for i := 0; i < t.NumField(); i++ { | ||
414 | f := t.Field(i) | ||
415 | if f.Type.Kind() != reflect.Interface { | ||
416 | continue | ||
417 | } | ||
418 | if !oop.Type.AssignableTo(f.Type) { | ||
419 | continue | ||
420 | } | ||
421 | oop.Field = i | ||
422 | break | ||
423 | } | ||
424 | prop.OneofTypes[oop.Prop.OrigName] = oop | ||
425 | } | ||
426 | } | ||
427 | |||
428 | // build required counts | ||
429 | // build tags | ||
430 | reqCount := 0 | ||
431 | prop.decoderOrigNames = make(map[string]int) | ||
432 | for i, p := range prop.Prop { | ||
433 | if strings.HasPrefix(p.Name, "XXX_") { | ||
434 | // Internal fields should not appear in tags/origNames maps. | ||
435 | // They are handled specially when encoding and decoding. | ||
436 | continue | ||
437 | } | ||
438 | if p.Required { | ||
439 | reqCount++ | ||
440 | } | ||
441 | prop.decoderTags.put(p.Tag, i) | ||
442 | prop.decoderOrigNames[p.OrigName] = i | ||
443 | } | ||
444 | prop.reqCount = reqCount | ||
445 | |||
446 | return prop | ||
447 | } | ||
448 | |||
449 | // A global registry of enum types. | ||
450 | // The generated code will register the generated maps by calling RegisterEnum. | ||
451 | |||
452 | var enumValueMaps = make(map[string]map[string]int32) | ||
453 | |||
454 | // RegisterEnum is called from the generated code to install the enum descriptor | ||
455 | // maps into the global table to aid parsing text format protocol buffers. | ||
456 | func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { | ||
457 | if _, ok := enumValueMaps[typeName]; ok { | ||
458 | panic("proto: duplicate enum registered: " + typeName) | ||
459 | } | ||
460 | enumValueMaps[typeName] = valueMap | ||
461 | } | ||
462 | |||
463 | // EnumValueMap returns the mapping from names to integers of the | ||
464 | // enum type enumType, or a nil if not found. | ||
465 | func EnumValueMap(enumType string) map[string]int32 { | ||
466 | return enumValueMaps[enumType] | ||
467 | } | ||
468 | |||
469 | // A registry of all linked message types. | ||
470 | // The string is a fully-qualified proto name ("pkg.Message"). | ||
471 | var ( | ||
472 | protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers | ||
473 | protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types | ||
474 | revProtoTypes = make(map[reflect.Type]string) | ||
475 | ) | ||
476 | |||
477 | // RegisterType is called from generated code and maps from the fully qualified | ||
478 | // proto name to the type (pointer to struct) of the protocol buffer. | ||
479 | func RegisterType(x Message, name string) { | ||
480 | if _, ok := protoTypedNils[name]; ok { | ||
481 | // TODO: Some day, make this a panic. | ||
482 | log.Printf("proto: duplicate proto type registered: %s", name) | ||
483 | return | ||
484 | } | ||
485 | t := reflect.TypeOf(x) | ||
486 | if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { | ||
487 | // Generated code always calls RegisterType with nil x. | ||
488 | // This check is just for extra safety. | ||
489 | protoTypedNils[name] = x | ||
490 | } else { | ||
491 | protoTypedNils[name] = reflect.Zero(t).Interface().(Message) | ||
492 | } | ||
493 | revProtoTypes[t] = name | ||
494 | } | ||
495 | |||
496 | // RegisterMapType is called from generated code and maps from the fully qualified | ||
497 | // proto name to the native map type of the proto map definition. | ||
498 | func RegisterMapType(x interface{}, name string) { | ||
499 | if reflect.TypeOf(x).Kind() != reflect.Map { | ||
500 | panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) | ||
501 | } | ||
502 | if _, ok := protoMapTypes[name]; ok { | ||
503 | log.Printf("proto: duplicate proto type registered: %s", name) | ||
504 | return | ||
505 | } | ||
506 | t := reflect.TypeOf(x) | ||
507 | protoMapTypes[name] = t | ||
508 | revProtoTypes[t] = name | ||
509 | } | ||
510 | |||
511 | // MessageName returns the fully-qualified proto name for the given message type. | ||
512 | func MessageName(x Message) string { | ||
513 | type xname interface { | ||
514 | XXX_MessageName() string | ||
515 | } | ||
516 | if m, ok := x.(xname); ok { | ||
517 | return m.XXX_MessageName() | ||
518 | } | ||
519 | return revProtoTypes[reflect.TypeOf(x)] | ||
520 | } | ||
521 | |||
522 | // MessageType returns the message type (pointer to struct) for a named message. | ||
523 | // The type is not guaranteed to implement proto.Message if the name refers to a | ||
524 | // map entry. | ||
525 | func MessageType(name string) reflect.Type { | ||
526 | if t, ok := protoTypedNils[name]; ok { | ||
527 | return reflect.TypeOf(t) | ||
528 | } | ||
529 | return protoMapTypes[name] | ||
530 | } | ||
531 | |||
532 | // A registry of all linked proto files. | ||
533 | var ( | ||
534 | protoFiles = make(map[string][]byte) // file name => fileDescriptor | ||
535 | ) | ||
536 | |||
537 | // RegisterFile is called from generated code and maps from the | ||
538 | // full file name of a .proto file to its compressed FileDescriptorProto. | ||
539 | func RegisterFile(filename string, fileDescriptor []byte) { | ||
540 | protoFiles[filename] = fileDescriptor | ||
541 | } | ||
542 | |||
543 | // FileDescriptor returns the compressed FileDescriptorProto for a .proto file. | ||
544 | func FileDescriptor(filename string) []byte { return protoFiles[filename] } | ||