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