// 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.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();
    return appView
        .appInfo()
        .resolveField(object.asLiveProtoFieldObject().getField())
        .getSingleProgramField();
  }

  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();
    return appView
        .appInfo()
        .resolveField(object.asLiveProtoFieldObject().getField())
        .getSingleProgramField();
  }

  /**
   * 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();
    return appView
        .appInfo()
        .resolveField(object.asLiveProtoFieldObject().getField())
        .getProgramField();
  }

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