1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepackage com.google.protobuf;
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport com.google.protobuf.Descriptors.Descriptor;
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport com.google.protobuf.Descriptors.FieldDescriptor;
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.InputStream;
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.IOException;
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.util.Map;
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/**
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * An implementation of {@link Message} that can represent arbitrary types,
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * given a {@link Descriptors.Descriptor}.
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @author kenton@google.com Kenton Varda
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepublic final class DynamicMessage extends AbstractMessage {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private final Descriptor type;
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private final FieldSet<FieldDescriptor> fields;
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private final UnknownFieldSet unknownFields;
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int memoizedSize = -1;
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Construct a {@code DynamicMessage} using the given {@code FieldSet}.
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields,
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         UnknownFieldSet unknownFields) {
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    this.type = type;
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    this.fields = fields;
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    this.unknownFields = unknownFields;
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Get a {@code DynamicMessage} representing the default instance of the
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * given type.
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage getDefaultInstance(Descriptor type) {
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(),
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                              UnknownFieldSet.getDefaultInstance());
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse a message of the given type from the given input stream. */
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type,
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         CodedInputStream input)
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws IOException {
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(input).buildParsed();
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse a message of the given type from the given input stream. */
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      Descriptor type,
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      CodedInputStream input,
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ExtensionRegistry extensionRegistry)
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throws IOException {
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse {@code data} as a message of the given type and return it. */
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type, ByteString data)
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws InvalidProtocolBufferException {
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(data).buildParsed();
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse {@code data} as a message of the given type and return it. */
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type, ByteString data,
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         ExtensionRegistry extensionRegistry)
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws InvalidProtocolBufferException {
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse {@code data} as a message of the given type and return it. */
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type, byte[] data)
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws InvalidProtocolBufferException {
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(data).buildParsed();
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse {@code data} as a message of the given type and return it. */
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type, byte[] data,
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         ExtensionRegistry extensionRegistry)
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws InvalidProtocolBufferException {
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse a message of the given type from {@code input} and return it. */
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type, InputStream input)
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws IOException {
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(input).buildParsed();
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Parse a message of the given type from {@code input} and return it. */
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static DynamicMessage parseFrom(Descriptor type, InputStream input,
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         ExtensionRegistry extensionRegistry)
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         throws IOException {
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Construct a {@link Message.Builder} for the given type. */
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static Builder newBuilder(Descriptor type) {
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new Builder(type);
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Construct a {@link Message.Builder} for a message of the same type as
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * {@code prototype}, and initialize it with {@code prototype}'s contents.
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static Builder newBuilder(Message prototype) {
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new Builder(prototype.getDescriptorForType()).mergeFrom(prototype);
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // -----------------------------------------------------------------
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Implementation of Message interface.
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public Descriptor getDescriptorForType() {
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return type;
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public DynamicMessage getDefaultInstanceForType() {
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return getDefaultInstance(type);
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public Map<FieldDescriptor, Object> getAllFields() {
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return fields.getAllFields();
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean hasField(FieldDescriptor field) {
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    verifyContainingType(field);
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return fields.hasField(field);
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public Object getField(FieldDescriptor field) {
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    verifyContainingType(field);
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Object result = fields.getField(field);
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (result == null) {
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result = getDefaultInstance(field.getMessageType());
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result = field.getDefaultValue();
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return result;
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int getRepeatedFieldCount(FieldDescriptor field) {
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    verifyContainingType(field);
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return fields.getRepeatedFieldCount(field);
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public Object getRepeatedField(FieldDescriptor field, int index) {
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    verifyContainingType(field);
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return fields.getRepeatedField(field, index);
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public UnknownFieldSet getUnknownFields() {
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return unknownFields;
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private static boolean isInitialized(Descriptor type,
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                       FieldSet<FieldDescriptor> fields) {
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Check that all required fields are present.
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (final FieldDescriptor field : type.getFields()) {
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field.isRequired()) {
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (!fields.hasField(field)) {
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return false;
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Check that embedded messages are initialized.
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return fields.isInitialized();
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean isInitialized() {
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return isInitialized(type, fields);
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void writeTo(CodedOutputStream output) throws IOException {
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (type.getOptions().getMessageSetWireFormat()) {
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.writeMessageSetTo(output);
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      unknownFields.writeAsMessageSetTo(output);
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.writeTo(output);
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      unknownFields.writeTo(output);
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int getSerializedSize() {
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int size = memoizedSize;
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size != -1) return size;
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (type.getOptions().getMessageSetWireFormat()) {
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      size = fields.getMessageSetSerializedSize();
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      size += unknownFields.getSerializedSizeAsMessageSet();
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      size = fields.getSerializedSize();
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      size += unknownFields.getSerializedSize();
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    memoizedSize = size;
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return size;
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public Builder newBuilderForType() {
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new Builder(type);
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public Builder toBuilder() {
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newBuilderForType().mergeFrom(this);
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Verifies that the field is a field of this message. */
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private void verifyContainingType(FieldDescriptor field) {
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field.getContainingType() != type) {
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new IllegalArgumentException(
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "FieldDescriptor does not match message type.");
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Builder for {@link DynamicMessage}s.
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static final class Builder extends AbstractMessage.Builder<Builder> {
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private final Descriptor type;
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private FieldSet<FieldDescriptor> fields;
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private UnknownFieldSet unknownFields;
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    /** Construct a {@code Builder} for the given type. */
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private Builder(Descriptor type) {
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      this.type = type;
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      this.fields = FieldSet.newFieldSet();
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      this.unknownFields = UnknownFieldSet.getDefaultInstance();
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // ---------------------------------------------------------------
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Implementation of Message.Builder interface.
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder clear() {
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (fields == null) {
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw new IllegalStateException("Cannot call clear() after build().");
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.clear();
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder mergeFrom(Message other) {
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (other instanceof DynamicMessage) {
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // This should be somewhat faster than calling super.mergeFrom().
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        DynamicMessage otherDynamicMessage = (DynamicMessage) other;
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (otherDynamicMessage.type != type) {
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          throw new IllegalArgumentException(
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "mergeFrom(Message) can only merge messages of the same type.");
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        fields.mergeFrom(otherDynamicMessage.fields);
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        mergeUnknownFields(otherDynamicMessage.unknownFields);
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return this;
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return super.mergeFrom(other);
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public DynamicMessage build() {
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // If fields == null, we'll throw an appropriate exception later.
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (fields != null && !isInitialized()) {
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw newUninitializedMessageException(
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          new DynamicMessage(type, fields, unknownFields));
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return buildPartial();
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    /**
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     * Helper for DynamicMessage.parseFrom() methods to call.  Throws
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     * {@link InvalidProtocolBufferException} instead of
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     * {@link UninitializedMessageException}.
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville     */
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private DynamicMessage buildParsed() throws InvalidProtocolBufferException {
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (!isInitialized()) {
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw newUninitializedMessageException(
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            new DynamicMessage(type, fields, unknownFields))
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          .asInvalidProtocolBufferException();
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return buildPartial();
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public DynamicMessage buildPartial() {
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (fields == null) {
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw new IllegalStateException(
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "build() has already been called on this Builder.");
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.makeImmutable();
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      DynamicMessage result =
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        new DynamicMessage(type, fields, unknownFields);
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields = null;
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      unknownFields = null;
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return result;
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder clone() {
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      Builder result = new Builder(type);
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result.fields.mergeFrom(fields);
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return result;
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public boolean isInitialized() {
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return DynamicMessage.isInitialized(type, fields);
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Descriptor getDescriptorForType() {
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return type;
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public DynamicMessage getDefaultInstanceForType() {
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return getDefaultInstance(type);
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Map<FieldDescriptor, Object> getAllFields() {
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return fields.getAllFields();
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder newBuilderForField(FieldDescriptor field) {
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw new IllegalArgumentException(
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "newBuilderForField is only valid for fields with message type.");
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return new Builder(field.getMessageType());
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public boolean hasField(FieldDescriptor field) {
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return fields.hasField(field);
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Object getField(FieldDescriptor field) {
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      Object result = fields.getField(field);
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (result == null) {
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          result = getDefaultInstance(field.getMessageType());
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          result = field.getDefaultValue();
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return result;
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder setField(FieldDescriptor field, Object value) {
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.setField(field, value);
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder clearField(FieldDescriptor field) {
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.clearField(field);
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public int getRepeatedFieldCount(FieldDescriptor field) {
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return fields.getRepeatedFieldCount(field);
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Object getRepeatedField(FieldDescriptor field, int index) {
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return fields.getRepeatedField(field, index);
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder setRepeatedField(FieldDescriptor field,
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                    int index, Object value) {
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.setRepeatedField(field, index, value);
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder addRepeatedField(FieldDescriptor field, Object value) {
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      verifyContainingType(field);
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      fields.addRepeatedField(field, value);
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public UnknownFieldSet getUnknownFields() {
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return unknownFields;
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder setUnknownFields(UnknownFieldSet unknownFields) {
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      this.unknownFields = unknownFields;
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      this.unknownFields =
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        UnknownFieldSet.newBuilder(this.unknownFields)
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                       .mergeFrom(unknownFields)
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                       .build();
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return this;
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    /** Verifies that the field is a field of this message. */
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    private void verifyContainingType(FieldDescriptor field) {
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field.getContainingType() != type) {
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw new IllegalArgumentException(
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "FieldDescriptor does not match message type.");
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
439