// 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 static com.google.protobuf.Internal.checkNotNull;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Main runtime interface for protobuf. Applications should interact with this interface (rather
 * than directly accessing internal APIs) in order to perform operations on protobuf messages.
 */
@ExperimentalApi
final class Protobuf {
  private static final Protobuf INSTANCE = new Protobuf();

  private final SchemaFactory schemaFactory;

  // TODO(nathanmittler): Consider using ClassValue instead.
  private final ConcurrentMap<Class<?>, Schema<?>> schemaCache =
      new ConcurrentHashMap<Class<?>, Schema<?>>();

  /** Gets the singleton instance of the Protobuf runtime. */
  public static Protobuf getInstance() {
    return INSTANCE;
  }

  /** Writes the given message to the target {@link Writer}. */
  public <T> void writeTo(T message, Writer writer) throws IOException {
    schemaFor(message).writeTo(message, writer);
  }

  /** Reads fields from the given {@link Reader} and merges them into the message. */
  public <T> void mergeFrom(T message, Reader reader) throws IOException {
    mergeFrom(message, reader, ExtensionRegistryLite.getEmptyRegistry());
  }

  /** Reads fields from the given {@link Reader} and merges them into the message. */
  public <T> void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
      throws IOException {
    schemaFor(message).mergeFrom(message, reader, extensionRegistry);
  }

  /** Marks repeated/map/extension/unknown fields as immutable. */
  public <T> void makeImmutable(T message) {
    schemaFor(message).makeImmutable(message);
  }

  /**
   * Checks if all required fields are set. TODO(xiaofeng): Make this package private when the tests
   * are moved to protobuf package.
   */
  public <T> boolean isInitialized(T message) {
    return schemaFor(message).isInitialized(message);
  }

  /** Gets the schema for the given message type. */
  public <T> Schema<T> schemaFor(Class<T> messageType) {
    checkNotNull(messageType, "messageType");
    @SuppressWarnings("unchecked")
    Schema<T> schema = (Schema<T>) schemaCache.get(messageType);
    if (schema == null) {
      schema = schemaFactory.createSchema(messageType);
      @SuppressWarnings("unchecked")
      Schema<T> previous = (Schema<T>) registerSchema(messageType, schema);
      if (previous != null) {
        // A new schema was registered by another thread.
        schema = previous;
      }
    }
    return schema;
  }

  /** Gets the schema for the given message. */
  @SuppressWarnings("unchecked")
  public <T> Schema<T> schemaFor(T message) {
    return schemaFor((Class<T>) message.getClass());
  }

  /**
   * Registers the given schema for the message type only if a schema was not already registered.
   *
   * @param messageType the type of message on which the schema operates.
   * @param schema the schema for the message type.
   * @return the previously registered schema, or {@code null} if the given schema was successfully
   *     registered.
   */
  public Schema<?> registerSchema(Class<?> messageType, Schema<?> schema) {
    checkNotNull(messageType, "messageType");
    checkNotNull(schema, "schema");
    return schemaCache.putIfAbsent(messageType, schema);
  }

  /**
   * Visible for testing only. Registers the given schema for the message type. If a schema was
   * previously registered, it will be replaced by the provided schema.
   *
   * @param messageType the type of message on which the schema operates.
   * @param schema the schema for the message type.
   * @return the previously registered schema, or {@code null} if no schema was registered
   *     previously.
   */
  public Schema<?> registerSchemaOverride(Class<?> messageType, Schema<?> schema) {
    checkNotNull(messageType, "messageType");
    checkNotNull(schema, "schema");
    return schemaCache.put(messageType, schema);
  }

  private Protobuf() {
    schemaFactory = new ManifestSchemaFactory();
  }

  int getTotalSchemaSize() {
    int result = 0;
    for (Schema<?> schema : schemaCache.values()) {
      if (schema instanceof MessageSchema) {
        result += ((MessageSchema) schema).getSchemaSize();
      }
    }
    return result;
  }
}
