// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.ir.analysis.proto.schema;

import static com.android.tools.r8.ir.analysis.proto.schema.ProtoMessageInfo.BITS_PER_HAS_BITS_WORD;

import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldResolutionResult;
import com.android.tools.r8.graph.ProgramField;
import java.util.List;
import java.util.OptionalInt;

public class ProtoFieldInfo {

  private final int number;
  private final ProtoFieldType type;

  /**
   * Index into {@link ProtoMessageInfo#oneOfObjects} or {@link ProtoMessageInfo#hasBitsObjects}.
   * Only used for oneof and proto2 singular fields.
   */
  private OptionalInt auxData;

  /**
   * For any non-oneof field, the first entry will be a reference to a java.lang.String literal. For
   * repeated message fields, the second entry will be a reference to java.lang.Class for the
   * message.
   */
  private final List<ProtoObject> objects;

  public ProtoFieldInfo(
      int number, ProtoFieldType type, OptionalInt auxData, List<ProtoObject> objects) {
    this.number = number;
    this.type = type;
    this.auxData = auxData;
    this.objects = objects;
  }

  public boolean hasAuxData() {
    return auxData.isPresent();
  }

  public int getAuxData() {
    assert hasAuxData();
    return auxData.getAsInt();
  }

  void setAuxData(int value) {
    assert hasAuxData();
    auxData = OptionalInt.of(value);
  }

  public int getNumber() {
    return number;
  }

  public List<ProtoObject> getObjects() {
    return objects;
  }

  public ProtoFieldType getType() {
    return type;
  }

  /**
   * For singular/repeated message-type fields, the type of the message.
   *
   * <p>This isn't populated for map-type fields because that's a bit difficult, but this doesn't
   * matter in practice. We only use this for determining whether to retain a field based on whether
   * it reaches a map/required field, but there's no need to go through that when we're already at
   * one.
   */
  public DexType getBaseMessageType(ProtoFieldTypeFactory factory) {
    if (type.isOneOf()) {
      ProtoFieldType actualFieldType = type.asOneOf().getActualFieldType(factory);
      if (actualFieldType.isGroup() || actualFieldType.isMessage()) {
        ProtoObject object = objects.get(0);
        assert object.isProtoTypeObject();
        return object.asProtoTypeObject().getType();
      }
      return null;
    }
    if (type.isMessage() || type.isGroup()) {
      ProtoObject object = objects.get(0);
      assert object.isLiveProtoFieldObject();
      return object.asLiveProtoFieldObject().getField().type;
    }
    if (type.isMessageList() || type.isGroupList()) {
      ProtoObject object = objects.get(1);
      assert object.isProtoTypeObject();
      return object.asProtoTypeObject().getType();
    }
    return null;
  }

  /**
   * (Proto2 singular fields only.)
   *
   * <p>Java field for denoting the presence of a protobuf field.
   *
   * <p>The generated Java code for:
   *
   * <pre>
   *   message MyMessage {
   *     optional int32 foo = 123;
   *     optional int32 bar = 456;
   *   }
   * </pre>
   *
   * looks like:
   *
   * <pre>
   *   boolean hasFoo() { return bitField0_ & 0x1; }
   *   boolean hasBar() { return bitField0_ & 0x2; }
   * </pre>
   */
  public boolean hasHazzerBitField(ProtoMessageInfo protoMessageInfo) {
    return type.hasAuxData(protoMessageInfo.isProto2());
  }

  public ProgramField getHazzerBitField(
      AppView<? extends AppInfoWithClassHierarchy> appView, ProtoMessageInfo protoMessageInfo) {
    assert hasHazzerBitField(protoMessageInfo);

    int hasBitsIndex = getAuxData() / BITS_PER_HAS_BITS_WORD;
    assert hasBitsIndex < protoMessageInfo.numberOfHasBitsObjects();

    ProtoObject object = protoMessageInfo.getHasBitsObjects().get(hasBitsIndex);
    assert object.isLiveProtoFieldObject();
    FieldResolutionResult resolutionResult =
        appView.appInfo().resolveField(object.asLiveProtoFieldObject().getField());
    if (resolutionResult.isSuccessfulResolution()) {
      return resolutionResult.asSuccessfulResolution().getResolutionPair().asProgramField();
    }
    return null;
  }

  public int getHazzerBitFieldIndex(ProtoMessageInfo protoMessageInfo) {
    assert hasHazzerBitField(protoMessageInfo);
    return (getAuxData() % BITS_PER_HAS_BITS_WORD) + 1;
  }

  /**
   * (One-of fields only.)
   *
   * <p>Java field identifying what the containing oneof is currently being used for.
   *
   * <p>The generated Java code for:
   *
   * <pre>
   *   message MyMessage {
   *     oneof my_oneof {
   *       int32 x = 123;
   *       ...
   *     }
   *   }
   * </pre>
   *
   * looks like:
   *
   * <pre>
   *   ... getMyOneofCase() { return myOneofCase_; }
   *   int getX() {
   *     if (myOneofCase_ == 123) return (Integer) myOneof_;
   *     return 0;
   *   }
   * </pre>
   */
  public ProgramField getOneOfCaseField(
      AppView<? extends AppInfoWithClassHierarchy> appView, ProtoMessageInfo protoMessageInfo) {
    assert type.isOneOf();
    ProtoObject object = protoMessageInfo.getOneOfObjects().get(getAuxData()).getOneOfCaseObject();
    assert object.isLiveProtoFieldObject();
    FieldResolutionResult resolutionResult =
        appView.appInfo().resolveField(object.asLiveProtoFieldObject().getField());
    if (resolutionResult.isSuccessfulResolution()) {
      return resolutionResult.asSuccessfulResolution().getResolutionPair().asProgramField();
    }
    return null;
  }

  /**
   * Data about the field as referenced from the Java implementation.
   *
   * <p>Java field into which the value is stored; constituents of a oneof all share the same
   * storage.
   */
  public ProgramField getValueStorage(
      AppView<? extends AppInfoWithClassHierarchy> appView, ProtoMessageInfo protoMessageInfo) {
    ProtoObject object =
        type.isOneOf()
            ? protoMessageInfo.getOneOfObjects().get(getAuxData()).getOneOfObject()
            : objects.get(0);
    assert object.isLiveProtoFieldObject();
    FieldResolutionResult resolutionResult =
        appView.appInfo().resolveField(object.asLiveProtoFieldObject().getField());
    if (resolutionResult.isSuccessfulResolution()) {
      return resolutionResult.asSuccessfulResolution().getResolutionPair().asProgramField();
    }
    return null;
  }

  @Override
  public String toString() {
    StringBuilder builder =
        new StringBuilder("ProtoFieldInfo(number=")
            .append(number)
            .append(", type=")
            .append(type)
            .append(", aux data=")
            .append(auxData)
            .append(", objects=[");
    if (objects.size() > 0) {
      builder.append(objects.get(0));
      for (int i = 1; i < objects.size(); i++) {
        builder.append(", ").append(objects.get(i));
      }
    }
    return builder.append("])").toString();
  }
}
