// 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 protoMessageInfo.isProto2() && type.isSingular();
  }

  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();
  }
}
