LazyFieldLite.java
Go to the documentation of this file.
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 java.io.IOException;
34 
56 public class LazyFieldLite {
57  private static final ExtensionRegistryLite EMPTY_REGISTRY =
59 
60  /*
61  * The value associated with the LazyFieldLite object is stored in one or more of the following
62  * three fields (delayedBytes, value, memoizedBytes). They should together be interpreted as
63  * follows.
64  *
65  * 1) delayedBytes can be non-null, while value and memoizedBytes is null. The object will be in
66  * this state while the value for the object has not yet been parsed.
67  *
68  * 2) Both delayedBytes and value are non-null. The object transitions to this state as soon as
69  * some caller needs to access the value (by invoking getValue()).
70  *
71  * 3) memoizedBytes is merely an optimization for calls to LazyFieldLite.toByteString() to avoid
72  * recomputing the ByteString representation on each call. Instead, when the value is parsed from
73  * delayedBytes, we will also assign the contents of delayedBytes to memoizedBytes (since that is
74  * the ByteString representation of value).
75  *
76  * 4) Finally, if the LazyFieldLite was created directly with a parsed MessageLite value, then
77  * delayedBytes will be null, and memoizedBytes will be initialized only upon the first call to
78  * LazyFieldLite.toByteString().
79  *
80  * <p>Given the above conditions, any caller that needs a serialized representation of this object
81  * must first check if the memoizedBytes or delayedBytes ByteString is non-null and use it
82  * directly; if both of those are null, it can look at the parsed value field. Similarly, any
83  * caller that needs a parsed value must first check if the value field is already non-null, if
84  * not it must parse the value from delayedBytes.
85  */
86 
95 
103 
108  protected volatile MessageLite value;
109 
115  private volatile ByteString memoizedBytes;
116 
120  this.extensionRegistry = extensionRegistry;
121  this.delayedBytes = bytes;
122  }
123 
125  public LazyFieldLite() {}
126 
132  LazyFieldLite lf = new LazyFieldLite();
133  lf.setValue(value);
134  return lf;
135  }
136 
137  @Override
138  public boolean equals(Object o) {
139  if (this == o) {
140  return true;
141  }
142 
143  if (!(o instanceof LazyFieldLite)) {
144  return false;
145  }
146 
147  LazyFieldLite other = (LazyFieldLite) o;
148 
149  // Lazy fields do not work well with equals... If both are delayedBytes, we do not have a
150  // mechanism to deserialize them so we rely on bytes equality. Otherwise we coerce into an
151  // actual message (if necessary) and call equals on the message itself. This implies that two
152  // messages can by unequal but then be turned equal simply be invoking a getter on a lazy field.
153  MessageLite value1 = value;
154  MessageLite value2 = other.value;
155  if (value1 == null && value2 == null) {
156  return toByteString().equals(other.toByteString());
157  } else if (value1 != null && value2 != null) {
158  return value1.equals(value2);
159  } else if (value1 != null) {
160  return value1.equals(other.getValue(value1.getDefaultInstanceForType()));
161  } else {
162  return getValue(value2.getDefaultInstanceForType()).equals(value2);
163  }
164  }
165 
166  @Override
167  public int hashCode() {
168  // We can't provide a memoizable hash code for lazy fields. The byte strings may have different
169  // hash codes but evaluate to equivalent messages. And we have no facility for constructing
170  // a message here if we were not already holding a value.
171  return 1;
172  }
173 
177  public boolean containsDefaultInstance() {
178  return memoizedBytes == ByteString.EMPTY
179  || value == null && (delayedBytes == null || delayedBytes == ByteString.EMPTY);
180  }
181 
188  public void clear() {
189  // Don't clear the ExtensionRegistry. It might prove useful later on when merging in another
190  // value, but there is no guarantee that it will contain all extensions that were directly set
191  // on the values that need to be merged.
192  delayedBytes = null;
193  value = null;
194  memoizedBytes = null;
195  }
196 
203  public void set(LazyFieldLite other) {
204  this.delayedBytes = other.delayedBytes;
205  this.value = other.value;
206  this.memoizedBytes = other.memoizedBytes;
207  // If the other LazyFieldLite was created by directly setting the value rather than first by
208  // parsing, then it will not have an extensionRegistry. In this case we hold on to the existing
209  // extensionRegistry, which has no guarantees that it has all the extensions that will be
210  // directly set on the value.
211  if (other.extensionRegistry != null) {
212  this.extensionRegistry = other.extensionRegistry;
213  }
214  }
215 
222  public MessageLite getValue(MessageLite defaultInstance) {
223  ensureInitialized(defaultInstance);
224  return value;
225  }
226 
234  MessageLite originalValue = this.value;
235  this.delayedBytes = null;
236  this.memoizedBytes = null;
237  this.value = value;
238  return originalValue;
239  }
240 
249  public void merge(LazyFieldLite other) {
250  if (other.containsDefaultInstance()) {
251  return;
252  }
253 
254  if (this.containsDefaultInstance()) {
255  set(other);
256  return;
257  }
258 
259  // If the other field has an extension registry but this does not, copy over the other extension
260  // registry.
261  if (this.extensionRegistry == null) {
262  this.extensionRegistry = other.extensionRegistry;
263  }
264 
265  // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
266  // the (probably rare) case that they have different extension registries there is a chance that
267  // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
268  // to outway the benefits of combining the extension registries, which is not normally done for
269  // lite protos anyways.
270  if (this.delayedBytes != null && other.delayedBytes != null) {
271  this.delayedBytes = this.delayedBytes.concat(other.delayedBytes);
272  return;
273  }
274 
275  // At least one is parsed and both contain data. We won't drop any extensions here directly, but
276  // in the case that the extension registries are not the same then we might in the future if we
277  // need to serialze and parse a message again.
278  if (this.value == null && other.value != null) {
279  setValue(mergeValueAndBytes(other.value, this.delayedBytes, this.extensionRegistry));
280  return;
281  } else if (this.value != null && other.value == null) {
282  setValue(mergeValueAndBytes(this.value, other.delayedBytes, other.extensionRegistry));
283  return;
284  }
285 
286  // At this point we have two fully parsed messages.
287  setValue(this.value.toBuilder().mergeFrom(other.value).build());
288  }
289 
297  throws IOException {
298  if (this.containsDefaultInstance()) {
299  setByteString(input.readBytes(), extensionRegistry);
300  return;
301  }
302 
303  // If the other field has an extension registry but this does not, copy over the other extension
304  // registry.
305  if (this.extensionRegistry == null) {
306  this.extensionRegistry = extensionRegistry;
307  }
308 
309  // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
310  // the (probably rare) case that they have different extension registries there is a chance that
311  // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
312  // to outway the benefits of combining the extension registries, which is not normally done for
313  // lite protos anyways.
314  if (this.delayedBytes != null) {
315  setByteString(this.delayedBytes.concat(input.readBytes()), this.extensionRegistry);
316  return;
317  }
318 
319  // We are parsed and both contain data. We won't drop any extensions here directly, but in the
320  // case that the extension registries are not the same then we might in the future if we
321  // need to serialize and parse a message again.
322  try {
323  setValue(value.toBuilder().mergeFrom(input, extensionRegistry).build());
324  } catch (InvalidProtocolBufferException e) {
325  // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
326  // was invalid.
327  }
328  }
329 
332  try {
333  return value.toBuilder().mergeFrom(otherBytes, extensionRegistry).build();
334  } catch (InvalidProtocolBufferException e) {
335  // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
336  // was invalid.
337  return value;
338  }
339  }
340 
344  this.delayedBytes = bytes;
345  this.extensionRegistry = extensionRegistry;
346  this.value = null;
347  this.memoizedBytes = null;
348  }
349 
354  public int getSerializedSize() {
355  // We *must* return delayed bytes size if it was ever set because the dependent messages may
356  // have memoized serialized size based off of it.
357  if (memoizedBytes != null) {
358  return memoizedBytes.size();
359  } else if (delayedBytes != null) {
360  return delayedBytes.size();
361  } else if (value != null) {
362  return value.getSerializedSize();
363  } else {
364  return 0;
365  }
366  }
367 
370  if (memoizedBytes != null) {
371  return memoizedBytes;
372  }
373  // We *must* return delayed bytes if it was set because the dependent messages may have
374  // memoized serialized size based off of it.
375  if (delayedBytes != null) {
376  return delayedBytes;
377  }
378  synchronized (this) {
379  if (memoizedBytes != null) {
380  return memoizedBytes;
381  }
382  if (value == null) {
384  } else {
385  memoizedBytes = value.toByteString();
386  }
387  return memoizedBytes;
388  }
389  }
390 
392  void writeTo(Writer writer, int fieldNumber) throws IOException {
393  if (memoizedBytes != null) {
394  writer.writeBytes(fieldNumber, memoizedBytes);
395  } else if (delayedBytes != null) {
396  writer.writeBytes(fieldNumber, delayedBytes);
397  } else if (value != null) {
398  writer.writeMessage(fieldNumber, value);
399  } else {
400  writer.writeBytes(fieldNumber, ByteString.EMPTY);
401  }
402  }
403 
405  protected void ensureInitialized(MessageLite defaultInstance) {
406  if (value != null) {
407  return;
408  }
409  synchronized (this) {
410  if (value != null) {
411  return;
412  }
413  try {
414  if (delayedBytes != null) {
415  // The extensionRegistry shouldn't be null here since we have delayedBytes.
416  MessageLite parsedValue =
417  defaultInstance.getParserForType().parseFrom(delayedBytes, extensionRegistry);
418  this.value = parsedValue;
419  this.memoizedBytes = delayedBytes;
420  } else {
421  this.value = defaultInstance;
422  this.memoizedBytes = ByteString.EMPTY;
423  }
424  } catch (InvalidProtocolBufferException e) {
425  // Nothing is logged and no exceptions are thrown. Clients will be unaware that this proto
426  // was invalid.
427  this.value = defaultInstance;
428  this.memoizedBytes = ByteString.EMPTY;
429  }
430  }
431  }
432 
434  if (extensionRegistry == null) {
435  throw new NullPointerException("found null ExtensionRegistry");
436  }
437  if (bytes == null) {
438  throw new NullPointerException("found null ByteString");
439  }
440  }
441 }
com.google.protobuf.LazyFieldLite.containsDefaultInstance
boolean containsDefaultInstance()
Definition: LazyFieldLite.java:177
com.google.protobuf.LazyFieldLite.hashCode
int hashCode()
Definition: LazyFieldLite.java:167
input
std::string input
Definition: tokenizer_unittest.cc:197
com.google.protobuf.LazyFieldLite.LazyFieldLite
LazyFieldLite()
Definition: LazyFieldLite.java:125
com.google.protobuf.LazyFieldLite.toByteString
ByteString toByteString()
Definition: LazyFieldLite.java:369
com.google.protobuf.LazyFieldLite.setValue
MessageLite setValue(MessageLite value)
Definition: LazyFieldLite.java:233
com.google.protobuf.LazyFieldLite.EMPTY_REGISTRY
static final ExtensionRegistryLite EMPTY_REGISTRY
Definition: LazyFieldLite.java:57
com.google.protobuf.ByteString.EMPTY
static final ByteString EMPTY
Definition: ByteString.java:85
com.google.protobuf.LazyFieldLite.checkArguments
static void checkArguments(ExtensionRegistryLite extensionRegistry, ByteString bytes)
Definition: LazyFieldLite.java:433
bytes
uint8 bytes[10]
Definition: coded_stream_unittest.cc:153
com.google.protobuf.LazyFieldLite.equals
boolean equals(Object o)
Definition: LazyFieldLite.java:138
com.google.protobuf.MessageLite.Builder.build
MessageLite build()
com.google.protobuf.LazyFieldLite.fromValue
static LazyFieldLite fromValue(MessageLite value)
Definition: LazyFieldLite.java:131
com.google.protobuf.LazyFieldLite.getSerializedSize
int getSerializedSize()
Definition: LazyFieldLite.java:354
com.google.protobuf.LazyFieldLite.value
volatile MessageLite value
Definition: LazyFieldLite.java:108
com.google.protobuf.LazyFieldLite.merge
void merge(LazyFieldLite other)
Definition: LazyFieldLite.java:249
com.google.protobuf.CodedInputStream
Definition: CodedInputStream.java:61
com.google.protobuf.LazyFieldLite.memoizedBytes
volatile ByteString memoizedBytes
Definition: LazyFieldLite.java:115
com.google.protobuf.LazyFieldLite.LazyFieldLite
LazyFieldLite(ExtensionRegistryLite extensionRegistry, ByteString bytes)
Definition: LazyFieldLite.java:118
com.google.protobuf.LazyFieldLite.setByteString
void setByteString(ByteString bytes, ExtensionRegistryLite extensionRegistry)
Definition: LazyFieldLite.java:342
com.google.protobuf.LazyFieldLite.clear
void clear()
Definition: LazyFieldLite.java:188
com.google.protobuf.LazyFieldLite.getValue
MessageLite getValue(MessageLite defaultInstance)
Definition: LazyFieldLite.java:222
com.google.protobuf.ExtensionRegistryLite
Definition: ExtensionRegistryLite.java:70
com.google.protobuf.LazyFieldLite
Definition: LazyFieldLite.java:56
com.google.protobuf.LazyFieldLite.delayedBytes
ByteString delayedBytes
Definition: LazyFieldLite.java:94
java
com.google.protobuf.MessageLiteOrBuilder.getDefaultInstanceForType
MessageLite getDefaultInstanceForType()
com.google.protobuf.MessageLite.toBuilder
Builder toBuilder()
com.google.protobuf.LazyFieldLite.extensionRegistry
ExtensionRegistryLite extensionRegistry
Definition: LazyFieldLite.java:102
com.google.protobuf.LazyFieldLite.ensureInitialized
void ensureInitialized(MessageLite defaultInstance)
Definition: LazyFieldLite.java:405
com.google.protobuf.InvalidProtocolBufferException
Definition: InvalidProtocolBufferException.java:41
com.google.protobuf.MessageLite.Builder.mergeFrom
Builder mergeFrom(CodedInputStream input)
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
com.google.protobuf.ExtensionRegistryLite.getEmptyRegistry
static ExtensionRegistryLite getEmptyRegistry()
Definition: ExtensionRegistryLite.java:125
com.google.protobuf.ByteString.size
abstract int size()
com.google.protobuf.LazyFieldLite.mergeValueAndBytes
static MessageLite mergeValueAndBytes(MessageLite value, ByteString otherBytes, ExtensionRegistryLite extensionRegistry)
Definition: LazyFieldLite.java:330
com.google.protobuf.MessageLite
Definition: MessageLite.java:65
com.google.protobuf.LazyFieldLite.mergeFrom
void mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
Definition: LazyFieldLite.java:296
com.google.protobuf.ByteString
Definition: ByteString.java:67
com.google.protobuf.MessageLite.getParserForType
Parser<? extends MessageLite > getParserForType()


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:55