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

Side by Side Diff: third_party/protobuf/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years 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 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 14 matching lines...) Expand all
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 package com.google.protobuf.util; 31 package com.google.protobuf.util;
32 32
33 import static com.google.common.base.Preconditions.checkArgument; 33 import static com.google.common.base.Preconditions.checkArgument;
34 34
35 import com.google.common.base.CaseFormat;
36 import com.google.common.base.Joiner;
37 import com.google.common.base.Splitter;
35 import com.google.common.primitives.Ints; 38 import com.google.common.primitives.Ints;
36 import com.google.protobuf.Descriptors.Descriptor; 39 import com.google.protobuf.Descriptors.Descriptor;
37 import com.google.protobuf.Descriptors.FieldDescriptor; 40 import com.google.protobuf.Descriptors.FieldDescriptor;
38 import com.google.protobuf.FieldMask; 41 import com.google.protobuf.FieldMask;
39 import com.google.protobuf.Internal; 42 import com.google.protobuf.Internal;
40 import com.google.protobuf.Message; 43 import com.google.protobuf.Message;
41 44
45 import java.util.ArrayList;
42 import java.util.Arrays; 46 import java.util.Arrays;
47 import java.util.List;
43 48
44 /** 49 /**
45 * Utility helper functions to work with {@link com.google.protobuf.FieldMask}. 50 * Utility helper functions to work with {@link com.google.protobuf.FieldMask}.
46 */ 51 */
47 public class FieldMaskUtil { 52 public class FieldMaskUtil {
48 private static final String FIELD_PATH_SEPARATOR = ","; 53 private static final String FIELD_PATH_SEPARATOR = ",";
49 private static final String FIELD_PATH_SEPARATOR_REGEX = ","; 54 private static final String FIELD_PATH_SEPARATOR_REGEX = ",";
50 private static final String FIELD_SEPARATOR_REGEX = "\\."; 55 private static final String FIELD_SEPARATOR_REGEX = "\\.";
51 56
52 private FieldMaskUtil() {} 57 private FieldMaskUtil() {}
53 58
54 /** 59 /**
55 * Converts a FieldMask to a string. 60 * Converts a FieldMask to a string.
56 */ 61 */
57 public static String toString(FieldMask fieldMask) { 62 public static String toString(FieldMask fieldMask) {
58 // TODO(xiaofeng): Consider using com.google.common.base.Joiner here instead . 63 // TODO(xiaofeng): Consider using com.google.common.base.Joiner here instead .
59 StringBuilder result = new StringBuilder(); 64 StringBuilder result = new StringBuilder();
60 boolean first = true; 65 boolean first = true;
61 for (String value : fieldMask.getPathsList()) { 66 for (String value : fieldMask.getPathsList()) {
62 if (value.isEmpty()) { 67 if (value.isEmpty()) {
63 // Ignore empty paths. 68 // Ignore empty paths.
64 continue; 69 continue;
65 } 70 }
66 if (first) { 71 if (first) {
67 first = false; 72 first = false;
68 } else { 73 } else {
69 result.append(FIELD_PATH_SEPARATOR); 74 result.append(FIELD_PATH_SEPARATOR);
70 } 75 }
71 result.append(value); 76 result.append(value);
72 } 77 }
73 return result.toString(); 78 return result.toString();
74 } 79 }
75 80
76 /** 81 /**
77 * Parses from a string to a FieldMask. 82 * Parses from a string to a FieldMask.
78 */ 83 */
79 public static FieldMask fromString(String value) { 84 public static FieldMask fromString(String value) {
80 // TODO(xiaofeng): Consider using com.google.common.base.Splitter here inste ad. 85 // TODO(xiaofeng): Consider using com.google.common.base.Splitter here inste ad.
81 return fromStringList( 86 return fromStringList(null, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_R EGEX)));
82 null, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX)));
83 } 87 }
84 88
85 /** 89 /**
86 * Parses from a string to a FieldMask and validates all field paths. 90 * Parses from a string to a FieldMask and validates all field paths.
87 * 91 *
88 * @throws IllegalArgumentException if any of the field path is invalid. 92 * @throws IllegalArgumentException if any of the field path is invalid.
89 */ 93 */
90 public static FieldMask fromString(Class<? extends Message> type, String value ) { 94 public static FieldMask fromString(Class<? extends Message> type, String value ) {
91 // TODO(xiaofeng): Consider using com.google.common.base.Splitter here inste ad. 95 // TODO(xiaofeng): Consider using com.google.common.base.Splitter here inste ad.
92 return fromStringList( 96 return fromStringList(type, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_R EGEX)));
93 type, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX)));
94 } 97 }
95 98
96 /** 99 /**
97 * Constructs a FieldMask for a list of field paths in a certain type. 100 * Constructs a FieldMask for a list of field paths in a certain type.
98 * 101 *
99 * @throws IllegalArgumentException if any of the field path is not valid. 102 * @throws IllegalArgumentException if any of the field path is not valid.
100 */ 103 */
101 // TODO(xiaofeng): Consider renaming fromStrings() 104 // TODO(xiaofeng): Consider renaming fromStrings()
102 public static FieldMask fromStringList( 105 public static FieldMask fromStringList(Class<? extends Message> type, Iterable <String> paths) {
103 Class<? extends Message> type, Iterable<String> paths) {
104 FieldMask.Builder builder = FieldMask.newBuilder(); 106 FieldMask.Builder builder = FieldMask.newBuilder();
105 for (String path : paths) { 107 for (String path : paths) {
106 if (path.isEmpty()) { 108 if (path.isEmpty()) {
107 // Ignore empty field paths. 109 // Ignore empty field paths.
108 continue; 110 continue;
109 } 111 }
110 if (type != null && !isValid(type, path)) { 112 if (type != null && !isValid(type, path)) {
111 throw new IllegalArgumentException( 113 throw new IllegalArgumentException(path + " is not a valid path for " + type);
112 path + " is not a valid path for " + type);
113 } 114 }
114 builder.addPaths(path); 115 builder.addPaths(path);
115 } 116 }
116 return builder.build(); 117 return builder.build();
117 } 118 }
118 119
119 /** 120 /**
120 * Constructs a FieldMask from the passed field numbers. 121 * Constructs a FieldMask from the passed field numbers.
121 * 122 *
122 * @throws IllegalArgumentException if any of the fields are invalid for the m essage. 123 * @throws IllegalArgumentException if any of the fields are invalid for the m essage.
(...skipping 16 matching lines...) Expand all
139 FieldDescriptor field = descriptor.findFieldByNumber(fieldNumber); 140 FieldDescriptor field = descriptor.findFieldByNumber(fieldNumber);
140 checkArgument( 141 checkArgument(
141 field != null, 142 field != null,
142 String.format("%s is not a valid field number for %s.", fieldNumber, t ype)); 143 String.format("%s is not a valid field number for %s.", fieldNumber, t ype));
143 builder.addPaths(field.getName()); 144 builder.addPaths(field.getName());
144 } 145 }
145 return builder.build(); 146 return builder.build();
146 } 147 }
147 148
148 /** 149 /**
150 * Converts a field mask to a Proto3 JSON string, that is converting from snak e case to camel
151 * case and joining all paths into one string with commas.
152 */
153 public static String toJsonString(FieldMask fieldMask) {
154 List<String> paths = new ArrayList<String>(fieldMask.getPathsCount());
155 for (String path : fieldMask.getPathsList()) {
156 if (path.isEmpty()) {
157 continue;
158 }
159 paths.add(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, path));
160 }
161 return Joiner.on(FIELD_PATH_SEPARATOR).join(paths);
162 }
163
164 /**
165 * Converts a field mask from a Proto3 JSON string, that is splitting the path s along commas and
166 * converting from camel case to snake case.
167 */
168 public static FieldMask fromJsonString(String value) {
169 Iterable<String> paths = Splitter.on(FIELD_PATH_SEPARATOR).split(value);
170 FieldMask.Builder builder = FieldMask.newBuilder();
171 for (String path : paths) {
172 if (path.isEmpty()) {
173 continue;
174 }
175 builder.addPaths(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pa th));
176 }
177 return builder.build();
178 }
179
180 /**
149 * Checks whether paths in a given fields mask are valid. 181 * Checks whether paths in a given fields mask are valid.
150 */ 182 */
151 public static boolean isValid(Class<? extends Message> type, FieldMask fieldMa sk) { 183 public static boolean isValid(Class<? extends Message> type, FieldMask fieldMa sk) {
152 Descriptor descriptor = 184 Descriptor descriptor = Internal.getDefaultInstance(type).getDescriptorForTy pe();
153 Internal.getDefaultInstance(type).getDescriptorForType(); 185
154
155 return isValid(descriptor, fieldMask); 186 return isValid(descriptor, fieldMask);
156 } 187 }
157 188
158 /** 189 /**
159 * Checks whether paths in a given fields mask are valid. 190 * Checks whether paths in a given fields mask are valid.
160 */ 191 */
161 public static boolean isValid(Descriptor descriptor, FieldMask fieldMask) { 192 public static boolean isValid(Descriptor descriptor, FieldMask fieldMask) {
162 for (String path : fieldMask.getPathsList()) { 193 for (String path : fieldMask.getPathsList()) {
163 if (!isValid(descriptor, path)) { 194 if (!isValid(descriptor, path)) {
164 return false; 195 return false;
165 } 196 }
166 } 197 }
167 return true; 198 return true;
168 } 199 }
169 200
170 /** 201 /**
171 * Checks whether a given field path is valid. 202 * Checks whether a given field path is valid.
172 */ 203 */
173 public static boolean isValid(Class<? extends Message> type, String path) { 204 public static boolean isValid(Class<? extends Message> type, String path) {
174 Descriptor descriptor = 205 Descriptor descriptor = Internal.getDefaultInstance(type).getDescriptorForTy pe();
175 Internal.getDefaultInstance(type).getDescriptorForType(); 206
176
177 return isValid(descriptor, path); 207 return isValid(descriptor, path);
178 } 208 }
179 209
180 /** 210 /**
181 * Checks whether paths in a given fields mask are valid. 211 * Checks whether paths in a given fields mask are valid.
182 */ 212 */
183 public static boolean isValid(Descriptor descriptor, String path) { 213 public static boolean isValid(Descriptor descriptor, String path) {
184 String[] parts = path.split(FIELD_SEPARATOR_REGEX); 214 String[] parts = path.split(FIELD_SEPARATOR_REGEX);
185 if (parts.length == 0) { 215 if (parts.length == 0) {
186 return false; 216 return false;
187 } 217 }
188 for (String name : parts) { 218 for (String name : parts) {
189 if (descriptor == null) { 219 if (descriptor == null) {
190 return false; 220 return false;
191 } 221 }
192 FieldDescriptor field = descriptor.findFieldByName(name); 222 FieldDescriptor field = descriptor.findFieldByName(name);
193 if (field == null) { 223 if (field == null) {
194 return false; 224 return false;
195 } 225 }
196 if (!field.isRepeated() 226 if (!field.isRepeated() && field.getJavaType() == FieldDescriptor.JavaType .MESSAGE) {
197 && field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
198 descriptor = field.getMessageType(); 227 descriptor = field.getMessageType();
199 } else { 228 } else {
200 descriptor = null; 229 descriptor = null;
201 } 230 }
202 } 231 }
203 return true; 232 return true;
204 } 233 }
205 234
206 /** 235 /**
207 * Converts a FieldMask to its canonical form. In the canonical form of a 236 * Converts a FieldMask to its canonical form. In the canonical form of a
208 * FieldMask, all field paths are sorted alphabetically and redundant field 237 * FieldMask, all field paths are sorted alphabetically and redundant field
209 * paths are moved. 238 * paths are moved.
210 */ 239 */
211 public static FieldMask normalize(FieldMask mask) { 240 public static FieldMask normalize(FieldMask mask) {
212 return new FieldMaskTree(mask).toFieldMask(); 241 return new FieldMaskTree(mask).toFieldMask();
213 } 242 }
214 243
215 /** 244 /**
(...skipping 28 matching lines...) Expand all
244 private boolean replaceRepeatedFields = false; 273 private boolean replaceRepeatedFields = false;
245 // TODO(b/28277137): change the default behavior to always replace primitive fields after 274 // TODO(b/28277137): change the default behavior to always replace primitive fields after
246 // fixing all failing TAP tests. 275 // fixing all failing TAP tests.
247 private boolean replacePrimitiveFields = false; 276 private boolean replacePrimitiveFields = false;
248 277
249 /** 278 /**
250 * Whether to replace message fields (i.e., discard existing content in 279 * Whether to replace message fields (i.e., discard existing content in
251 * destination message fields) when merging. 280 * destination message fields) when merging.
252 * Default behavior is to merge the source message field into the 281 * Default behavior is to merge the source message field into the
253 * destination message field. 282 * destination message field.
254 */ 283 */
255 public boolean replaceMessageFields() { 284 public boolean replaceMessageFields() {
256 return replaceMessageFields; 285 return replaceMessageFields;
257 } 286 }
258 287
259 /** 288 /**
260 * Whether to replace repeated fields (i.e., discard existing content in 289 * Whether to replace repeated fields (i.e., discard existing content in
261 * destination repeated fields) when merging. 290 * destination repeated fields) when merging.
262 * Default behavior is to append elements from source repeated field to the 291 * Default behavior is to append elements from source repeated field to the
263 * destination repeated field. 292 * destination repeated field.
264 */ 293 */
(...skipping 27 matching lines...) Expand all
292 321
293 public void setReplacePrimitiveFields(boolean value) { 322 public void setReplacePrimitiveFields(boolean value) {
294 replacePrimitiveFields = value; 323 replacePrimitiveFields = value;
295 } 324 }
296 } 325 }
297 326
298 /** 327 /**
299 * Merges fields specified by a FieldMask from one message to another with the 328 * Merges fields specified by a FieldMask from one message to another with the
300 * specified merge options. 329 * specified merge options.
301 */ 330 */
302 public static void merge(FieldMask mask, Message source, 331 public static void merge(
303 Message.Builder destination, MergeOptions options) { 332 FieldMask mask, Message source, Message.Builder destination, MergeOptions options) {
304 new FieldMaskTree(mask).merge(source, destination, options); 333 new FieldMaskTree(mask).merge(source, destination, options);
305 } 334 }
306 335
307 /** 336 /**
308 * Merges fields specified by a FieldMask from one message to another. 337 * Merges fields specified by a FieldMask from one message to another.
309 */ 338 */
310 public static void merge(FieldMask mask, Message source, 339 public static void merge(FieldMask mask, Message source, Message.Builder desti nation) {
311 Message.Builder destination) {
312 merge(mask, source, destination, new MergeOptions()); 340 merge(mask, source, destination, new MergeOptions());
313 } 341 }
314 } 342 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698