// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

import java.io.IOException;

/**
 * LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores
 * the message in a ByteString initially and then parses it on-demand.
 *
 * LazyFieldLite is thread-compatible: concurrent reads are safe once the proto that this
 * LazyFieldLite is a part of is no longer being mutated by its Builder. However, explicit
 * synchronization is needed under read/write situations.
 *
 * When a LazyFieldLite is used in the context of a MessageLite object, its behavior is considered
 * to be immutable and none of the setter methods in its API are expected to be invoked. All of the
 * getters are expected to be thread-safe. When used in the context of a MessageLite.Builder,
 * setters can be invoked, but there is no guarantee of thread safety.
 * 
 * TODO(yatin,dweis): Consider splitting this class's functionality and put the mutable methods
 * into a separate builder class to allow us to give stronger compile-time guarantees.
 *
 * This class is internal implementation detail of the protobuf library, so you don't need to use it
 * directly.
 *
 * @author xiangl@google.com (Xiang Li)
 */
public class LazyFieldLite {
  private static final ExtensionRegistryLite EMPTY_REGISTRY =
      ExtensionRegistryLite.getEmptyRegistry();

  /**
   * The value associated with the LazyFieldLite object is stored in one or more of the following
   * three fields (delayedBytes, value, memoizedBytes). They should together be interpreted as
   * follows.
   * 1) delayedBytes can be non-null, while value and memoizedBytes is null. The object will be in
   *    this state while the value for the object has not yet been parsed.
   * 2) Both delayedBytes and value are non-null. The object transitions to this state as soon as
   *    some caller needs to access the value (by invoking getValue()).
   * 3) memoizedBytes is merely an optimization for calls to LazyFieldLite.toByteString() to avoid
   *    recomputing the ByteString representation on each call. Instead, when the value is parsed
   *    from delayedBytes, we will also assign the contents of delayedBytes to memoizedBytes (since
   *    that is the ByteString representation of value).
   * 4) Finally, if the LazyFieldLite was created directly with a parsed MessageLite value, then
   *    delayedBytes will be null, and memoizedBytes will be initialized only upon the first call to
   *    LazyFieldLite.toByteString().
   *
   * Given the above conditions, any caller that needs a serialized representation of this object
   * must first check if the memoizedBytes or delayedBytes ByteString is non-null and use it
   * directly; if both of those are null, it can look at the parsed value field. Similarly, any
   * caller that needs a parsed value must first check if the value field is already non-null, if
   * not it must parse the value from delayedBytes.
   */

  /**
   * A delayed-parsed version of the contents of this field. When this field is non-null, then the
   * "value" field is allowed to be null until the time that the value needs to be read.
   *
   * When delayedBytes is non-null then {@code extensionRegistry} is required to also be non-null.
   * {@code value} and {@code memoizedBytes} will be initialized lazily.
   */
  private ByteString delayedBytes;

  /**
   * An {@code ExtensionRegistryLite} for parsing bytes. It is non-null on a best-effort basis. It
   * is only guaranteed to be non-null if this message was initialized using bytes and an
   * {@code ExtensionRegistry}. If it directly had a value set then it will be null, unless it has
   * been merged with another {@code LazyFieldLite} that had an {@code ExtensionRegistry}.
   */
  private ExtensionRegistryLite extensionRegistry;

  /**
   * The parsed value. When this is null and a caller needs access to the MessageLite value, then
   * {@code delayedBytes} will be parsed lazily at that time.
   */
  protected volatile MessageLite value;

  /**
   * The memoized bytes for {@code value}. This is an optimization for the toByteString() method to
   * not have to recompute its return-value on each invocation.
   * TODO(yatin): Figure out whether this optimization is actually necessary.
   */
  private volatile ByteString memoizedBytes;

  /**
   * Constructs a LazyFieldLite with bytes that will be parsed lazily.
   */
  public LazyFieldLite(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
    checkArguments(extensionRegistry, bytes);
    this.extensionRegistry = extensionRegistry;
    this.delayedBytes = bytes;
  }

  /**
   * Constructs a LazyFieldLite with no contents, and no ability to parse extensions.
   */
  public LazyFieldLite() {
  }

