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