// 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 com.google.protobuf.Internal.EnumVerifier;
import java.lang.reflect.Field;

/** Information for a single field in a protobuf message class. */
@ExperimentalApi
final class FieldInfo implements Comparable<FieldInfo> {
  private final Field field;
  private final FieldType type;
  private final Class<?> messageClass; // The message type for repeated message fields.
  private final int fieldNumber;
  private final Field presenceField;
  private final int presenceMask;
  private final boolean required;
  private final boolean enforceUtf8;
  private final OneofInfo oneof;
  private final Field cachedSizeField;
  /**
   * The actual type stored in the oneof value for this field. Since the oneof value is an {@link
   * Object}, primitives will store their boxed type. Only valid in conjunction with {@link #oneof}
   * (both must be either null or non-null.
   */
  private final Class<?> oneofStoredType;

  // TODO(liujisi): make map default entry lazy?
  private final Object mapDefaultEntry;

  private final EnumVerifier enumVerifier;

  /** Constructs a new descriptor for a field. */
  public static FieldInfo forField(
      Field field, int fieldNumber, FieldType fieldType, boolean enforceUtf8) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    checkNotNull(fieldType, "fieldType");
    if (fieldType == FieldType.MESSAGE_LIST || fieldType == FieldType.GROUP_LIST) {
      throw new IllegalStateException("Shouldn't be called for repeated message fields.");
    }
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        enforceUtf8,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        /* enumVerifier= */ null,
        /* cachedSizeField= */ null);
  }

  /** Constructs a new descriptor for a packed field. */
  public static FieldInfo forPackedField(
      Field field, int fieldNumber, FieldType fieldType, Field cachedSizeField) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    checkNotNull(fieldType, "fieldType");
    if (fieldType == FieldType.MESSAGE_LIST || fieldType == FieldType.GROUP_LIST) {
      throw new IllegalStateException("Shouldn't be called for repeated message fields.");
    }
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        /* enforceUtf8= */ false,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        /* enumVerifier= */ null,
        cachedSizeField);
  }

  /** Constructs a new descriptor for a repeated message field. */
  public static FieldInfo forRepeatedMessageField(
      Field field, int fieldNumber, FieldType fieldType, Class<?> messageClass) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    checkNotNull(fieldType, "fieldType");
    checkNotNull(messageClass, "messageClass");
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        messageClass,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        /* enforceUtf8= */ false,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        /* enumVerifier= */ null,
        /* cachedSizeField= */ null);
  }

  public static FieldInfo forFieldWithEnumVerifier(
      Field field, int fieldNumber, FieldType fieldType, EnumVerifier enumVerifier) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        /* enforceUtf8= */ false,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        enumVerifier,
        /* cachedSizeField= */ null);
  }

  public static FieldInfo forPackedFieldWithEnumVerifier(
      Field field,
      int fieldNumber,
      FieldType fieldType,
      EnumVerifier enumVerifier,
      Field cachedSizeField) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        /* enforceUtf8= */ false,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        enumVerifier,
        cachedSizeField);
  }

  /** Constructor for a proto2 optional field. */
  public static FieldInfo forProto2OptionalField(
      Field field,
      int fieldNumber,
      FieldType fieldType,
      Field presenceField,
      int presenceMask,
      boolean enforceUtf8,
      EnumVerifier enumVerifier) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    checkNotNull(fieldType, "fieldType");
    checkNotNull(presenceField, "presenceField");
    if (presenceField != null && !isExactlyOneBitSet(presenceMask)) {
      throw new IllegalArgumentException(
          "presenceMask must have exactly one bit set: " + presenceMask);
    }
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        presenceField,
        presenceMask,
        /* required= */ false,
        enforceUtf8,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        enumVerifier,
        /* cachedSizeField= */ null);
  }

  /**
   * Constructor for a field that is part of a oneof.
   *
   * @param fieldNumber the unique field number for this field within the message.
   * @param fieldType the type of the field (must be non-null).
   * @param oneof the oneof for which this field is associated (must be non-null).
   * @param oneofStoredType the actual type stored in the oneof value for this field. Since the
   *     oneof value is an {@link Object}, primitives will store their boxed type. Must be non-null.
   * @param enforceUtf8 Only used for string fields. If {@code true}, will enforce UTF-8 on a string
   *     field.
   * @return the {@link FieldInfo} describing this field.
   */
  public static FieldInfo forOneofMemberField(
      int fieldNumber,
      FieldType fieldType,
      OneofInfo oneof,
      Class<?> oneofStoredType,
      boolean enforceUtf8,
      EnumVerifier enumVerifier) {
    checkFieldNumber(fieldNumber);
    checkNotNull(fieldType, "fieldType");
    checkNotNull(oneof, "oneof");
    checkNotNull(oneofStoredType, "oneofStoredType");
    if (!fieldType.isScalar()) {
      throw new IllegalArgumentException(
          "Oneof is only supported for scalar fields. Field "
              + fieldNumber
              + " is of type "
              + fieldType);
    }
    return new FieldInfo(
        /* field= */ null,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        enforceUtf8,
        oneof,
        oneofStoredType,
        /* mapDefaultEntry= */ null,
        enumVerifier,
        /* cachedSizeField= */ null);
  }

  private static void checkFieldNumber(int fieldNumber) {
    if (fieldNumber <= 0) {
      throw new IllegalArgumentException("fieldNumber must be positive: " + fieldNumber);
    }
  }

  /** Constructor for a proto2 required field. */
  public static FieldInfo forProto2RequiredField(
      Field field,
      int fieldNumber,
      FieldType fieldType,
      Field presenceField,
      int presenceMask,
      boolean enforceUtf8,
      EnumVerifier enumVerifier) {
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    checkNotNull(fieldType, "fieldType");
    checkNotNull(presenceField, "presenceField");
    if (presenceField != null && !isExactlyOneBitSet(presenceMask)) {
      throw new IllegalArgumentException(
          "presenceMask must have exactly one bit set: " + presenceMask);
    }
    return new FieldInfo(
        field,
        fieldNumber,
        fieldType,
        /* messageClass= */ null,
        presenceField,
        presenceMask,
        /* required= */ true,
        enforceUtf8,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        /* mapDefaultEntry= */ null,
        /* enumVerifier= */ enumVerifier,
        /* cachedSizeField= */ null);
  }

  public static FieldInfo forMapField(
      Field field, int fieldNumber, Object mapDefaultEntry, EnumVerifier enumVerifier) {
    checkNotNull(mapDefaultEntry, "mapDefaultEntry");
    checkFieldNumber(fieldNumber);
    checkNotNull(field, "field");
    return new FieldInfo(
        field,
        fieldNumber,
        FieldType.MAP,
        /* messageClass= */ null,
        /* presenceField= */ null,
        /* presenceMask= */ 0,
        /* required= */ false,
        /* enforceUtf8= */ true,
        /* oneof= */ null,
        /* oneofStoredType= */ null,
        mapDefaultEntry,
        enumVerifier,
        /* cachedSizeField= */ null);
  }

  private FieldInfo(
      Field field,
      int fieldNumber,
      FieldType type,
      Class<?> messageClass,
      Field presenceField,
      int presenceMask,
      boolean required,
      boolean enforceUtf8,
      OneofInfo oneof,
      Class<?> oneofStoredType,
      Object mapDefaultEntry,
      EnumVerifier enumVerifier,
      Field cachedSizeField) {
    this.field = field;
    this.type = type;
    this.messageClass = messageClass;
    this.fieldNumber = fieldNumber;
    this.presenceField = presenceField;
    this.presenceMask = presenceMask;
    this.required = required;
    this.enforceUtf8 = enforceUtf8;
    this.oneof = oneof;
    this.oneofStoredType = oneofStoredType;
    this.mapDefaultEntry = mapDefaultEntry;
    this.enumVerifier = enumVerifier;
    this.cachedSizeField = cachedSizeField;
  }

  /** Gets the field number for the field. */
  public int getFieldNumber() {
    return fieldNumber;
  }

  /** Gets the subject {@link Field} of this descriptor. */
  public Field getField() {
    return field;
  }

  /** Gets the type information for the field. */
  public FieldType getType() {
    return type;
  }

  /** Gets the oneof for which this field is a member, or {@code null} if not part of a oneof. */
  public OneofInfo getOneof() {
    return oneof;
  }

  /**
   * Gets the actual type stored in the oneof value by this field. Since the oneof value is an
   * {@link Object}, primitives will store their boxed type. For non-oneof fields, this will always
   * be {@code null}.
   */
  public Class<?> getOneofStoredType() {
    return oneofStoredType;
  }

  /** Gets the {@code EnumVerifier} if the field is an enum field. */
  public EnumVerifier getEnumVerifier() {
    return enumVerifier;
  }

  @Override
  public int compareTo(FieldInfo o) {
    return fieldNumber - o.fieldNumber;
  }

  /**
   * For repeated message fields, returns the message type of the field. For other fields, returns
   * {@code null}.
   */
  public Class<?> getListElementType() {
    return messageClass;
  }

  /** Gets the presence bit field. Only valid for unary fields. For lists, returns {@code null}. */
  public Field getPresenceField() {
    return presenceField;
  }

  public Object getMapDefaultEntry() {
    return mapDefaultEntry;
  }

  /**
   * If {@link #getPresenceField()} is non-{@code null}, returns the mask used to identify the
   * presence bit for this field in the message.
   */
  public int getPresenceMask() {
    return presenceMask;
  }

  /** Whether this is a required field. */
  public boolean isRequired() {
    return required;
  }

  /**
   * Whether a UTF-8 should be enforced on string fields. Only applies to strings and string lists.
   */
  public boolean isEnforceUtf8() {
    return enforceUtf8;
  }

  public Field getCachedSizeField() {
    return cachedSizeField;
  }

  /**
   * For singular or repeated message fields, returns the message type. For other fields, returns
   * {@code null}.
   */
  public Class<?> getMessageFieldClass() {
    switch (type) {
      case MESSAGE:
      case GROUP:
        return field != null ? field.getType() : oneofStoredType;
      case MESSAGE_LIST:
      case GROUP_LIST:
        return messageClass;
      default:
        return null;
    }
  }

  public static Builder newBuilder() {
    return new Builder();
  }

  /** A builder for {@link FieldInfo} instances. */
  public static final class Builder {
    private Field field;
    private FieldType type;
    private int fieldNumber;
    private Field presenceField;
    private int presenceMask;
    private boolean required;
    private boolean enforceUtf8;
    private OneofInfo oneof;
    private Class<?> oneofStoredType;
    private Object mapDefaultEntry;
    private EnumVerifier enumVerifier;
    private Field cachedSizeField;

    private Builder() {}

    /**
     * Specifies the actual field on the message represented by this field. This should not be
     * called for oneof member fields.
     */
    public Builder withField(Field field) {
      if (oneof != null) {
        throw new IllegalStateException("Cannot set field when building a oneof.");
      }
      this.field = field;
      return this;
    }

    /** Specifies the type of this field. */
    public Builder withType(FieldType type) {
      this.type = type;
      return this;
    }

    /** Specifies the unique field number for this field within the message. */
    public Builder withFieldNumber(int fieldNumber) {
      this.fieldNumber = fieldNumber;
      return this;
    }

    /** Specifies proto2 presence information. This should not be called for oneof fields. */
    public Builder withPresence(Field presenceField, int presenceMask) {
      this.presenceField = checkNotNull(presenceField, "presenceField");
      this.presenceMask = presenceMask;
      return this;
    }

    /**
     * Sets the information for building a oneof member field. This is incompatible with {@link
     * #withField(Field)} and {@link #withPresence(Field, int)}.
     *
     * @param oneof the oneof for which this field is associated.
     * @param oneofStoredType the actual type stored in the oneof value for this field. Since the
     *     oneof value is an {@link Object}, primitives will store their boxed type.
     */
    public Builder withOneof(OneofInfo oneof, Class<?> oneofStoredType) {
      if (field != null || presenceField != null) {
        throw new IllegalStateException(
            "Cannot set oneof when field or presenceField have been provided");
      }
      this.oneof = oneof;
      this.oneofStoredType = oneofStoredType;
      return this;
    }

    public Builder withRequired(boolean required) {
      this.required = required;
      return this;
    }

    public Builder withMapDefaultEntry(Object mapDefaultEntry) {
      this.mapDefaultEntry = mapDefaultEntry;
      return this;
    }

    public Builder withEnforceUtf8(boolean enforceUtf8) {
      this.enforceUtf8 = enforceUtf8;
      return this;
    }

    public Builder withEnumVerifier(EnumVerifier enumVerifier) {
      this.enumVerifier = enumVerifier;
      return this;
    }

    public Builder withCachedSizeField(Field cachedSizeField) {
      this.cachedSizeField = cachedSizeField;
      return this;
    }

    public FieldInfo build() {
      if (oneof != null) {
        return forOneofMemberField(
            fieldNumber, type, oneof, oneofStoredType, enforceUtf8, enumVerifier);
      }
      if (mapDefaultEntry != null) {
        return forMapField(field, fieldNumber, mapDefaultEntry, enumVerifier);
      }
      if (presenceField != null) {
        if (required) {
          return forProto2RequiredField(
              field, fieldNumber, type, presenceField, presenceMask, enforceUtf8, enumVerifier);
        } else {
          return forProto2OptionalField(
              field, fieldNumber, type, presenceField, presenceMask, enforceUtf8, enumVerifier);
        }
      }
      if (enumVerifier != null) {
        if (cachedSizeField == null) {
          return forFieldWithEnumVerifier(field, fieldNumber, type, enumVerifier);
        } else {
          return forPackedFieldWithEnumVerifier(
              field, fieldNumber, type, enumVerifier, cachedSizeField);
        }
      } else {
        if (cachedSizeField == null) {
          return forField(field, fieldNumber, type, enforceUtf8);
        } else {
          return forPackedField(field, fieldNumber, type, cachedSizeField);
        }
      }
    }
  }

  private static boolean isExactlyOneBitSet(int value) {
    return value != 0 && (value & (value - 1)) == 0;
  }
}