  /**
   * Constructs a LazyFieldLite instance with a value. The LazyFieldLite may not be able to parse
   * the extensions in the value as it has no ExtensionRegistry.
   */
  public static LazyFieldLite fromValue(MessageLite value) {
    LazyFieldLite lf = new LazyFieldLite();
    lf.setValue(value);
    return lf;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    
    if (!(o instanceof LazyFieldLite)) {
      return false;
    }

    LazyFieldLite other = (LazyFieldLite) o;
    
    // Lazy fields do not work well with equals... If both are delayedBytes, we do not have a
    // mechanism to deserialize them so we rely on bytes equality. Otherwise we coerce into an
    // actual message (if necessary) and call equals on the message itself. This implies that two
    // messages can by unequal but then be turned equal simply be invoking a getter on a lazy field.
    MessageLite value1 = value;
    MessageLite value2 = other.value;
    if (value1 == null && value2 == null) {
      return toByteString().equals(other.toByteString());
    } else if (value1 != null && value2 != null) {
      return value1.equals(value2);
    } else if (value1 != null) {
      return value1.equals(other.getValue(value1.getDefaultInstanceForType()));
    } else {
      return getValue(value2.getDefaultInstanceForType()).equals(value2);
    }
  }
  
  @Override
  public int hashCode() {
    // We can't provide a memoizable hash code for lazy fields. The byte strings may have different
    // hash codes but evaluate to equivalent messages. And we have no facility for constructing
    // a message here if we were not already holding a value.
    return 1;
  }
  
  /**
   * Determines whether this LazyFieldLite instance represents the default instance of this type.
   */
  public boolean containsDefaultInstance() {
    return memoizedBytes == ByteString.EMPTY
        || value == null && (delayedBytes == null || delayedBytes == ByteString.EMPTY);
  }

  /**
   * Clears the value state of this instance.
   *
   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
   * under read/write situations.
   */
  public void clear() {
    // Don't clear the ExtensionRegistry. It might prove useful later on when merging in another
    // value, but there is no guarantee that it will contain all extensions that were directly set
    // on the values that need to be merged.
    delayedBytes = null;
    value = null;
    memoizedBytes = null;
  }

  /**
   * Overrides the contents of this LazyField.
   *
   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
   * under read/write situations.
   */
  public void set(LazyFieldLite other) {
    this.delayedBytes = other.delayedBytes;
    this.value = other.value;
    this.memoizedBytes = other.memoizedBytes;
    // If the other LazyFieldLite was created by directly setting the value rather than first by
    // parsing, then it will not have an extensionRegistry. In this case we hold on to the existing
    // extensionRegistry, which has no guarantees that it has all the extensions that will be
    // directly set on the value.
    if (other.extensionRegistry != null) {
      this.extensionRegistry = other.extensionRegistry;
    }
  }

  /**
   * Returns message instance. It may do some thread-safe delayed parsing of bytes.
   *
   * @param defaultInstance its message's default instance. It's also used to get parser for the
   * message type.
   */
  public MessageLite getValue(MessageLite defaultInstance) {
    ensureInitialized(defaultInstance);
    return value;
  }

  /**
   * Sets the value of the instance and returns the old value without delay parsing anything.
   *
   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
   * under read/write situations.
   */
  public MessageLite setValue(MessageLite value) {
    MessageLite originalValue = this.value;
    this.delayedBytes = null;
    this.memoizedBytes = null;
    this.value = value;
    return originalValue;
  }

  /**
   * Merges another instance's contents. In some cases may drop some extensions if both fields
   * contain data. If the other field has an {@code ExtensionRegistry} but this does not, then this
   * field will copy over that {@code ExtensionRegistry}.
   *
   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
   * under read/write situations.
   */
  public void merge(LazyFieldLite other) {
    if (other.containsDefaultInstance()) {
      return;
    }

    if (this.containsDefaultInstance()) {
      set(other);
      return;
    }

    // If the other field has an extension registry but this does not, copy over the other extension
    // registry.
    if (this.extensionRegistry == null) {
      this.extensionRegistry = other.extensionRegistry;
    }

    // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
    // the (probably rare) case that they have different extension registries there is a chance that
    // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
    // to outway the benefits of combining the extension registries, which is not normally done for
    // lite protos anyways.
    if (this.delayedBytes != null && other.delayedBytes != null) {
      this.delayedBytes = this.delayedBytes.concat(other.delayedBytes);
      return;
    }

    // At least one is parsed and both contain data. We won't drop any extensions here directly, but
    // in the case that the extension registries are not the same then we might in the future if we
    // need to serialze and parse a message again.
    if (this.value == null && other.value != null) {
      setValue(mergeValueAndBytes(other.value, this.delayedBytes, this.extensionRegistry));
      return;
    } else if (this.value != null && other.value == null) {
      setValue(mergeValueAndBytes(this.value, other.delayedBytes, other.extensionRegistry));
      return;
    }

    // At this point we have two fully parsed messages.
    setValue(this.value.toBuilder().mergeFrom(other.value).build());
  }
  
