Chromium Code Reviews| Index: common/proto/google/descutil/tags.go |
| diff --git a/common/proto/google/descutil/tags.go b/common/proto/google/descutil/tags.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..443eab4d14388240aefe738c87246f9b2b93f015 |
| --- /dev/null |
| +++ b/common/proto/google/descutil/tags.go |
| @@ -0,0 +1,91 @@ |
| +// Copyright 2015 The LUCI Authors. All rights reserved. |
| +// Use of this source code is governed under the Apache License, Version 2.0 |
| +// that can be found in the LICENSE file. |
| + |
| +package descutil |
| + |
| +import ( |
| + "fmt" |
| + "reflect" |
| + |
| + "github.com/golang/protobuf/proto" |
| + pb "google.golang.org/genproto/protobuf" |
| +) |
| + |
| +var ( |
| + // FileDescriptorProtoPackageTag is the number of package field |
| + // in FileDescriptorProto message. |
| + FileDescriptorProtoPackageTag int |
| + // FileDescriptorProtoMessageTag is the number of message field |
| + // in FileDescriptorProto message. |
| + FileDescriptorProtoMessageTag int |
| + // FileDescriptorProtoEnumTag is the number of enum field |
| + // in FileDescriptorProto message. |
| + FileDescriptorProtoEnumTag int |
| + // FileDescriptorProtoServiceTag is the number of service field |
| + // in FileDescriptorProto message. |
| + FileDescriptorProtoServiceTag int |
| + |
| + // ServiceDescriptorProtoMethodTag is the number of method field |
| + // in ServiceDescriptorProto message. |
| + ServiceDescriptorProtoMethodTag int |
| + |
| + // DescriptorProtoFieldTag is the number of field field |
| + // in DescriptorProto message. |
| + DescriptorProtoFieldTag int |
| + // DescriptorProtoNestedTypeTag is the number of nested_type field |
| + // in DescriptorProto message. |
| + DescriptorProtoNestedTypeTag int |
| + // DescriptorProtoEnumTypeTag is the number of enum_type field |
| + // in DescriptorProto message. |
| + DescriptorProtoEnumTypeTag int |
| + // DescriptorProtoOneOfTag is the number of oneof_decl field |
| + // in DescriptorProto message. |
| + DescriptorProtoOneOfTag int |
| + |
| + // EnumDescriptorProtoValueTag is the number of value field |
| + // in EnumDescriptorProto message. |
| + EnumDescriptorProtoValueTag int |
| +) |
| + |
| +func init() { |
| + resolveTagsFor(&pb.FileDescriptorProto{}, func(resolve func(string) int) { |
|
nodir
2016/08/05 17:15:38
but why?
proto tags are actually constants (will
dnj (Google)
2016/08/05 18:21:57
Since we no longer host the Protos, I think it is
|
| + FileDescriptorProtoPackageTag = resolve("Package") |
| + FileDescriptorProtoMessageTag = resolve("MessageType") |
| + FileDescriptorProtoEnumTag = resolve("EnumType") |
| + FileDescriptorProtoServiceTag = resolve("Service") |
| + }) |
| + |
| + resolveTagsFor(&pb.ServiceDescriptorProto{}, func(resolve func(string) int) { |
| + ServiceDescriptorProtoMethodTag = resolve("Method") |
| + }) |
| + |
| + resolveTagsFor(&pb.DescriptorProto{}, func(resolve func(string) int) { |
| + DescriptorProtoFieldTag = resolve("Field") |
| + DescriptorProtoNestedTypeTag = resolve("NestedType") |
| + DescriptorProtoEnumTypeTag = resolve("EnumType") |
| + DescriptorProtoOneOfTag = resolve("OneofDecl") |
| + }) |
| + |
| + resolveTagsFor(&pb.EnumDescriptorProto{}, func(resolve func(string) int) { |
| + EnumDescriptorProtoValueTag = resolve("Value") |
| + }) |
| +} |
| + |
| +func resolveTagsFor(msg proto.Message, fn func(func(string) int)) { |
| + t := reflect.TypeOf(msg).Elem() |
|
nodir
2016/08/05 17:15:39
the more correct of doing this is to use https://g
|
| + if t.Kind() != reflect.Struct { |
| + panic(fmt.Errorf("not a struct: %T", msg)) |
| + } |
| + |
| + fn(func(fieldName string) int { |
| + f, ok := t.FieldByName(fieldName) |
| + if !ok { |
| + panic(fmt.Errorf("struct %T has no field named %q", msg, fieldName)) |
| + } |
| + |
| + var p proto.Properties |
| + p.Parse(f.Tag.Get("protobuf")) |
| + return p.Tag |
| + }) |
| +} |