Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: client/flagpb/unmarshal.go

Issue 1940683002: client/flagpb: fix unmarshaling of maps (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@flagpb-parse-value
Patch Set: -mapcase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | client/flagpb/unmarshal_test.desc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 flagpb 5 package flagpb
6 6
7 import ( 7 import (
8 "encoding/hex" 8 "encoding/hex"
9 "fmt" 9 "fmt"
10 "strconv" 10 "strconv"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 if err != nil { 86 if err != nil {
87 return nil, err 87 return nil, err
88 } 88 }
89 89
90 // Where to assign the value? 90 // Where to assign the value?
91 target := &root 91 target := &root
92 if len(pathMsgs) > 0 { 92 if len(pathMsgs) > 0 {
93 lastMsg := pathMsgs[len(pathMsgs)-1] 93 lastMsg := pathMsgs[len(pathMsgs)-1]
94 target = &lastMsg.message 94 target = &lastMsg.message
95 } 95 }
96 name := fieldPath[len(fieldPath)-1]
96 97
97 » // Resolve last field name. 98 » // Resolve target field.
98 » name := fieldPath[len(fieldPath)-1] 99 » var fieldIndex int
99 » fi := target.desc.FindField(name) 100 » if target.desc.GetOptions().GetMapEntry() {
100 » if fi == -1 { 101 » » if fieldIndex = target.desc.FindField("value"); fieldIndex == -1 {
101 » » return nil, fmt.Errorf("field %s not found in message %s", name, target.desc.GetName()) 102 » » » return nil, fmt.Errorf("map entry type %s does not have value field", target.desc.GetName())
103 » » }
104 » } else {
105 » » if fieldIndex = target.desc.FindField(name); fieldIndex == -1 {
106 » » » return nil, fmt.Errorf("field %s not found in message %s ", name, target.desc.GetName())
107 » » }
102 } 108 }
103 » field := target.desc.Field[fi] 109 » field := target.desc.Field[fieldIndex]
104 110
105 var value interface{} 111 var value interface{}
106 hasValue := false 112 hasValue := false
107 113
108 if !hasValueStr { 114 if !hasValueStr {
109 switch { 115 switch {
110 // Boolean and repeated message fields may have no value and ign ore 116 // Boolean and repeated message fields may have no value and ign ore
111 // next argument. 117 // next argument.
112 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_BOO L: 118 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_BOO L:
113 value = true 119 value = true
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 // If a field is repeated, returns the last message. 175 // If a field is repeated, returns the last message.
170 // 176 //
171 // If a field value is nil, initializes it with an empty message or slice. 177 // If a field value is nil, initializes it with an empty message or slice.
172 // If a field is not a message field, returns an error. 178 // If a field is not a message field, returns an error.
173 func (p *parser) subMessages(root message, path []string) ([]subMsg, error) { 179 func (p *parser) subMessages(root message, path []string) ([]subMsg, error) {
174 result := make([]subMsg, 0, len(path)) 180 result := make([]subMsg, 0, len(path))
175 181
176 parent := &root 182 parent := &root
177 for i, name := range path { 183 for i, name := range path {
178 curPath := path[:i+1] 184 curPath := path[:i+1]
179 » » fi := parent.desc.FindField(name) 185
180 » » if fi == -1 { 186 » » var fieldIndex int
181 » » » return nil, fmt.Errorf("field %q not found in message %s ", name, parent.desc.GetName()) 187 » » if parent.desc.GetOptions().GetMapEntry() {
188 » » » if fieldIndex = parent.desc.FindField("value"); fieldInd ex == -1 {
189 » » » » return nil, fmt.Errorf("map entry type %s does n ot have value field", parent.desc.GetName())
190 » » » }
191 » » } else {
192 » » » if fieldIndex = parent.desc.FindField(name); fieldIndex == -1 {
193 » » » » return nil, fmt.Errorf("field %q not found in me ssage %s", name, parent.desc.GetName())
194 » » » }
nodir 2016/04/30 04:43:58 deduping this would causes an obscure abstraction
182 } 195 }
183 196
184 » » f := parent.desc.Field[fi] 197 » » f := parent.desc.Field[fieldIndex]
185 if f.GetType() != descriptor.FieldDescriptorProto_TYPE_MESSAGE { 198 if f.GetType() != descriptor.FieldDescriptorProto_TYPE_MESSAGE {
186 return nil, fmt.Errorf("field %s is not a message", stri ngs.Join(curPath, ".")) 199 return nil, fmt.Errorf("field %s is not a message", stri ngs.Join(curPath, "."))
187 } 200 }
188 201
189 subDescInterface, err := p.resolve(f.GetTypeName()) 202 subDescInterface, err := p.resolve(f.GetTypeName())
190 if err != nil { 203 if err != nil {
191 return nil, err 204 return nil, err
192 } 205 }
193 subDesc, ok := subDescInterface.(*descriptor.DescriptorProto) 206 subDesc, ok := subDescInterface.(*descriptor.DescriptorProto)
194 if !ok { 207 if !ok {
195 return nil, fmt.Errorf("%s is not a message", f.GetTypeN ame()) 208 return nil, fmt.Errorf("%s is not a message", f.GetTypeN ame())
196 } 209 }
197 210
198 sub := subMsg{ 211 sub := subMsg{
199 message: message{desc: subDesc}, 212 message: message{desc: subDesc},
200 » » » repeated: f.Repeated(), 213 » » » repeated: f.Repeated() && !subDesc.GetOptions().GetMapEn try(),
201 path: curPath, 214 path: curPath,
202 } 215 }
203 if value, ok := parent.data[name]; !ok { 216 if value, ok := parent.data[name]; !ok {
204 sub.data = map[string]interface{}{} 217 sub.data = map[string]interface{}{}
205 if sub.repeated { 218 if sub.repeated {
206 parent.data[name] = []interface{}{sub.data} 219 parent.data[name] = []interface{}{sub.data}
207 } else { 220 } else {
208 parent.data[name] = sub.data 221 parent.data[name] = sub.data
209 } 222 }
210 } else { 223 } else {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 341 }
329 return enum.Value[i].GetNumber(), nil 342 return enum.Value[i].GetNumber(), nil
330 } 343 }
331 344
332 func asSlice(x interface{}) []interface{} { 345 func asSlice(x interface{}) []interface{} {
333 if x == nil { 346 if x == nil {
334 return nil 347 return nil
335 } 348 }
336 return x.([]interface{}) 349 return x.([]interface{})
337 } 350 }
OLDNEW
« no previous file with comments | « no previous file | client/flagpb/unmarshal_test.desc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698