Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/tools/ExternalEvaluation/Java/ExternalEvaluation.Service/src/com/google/protobuf/GeneratedMessageLite.java @ 15014

Last change on this file since 15014 was 15014, checked in by pfleck, 7 years ago

Added code and tools for the ExternalEvaluationProblem. (e.g. Java-side evaluation)

File size: 26.6 KB
Line 
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.io.ObjectStreamException;
35import java.io.Serializable;
36import java.lang.reflect.InvocationTargetException;
37import java.lang.reflect.Method;
38import java.util.Collections;
39import java.util.Iterator;
40import java.util.List;
41import java.util.Map;
42
43/**
44 * Lite version of {@link GeneratedMessage}.
45 *
46 * @author kenton@google.com Kenton Varda
47 */
48public abstract class GeneratedMessageLite extends AbstractMessageLite
49    implements Serializable {
50  private static final long serialVersionUID = 1L;
51
52  protected GeneratedMessageLite() {
53  }
54
55  protected GeneratedMessageLite(Builder builder) {
56  }
57
58  @SuppressWarnings("unchecked")
59  public abstract static class Builder<MessageType extends GeneratedMessageLite,
60                                       BuilderType extends Builder>
61      extends AbstractMessageLite.Builder<BuilderType> {
62    protected Builder() {}
63
64    //@Override (Java 1.6 override semantics, but we must support 1.5)
65    public BuilderType clear() {
66      return (BuilderType) this;
67    }
68
69    // This is implemented here only to work around an apparent bug in the
70    // Java compiler and/or build system.  See bug #1898463.  The mere presence
71    // of this dummy clone() implementation makes it go away.
72    @Override
73    public BuilderType clone() {
74      throw new UnsupportedOperationException(
75          "This is supposed to be overridden by subclasses.");
76    }
77
78    /** All subclasses implement this. */
79    public abstract BuilderType mergeFrom(MessageType message);
80
81    // Defined here for return type covariance.
82    public abstract MessageType getDefaultInstanceForType();
83
84    /**
85     * Called by subclasses to parse an unknown field.
86     * @return {@code true} unless the tag is an end-group tag.
87     */
88    protected boolean parseUnknownField(
89        final CodedInputStream input,
90        final ExtensionRegistryLite extensionRegistry,
91        final int tag) throws IOException {
92      return input.skipField(tag);
93    }
94  }
95
96  // =================================================================
97  // Extensions-related stuff
98
99  /**
100   * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
101   */
102  public interface ExtendableMessageOrBuilder<
103      MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
104
105    /** Check if a singular extension is present. */
106    <Type> boolean hasExtension(
107        GeneratedExtension<MessageType, Type> extension);
108
109    /** Get the number of elements in a repeated extension. */
110    <Type> int getExtensionCount(
111        GeneratedExtension<MessageType, List<Type>> extension);
112
113    /** Get the value of an extension. */
114    <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
115
116    /** Get one element of a repeated extension. */
117    <Type> Type getExtension(
118        GeneratedExtension<MessageType, List<Type>> extension,
119        int index);
120  }
121
122  /**
123   * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
124   */
125  public abstract static class ExtendableMessage<
126        MessageType extends ExtendableMessage<MessageType>>
127      extends GeneratedMessageLite
128      implements ExtendableMessageOrBuilder<MessageType> {
129
130    private final FieldSet<ExtensionDescriptor> extensions;
131
132    protected ExtendableMessage() {
133      this.extensions = FieldSet.newFieldSet();
134    }
135
136    protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
137      this.extensions = builder.buildExtensions();
138    }
139
140    private void verifyExtensionContainingType(
141        final GeneratedExtension<MessageType, ?> extension) {
142      if (extension.getContainingTypeDefaultInstance() !=
143          getDefaultInstanceForType()) {
144        // This can only happen if someone uses unchecked operations.
145        throw new IllegalArgumentException(
146          "This extension is for a different message type.  Please make " +
147          "sure that you are not suppressing any generics type warnings.");
148      }
149    }
150
151    /** Check if a singular extension is present. */
152    //@Override (Java 1.6 override semantics, but we must support 1.5)
153    public final <Type> boolean hasExtension(
154        final GeneratedExtension<MessageType, Type> extension) {
155      verifyExtensionContainingType(extension);
156      return extensions.hasField(extension.descriptor);
157    }
158
159    /** Get the number of elements in a repeated extension. */
160    //@Override (Java 1.6 override semantics, but we must support 1.5)
161    public final <Type> int getExtensionCount(
162        final GeneratedExtension<MessageType, List<Type>> extension) {
163      verifyExtensionContainingType(extension);
164      return extensions.getRepeatedFieldCount(extension.descriptor);
165    }
166
167    /** Get the value of an extension. */
168    //@Override (Java 1.6 override semantics, but we must support 1.5)
169    @SuppressWarnings("unchecked")
170    public final <Type> Type getExtension(
171        final GeneratedExtension<MessageType, Type> extension) {
172      verifyExtensionContainingType(extension);
173      final Object value = extensions.getField(extension.descriptor);
174      if (value == null) {
175        return extension.defaultValue;
176      } else {
177        return (Type) value;
178      }
179    }
180
181    /** Get one element of a repeated extension. */
182    //@Override (Java 1.6 override semantics, but we must support 1.5)
183    @SuppressWarnings("unchecked")
184    public final <Type> Type getExtension(
185        final GeneratedExtension<MessageType, List<Type>> extension,
186        final int index) {
187      verifyExtensionContainingType(extension);
188      return (Type) extensions.getRepeatedField(extension.descriptor, index);
189    }
190
191    /** Called by subclasses to check if all extensions are initialized. */
192    protected boolean extensionsAreInitialized() {
193      return extensions.isInitialized();
194    }
195
196    /**
197     * Used by subclasses to serialize extensions.  Extension ranges may be
198     * interleaved with field numbers, but we must write them in canonical
199     * (sorted by field number) order.  ExtensionWriter helps us write
200     * individual ranges of extensions at once.
201     */
202    protected class ExtensionWriter {
203      // Imagine how much simpler this code would be if Java iterators had
204      // a way to get the next element without advancing the iterator.
205
206      private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
207            extensions.iterator();
208      private Map.Entry<ExtensionDescriptor, Object> next;
209      private final boolean messageSetWireFormat;
210
211      private ExtensionWriter(boolean messageSetWireFormat) {
212        if (iter.hasNext()) {
213          next = iter.next();
214        }
215        this.messageSetWireFormat = messageSetWireFormat;
216      }
217
218      public void writeUntil(final int end, final CodedOutputStream output)
219                             throws IOException {
220        while (next != null && next.getKey().getNumber() < end) {
221          ExtensionDescriptor extension = next.getKey();
222          if (messageSetWireFormat && extension.getLiteJavaType() ==
223                  WireFormat.JavaType.MESSAGE &&
224              !extension.isRepeated()) {
225            output.writeMessageSetExtension(extension.getNumber(),
226                                            (MessageLite) next.getValue());
227          } else {
228            FieldSet.writeField(extension, next.getValue(), output);
229          }
230          if (iter.hasNext()) {
231            next = iter.next();
232          } else {
233            next = null;
234          }
235        }
236      }
237    }
238
239    protected ExtensionWriter newExtensionWriter() {
240      return new ExtensionWriter(false);
241    }
242    protected ExtensionWriter newMessageSetExtensionWriter() {
243      return new ExtensionWriter(true);
244    }
245
246    /** Called by subclasses to compute the size of extensions. */
247    protected int extensionsSerializedSize() {
248      return extensions.getSerializedSize();
249    }
250    protected int extensionsSerializedSizeAsMessageSet() {
251      return extensions.getMessageSetSerializedSize();
252    }
253  }
254
255  /**
256   * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
257   */
258  @SuppressWarnings("unchecked")
259  public abstract static class ExtendableBuilder<
260        MessageType extends ExtendableMessage<MessageType>,
261        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
262      extends Builder<MessageType, BuilderType>
263      implements ExtendableMessageOrBuilder<MessageType> {
264    protected ExtendableBuilder() {}
265
266    private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
267    private boolean extensionsIsMutable;
268
269    @Override
270    public BuilderType clear() {
271      extensions.clear();
272      extensionsIsMutable = false;
273      return super.clear();
274    }
275
276    private void ensureExtensionsIsMutable() {
277      if (!extensionsIsMutable) {
278        extensions = extensions.clone();
279        extensionsIsMutable = true;
280      }
281    }
282
283    /**
284     * Called by the build code path to create a copy of the extensions for
285     * building the message.
286     */
287    private FieldSet<ExtensionDescriptor> buildExtensions() {
288      extensions.makeImmutable();
289      extensionsIsMutable = false;
290      return extensions;
291    }
292
293    private void verifyExtensionContainingType(
294        final GeneratedExtension<MessageType, ?> extension) {
295      if (extension.getContainingTypeDefaultInstance() !=
296          getDefaultInstanceForType()) {
297        // This can only happen if someone uses unchecked operations.
298        throw new IllegalArgumentException(
299          "This extension is for a different message type.  Please make " +
300          "sure that you are not suppressing any generics type warnings.");
301      }
302    }
303
304    /** Check if a singular extension is present. */
305    //@Override (Java 1.6 override semantics, but we must support 1.5)
306    public final <Type> boolean hasExtension(
307        final GeneratedExtension<MessageType, Type> extension) {
308      verifyExtensionContainingType(extension);
309      return extensions.hasField(extension.descriptor);
310    }
311
312    /** Get the number of elements in a repeated extension. */
313    //@Override (Java 1.6 override semantics, but we must support 1.5)
314    public final <Type> int getExtensionCount(
315        final GeneratedExtension<MessageType, List<Type>> extension) {
316      verifyExtensionContainingType(extension);
317      return extensions.getRepeatedFieldCount(extension.descriptor);
318    }
319
320    /** Get the value of an extension. */
321    //@Override (Java 1.6 override semantics, but we must support 1.5)
322    @SuppressWarnings("unchecked")
323    public final <Type> Type getExtension(
324        final GeneratedExtension<MessageType, Type> extension) {
325      verifyExtensionContainingType(extension);
326      final Object value = extensions.getField(extension.descriptor);
327      if (value == null) {
328        return extension.defaultValue;
329      } else {
330        return (Type) value;
331      }
332    }
333
334    /** Get one element of a repeated extension. */
335    @SuppressWarnings("unchecked")
336    //@Override (Java 1.6 override semantics, but we must support 1.5)
337    public final <Type> Type getExtension(
338        final GeneratedExtension<MessageType, List<Type>> extension,
339        final int index) {
340      verifyExtensionContainingType(extension);
341      return (Type) extensions.getRepeatedField(extension.descriptor, index);
342    }
343
344    // This is implemented here only to work around an apparent bug in the
345    // Java compiler and/or build system.  See bug #1898463.  The mere presence
346    // of this dummy clone() implementation makes it go away.
347    @Override
348    public BuilderType clone() {
349      throw new UnsupportedOperationException(
350          "This is supposed to be overridden by subclasses.");
351    }
352
353    /** Set the value of an extension. */
354    public final <Type> BuilderType setExtension(
355        final GeneratedExtension<MessageType, Type> extension,
356        final Type value) {
357      verifyExtensionContainingType(extension);
358      ensureExtensionsIsMutable();
359      extensions.setField(extension.descriptor, value);
360      return (BuilderType) this;
361    }
362
363    /** Set the value of one element of a repeated extension. */
364    public final <Type> BuilderType setExtension(
365        final GeneratedExtension<MessageType, List<Type>> extension,
366        final int index, final Type value) {
367      verifyExtensionContainingType(extension);
368      ensureExtensionsIsMutable();
369      extensions.setRepeatedField(extension.descriptor, index, value);
370      return (BuilderType) this;
371    }
372
373    /** Append a value to a repeated extension. */
374    public final <Type> BuilderType addExtension(
375        final GeneratedExtension<MessageType, List<Type>> extension,
376        final Type value) {
377      verifyExtensionContainingType(extension);
378      ensureExtensionsIsMutable();
379      extensions.addRepeatedField(extension.descriptor, value);
380      return (BuilderType) this;
381    }
382
383    /** Clear an extension. */
384    public final <Type> BuilderType clearExtension(
385        final GeneratedExtension<MessageType, ?> extension) {
386      verifyExtensionContainingType(extension);
387      ensureExtensionsIsMutable();
388      extensions.clearField(extension.descriptor);
389      return (BuilderType) this;
390    }
391
392    /** Called by subclasses to check if all extensions are initialized. */
393    protected boolean extensionsAreInitialized() {
394      return extensions.isInitialized();
395    }
396
397    /**
398     * Called by subclasses to parse an unknown field or an extension.
399     * @return {@code true} unless the tag is an end-group tag.
400     */
401    @Override
402    protected boolean parseUnknownField(
403        final CodedInputStream input,
404        final ExtensionRegistryLite extensionRegistry,
405        final int tag) throws IOException {
406      final int wireType = WireFormat.getTagWireType(tag);
407      final int fieldNumber = WireFormat.getTagFieldNumber(tag);
408
409      final GeneratedExtension<MessageType, ?> extension =
410        extensionRegistry.findLiteExtensionByNumber(
411            getDefaultInstanceForType(), fieldNumber);
412
413      boolean unknown = false;
414      boolean packed = false;
415      if (extension == null) {
416        unknown = true;  // Unknown field.
417      } else if (wireType == FieldSet.getWireFormatForFieldType(
418                   extension.descriptor.getLiteType(),
419                   false  /* isPacked */)) {
420        packed = false;  // Normal, unpacked value.
421      } else if (extension.descriptor.isRepeated &&
422                 extension.descriptor.type.isPackable() &&
423                 wireType == FieldSet.getWireFormatForFieldType(
424                   extension.descriptor.getLiteType(),
425                   true  /* isPacked */)) {
426        packed = true;  // Packed value.
427      } else {
428        unknown = true;  // Wrong wire type.
429      }
430
431      if (unknown) {  // Unknown field or wrong wire type.  Skip.
432        return input.skipField(tag);
433      }
434
435      if (packed) {
436        final int length = input.readRawVarint32();
437        final int limit = input.pushLimit(length);
438        if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
439          while (input.getBytesUntilLimit() > 0) {
440            final int rawValue = input.readEnum();
441            final Object value =
442                extension.descriptor.getEnumType().findValueByNumber(rawValue);
443            if (value == null) {
444              // If the number isn't recognized as a valid value for this
445              // enum, drop it (don't even add it to unknownFields).
446              return true;
447            }
448            ensureExtensionsIsMutable();
449            extensions.addRepeatedField(extension.descriptor, value);
450          }
451        } else {
452          while (input.getBytesUntilLimit() > 0) {
453            final Object value =
454              FieldSet.readPrimitiveField(input,
455                                          extension.descriptor.getLiteType());
456            ensureExtensionsIsMutable();
457            extensions.addRepeatedField(extension.descriptor, value);
458          }
459        }
460        input.popLimit(limit);
461      } else {
462        final Object value;
463        switch (extension.descriptor.getLiteJavaType()) {
464          case MESSAGE: {
465            MessageLite.Builder subBuilder = null;
466            if (!extension.descriptor.isRepeated()) {
467              MessageLite existingValue =
468                  (MessageLite) extensions.getField(extension.descriptor);
469              if (existingValue != null) {
470                subBuilder = existingValue.toBuilder();
471              }
472            }
473            if (subBuilder == null) {
474              subBuilder = extension.messageDefaultInstance.newBuilderForType();
475            }
476            if (extension.descriptor.getLiteType() ==
477                WireFormat.FieldType.GROUP) {
478              input.readGroup(extension.getNumber(),
479                              subBuilder, extensionRegistry);
480            } else {
481              input.readMessage(subBuilder, extensionRegistry);
482            }
483            value = subBuilder.build();
484            break;
485          }
486          case ENUM:
487            final int rawValue = input.readEnum();
488            value = extension.descriptor.getEnumType()
489                             .findValueByNumber(rawValue);
490            // If the number isn't recognized as a valid value for this enum,
491            // drop it.
492            if (value == null) {
493              return true;
494            }
495            break;
496          default:
497            value = FieldSet.readPrimitiveField(input,
498                extension.descriptor.getLiteType());
499            break;
500        }
501
502        if (extension.descriptor.isRepeated()) {
503          ensureExtensionsIsMutable();
504          extensions.addRepeatedField(extension.descriptor, value);
505        } else {
506          ensureExtensionsIsMutable();
507          extensions.setField(extension.descriptor, value);
508        }
509      }
510
511      return true;
512    }
513
514    protected final void mergeExtensionFields(final MessageType other) {
515      ensureExtensionsIsMutable();
516      extensions.mergeFrom(((ExtendableMessage) other).extensions);
517    }
518  }
519
520  // -----------------------------------------------------------------
521
522  /** For use by generated code only. */
523  public static <ContainingType extends MessageLite, Type>
524      GeneratedExtension<ContainingType, Type>
525          newSingularGeneratedExtension(
526              final ContainingType containingTypeDefaultInstance,
527              final Type defaultValue,
528              final MessageLite messageDefaultInstance,
529              final Internal.EnumLiteMap<?> enumTypeMap,
530              final int number,
531              final WireFormat.FieldType type) {
532    return new GeneratedExtension<ContainingType, Type>(
533        containingTypeDefaultInstance,
534        defaultValue,
535        messageDefaultInstance,
536        new ExtensionDescriptor(enumTypeMap, number, type,
537                                false /* isRepeated */,
538                                false /* isPacked */));
539  }
540
541  /** For use by generated code only. */
542  public static <ContainingType extends MessageLite, Type>
543      GeneratedExtension<ContainingType, Type>
544          newRepeatedGeneratedExtension(
545              final ContainingType containingTypeDefaultInstance,
546              final MessageLite messageDefaultInstance,
547              final Internal.EnumLiteMap<?> enumTypeMap,
548              final int number,
549              final WireFormat.FieldType type,
550              final boolean isPacked) {
551    @SuppressWarnings("unchecked")  // Subclasses ensure Type is a List
552    Type emptyList = (Type) Collections.emptyList();
553    return new GeneratedExtension<ContainingType, Type>(
554        containingTypeDefaultInstance,
555        emptyList,
556        messageDefaultInstance,
557        new ExtensionDescriptor(
558            enumTypeMap, number, type, true /* isRepeated */, isPacked));
559  }
560
561  private static final class ExtensionDescriptor
562      implements FieldSet.FieldDescriptorLite<
563        ExtensionDescriptor> {
564    private ExtensionDescriptor(
565        final Internal.EnumLiteMap<?> enumTypeMap,
566        final int number,
567        final WireFormat.FieldType type,
568        final boolean isRepeated,
569        final boolean isPacked) {
570      this.enumTypeMap = enumTypeMap;
571      this.number = number;
572      this.type = type;
573      this.isRepeated = isRepeated;
574      this.isPacked = isPacked;
575    }
576
577    private final Internal.EnumLiteMap<?> enumTypeMap;
578    private final int number;
579    private final WireFormat.FieldType type;
580    private final boolean isRepeated;
581    private final boolean isPacked;
582
583    public int getNumber() {
584      return number;
585    }
586
587    public WireFormat.FieldType getLiteType() {
588      return type;
589    }
590
591    public WireFormat.JavaType getLiteJavaType() {
592      return type.getJavaType();
593    }
594
595    public boolean isRepeated() {
596      return isRepeated;
597    }
598
599    public boolean isPacked() {
600      return isPacked;
601    }
602
603    public Internal.EnumLiteMap<?> getEnumType() {
604      return enumTypeMap;
605    }
606
607    @SuppressWarnings("unchecked")
608    public MessageLite.Builder internalMergeFrom(
609        MessageLite.Builder to, MessageLite from) {
610      return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
611    }
612
613    public int compareTo(ExtensionDescriptor other) {
614      return number - other.number;
615    }
616  }
617
618  /**
619   * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
620   *
621   * Users should ignore the contents of this class and only use objects of
622   * this type as parameters to extension accessors and ExtensionRegistry.add().
623   */
624  public static final class GeneratedExtension<
625      ContainingType extends MessageLite, Type> {
626
627    private GeneratedExtension(
628        final ContainingType containingTypeDefaultInstance,
629        final Type defaultValue,
630        final MessageLite messageDefaultInstance,
631        final ExtensionDescriptor descriptor) {
632      // Defensive checks to verify the correct initialization order of
633      // GeneratedExtensions and their related GeneratedMessages.
634      if (containingTypeDefaultInstance == null) {
635        throw new IllegalArgumentException(
636            "Null containingTypeDefaultInstance");
637      }
638      if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
639          messageDefaultInstance == null) {
640        throw new IllegalArgumentException(
641            "Null messageDefaultInstance");
642      }
643      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
644      this.defaultValue = defaultValue;
645      this.messageDefaultInstance = messageDefaultInstance;
646      this.descriptor = descriptor;
647    }
648
649    private final ContainingType containingTypeDefaultInstance;
650    private final Type defaultValue;
651    private final MessageLite messageDefaultInstance;
652    private final ExtensionDescriptor descriptor;
653
654    /**
655     * Default instance of the type being extended, used to identify that type.
656     */
657    public ContainingType getContainingTypeDefaultInstance() {
658      return containingTypeDefaultInstance;
659    }
660
661    /** Get the field number. */
662    public int getNumber() {
663      return descriptor.getNumber();
664    }
665
666    /**
667     * If the extension is an embedded message, this is the default instance of
668     * that type.
669     */
670    public MessageLite getMessageDefaultInstance() {
671      return messageDefaultInstance;
672    }
673  }
674
675  /**
676   * A serialized (serializable) form of the generated message.  Stores the
677   * message as a class name and a byte array.
678   */
679  static final class SerializedForm implements Serializable {
680    private static final long serialVersionUID = 0L;
681
682    private String messageClassName;
683    private byte[] asBytes;
684
685    /**
686     * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
687     * @param regularForm the message to serialize
688     */
689    SerializedForm(MessageLite regularForm) {
690      messageClassName = regularForm.getClass().getName();
691      asBytes = regularForm.toByteArray();
692    }
693
694    /**
695     * When read from an ObjectInputStream, this method converts this object
696     * back to the regular form.  Part of Java's serialization magic.
697     * @return a GeneratedMessage of the type that was serialized
698     */
699    @SuppressWarnings("unchecked")
700    protected Object readResolve() throws ObjectStreamException {
701      try {
702        Class messageClass = Class.forName(messageClassName);
703        Method newBuilder = messageClass.getMethod("newBuilder");
704        MessageLite.Builder builder =
705            (MessageLite.Builder) newBuilder.invoke(null);
706        builder.mergeFrom(asBytes);
707        return builder.buildPartial();
708      } catch (ClassNotFoundException e) {
709        throw new RuntimeException("Unable to find proto buffer class", e);
710      } catch (NoSuchMethodException e) {
711        throw new RuntimeException("Unable to find newBuilder method", e);
712      } catch (IllegalAccessException e) {
713        throw new RuntimeException("Unable to call newBuilder method", e);
714      } catch (InvocationTargetException e) {
715        throw new RuntimeException("Error calling newBuilder", e.getCause());
716      } catch (InvalidProtocolBufferException e) {
717        throw new RuntimeException("Unable to understand proto buffer", e);
718      }
719    }
720  }
721
722  /**
723   * Replaces this object in the output stream with a serialized form.
724   * Part of Java's serialization magic.  Generated sub-classes must override
725   * this method by calling <code>return super.writeReplace();</code>
726   * @return a SerializedForm of this message
727   */
728  protected Object writeReplace() throws ObjectStreamException {
729    return new SerializedForm(this);
730  }
731}
Note: See TracBrowser for help on using the repository browser.