| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |