Committing vendored dependencies and generated protos
Change-Id: I349c149b513d9de7d9f60bde2c954a939da2fc54
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go
new file mode 100644
index 0000000..341aad5
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go
@@ -0,0 +1,82 @@
+package runtime
+
+import (
+ "encoding/json"
+ "io"
+ "strings"
+
+ descriptor2 "github.com/golang/protobuf/descriptor"
+ "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ "google.golang.org/genproto/protobuf/field_mask"
+)
+
+func translateName(name string, md *descriptor.DescriptorProto) (string, *descriptor.DescriptorProto) {
+ // TODO - should really gate this with a test that the marshaller has used json names
+ if md != nil {
+ for _, f := range md.Field {
+ if f.JsonName != nil && f.Name != nil && *f.JsonName == name {
+ var subType *descriptor.DescriptorProto
+
+ // If the field has a TypeName then we retrieve the nested type for translating the embedded message names.
+ if f.TypeName != nil {
+ typeSplit := strings.Split(*f.TypeName, ".")
+ typeName := typeSplit[len(typeSplit)-1]
+ for _, t := range md.NestedType {
+ if typeName == *t.Name {
+ subType = t
+ }
+ }
+ }
+ return *f.Name, subType
+ }
+ }
+ }
+ return name, nil
+}
+
+// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.
+func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*field_mask.FieldMask, error) {
+ fm := &field_mask.FieldMask{}
+ var root interface{}
+ if err := json.NewDecoder(r).Decode(&root); err != nil {
+ if err == io.EOF {
+ return fm, nil
+ }
+ return nil, err
+ }
+
+ queue := []fieldMaskPathItem{{node: root, md: md}}
+ for len(queue) > 0 {
+ // dequeue an item
+ item := queue[0]
+ queue = queue[1:]
+
+ if m, ok := item.node.(map[string]interface{}); ok {
+ // if the item is an object, then enqueue all of its children
+ for k, v := range m {
+ protoName, subMd := translateName(k, item.md)
+ if subMsg, ok := v.(descriptor2.Message); ok {
+ _, subMd = descriptor2.ForMessage(subMsg)
+ }
+ queue = append(queue, fieldMaskPathItem{path: append(item.path, protoName), node: v, md: subMd})
+ }
+ } else if len(item.path) > 0 {
+ // otherwise, it's a leaf node so print its path
+ fm.Paths = append(fm.Paths, strings.Join(item.path, "."))
+ }
+ }
+
+ return fm, nil
+}
+
+// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask
+type fieldMaskPathItem struct {
+ // the list of prior fields leading up to node
+ path []string
+
+ // a generic decoded json object the current item to inspect for further path extraction
+ node interface{}
+
+ // descriptor for parent message
+ md *descriptor.DescriptorProto
+}