  /**
   * Merges another instance's contents from a stream.
   *
   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
   * under read/write situations.
   */
  public void mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
      throws IOException {
    if (this.containsDefaultInstance()) {
      setByteString(input.readBytes(), extensionRegistry);
      return;
    }

    // If the other field has an extension registry but this does not, copy over the other extension
    // registry.
    if (this.extensionRegistry == null) {
      this.extensionRegistry = extensionRegistry;
    }

    // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
    // the (probably rare) case that they have different extension registries there is a chance that
    // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
    // to outway the benefits of combining the extension registries, which is not normally done for
    // lite protos anyways.
    if (this.delayedBytes != null) {
      setByteString(this.delayedBytes.concat(input.readBytes()), this.extensionRegistry);
      return;
    }

    // We are parsed and both contain data. We won't drop any extensions here directly, but in the
    // case that the extension registries are not the same then we might in the future if we
    // need to serialize and parse a message again.
    try {
      setValue(value.toBuilder().mergeFrom(input, extensionRegistry).build());
    } catch (InvalidProtocolBufferException e) {
      // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
      // was invalid.
    }
  }

  private static MessageLite mergeValueAndBytes(
      MessageLite value, ByteString otherBytes, ExtensionRegistryLite extensionRegistry) {
    try {
      return value.toBuilder().mergeFrom(otherBytes, extensionRegistry).build();
    } catch (InvalidProtocolBufferException e) {
      // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
      // was invalid.
      return value;
    }
  }

  /**
   * Sets this field with bytes to delay-parse.
   */
  public void setByteString(ByteString bytes, ExtensionRegistryLite extensionRegistry) {
    checkArguments(extensionRegistry, bytes);
    this.delayedBytes = bytes;
    this.extensionRegistry = extensionRegistry;
    this.value = null;
    this.memoizedBytes = null;
  }

  /**
   * Due to the optional field can be duplicated at the end of serialized
   * bytes, which will make the serialized size changed after LazyField
   * parsed. Be careful when using this method.
   */
  public int getSerializedSize() {
    // We *must* return delayed bytes size if it was ever set because the dependent messages may
    // have memoized serialized size based off of it.
    if (memoizedBytes != null) {
      return memoizedBytes.size();
    } else if (delayedBytes != null) {
      return delayedBytes.size();
    } else if (value != null) {
      return value.getSerializedSize();
    } else {
      return 0;
    }
  }

  /**
   * Returns a BytesString for this field in a thread-safe way.
   */
  public ByteString toByteString() {
    if (memoizedBytes != null) {
      return memoizedBytes;
    }
    // We *must* return delayed bytes if it was set because the dependent messages may have
    // memoized serialized size based off of it.
    if (delayedBytes != null) {
      return delayedBytes;
    }
    synchronized (this) {
      if (memoizedBytes != null) {
        return memoizedBytes;
      }
      if (value == null) {
        memoizedBytes = ByteString.EMPTY;
      } else {
        memoizedBytes = value.toByteString();
      }
      return memoizedBytes;
    }
  }


  /**
   * Might lazily parse the bytes that were previously passed in. Is thread-safe.
   */
  protected void ensureInitialized(MessageLite defaultInstance) {
    if (value != null) {
      return;
    }
    synchronized (this) {
      if (value != null) {
        return;
      }
      try {
        if (delayedBytes != null) {
          // The extensionRegistry shouldn't be null here since we have delayedBytes.
          MessageLite parsedValue = defaultInstance.getParserForType()
              .parseFrom(delayedBytes, extensionRegistry);
          this.value = parsedValue;
          this.memoizedBytes = delayedBytes;
        } else {
          this.value = defaultInstance;
          this.memoizedBytes = ByteString.EMPTY;
        }
      } catch (InvalidProtocolBufferException e) {
        // Nothing is logged and no exceptions are thrown. Clients will be unaware that this proto
        // was invalid.
        this.value = defaultInstance;
        this.memoizedBytes = ByteString.EMPTY;
      }
    }
  }


  private static void checkArguments(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
    if (extensionRegistry == null) {
      throw new NullPointerException("found null ExtensionRegistry");
    }
    if (bytes == null) {
      throw new NullPointerException("found null ByteString");
    }
  }
}
