• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import com.google.protobuf.GeneratedMessageLite.ExtensionDescriptor;
11 import java.io.IOException;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15 
16 @CheckReturnValue
17 @SuppressWarnings("unchecked")
18 final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
19 
20   @Override
hasExtensions(MessageLite prototype)21   boolean hasExtensions(MessageLite prototype) {
22     return prototype instanceof GeneratedMessageLite.ExtendableMessage;
23   }
24 
25   @Override
getExtensions(Object message)26   FieldSet<ExtensionDescriptor> getExtensions(Object message) {
27     return ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).extensions;
28   }
29 
30   @Override
setExtensions(Object message, FieldSet<ExtensionDescriptor> extensions)31   void setExtensions(Object message, FieldSet<ExtensionDescriptor> extensions) {
32     ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).extensions = extensions;
33   }
34 
35   @Override
getMutableExtensions(Object message)36   FieldSet<ExtensionDescriptor> getMutableExtensions(Object message) {
37     return ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
38   }
39 
40   @Override
makeImmutable(Object message)41   void makeImmutable(Object message) {
42     getExtensions(message).makeImmutable();
43   }
44 
45   @Override
parseExtension( Object containerMessage, Reader reader, Object extensionObject, ExtensionRegistryLite extensionRegistry, FieldSet<ExtensionDescriptor> extensions, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema)46   <UT, UB> UB parseExtension(
47       Object containerMessage,
48       Reader reader,
49       Object extensionObject,
50       ExtensionRegistryLite extensionRegistry,
51       FieldSet<ExtensionDescriptor> extensions,
52       UB unknownFields,
53       UnknownFieldSchema<UT, UB> unknownFieldSchema)
54       throws IOException {
55     GeneratedMessageLite.GeneratedExtension<?, ?> extension =
56         (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
57     int fieldNumber = extension.getNumber();
58 
59     if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) {
60       Object value = null;
61       switch (extension.getLiteType()) {
62         case DOUBLE:
63           {
64             List<Double> list = new ArrayList<Double>();
65             reader.readDoubleList(list);
66             value = list;
67             break;
68           }
69         case FLOAT:
70           {
71             List<Float> list = new ArrayList<Float>();
72             reader.readFloatList(list);
73             value = list;
74             break;
75           }
76         case INT64:
77           {
78             List<Long> list = new ArrayList<Long>();
79             reader.readInt64List(list);
80             value = list;
81             break;
82           }
83         case UINT64:
84           {
85             List<Long> list = new ArrayList<Long>();
86             reader.readUInt64List(list);
87             value = list;
88             break;
89           }
90         case INT32:
91           {
92             List<Integer> list = new ArrayList<Integer>();
93             reader.readInt32List(list);
94             value = list;
95             break;
96           }
97         case FIXED64:
98           {
99             List<Long> list = new ArrayList<Long>();
100             reader.readFixed64List(list);
101             value = list;
102             break;
103           }
104         case FIXED32:
105           {
106             List<Integer> list = new ArrayList<Integer>();
107             reader.readFixed32List(list);
108             value = list;
109             break;
110           }
111         case BOOL:
112           {
113             List<Boolean> list = new ArrayList<Boolean>();
114             reader.readBoolList(list);
115             value = list;
116             break;
117           }
118         case UINT32:
119           {
120             List<Integer> list = new ArrayList<Integer>();
121             reader.readUInt32List(list);
122             value = list;
123             break;
124           }
125         case SFIXED32:
126           {
127             List<Integer> list = new ArrayList<Integer>();
128             reader.readSFixed32List(list);
129             value = list;
130             break;
131           }
132         case SFIXED64:
133           {
134             List<Long> list = new ArrayList<Long>();
135             reader.readSFixed64List(list);
136             value = list;
137             break;
138           }
139         case SINT32:
140           {
141             List<Integer> list = new ArrayList<Integer>();
142             reader.readSInt32List(list);
143             value = list;
144             break;
145           }
146         case SINT64:
147           {
148             List<Long> list = new ArrayList<Long>();
149             reader.readSInt64List(list);
150             value = list;
151             break;
152           }
153         case ENUM:
154           {
155             List<Integer> list = new ArrayList<Integer>();
156             reader.readEnumList(list);
157             unknownFields =
158                 SchemaUtil.filterUnknownEnumList(
159                     containerMessage,
160                     fieldNumber,
161                     list,
162                     extension.descriptor.getEnumType(),
163                     unknownFields,
164                     unknownFieldSchema);
165             value = list;
166             break;
167           }
168         default:
169           throw new IllegalStateException(
170               "Type cannot be packed: " + extension.descriptor.getLiteType());
171       }
172       extensions.setField(extension.descriptor, value);
173     } else {
174       Object value = null;
175       // Enum is a special case because unknown enum values will be put into UnknownFieldSetLite.
176       if (extension.getLiteType() == WireFormat.FieldType.ENUM) {
177         int number = reader.readInt32();
178         Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
179         if (enumValue == null) {
180           return SchemaUtil.storeUnknownEnum(
181               containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema);
182         }
183         // Note, we store the integer value instead of the actual enum object in FieldSet.
184         // This is also different from full-runtime where we store EnumValueDescriptor.
185         value = number;
186       } else {
187         switch (extension.getLiteType()) {
188           case DOUBLE:
189             value = reader.readDouble();
190             break;
191           case FLOAT:
192             value = reader.readFloat();
193             break;
194           case INT64:
195             value = reader.readInt64();
196             break;
197           case UINT64:
198             value = reader.readUInt64();
199             break;
200           case INT32:
201             value = reader.readInt32();
202             break;
203           case FIXED64:
204             value = reader.readFixed64();
205             break;
206           case FIXED32:
207             value = reader.readFixed32();
208             break;
209           case BOOL:
210             value = reader.readBool();
211             break;
212           case BYTES:
213             value = reader.readBytes();
214             break;
215           case UINT32:
216             value = reader.readUInt32();
217             break;
218           case SFIXED32:
219             value = reader.readSFixed32();
220             break;
221           case SFIXED64:
222             value = reader.readSFixed64();
223             break;
224           case SINT32:
225             value = reader.readSInt32();
226             break;
227           case SINT64:
228             value = reader.readSInt64();
229             break;
230 
231           case STRING:
232             value = reader.readString();
233             break;
234           case GROUP:
235             // Special case handling for non-repeated sub-messages: merge in-place rather than
236             // building up new sub-messages and merging those, which is too slow.
237             // TODO: clean this up
238             if (!extension.isRepeated()) {
239               Object oldValue = extensions.getField(extension.descriptor);
240               if (oldValue instanceof GeneratedMessageLite) {
241                 Schema extSchema = Protobuf.getInstance().schemaFor(oldValue);
242                 if (!((GeneratedMessageLite<?, ?>) oldValue).isMutable()) {
243                   Object newValue = extSchema.newInstance();
244                   extSchema.mergeFrom(newValue, oldValue);
245                   extensions.setField(extension.descriptor, newValue);
246                   oldValue = newValue;
247                 }
248                 reader.mergeGroupField(oldValue, extSchema, extensionRegistry);
249                 return unknownFields;
250               }
251             }
252             value =
253                 reader.readGroup(
254                     extension.getMessageDefaultInstance().getClass(), extensionRegistry);
255             break;
256 
257           case MESSAGE:
258             // Special case handling for non-repeated sub-messages: merge in-place rather than
259             // building up new sub-messages and merging those, which is too slow.
260             // TODO: clean this up
261             if (!extension.isRepeated()) {
262               Object oldValue = extensions.getField(extension.descriptor);
263               if (oldValue instanceof GeneratedMessageLite) {
264                 Schema extSchema = Protobuf.getInstance().schemaFor(oldValue);
265                 if (!((GeneratedMessageLite<?, ?>) oldValue).isMutable()) {
266                   Object newValue = extSchema.newInstance();
267                   extSchema.mergeFrom(newValue, oldValue);
268                   extensions.setField(extension.descriptor, newValue);
269                   oldValue = newValue;
270                 }
271                 reader.mergeMessageField(oldValue, extSchema, extensionRegistry);
272                 return unknownFields;
273               }
274             }
275             value =
276                 reader.readMessage(
277                     extension.getMessageDefaultInstance().getClass(), extensionRegistry);
278             break;
279 
280           case ENUM:
281             throw new IllegalStateException("Shouldn't reach here.");
282         }
283       }
284       if (extension.isRepeated()) {
285         extensions.addRepeatedField(extension.descriptor, value);
286       } else {
287         switch (extension.getLiteType()) {
288           case MESSAGE:
289           case GROUP:
290             // TODO: this shouldn't be reachable, clean this up
291             Object oldValue = extensions.getField(extension.descriptor);
292             if (oldValue != null) {
293               value = Internal.mergeMessage(oldValue, value);
294             }
295             break;
296           default:
297             break;
298         }
299         extensions.setField(extension.descriptor, value);
300       }
301     }
302     return unknownFields;
303   }
304 
305   @Override
extensionNumber(Map.Entry<?, ?> extension)306   int extensionNumber(Map.Entry<?, ?> extension) {
307     GeneratedMessageLite.ExtensionDescriptor descriptor =
308         (GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
309     return descriptor.getNumber();
310   }
311 
312   @Override
serializeExtension(Writer writer, Map.Entry<?, ?> extension)313   void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException {
314     GeneratedMessageLite.ExtensionDescriptor descriptor =
315         (GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
316     if (descriptor.isRepeated()) {
317       switch (descriptor.getLiteType()) {
318         case DOUBLE:
319           SchemaUtil.writeDoubleList(
320               descriptor.getNumber(),
321               (List<Double>) extension.getValue(),
322               writer,
323               descriptor.isPacked());
324           break;
325         case FLOAT:
326           SchemaUtil.writeFloatList(
327               descriptor.getNumber(),
328               (List<Float>) extension.getValue(),
329               writer,
330               descriptor.isPacked());
331           break;
332         case INT64:
333           SchemaUtil.writeInt64List(
334               descriptor.getNumber(),
335               (List<Long>) extension.getValue(),
336               writer,
337               descriptor.isPacked());
338           break;
339         case UINT64:
340           SchemaUtil.writeUInt64List(
341               descriptor.getNumber(),
342               (List<Long>) extension.getValue(),
343               writer,
344               descriptor.isPacked());
345           break;
346         case INT32:
347           SchemaUtil.writeInt32List(
348               descriptor.getNumber(),
349               (List<Integer>) extension.getValue(),
350               writer,
351               descriptor.isPacked());
352           break;
353         case FIXED64:
354           SchemaUtil.writeFixed64List(
355               descriptor.getNumber(),
356               (List<Long>) extension.getValue(),
357               writer,
358               descriptor.isPacked());
359           break;
360         case FIXED32:
361           SchemaUtil.writeFixed32List(
362               descriptor.getNumber(),
363               (List<Integer>) extension.getValue(),
364               writer,
365               descriptor.isPacked());
366           break;
367         case BOOL:
368           SchemaUtil.writeBoolList(
369               descriptor.getNumber(),
370               (List<Boolean>) extension.getValue(),
371               writer,
372               descriptor.isPacked());
373           break;
374         case BYTES:
375           SchemaUtil.writeBytesList(
376               descriptor.getNumber(), (List<ByteString>) extension.getValue(), writer);
377           break;
378         case UINT32:
379           SchemaUtil.writeUInt32List(
380               descriptor.getNumber(),
381               (List<Integer>) extension.getValue(),
382               writer,
383               descriptor.isPacked());
384           break;
385         case SFIXED32:
386           SchemaUtil.writeSFixed32List(
387               descriptor.getNumber(),
388               (List<Integer>) extension.getValue(),
389               writer,
390               descriptor.isPacked());
391           break;
392         case SFIXED64:
393           SchemaUtil.writeSFixed64List(
394               descriptor.getNumber(),
395               (List<Long>) extension.getValue(),
396               writer,
397               descriptor.isPacked());
398           break;
399         case SINT32:
400           SchemaUtil.writeSInt32List(
401               descriptor.getNumber(),
402               (List<Integer>) extension.getValue(),
403               writer,
404               descriptor.isPacked());
405           break;
406         case SINT64:
407           SchemaUtil.writeSInt64List(
408               descriptor.getNumber(),
409               (List<Long>) extension.getValue(),
410               writer,
411               descriptor.isPacked());
412           break;
413         case ENUM:
414           SchemaUtil.writeInt32List(
415               descriptor.getNumber(),
416               (List<Integer>) extension.getValue(),
417               writer,
418               descriptor.isPacked());
419           break;
420         case STRING:
421           SchemaUtil.writeStringList(
422               descriptor.getNumber(), (List<String>) extension.getValue(), writer);
423           break;
424         case GROUP:
425           {
426             List<?> data = (List<?>) extension.getValue();
427             if (data != null && !data.isEmpty()) {
428               SchemaUtil.writeGroupList(
429                   descriptor.getNumber(),
430                   (List<?>) extension.getValue(),
431                   writer,
432                   Protobuf.getInstance().schemaFor(data.get(0).getClass()));
433             }
434           }
435           break;
436         case MESSAGE:
437           {
438             List<?> data = (List<?>) extension.getValue();
439             if (data != null && !data.isEmpty()) {
440               SchemaUtil.writeMessageList(
441                   descriptor.getNumber(),
442                   (List<?>) extension.getValue(),
443                   writer,
444                   Protobuf.getInstance().schemaFor(data.get(0).getClass()));
445             }
446           }
447           break;
448       }
449     } else {
450       switch (descriptor.getLiteType()) {
451         case DOUBLE:
452           writer.writeDouble(descriptor.getNumber(), (Double) extension.getValue());
453           break;
454         case FLOAT:
455           writer.writeFloat(descriptor.getNumber(), (Float) extension.getValue());
456           break;
457         case INT64:
458           writer.writeInt64(descriptor.getNumber(), (Long) extension.getValue());
459           break;
460         case UINT64:
461           writer.writeUInt64(descriptor.getNumber(), (Long) extension.getValue());
462           break;
463         case INT32:
464           writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
465           break;
466         case FIXED64:
467           writer.writeFixed64(descriptor.getNumber(), (Long) extension.getValue());
468           break;
469         case FIXED32:
470           writer.writeFixed32(descriptor.getNumber(), (Integer) extension.getValue());
471           break;
472         case BOOL:
473           writer.writeBool(descriptor.getNumber(), (Boolean) extension.getValue());
474           break;
475         case BYTES:
476           writer.writeBytes(descriptor.getNumber(), (ByteString) extension.getValue());
477           break;
478         case UINT32:
479           writer.writeUInt32(descriptor.getNumber(), (Integer) extension.getValue());
480           break;
481         case SFIXED32:
482           writer.writeSFixed32(descriptor.getNumber(), (Integer) extension.getValue());
483           break;
484         case SFIXED64:
485           writer.writeSFixed64(descriptor.getNumber(), (Long) extension.getValue());
486           break;
487         case SINT32:
488           writer.writeSInt32(descriptor.getNumber(), (Integer) extension.getValue());
489           break;
490         case SINT64:
491           writer.writeSInt64(descriptor.getNumber(), (Long) extension.getValue());
492           break;
493         case ENUM:
494           writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
495           break;
496         case STRING:
497           writer.writeString(descriptor.getNumber(), (String) extension.getValue());
498           break;
499         case GROUP:
500           writer.writeGroup(
501               descriptor.getNumber(),
502               extension.getValue(),
503               Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
504           break;
505         case MESSAGE:
506           writer.writeMessage(
507               descriptor.getNumber(),
508               extension.getValue(),
509               Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
510           break;
511       }
512     }
513   }
514 
515   @Override
findExtensionByNumber( ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number)516   Object findExtensionByNumber(
517       ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) {
518     return extensionRegistry.findLiteExtensionByNumber(defaultInstance, number);
519   }
520 
521   @Override
parseLengthPrefixedMessageSetItem( Reader reader, Object extensionObject, ExtensionRegistryLite extensionRegistry, FieldSet<ExtensionDescriptor> extensions)522   void parseLengthPrefixedMessageSetItem(
523       Reader reader,
524       Object extensionObject,
525       ExtensionRegistryLite extensionRegistry,
526       FieldSet<ExtensionDescriptor> extensions)
527       throws IOException {
528     GeneratedMessageLite.GeneratedExtension<?, ?> extension =
529         (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
530     Object value =
531         reader.readMessage(extension.getMessageDefaultInstance().getClass(), extensionRegistry);
532     extensions.setField(extension.descriptor, value);
533   }
534 
535   @Override
parseMessageSetItem( ByteString data, Object extensionObject, ExtensionRegistryLite extensionRegistry, FieldSet<ExtensionDescriptor> extensions)536   void parseMessageSetItem(
537       ByteString data,
538       Object extensionObject,
539       ExtensionRegistryLite extensionRegistry,
540       FieldSet<ExtensionDescriptor> extensions)
541       throws IOException {
542     GeneratedMessageLite.GeneratedExtension<?, ?> extension =
543         (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
544 
545     MessageLite.Builder builder = extension.getMessageDefaultInstance().newBuilderForType();
546 
547     final CodedInputStream input = data.newCodedInput();
548 
549     builder.mergeFrom(input, extensionRegistry);
550     extensions.setField(extension.descriptor, builder.buildPartial());
551     input.checkLastTagWas(0);
552   }
553 }
554