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

Side by Side Diff: third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapEntry.java

Issue 2599263002: third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Address comments Created 3 years, 12 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 // 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 23 matching lines...) Expand all
34 import com.google.protobuf.Descriptors.EnumValueDescriptor; 34 import com.google.protobuf.Descriptors.EnumValueDescriptor;
35 import com.google.protobuf.Descriptors.FieldDescriptor; 35 import com.google.protobuf.Descriptors.FieldDescriptor;
36 36
37 import java.io.IOException; 37 import java.io.IOException;
38 import java.util.Collections; 38 import java.util.Collections;
39 import java.util.Map; 39 import java.util.Map;
40 import java.util.TreeMap; 40 import java.util.TreeMap;
41 41
42 /** 42 /**
43 * Implements MapEntry messages. 43 * Implements MapEntry messages.
44 * 44 *
45 * In reflection API, map fields will be treated as repeated message fields and 45 * In reflection API, map fields will be treated as repeated message fields and
46 * each map entry is accessed as a message. This MapEntry class is used to 46 * each map entry is accessed as a message. This MapEntry class is used to
47 * represent these map entry messages in reflection API. 47 * represent these map entry messages in reflection API.
48 * 48 *
49 * Protobuf internal. Users shouldn't use this class. 49 * Protobuf internal. Users shouldn't use this class.
50 */ 50 */
51 public final class MapEntry<K, V> extends AbstractMessage { 51 public final class MapEntry<K, V> extends AbstractMessage {
52 private static class Metadata<K, V> { 52
53 public final Descriptor descriptor; 53 private static final class Metadata<K, V> extends MapEntryLite.Metadata<K, V> {
54 public final MapEntry<K, V> defaultInstance; 54
55 public final AbstractParser<MapEntry<K, V>> parser; 55 public final Descriptor descriptor;
56 56 public final Parser<MapEntry<K, V>> parser;
57
57 public Metadata( 58 public Metadata(
58 final Descriptor descriptor, final MapEntry<K, V> defaultInstance) { 59 Descriptor descriptor,
60 MapEntry<K, V> defaultInstance,
61 WireFormat.FieldType keyType,
62 WireFormat.FieldType valueType) {
63 super(keyType, defaultInstance.key, valueType, defaultInstance.value);
59 this.descriptor = descriptor; 64 this.descriptor = descriptor;
60 this.defaultInstance = defaultInstance;
61 final Metadata<K, V> thisMetadata = this;
62 this.parser = new AbstractParser<MapEntry<K, V>>() { 65 this.parser = new AbstractParser<MapEntry<K, V>>() {
63 private final Parser<MapEntryLite<K, V>> dataParser = 66
64 defaultInstance.data.getParserForType();
65 @Override 67 @Override
66 public MapEntry<K, V> parsePartialFrom( 68 public MapEntry<K, V> parsePartialFrom(
67 CodedInputStream input, ExtensionRegistryLite extensionRegistry) 69 CodedInputStream input, ExtensionRegistryLite extensionRegistry)
68 throws InvalidProtocolBufferException { 70 throws InvalidProtocolBufferException {
69 MapEntryLite<K, V> data = 71 return new MapEntry<K, V>(Metadata.this, input, extensionRegistry);
70 dataParser.parsePartialFrom(input, extensionRegistry);
71 return new MapEntry<K, V>(thisMetadata, data);
72 } 72 }
73
74 }; 73 };
75 } 74 }
76 } 75 }
77 76
77 private final K key;
78 private final V value;
78 private final Metadata<K, V> metadata; 79 private final Metadata<K, V> metadata;
79 private final MapEntryLite<K, V> data; 80
80
81 /** Create a default MapEntry instance. */ 81 /** Create a default MapEntry instance. */
82 private MapEntry(Descriptor descriptor, 82 private MapEntry(
83 Descriptor descriptor,
83 WireFormat.FieldType keyType, K defaultKey, 84 WireFormat.FieldType keyType, K defaultKey,
84 WireFormat.FieldType valueType, V defaultValue) { 85 WireFormat.FieldType valueType, V defaultValue) {
85 this.data = MapEntryLite.newDefaultInstance( 86 this.key = defaultKey;
86 keyType, defaultKey, valueType, defaultValue); 87 this.value = defaultValue;
87 this.metadata = new Metadata<K, V>(descriptor, this); 88 this.metadata = new Metadata<K, V>(descriptor, this, keyType, valueType);
88 } 89 }
89 90
90 /** Create a new MapEntry message. */ 91 /** Create a MapEntry with the provided key and value. */
91 private MapEntry(Metadata<K, V> metadata, MapEntryLite<K, V> data) { 92 private MapEntry(Metadata metadata, K key, V value) {
93 this.key = key;
94 this.value = value;
92 this.metadata = metadata; 95 this.metadata = metadata;
93 this.data = data;
94 } 96 }
95 97
98 /** Parsing constructor. */
99 private MapEntry(
100 Metadata<K, V> metadata,
101 CodedInputStream input,
102 ExtensionRegistryLite extensionRegistry)
103 throws InvalidProtocolBufferException {
104 try {
105 this.metadata = metadata;
106 Map.Entry<K, V> entry = MapEntryLite.parseEntry(input, metadata, extension Registry);
107 this.key = entry.getKey();
108 this.value = entry.getValue();
109 } catch (InvalidProtocolBufferException e) {
110 throw e.setUnfinishedMessage(this);
111 } catch (IOException e) {
112 throw new InvalidProtocolBufferException(e).setUnfinishedMessage(this);
113 }
114 }
115
96 /** 116 /**
97 * Create a default MapEntry instance. A default MapEntry instance should be 117 * Create a default MapEntry instance. A default MapEntry instance should be
98 * created only once for each map entry message type. Generated code should 118 * created only once for each map entry message type. Generated code should
99 * store the created default instance and use it later to create new MapEntry 119 * store the created default instance and use it later to create new MapEntry
100 * messages of the same type. 120 * messages of the same type.
101 */ 121 */
102 public static <K, V> MapEntry<K, V> newDefaultInstance( 122 public static <K, V> MapEntry<K, V> newDefaultInstance(
103 Descriptor descriptor, 123 Descriptor descriptor,
104 WireFormat.FieldType keyType, K defaultKey, 124 WireFormat.FieldType keyType, K defaultKey,
105 WireFormat.FieldType valueType, V defaultValue) { 125 WireFormat.FieldType valueType, V defaultValue) {
106 return new MapEntry<K, V>( 126 return new MapEntry<K, V>(
107 descriptor, keyType, defaultKey, valueType, defaultValue); 127 descriptor, keyType, defaultKey, valueType, defaultValue);
108 } 128 }
109 129
110 public K getKey() { 130 public K getKey() {
111 return data.getKey(); 131 return key;
112 } 132 }
113 133
114 public V getValue() { 134 public V getValue() {
115 return data.getValue(); 135 return value;
116 } 136 }
117 137
138 private volatile int cachedSerializedSize = -1;
139
118 @Override 140 @Override
119 public int getSerializedSize() { 141 public int getSerializedSize() {
120 return data.getSerializedSize(); 142 if (cachedSerializedSize != -1) {
143 return cachedSerializedSize;
144 }
145
146 int size = MapEntryLite.computeSerializedSize(metadata, key, value);
147 cachedSerializedSize = size;
148 return size;
121 } 149 }
122 150
123 @Override 151 @Override
124 public void writeTo(CodedOutputStream output) throws IOException { 152 public void writeTo(CodedOutputStream output) throws IOException {
125 data.writeTo(output); 153 MapEntryLite.writeTo(output, metadata, key, value);
126 } 154 }
127 155
128 @Override 156 @Override
129 public boolean isInitialized() { 157 public boolean isInitialized() {
130 return data.isInitialized(); 158 return isInitialized(metadata, value);
131 } 159 }
132 160
133 @Override 161 @Override
134 public Parser<MapEntry<K, V>> getParserForType() { 162 public Parser<MapEntry<K, V>> getParserForType() {
135 return metadata.parser; 163 return metadata.parser;
136 } 164 }
137 165
138 @Override 166 @Override
139 public Builder<K, V> newBuilderForType() { 167 public Builder<K, V> newBuilderForType() {
140 return new Builder<K, V>(metadata); 168 return new Builder<K, V>(metadata);
141 } 169 }
142 170
143 @Override 171 @Override
144 public Builder<K, V> toBuilder() { 172 public Builder<K, V> toBuilder() {
145 return new Builder<K, V>(metadata, data); 173 return new Builder<K, V>(metadata, key, value);
146 } 174 }
147 175
148 @Override 176 @Override
149 public MapEntry<K, V> getDefaultInstanceForType() { 177 public MapEntry<K, V> getDefaultInstanceForType() {
150 return metadata.defaultInstance; 178 return new MapEntry<K, V>(metadata, metadata.defaultKey, metadata.defaultVal ue);
151 } 179 }
152 180
153 @Override 181 @Override
154 public Descriptor getDescriptorForType() { 182 public Descriptor getDescriptorForType() {
155 return metadata.descriptor; 183 return metadata.descriptor;
156 } 184 }
157 185
158 @Override 186 @Override
159 public Map<FieldDescriptor, Object> getAllFields() { 187 public Map<FieldDescriptor, Object> getAllFields() {
160 final TreeMap<FieldDescriptor, Object> result = 188 TreeMap<FieldDescriptor, Object> result = new TreeMap<FieldDescriptor, Objec t>();
161 new TreeMap<FieldDescriptor, Object>();
162 for (final FieldDescriptor field : metadata.descriptor.getFields()) { 189 for (final FieldDescriptor field : metadata.descriptor.getFields()) {
163 if (hasField(field)) { 190 if (hasField(field)) {
164 result.put(field, getField(field)); 191 result.put(field, getField(field));
165 } 192 }
166 } 193 }
167 return Collections.unmodifiableMap(result); 194 return Collections.unmodifiableMap(result);
168 } 195 }
169 196
170 private void checkFieldDescriptor(FieldDescriptor field) { 197 private void checkFieldDescriptor(FieldDescriptor field) {
171 if (field.getContainingType() != metadata.descriptor) { 198 if (field.getContainingType() != metadata.descriptor) {
172 throw new RuntimeException( 199 throw new RuntimeException(
173 "Wrong FieldDescriptor \"" + field.getFullName() 200 "Wrong FieldDescriptor \"" + field.getFullName()
174 + "\" used in message \"" + metadata.descriptor.getFullName()); 201 + "\" used in message \"" + metadata.descriptor.getFullName());
175 } 202 }
176 } 203 }
177 204
178 @Override 205 @Override
179 public boolean hasField(FieldDescriptor field) { 206 public boolean hasField(FieldDescriptor field) {
180 checkFieldDescriptor(field);; 207 checkFieldDescriptor(field);;
181 // A MapEntry always contains two fields. 208 // A MapEntry always contains two fields.
182 return true; 209 return true;
183 } 210 }
184 211
(...skipping 25 matching lines...) Expand all
210 public UnknownFieldSet getUnknownFields() { 237 public UnknownFieldSet getUnknownFields() {
211 return UnknownFieldSet.getDefaultInstance(); 238 return UnknownFieldSet.getDefaultInstance();
212 } 239 }
213 240
214 /** 241 /**
215 * Builder to create {@link MapEntry} messages. 242 * Builder to create {@link MapEntry} messages.
216 */ 243 */
217 public static class Builder<K, V> 244 public static class Builder<K, V>
218 extends AbstractMessage.Builder<Builder<K, V>> { 245 extends AbstractMessage.Builder<Builder<K, V>> {
219 private final Metadata<K, V> metadata; 246 private final Metadata<K, V> metadata;
220 private MapEntryLite<K, V> data; 247 private K key;
221 private MapEntryLite.Builder<K, V> dataBuilder; 248 private V value;
222 249
223 private Builder(Metadata<K, V> metadata) { 250 private Builder(Metadata<K, V> metadata) {
251 this(metadata, metadata.defaultKey, metadata.defaultValue);
252 }
253
254 private Builder(Metadata<K, V> metadata, K key, V value) {
224 this.metadata = metadata; 255 this.metadata = metadata;
225 this.data = metadata.defaultInstance.data; 256 this.key = key;
226 this.dataBuilder = null; 257 this.value = value;
227 } 258 }
228 259
229 private Builder(Metadata<K, V> metadata, MapEntryLite<K, V> data) { 260 public K getKey() {
230 this.metadata = metadata; 261 return key;
231 this.data = data;
232 this.dataBuilder = null;
233 } 262 }
234 263
235 public K getKey() { 264 public V getValue() {
236 return dataBuilder == null ? data.getKey() : dataBuilder.getKey(); 265 return value;
237 } 266 }
238 267
239 public V getValue() {
240 return dataBuilder == null ? data.getValue() : dataBuilder.getValue();
241 }
242
243 private void ensureMutable() {
244 if (dataBuilder == null) {
245 dataBuilder = data.toBuilder();
246 }
247 }
248
249 public Builder<K, V> setKey(K key) { 268 public Builder<K, V> setKey(K key) {
250 ensureMutable(); 269 this.key = key;
251 dataBuilder.setKey(key);
252 return this;
253 }
254
255 public Builder<K, V> clearKey() {
256 ensureMutable();
257 dataBuilder.clearKey();
258 return this;
259 }
260
261 public Builder<K, V> setValue(V value) {
262 ensureMutable();
263 dataBuilder.setValue(value);
264 return this;
265 }
266
267 public Builder<K, V> clearValue() {
268 ensureMutable();
269 dataBuilder.clearValue();
270 return this; 270 return this;
271 } 271 }
272 272
273 public Builder<K, V> clearKey() {
274 this.key = metadata.defaultKey;
275 return this;
276 }
277
278 public Builder<K, V> setValue(V value) {
279 this.value = value;
280 return this;
281 }
282
283 public Builder<K, V> clearValue() {
284 this.value = metadata.defaultValue;
285 return this;
286 }
287
273 @Override 288 @Override
274 public MapEntry<K, V> build() { 289 public MapEntry<K, V> build() {
275 MapEntry<K, V> result = buildPartial(); 290 MapEntry<K, V> result = buildPartial();
276 if (!result.isInitialized()) { 291 if (!result.isInitialized()) {
277 throw newUninitializedMessageException(result); 292 throw newUninitializedMessageException(result);
278 } 293 }
279 return result; 294 return result;
280 } 295 }
281 296
282 @Override 297 @Override
283 public MapEntry<K, V> buildPartial() { 298 public MapEntry<K, V> buildPartial() {
284 if (dataBuilder != null) { 299 return new MapEntry<K, V>(metadata, key, value);
285 data = dataBuilder.buildPartial();
286 dataBuilder = null;
287 }
288 return new MapEntry<K, V>(metadata, data);
289 } 300 }
290 301
291 @Override 302 @Override
292 public Descriptor getDescriptorForType() { 303 public Descriptor getDescriptorForType() {
293 return metadata.descriptor; 304 return metadata.descriptor;
294 } 305 }
295 306
296 private void checkFieldDescriptor(FieldDescriptor field) { 307 private void checkFieldDescriptor(FieldDescriptor field) {
297 if (field.getContainingType() != metadata.descriptor) { 308 if (field.getContainingType() != metadata.descriptor) {
298 throw new RuntimeException( 309 throw new RuntimeException(
299 "Wrong FieldDescriptor \"" + field.getFullName() 310 "Wrong FieldDescriptor \"" + field.getFullName()
300 + "\" used in message \"" + metadata.descriptor.getFullName()); 311 + "\" used in message \"" + metadata.descriptor.getFullName());
301 } 312 }
302 } 313 }
303 314
304 @Override 315 @Override
305 public com.google.protobuf.Message.Builder newBuilderForField( 316 public Message.Builder newBuilderForField(FieldDescriptor field) {
306 FieldDescriptor field) {
307 checkFieldDescriptor(field);; 317 checkFieldDescriptor(field);;
308 // This method should be called for message fields and in a MapEntry 318 // This method should be called for message fields and in a MapEntry
309 // message only the value field can possibly be a message field. 319 // message only the value field can possibly be a message field.
310 if (field.getNumber() != 2 320 if (field.getNumber() != 2
311 || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { 321 || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
312 throw new RuntimeException( 322 throw new RuntimeException(
313 "\"" + field.getFullName() + "\" is not a message value field."); 323 "\"" + field.getFullName() + "\" is not a message value field.");
314 } 324 }
315 return ((Message) data.getValue()).newBuilderForType(); 325 return ((Message) value).newBuilderForType();
316 } 326 }
317 327
318 @SuppressWarnings("unchecked") 328 @SuppressWarnings("unchecked")
319 @Override 329 @Override
320 public Builder<K, V> setField(FieldDescriptor field, Object value) { 330 public Builder<K, V> setField(FieldDescriptor field, Object value) {
321 checkFieldDescriptor(field); 331 checkFieldDescriptor(field);
322 if (field.getNumber() == 1) { 332 if (field.getNumber() == 1) {
323 setKey((K) value); 333 setKey((K) value);
324 } else { 334 } else {
325 if (field.getType() == FieldDescriptor.Type.ENUM) { 335 if (field.getType() == FieldDescriptor.Type.ENUM) {
326 value = ((EnumValueDescriptor) value).getNumber(); 336 value = ((EnumValueDescriptor) value).getNumber();
337 } else if (field.getType() == FieldDescriptor.Type.MESSAGE) {
338 if (value != null && !metadata.defaultValue.getClass().isInstance(valu e)) {
339 // The value is not the exact right message type. However, if it
340 // is an alternative implementation of the same type -- e.g. a
341 // DynamicMessage -- we should accept it. In this case we can make
342 // a copy of the message.
343 value =
344 ((Message) metadata.defaultValue).toBuilder().mergeFrom((Message ) value).build();
345 }
327 } 346 }
328 setValue((V) value); 347 setValue((V) value);
329 } 348 }
330 return this; 349 return this;
331 } 350 }
332 351
333 @Override 352 @Override
334 public Builder<K, V> clearField(FieldDescriptor field) { 353 public Builder<K, V> clearField(FieldDescriptor field) {
335 checkFieldDescriptor(field); 354 checkFieldDescriptor(field);
336 if (field.getNumber() == 1) { 355 if (field.getNumber() == 1) {
(...skipping 18 matching lines...) Expand all
355 } 374 }
356 375
357 @Override 376 @Override
358 public Builder<K, V> setUnknownFields(UnknownFieldSet unknownFields) { 377 public Builder<K, V> setUnknownFields(UnknownFieldSet unknownFields) {
359 // Unknown fields are discarded for MapEntry message. 378 // Unknown fields are discarded for MapEntry message.
360 return this; 379 return this;
361 } 380 }
362 381
363 @Override 382 @Override
364 public MapEntry<K, V> getDefaultInstanceForType() { 383 public MapEntry<K, V> getDefaultInstanceForType() {
365 return metadata.defaultInstance; 384 return new MapEntry<K, V>(metadata, metadata.defaultKey, metadata.defaultV alue);
366 } 385 }
367 386
368 @Override 387 @Override
369 public boolean isInitialized() { 388 public boolean isInitialized() {
370 if (dataBuilder != null) { 389 return MapEntry.isInitialized(metadata, value);
371 return dataBuilder.isInitialized();
372 } else {
373 return data.isInitialized();
374 }
375 } 390 }
376 391
377 @Override 392 @Override
378 public Map<FieldDescriptor, Object> getAllFields() { 393 public Map<FieldDescriptor, Object> getAllFields() {
379 final TreeMap<FieldDescriptor, Object> result = 394 final TreeMap<FieldDescriptor, Object> result = new TreeMap<FieldDescripto r, Object>();
380 new TreeMap<FieldDescriptor, Object>();
381 for (final FieldDescriptor field : metadata.descriptor.getFields()) { 395 for (final FieldDescriptor field : metadata.descriptor.getFields()) {
382 if (hasField(field)) { 396 if (hasField(field)) {
383 result.put(field, getField(field)); 397 result.put(field, getField(field));
384 } 398 }
385 } 399 }
386 return Collections.unmodifiableMap(result); 400 return Collections.unmodifiableMap(result);
387 } 401 }
388 402
389 @Override 403 @Override
390 public boolean hasField(FieldDescriptor field) { 404 public boolean hasField(FieldDescriptor field) {
391 checkFieldDescriptor(field); 405 checkFieldDescriptor(field);
392 return true; 406 return true;
393 } 407 }
394 408
395 @Override 409 @Override
396 public Object getField(FieldDescriptor field) { 410 public Object getField(FieldDescriptor field) {
397 checkFieldDescriptor(field); 411 checkFieldDescriptor(field);
398 Object result = field.getNumber() == 1 ? getKey() : getValue(); 412 Object result = field.getNumber() == 1 ? getKey() : getValue();
399 // Convert enums to EnumValueDescriptor. 413 // Convert enums to EnumValueDescriptor.
400 if (field.getType() == FieldDescriptor.Type.ENUM) { 414 if (field.getType() == FieldDescriptor.Type.ENUM) {
401 result = field.getEnumType().findValueByNumberCreatingIfUnknown( 415 result = field.getEnumType().findValueByNumberCreatingIfUnknown((Integer ) result);
402 (java.lang.Integer) result);
403 } 416 }
404 return result; 417 return result;
405 } 418 }
406 419
407 @Override 420 @Override
408 public int getRepeatedFieldCount(FieldDescriptor field) { 421 public int getRepeatedFieldCount(FieldDescriptor field) {
409 throw new RuntimeException( 422 throw new RuntimeException(
410 "There is no repeated field in a map entry message."); 423 "There is no repeated field in a map entry message.");
411 } 424 }
412 425
413 @Override 426 @Override
414 public Object getRepeatedField(FieldDescriptor field, int index) { 427 public Object getRepeatedField(FieldDescriptor field, int index) {
415 throw new RuntimeException( 428 throw new RuntimeException(
416 "There is no repeated field in a map entry message."); 429 "There is no repeated field in a map entry message.");
417 } 430 }
418 431
419 @Override 432 @Override
420 public UnknownFieldSet getUnknownFields() { 433 public UnknownFieldSet getUnknownFields() {
421 return UnknownFieldSet.getDefaultInstance(); 434 return UnknownFieldSet.getDefaultInstance();
422 } 435 }
423 436
424 @Override 437 @Override
425 public Builder<K, V> clone() { 438 public Builder<K, V> clone() {
426 if (dataBuilder == null) { 439 return new Builder(metadata, key, value);
427 return new Builder<K, V>(metadata, data);
428 } else {
429 return new Builder<K, V>(metadata, dataBuilder.build());
430 }
431 } 440 }
432 } 441 }
442
443 private static <V> boolean isInitialized(Metadata metadata, V value) {
444 if (metadata.valueType.getJavaType() == WireFormat.JavaType.MESSAGE) {
445 return ((MessageLite) value).isInitialized();
446 }
447 return true;
448 }
433 } 449 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698