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

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

Issue 2219023003: Update APIs to use new Google cloud paths. (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Created 4 years, 4 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
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package flagpb 5 package flagpb
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/hex" 9 "encoding/hex"
10 "encoding/json" 10 "encoding/json"
11 "fmt" 11 "fmt"
12 "strconv" 12 "strconv"
13 "strings" 13 "strings"
14 14
15 "github.com/luci/luci-go/common/proto/google/descutil"
16
15 "github.com/golang/protobuf/jsonpb" 17 "github.com/golang/protobuf/jsonpb"
16 "github.com/golang/protobuf/proto" 18 "github.com/golang/protobuf/proto"
17 » "github.com/luci/luci-go/common/proto/google/descriptor" 19 » "google.golang.org/genproto/protobuf"
18 ) 20 )
19 21
20 // UnmarshalMessage unmarshals the proto message from flags. 22 // UnmarshalMessage unmarshals the proto message from flags.
21 // 23 //
22 // The descriptor set should be obtained from the `cproto` compiled packages' 24 // The descriptor set should be obtained from the `cproto` compiled packages'
23 // FileDescriptorSet() method. 25 // FileDescriptorSet() method.
24 func UnmarshalMessage(flags []string, resolver Resolver, msg proto.Message) erro r { 26 func UnmarshalMessage(flags []string, resolver Resolver, msg proto.Message) erro r {
25 // TODO(iannucci): avoid round-trip through parser and jsonpb and popula te the 27 // TODO(iannucci): avoid round-trip through parser and jsonpb and popula te the
26 // message directly. This would involve writing some additional reflecti on 28 // message directly. This would involve writing some additional reflecti on
27 // code that may depend on implementation details of proto's generated G o 29 // code that may depend on implementation details of proto's generated G o
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 target := &root 125 target := &root
124 if len(pathMsgs) > 0 { 126 if len(pathMsgs) > 0 {
125 lastMsg := pathMsgs[len(pathMsgs)-1] 127 lastMsg := pathMsgs[len(pathMsgs)-1]
126 target = &lastMsg.message 128 target = &lastMsg.message
127 } 129 }
128 name := fieldPath[len(fieldPath)-1] 130 name := fieldPath[len(fieldPath)-1]
129 131
130 // Resolve target field. 132 // Resolve target field.
131 var fieldIndex int 133 var fieldIndex int
132 if target.desc.GetOptions().GetMapEntry() { 134 if target.desc.GetOptions().GetMapEntry() {
133 » » if fieldIndex = target.desc.FindField("value"); fieldIndex == -1 { 135 » » if fieldIndex = descutil.FindField(target.desc, "value"); fieldI ndex == -1 {
134 return nil, fmt.Errorf("map entry type %s does not have value field", target.desc.GetName()) 136 return nil, fmt.Errorf("map entry type %s does not have value field", target.desc.GetName())
135 } 137 }
136 } else { 138 } else {
137 » » if fieldIndex = target.desc.FindField(name); fieldIndex == -1 { 139 » » if fieldIndex = descutil.FindField(target.desc, name); fieldInde x == -1 {
138 return nil, fmt.Errorf("field %s not found in message %s ", name, target.desc.GetName()) 140 return nil, fmt.Errorf("field %s not found in message %s ", name, target.desc.GetName())
139 } 141 }
140 } 142 }
141 field := target.desc.Field[fieldIndex] 143 field := target.desc.Field[fieldIndex]
142 144
143 var value interface{} 145 var value interface{}
144 hasValue := false 146 hasValue := false
145 147
146 if !hasValueStr { 148 if !hasValueStr {
147 switch { 149 switch {
148 // Boolean and repeated message fields may have no value and ign ore 150 // Boolean and repeated message fields may have no value and ign ore
149 // next argument. 151 // next argument.
150 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_BOO L: 152 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_BOO L:
151 value = true 153 value = true
152 hasValue = true 154 hasValue = true
153 » » case field.GetType() == descriptor.FieldDescriptorProto_TYPE_MES SAGE && field.Repeated(): 155 » » case field.GetType() == descriptor.FieldDescriptorProto_TYPE_MES SAGE && descutil.Repeated(field):
154 value = map[string]interface{}{} 156 value = map[string]interface{}{}
155 hasValue = true 157 hasValue = true
156 158
157 default: 159 default:
158 // Read next argument as a value. 160 // Read next argument as a value.
159 if len(flags) == 0 { 161 if len(flags) == 0 {
160 return nil, fmt.Errorf("value was expected") 162 return nil, fmt.Errorf("value was expected")
161 } 163 }
162 valueStr, flags = flags[0], flags[1:] 164 valueStr, flags = flags[0], flags[1:]
163 } 165 }
164 } 166 }
165 167
166 // Check if the value is already set. 168 // Check if the value is already set.
167 » if target.data[name] != nil && !field.Repeated() { 169 » if target.data[name] != nil && !descutil.Repeated(field) {
168 repeatedFields := make([]string, 0, len(pathMsgs)) 170 repeatedFields := make([]string, 0, len(pathMsgs))
169 for _, m := range pathMsgs { 171 for _, m := range pathMsgs {
170 if m.repeated { 172 if m.repeated {
171 repeatedFields = append(repeatedFields, "-"+stri ngs.Join(m.path, ".")) 173 repeatedFields = append(repeatedFields, "-"+stri ngs.Join(m.path, "."))
172 } 174 }
173 } 175 }
174 if len(repeatedFields) == 0 { 176 if len(repeatedFields) == 0 {
175 return nil, fmt.Errorf("value is already set to %v", tar get.data[name]) 177 return nil, fmt.Errorf("value is already set to %v", tar get.data[name])
176 } 178 }
177 return nil, fmt.Errorf( 179 return nil, fmt.Errorf(
178 "value is already set to %v. Did you forgot to insert %s in between to declare a new repeated message?", 180 "value is already set to %v. Did you forgot to insert %s in between to declare a new repeated message?",
179 target.data[name], strings.Join(repeatedFields, " or ")) 181 target.data[name], strings.Join(repeatedFields, " or "))
180 } 182 }
181 183
182 if !hasValue { 184 if !hasValue {
183 value, err = p.parseFieldValue(valueStr, target.desc.GetName(), field) 185 value, err = p.parseFieldValue(valueStr, target.desc.GetName(), field)
184 if err != nil { 186 if err != nil {
185 return nil, err 187 return nil, err
186 } 188 }
187 } 189 }
188 190
189 » if !field.Repeated() { 191 » if !descutil.Repeated(field) {
190 target.data[name] = value 192 target.data[name] = value
191 } else { 193 } else {
192 target.data[name] = append(asSlice(target.data[name]), value) 194 target.data[name] = append(asSlice(target.data[name]), value)
193 } 195 }
194 196
195 return flags, nil 197 return flags, nil
196 } 198 }
197 199
198 type subMsg struct { 200 type subMsg struct {
199 message 201 message
(...skipping 10 matching lines...) Expand all
210 // If a field is not a message field, returns an error. 212 // If a field is not a message field, returns an error.
211 func (p *parser) subMessages(root message, path []string) ([]subMsg, error) { 213 func (p *parser) subMessages(root message, path []string) ([]subMsg, error) {
212 result := make([]subMsg, 0, len(path)) 214 result := make([]subMsg, 0, len(path))
213 215
214 parent := &root 216 parent := &root
215 for i, name := range path { 217 for i, name := range path {
216 curPath := path[:i+1] 218 curPath := path[:i+1]
217 219
218 var fieldIndex int 220 var fieldIndex int
219 if parent.desc.GetOptions().GetMapEntry() { 221 if parent.desc.GetOptions().GetMapEntry() {
220 » » » if fieldIndex = parent.desc.FindField("value"); fieldInd ex == -1 { 222 » » » if fieldIndex = descutil.FindField(parent.desc, "value") ; fieldIndex == -1 {
221 return nil, fmt.Errorf("map entry type %s does n ot have value field", parent.desc.GetName()) 223 return nil, fmt.Errorf("map entry type %s does n ot have value field", parent.desc.GetName())
222 } 224 }
223 } else { 225 } else {
224 » » » if fieldIndex = parent.desc.FindField(name); fieldIndex == -1 { 226 » » » if fieldIndex = descutil.FindField(parent.desc, name); f ieldIndex == -1 {
225 return nil, fmt.Errorf("field %q not found in me ssage %s", name, parent.desc.GetName()) 227 return nil, fmt.Errorf("field %q not found in me ssage %s", name, parent.desc.GetName())
226 } 228 }
227 } 229 }
228 230
229 f := parent.desc.Field[fieldIndex] 231 f := parent.desc.Field[fieldIndex]
230 if f.GetType() != descriptor.FieldDescriptorProto_TYPE_MESSAGE { 232 if f.GetType() != descriptor.FieldDescriptorProto_TYPE_MESSAGE {
231 return nil, fmt.Errorf("field %s is not a message", stri ngs.Join(curPath, ".")) 233 return nil, fmt.Errorf("field %s is not a message", stri ngs.Join(curPath, "."))
232 } 234 }
233 235
234 subDescInterface, err := p.resolve(f.GetTypeName()) 236 subDescInterface, err := p.resolve(f.GetTypeName())
235 if err != nil { 237 if err != nil {
236 return nil, err 238 return nil, err
237 } 239 }
238 subDesc, ok := subDescInterface.(*descriptor.DescriptorProto) 240 subDesc, ok := subDescInterface.(*descriptor.DescriptorProto)
239 if !ok { 241 if !ok {
240 return nil, fmt.Errorf("%s is not a message", f.GetTypeN ame()) 242 return nil, fmt.Errorf("%s is not a message", f.GetTypeN ame())
241 } 243 }
242 244
243 sub := subMsg{ 245 sub := subMsg{
244 message: message{desc: subDesc}, 246 message: message{desc: subDesc},
245 » » » repeated: f.Repeated() && !subDesc.GetOptions().GetMapEn try(), 247 » » » repeated: descutil.Repeated(f) && !subDesc.GetOptions(). GetMapEntry(),
246 path: curPath, 248 path: curPath,
247 } 249 }
248 if value, ok := parent.data[name]; !ok { 250 if value, ok := parent.data[name]; !ok {
249 sub.data = map[string]interface{}{} 251 sub.data = map[string]interface{}{}
250 if sub.repeated { 252 if sub.repeated {
251 parent.data[name] = []interface{}{sub.data} 253 parent.data[name] = []interface{}{sub.data}
252 } else { 254 } else {
253 parent.data[name] = sub.data 255 parent.data[name] = sub.data
254 } 256 }
255 } else { 257 } else {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 case 2: 356 case 2:
355 key = parts[0] 357 key = parts[0]
356 value = parts[1] 358 value = parts[1]
357 hasValue = true 359 hasValue = true
358 } 360 }
359 return 361 return
360 } 362 }
361 363
362 // parseEnum returns the number of an enum member, which can be name or number. 364 // parseEnum returns the number of an enum member, which can be name or number.
363 func parseEnum(enum *descriptor.EnumDescriptorProto, member string) (int32, erro r) { 365 func parseEnum(enum *descriptor.EnumDescriptorProto, member string) (int32, erro r) {
364 » i := enum.FindValue(member) 366 » i := descutil.FindEnumValue(enum, member)
365 if i < 0 { 367 if i < 0 {
366 // Is member the number? 368 // Is member the number?
367 if number, err := strconv.ParseInt(member, 10, 32); err == nil { 369 if number, err := strconv.ParseInt(member, 10, 32); err == nil {
368 » » » i = enum.FindValueByNumber(int32(number)) 370 » » » i = descutil.FindValueByNumber(enum, int32(number))
369 } 371 }
370 } 372 }
371 if i < 0 { 373 if i < 0 {
372 return 0, fmt.Errorf("invalid value %q for enum %s", member, enu m.GetName()) 374 return 0, fmt.Errorf("invalid value %q for enum %s", member, enu m.GetName())
373 } 375 }
374 return enum.Value[i].GetNumber(), nil 376 return enum.Value[i].GetNumber(), nil
375 } 377 }
376 378
377 func asSlice(x interface{}) []interface{} { 379 func asSlice(x interface{}) []interface{} {
378 if x == nil { 380 if x == nil {
379 return nil 381 return nil
380 } 382 }
381 return x.([]interface{}) 383 return x.([]interface{})
382 } 384 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698