1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
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
31package com.google.protobuf;
32
33import java.io.IOException;
34import java.util.Collections;
35import java.util.Iterator;
36import java.util.List;
37import java.util.Map;
38
39/**
40 * Lite version of {@link GeneratedMessage}.
41 *
42 * @author kenton@google.com Kenton Varda
43 */
44public abstract class GeneratedMessageLite extends AbstractMessageLite {
45  protected GeneratedMessageLite() {}
46
47  @SuppressWarnings("unchecked")
48  public abstract static class Builder<MessageType extends GeneratedMessageLite,
49                                       BuilderType extends Builder>
50      extends AbstractMessageLite.Builder<BuilderType> {
51    protected Builder() {}
52
53    // This is implemented here only to work around an apparent bug in the
54    // Java compiler and/or build system.  See bug #1898463.  The mere presence
55    // of this dummy clone() implementation makes it go away.
56    @Override
57    public BuilderType clone() {
58      throw new UnsupportedOperationException(
59          "This is supposed to be overridden by subclasses.");
60    }
61
62    /** All subclasses implement this. */
63    public abstract BuilderType mergeFrom(MessageType message);
64
65    // Defined here for return type covariance.
66    public abstract MessageType getDefaultInstanceForType();
67
68    /**
69     * Get the message being built.  We don't just pass this to the
70     * constructor because it becomes null when build() is called.
71     */
72    protected abstract MessageType internalGetResult();
73
74    /**
75     * Called by subclasses to parse an unknown field.
76     * @return {@code true} unless the tag is an end-group tag.
77     */
78    protected boolean parseUnknownField(
79        final CodedInputStream input,
80        final ExtensionRegistryLite extensionRegistry,
81        final int tag) throws IOException {
82      return input.skipField(tag);
83    }
84  }
85
86  // =================================================================
87  // Extensions-related stuff
88
89  /**
90   * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
91   */
92  public abstract static class ExtendableMessage<
93        MessageType extends ExtendableMessage<MessageType>>
94      extends GeneratedMessageLite {
95    protected ExtendableMessage() {}
96    private final FieldSet<ExtensionDescriptor> extensions =
97        FieldSet.newFieldSet();
98
99    private void verifyExtensionContainingType(
100        final GeneratedExtension<MessageType, ?> extension) {
101      if (extension.getContainingTypeDefaultInstance() !=
102          getDefaultInstanceForType()) {
103        // This can only happen if someone uses unchecked operations.
104        throw new IllegalArgumentException(
105          "This extension is for a different message type.  Please make " +
106          "sure that you are not suppressing any generics type warnings.");
107      }
108    }
109
110    /** Check if a singular extension is present. */
111    public final boolean hasExtension(
112        final GeneratedExtension<MessageType, ?> extension) {
113      verifyExtensionContainingType(extension);
114      return extensions.hasField(extension.descriptor);
115    }
116
117    /** Get the number of elements in a repeated extension. */
118    public final <Type> int getExtensionCount(
119        final GeneratedExtension<MessageType, List<Type>> extension) {
120      verifyExtensionContainingType(extension);
121      return extensions.getRepeatedFieldCount(extension.descriptor);
122    }
123
124    /** Get the value of an extension. */
125    @SuppressWarnings("unchecked")
126    public final <Type> Type getExtension(
127        final GeneratedExtension<MessageType, Type> extension) {
128      verifyExtensionContainingType(extension);
129      final Object value = extensions.getField(extension.descriptor);
130      if (value == null) {
131        return extension.defaultValue;
132      } else {
133        return (Type) value;
134      }
135    }
136
137    /** Get one element of a repeated extension. */
138    @SuppressWarnings("unchecked")
139    public final <Type> Type getExtension(
140        final GeneratedExtension<MessageType, List<Type>> extension,
141        final int index) {
142      verifyExtensionContainingType(extension);
143      return (Type) extensions.getRepeatedField(extension.descriptor, index);
144    }
145
146    /** Called by subclasses to check if all extensions are initialized. */
147    protected boolean extensionsAreInitialized() {
148      return extensions.isInitialized();
149    }
150
151    /**
152     * Used by subclasses to serialize extensions.  Extension ranges may be
153     * interleaved with field numbers, but we must write them in canonical
154     * (sorted by field number) order.  ExtensionWriter helps us write
155     * individual ranges of extensions at once.
156     */
157    protected class ExtensionWriter {
158      // Imagine how much simpler this code would be if Java iterators had
159      // a way to get the next element without advancing the iterator.
160
161      private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
162            extensions.iterator();
163      private Map.Entry<ExtensionDescriptor, Object> next;
164      private final boolean messageSetWireFormat;
165
166      private ExtensionWriter(boolean messageSetWireFormat) {
167        if (iter.hasNext()) {
168          next = iter.next();
169        }
170        this.messageSetWireFormat = messageSetWireFormat;
171      }
172
173      public void writeUntil(final int end, final CodedOutputStream output)
174                             throws IOException {
175        while (next != null && next.getKey().getNumber() < end) {
176          ExtensionDescriptor extension = next.getKey();
177          if (messageSetWireFormat && extension.getLiteJavaType() ==
178                  WireFormat.JavaType.MESSAGE &&
179              !extension.isRepeated()) {
180            output.writeMessageSetExtension(extension.getNumber(),
181                                            (MessageLite) next.getValue());
182          } else {
183            FieldSet.writeField(extension, next.getValue(), output);
184          }
185          if (iter.hasNext()) {
186            next = iter.next();
187          } else {
188            next = null;
189          }
190        }
191      }
192    }
193
194    protected ExtensionWriter newExtensionWriter() {
195      return new ExtensionWriter(false);
196    }
197    protected ExtensionWriter newMessageSetExtensionWriter() {
198      return new ExtensionWriter(true);
199    }
200
201    /** Called by subclasses to compute the size of extensions. */
202    protected int extensionsSerializedSize() {
203      return extensions.getSerializedSize();
204    }
205    protected int extensionsSerializedSizeAsMessageSet() {
206      return extensions.getMessageSetSerializedSize();
207    }
208  }
209
210  /**
211   * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
212   */
213  @SuppressWarnings("unchecked")
214  public abstract static class ExtendableBuilder<
215        MessageType extends ExtendableMessage<MessageType>,
216        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
217      extends Builder<MessageType, BuilderType> {
218    protected ExtendableBuilder() {}
219
220    // This is implemented here only to work around an apparent bug in the
221    // Java compiler and/or build system.  See bug #1898463.  The mere presence
222    // of this dummy clone() implementation makes it go away.
223    @Override
224    public BuilderType clone() {
225      throw new UnsupportedOperationException(
226          "This is supposed to be overridden by subclasses.");
227    }
228
229    @Override
230    protected abstract MessageType internalGetResult();
231
232    /** Check if a singular extension is present. */
233    public final boolean hasExtension(
234        final GeneratedExtension<MessageType, ?> extension) {
235      return internalGetResult().hasExtension(extension);
236    }
237
238    /** Get the number of elements in a repeated extension. */
239    public final <Type> int getExtensionCount(
240        final GeneratedExtension<MessageType, List<Type>> extension) {
241      return internalGetResult().getExtensionCount(extension);
242    }
243
244    /** Get the value of an extension. */
245    public final <Type> Type getExtension(
246        final GeneratedExtension<MessageType, Type> extension) {
247      return internalGetResult().getExtension(extension);
248    }
249
250    /** Get one element of a repeated extension. */
251    public final <Type> Type getExtension(
252        final GeneratedExtension<MessageType, List<Type>> extension,
253        final int index) {
254      return internalGetResult().getExtension(extension, index);
255    }
256
257    /** Set the value of an extension. */
258    public final <Type> BuilderType setExtension(
259        final GeneratedExtension<MessageType, Type> extension,
260        final Type value) {
261      final ExtendableMessage<MessageType> message = internalGetResult();
262      message.verifyExtensionContainingType(extension);
263      message.extensions.setField(extension.descriptor, value);
264      return (BuilderType) this;
265    }
266
267    /** Set the value of one element of a repeated extension. */
268    public final <Type> BuilderType setExtension(
269        final GeneratedExtension<MessageType, List<Type>> extension,
270        final int index, final Type value) {
271      final ExtendableMessage<MessageType> message = internalGetResult();
272      message.verifyExtensionContainingType(extension);
273      message.extensions.setRepeatedField(extension.descriptor, index, value);
274      return (BuilderType) this;
275    }
276
277    /** Append a value to a repeated extension. */
278    public final <Type> BuilderType addExtension(
279        final GeneratedExtension<MessageType, List<Type>> extension,
280        final Type value) {
281      final ExtendableMessage<MessageType> message = internalGetResult();
282      message.verifyExtensionContainingType(extension);
283      message.extensions.addRepeatedField(extension.descriptor, value);
284      return (BuilderType) this;
285    }
286
287    /** Clear an extension. */
288    public final <Type> BuilderType clearExtension(
289        final GeneratedExtension<MessageType, ?> extension) {
290      final ExtendableMessage<MessageType> message = internalGetResult();
291      message.verifyExtensionContainingType(extension);
292      message.extensions.clearField(extension.descriptor);
293      return (BuilderType) this;
294    }
295
296    /**
297     * Called by subclasses to parse an unknown field or an extension.
298     * @return {@code true} unless the tag is an end-group tag.
299     */
300    @Override
301    protected boolean parseUnknownField(
302        final CodedInputStream input,
303        final ExtensionRegistryLite extensionRegistry,
304        final int tag) throws IOException {
305      final FieldSet<ExtensionDescriptor> extensions =
306          ((ExtendableMessage) internalGetResult()).extensions;
307
308      final int wireType = WireFormat.getTagWireType(tag);
309      final int fieldNumber = WireFormat.getTagFieldNumber(tag);
310
311      final GeneratedExtension<MessageType, ?> extension =
312        extensionRegistry.findLiteExtensionByNumber(
313            getDefaultInstanceForType(), fieldNumber);
314
315      boolean unknown = false;
316      boolean packed = false;
317      if (extension == null) {
318        unknown = true;  // Unknown field.
319      } else if (wireType == FieldSet.getWireFormatForFieldType(
320                   extension.descriptor.getLiteType(),
321                   false  /* isPacked */)) {
322        packed = false;  // Normal, unpacked value.
323      } else if (extension.descriptor.isRepeated &&
324                 extension.descriptor.type.isPackable() &&
325                 wireType == FieldSet.getWireFormatForFieldType(
326                   extension.descriptor.getLiteType(),
327                   true  /* isPacked */)) {
328        packed = true;  // Packed value.
329      } else {
330        unknown = true;  // Wrong wire type.
331      }
332
333      if (unknown) {  // Unknown field or wrong wire type.  Skip.
334        return input.skipField(tag);
335      }
336
337      if (packed) {
338        final int length = input.readRawVarint32();
339        final int limit = input.pushLimit(length);
340        if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
341          while (input.getBytesUntilLimit() > 0) {
342            final int rawValue = input.readEnum();
343            final Object value =
344                extension.descriptor.getEnumType().findValueByNumber(rawValue);
345            if (value == null) {
346              // If the number isn't recognized as a valid value for this
347              // enum, drop it (don't even add it to unknownFields).
348              return true;
349            }
350            extensions.addRepeatedField(extension.descriptor, value);
351          }
352        } else {
353          while (input.getBytesUntilLimit() > 0) {
354            final Object value =
355              FieldSet.readPrimitiveField(input,
356                                          extension.descriptor.getLiteType());
357            extensions.addRepeatedField(extension.descriptor, value);
358          }
359        }
360        input.popLimit(limit);
361      } else {
362        final Object value;
363        switch (extension.descriptor.getLiteJavaType()) {
364          case MESSAGE: {
365            MessageLite.Builder subBuilder = null;
366            if (!extension.descriptor.isRepeated()) {
367              MessageLite existingValue =
368                  (MessageLite) extensions.getField(extension.descriptor);
369              if (existingValue != null) {
370                subBuilder = existingValue.toBuilder();
371              }
372            }
373            if (subBuilder == null) {
374              subBuilder = extension.messageDefaultInstance.newBuilderForType();
375            }
376            if (extension.descriptor.getLiteType() ==
377                WireFormat.FieldType.GROUP) {
378              input.readGroup(extension.getNumber(),
379                              subBuilder, extensionRegistry);
380            } else {
381              input.readMessage(subBuilder, extensionRegistry);
382            }
383            value = subBuilder.build();
384            break;
385          }
386          case ENUM:
387            final int rawValue = input.readEnum();
388            value = extension.descriptor.getEnumType()
389                             .findValueByNumber(rawValue);
390            // If the number isn't recognized as a valid value for this enum,
391            // drop it.
392            if (value == null) {
393              return true;
394            }
395            break;
396          default:
397            value = FieldSet.readPrimitiveField(input,
398                extension.descriptor.getLiteType());
399            break;
400        }
401
402        if (extension.descriptor.isRepeated()) {
403          extensions.addRepeatedField(extension.descriptor, value);
404        } else {
405          extensions.setField(extension.descriptor, value);
406        }
407      }
408
409      return true;
410    }
411
412    protected final void mergeExtensionFields(final MessageType other) {
413      ((ExtendableMessage) internalGetResult()).extensions.mergeFrom(
414          ((ExtendableMessage) other).extensions);
415    }
416  }
417
418  // -----------------------------------------------------------------
419
420  /** For use by generated code only. */
421  public static <ContainingType extends MessageLite, Type>
422      GeneratedExtension<ContainingType, Type>
423      newGeneratedExtension() {
424    return new GeneratedExtension<ContainingType, Type>();
425  }
426
427  private static final class ExtensionDescriptor
428      implements FieldSet.FieldDescriptorLite<
429        ExtensionDescriptor> {
430    private ExtensionDescriptor(
431        final Internal.EnumLiteMap<?> enumTypeMap,
432        final int number,
433        final WireFormat.FieldType type,
434        final boolean isRepeated,
435        final boolean isPacked) {
436      this.enumTypeMap = enumTypeMap;
437      this.number = number;
438      this.type = type;
439      this.isRepeated = isRepeated;
440      this.isPacked = isPacked;
441    }
442
443    private final Internal.EnumLiteMap<?> enumTypeMap;
444    private final int number;
445    private final WireFormat.FieldType type;
446    private final boolean isRepeated;
447    private final boolean isPacked;
448
449    public int getNumber() {
450      return number;
451    }
452
453    public WireFormat.FieldType getLiteType() {
454      return type;
455    }
456
457    public WireFormat.JavaType getLiteJavaType() {
458      return type.getJavaType();
459    }
460
461    public boolean isRepeated() {
462      return isRepeated;
463    }
464
465    public boolean isPacked() {
466      return isPacked;
467    }
468
469    public Internal.EnumLiteMap<?> getEnumType() {
470      return enumTypeMap;
471    }
472
473    @SuppressWarnings("unchecked")
474    public MessageLite.Builder internalMergeFrom(
475        MessageLite.Builder to, MessageLite from) {
476      return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
477    }
478
479    public int compareTo(ExtensionDescriptor other) {
480      return number - other.number;
481    }
482  }
483
484  /**
485   * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
486   *
487   * Users should ignore the contents of this class and only use objects of
488   * this type as parameters to extension accessors and ExtensionRegistry.add().
489   */
490  public static final class GeneratedExtension<
491      ContainingType extends MessageLite, Type> {
492    // We can't always initialize a GeneratedExtension when we first construct
493    // it due to initialization order difficulties (namely, the default
494    // instances may not have been constructed yet).  So, we construct an
495    // uninitialized GeneratedExtension once, then call internalInit() on it
496    // later.  Generated code will always call internalInit() on all extensions
497    // as part of the static initialization code, and internalInit() throws an
498    // exception if called more than once, so this method is useless to users.
499    private GeneratedExtension() {}
500
501    private void internalInit(
502        final ContainingType containingTypeDefaultInstance,
503        final Type defaultValue,
504        final MessageLite messageDefaultInstance,
505        final ExtensionDescriptor descriptor) {
506      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
507      this.defaultValue = defaultValue;
508      this.messageDefaultInstance = messageDefaultInstance;
509      this.descriptor = descriptor;
510    }
511
512    /** For use by generated code only. */
513    public void internalInitSingular(
514        final ContainingType containingTypeDefaultInstance,
515        final Type defaultValue,
516        final MessageLite messageDefaultInstance,
517        final Internal.EnumLiteMap<?> enumTypeMap,
518        final int number,
519        final WireFormat.FieldType type) {
520      internalInit(
521        containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
522        new ExtensionDescriptor(enumTypeMap, number, type,
523          false /* isRepeated */, false /* isPacked */));
524    }
525
526    /** For use by generated code only. */
527    public void internalInitRepeated(
528        final ContainingType containingTypeDefaultInstance,
529        final MessageLite messageDefaultInstance,
530        final Internal.EnumLiteMap<?> enumTypeMap,
531        final int number,
532        final WireFormat.FieldType type,
533        final boolean isPacked) {
534      internalInit(
535        containingTypeDefaultInstance, (Type) Collections.emptyList(),
536        messageDefaultInstance,
537        new ExtensionDescriptor(
538          enumTypeMap, number, type, true /* isRepeated */, isPacked));
539    }
540
541    private ContainingType containingTypeDefaultInstance;
542    private Type defaultValue;
543    private MessageLite messageDefaultInstance;
544    private ExtensionDescriptor descriptor;
545
546    /**
547     * Default instance of the type being extended, used to identify that type.
548     */
549    public ContainingType getContainingTypeDefaultInstance() {
550      return containingTypeDefaultInstance;
551    }
552
553    /** Get the field number. */
554    public int getNumber() {
555      return descriptor.getNumber();
556    }
557
558    /**
559     * If the extension is an embedded message, this is the default instance of
560     * that type.
561     */
562    public MessageLite getMessageDefaultInstance() {
563      return messageDefaultInstance;
564    }
565  }
566}
567