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

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

Issue 1935923002: client/flagpb: fix repeated bool without value (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return nil, fmt.Errorf("a flag was expected") 68 return nil, fmt.Errorf("a flag was expected")
69 } 69 }
70 flagName := strings.TrimPrefix(firstArg, "-") // -foo 70 flagName := strings.TrimPrefix(firstArg, "-") // -foo
71 flagName = strings.TrimPrefix(flagName, "-") // --foo 71 flagName = strings.TrimPrefix(flagName, "-") // --foo
72 if strings.HasPrefix(flagName, "-") { 72 if strings.HasPrefix(flagName, "-") {
73 // Triple dash is too much. 73 // Triple dash is too much.
74 return nil, fmt.Errorf("bad flag syntax") 74 return nil, fmt.Errorf("bad flag syntax")
75 } 75 }
76 76
77 // Split key-value pair x=y. 77 // Split key-value pair x=y.
78 » flagName, value, hasValue := p.splitKeyValuePair(flagName) 78 » flagName, valueStr, hasValueStr := p.splitKeyValuePair(flagName)
79 if flagName == "" { 79 if flagName == "" {
80 return nil, fmt.Errorf("bad flag syntax") 80 return nil, fmt.Errorf("bad flag syntax")
81 } 81 }
82 82
83 // Split field path "a.b.c" and resolve field names. 83 // Split field path "a.b.c" and resolve field names.
84 fieldPath := strings.Split(flagName, ".") 84 fieldPath := strings.Split(flagName, ".")
85 pathMsgs, err := p.subMessages(root, fieldPath[:len(fieldPath)-1]) 85 pathMsgs, err := p.subMessages(root, fieldPath[:len(fieldPath)-1])
86 if err != nil { 86 if err != nil {
87 return nil, err 87 return nil, err
88 } 88 }
89 89
90 » // Where to assign a 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 96
97 // Resolve last field name. 97 // Resolve last field name.
98 name := fieldPath[len(fieldPath)-1] 98 name := fieldPath[len(fieldPath)-1]
99 fi := target.desc.FindField(name) 99 fi := target.desc.FindField(name)
100 if fi == -1 { 100 if fi == -1 {
101 return nil, fmt.Errorf("field %s not found in message %s", name, target.desc.GetName()) 101 return nil, fmt.Errorf("field %s not found in message %s", name, target.desc.GetName())
102 } 102 }
103 field := target.desc.Field[fi] 103 field := target.desc.Field[fi]
104 104
105 » if !hasValue { 105 » var value interface{}
106 » hasValue := false
107
108 » if !hasValueStr {
106 switch { 109 switch {
107 // Boolean and repeated message fields may have no value and ign ore 110 // Boolean and repeated message fields may have no value and ign ore
108 // next argument. 111 // next argument.
109 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_BOO L: 112 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_BOO L:
110 » » » target.data[name] = true 113 » » » value = true
111 » » » return flags, nil 114 » » » hasValue = true
112 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_MES SAGE && field.Repeated(): 115 case field.GetType() == descriptor.FieldDescriptorProto_TYPE_MES SAGE && field.Repeated():
113 » » » target.data[name] = append(asSlice(target.data[name]), m ap[string]interface{}{}) 116 » » » value = map[string]interface{}{}
114 » » » return flags, nil 117 » » » hasValue = true
115 118
116 // Read next argument as a value.
117 default: 119 default:
120 // Read next argument as a value.
118 if len(flags) == 0 { 121 if len(flags) == 0 {
119 return nil, fmt.Errorf("value was expected") 122 return nil, fmt.Errorf("value was expected")
120 } 123 }
121 » » » value, flags = flags[0], flags[1:] 124 » » » valueStr, flags = flags[0], flags[1:]
122 } 125 }
123 } 126 }
124 127
125 // Check if the value is already set. 128 // Check if the value is already set.
126 if target.data[name] != nil && !field.Repeated() { 129 if target.data[name] != nil && !field.Repeated() {
127 repeatedFields := make([]string, 0, len(pathMsgs)) 130 repeatedFields := make([]string, 0, len(pathMsgs))
128 for _, m := range pathMsgs { 131 for _, m := range pathMsgs {
129 if m.repeated { 132 if m.repeated {
130 repeatedFields = append(repeatedFields, "-"+stri ngs.Join(m.path, ".")) 133 repeatedFields = append(repeatedFields, "-"+stri ngs.Join(m.path, "."))
131 } 134 }
132 } 135 }
133 if len(repeatedFields) == 0 { 136 if len(repeatedFields) == 0 {
134 return nil, fmt.Errorf("value is already set to %v", tar get.data[name]) 137 return nil, fmt.Errorf("value is already set to %v", tar get.data[name])
135 } 138 }
136 return nil, fmt.Errorf( 139 return nil, fmt.Errorf(
137 "value is already set to %v. Did you forgot to insert %s in between to declare a new repeated message?", 140 "value is already set to %v. Did you forgot to insert %s in between to declare a new repeated message?",
138 target.data[name], strings.Join(repeatedFields, " or ")) 141 target.data[name], strings.Join(repeatedFields, " or "))
139 } 142 }
140 143
141 » // Parse the value and set/append it. 144 » if !hasValue {
142 » parsedValue, err := p.parseFieldValue(value, target.desc.GetName(), fiel d) 145 » » value, err = p.parseFieldValue(valueStr, target.desc.GetName(), field)
143 » if err != nil { 146 » » if err != nil {
144 » » return nil, err 147 » » » return nil, err
148 » » }
145 } 149 }
146 150
147 if !field.Repeated() { 151 if !field.Repeated() {
148 » » target.data[name] = parsedValue 152 » » target.data[name] = value
149 } else { 153 } else {
150 » » target.data[name] = append(asSlice(target.data[name]), parsedVal ue) 154 » » target.data[name] = append(asSlice(target.data[name]), value)
151 } 155 }
156
152 return flags, nil 157 return flags, nil
153 } 158 }
154 159
155 type subMsg struct { 160 type subMsg struct {
156 message 161 message
157 path []string 162 path []string
158 repeated bool 163 repeated bool
159 } 164 }
160 165
161 // subMessages returns message field values at each component of the path. 166 // subMessages returns message field values at each component of the path.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 328 }
324 return enum.Value[i].GetNumber(), nil 329 return enum.Value[i].GetNumber(), nil
325 } 330 }
326 331
327 func asSlice(x interface{}) []interface{} { 332 func asSlice(x interface{}) []interface{} {
328 if x == nil { 333 if x == nil {
329 return nil 334 return nil
330 } 335 }
331 return x.([]interface{}) 336 return x.([]interface{})
332 } 337 }
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