// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.skyframe.serialization.autocodec;

import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
import com.google.devtools.build.lib.unsafe.UnsafeProvider;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;

/**
 * Generates code for a specific field.
 *
 * <p>Always stores the offset of the field in a variable named {@link #getOffsetName}.
 */
abstract class FieldGenerator {
  /**
   * A string that should never occur in user code identifiers.
   *
   * <p>This is used to create unique identifiers that won't collide.
   */
  private static final String GENERATED_TAG = "$AutoCodec$";

  private static final String OFFSET_SUFFIX = "_offset";

  private final VariableElement variable;
  private final ClassName parentName;
  private final String namePrefix;

  /**
   * Constructor.
   *
   * @param variable the field being serialized. Note that {@link VariableElement} contains a
   *     reference to the enclosing class.
   * @param hierarchyLevel a variable could occur in either the class being serialized or in one of
   *     its ancestor classes. This is 0 for the class itself, 1 for its superclass, and so on. It
   *     is used to avoid naming collisions, particularly in the case of shadowed variables.
   */
  FieldGenerator(VariableElement variable, int hierarchyLevel) {
    this.variable = variable;
    this.parentName = ClassName.get((TypeElement) variable.getEnclosingElement());
    this.namePrefix = variable.getSimpleName() + GENERATED_TAG + hierarchyLevel;
  }

  /** Any created member variables should start with this prefix. */
  final String getNamePrefix() {
    return namePrefix;
  }

  /** The name of the enclosing class, used in generated code. */
  final ClassName getParentName() {
    return parentName;
  }

  /**
   * Generated codecs store the offset of every field of the serialized class in a member variable.
   *
   * @return name of the offset member variable
   */
  final String getOffsetName() {
    return namePrefix + OFFSET_SUFFIX;
  }

  /**
   * Name of the field being serialized.
   *
   * <p>Implementations may refer to this for reflection.
   */
  final Name getParameterName() {
    return variable.getSimpleName();
  }

  final void generateOffsetMember(TypeSpec.Builder classBuilder, MethodSpec.Builder constructor) {
    classBuilder.addField(long.class, getOffsetName(), Modifier.PRIVATE, Modifier.FINAL);
    constructor.addStatement(
        "this.$L = $T.unsafe().objectFieldOffset($T.class.getDeclaredField(\"$L\"))",
        getOffsetName(),
        UnsafeProvider.class,
        getParentName(),
        variable.getSimpleName());
  }

  /**
   * Generates any additional member variables needed for this field.
   *
   * <p>To avoid collisions, field specific field names should be prefixed with {@link #namePrefix}.
   *
   * <p>The *offset* field is already generated by {@link #generateOffsetMember}.
   */
  void generateAdditionalMemberVariables(TypeSpec.Builder classBuilder) {}

  /**
   * Adds field specific code to the constructor.
   *
   * <p>Many implementations don't need to do anything here given that the offset is already
   * initialized by {@link #generateOffsetMember}.
   */
  void generateConstructorCode(MethodSpec.Builder constructor) {}

  /**
   * Adds {@link ObjectCodec#serialize} code to serialize this field.
   *
   * <p>Implementations may assume that the parameters of {@link ObjectCodec#serialize} are present
   * in the generated method's scope and may be referenced.
   */
  abstract void generateSerializeCode(MethodSpec.Builder serialize);

  /**
   * Adds field specific deserialize code.
   *
   * <p>Implementations may assume the presence of parameters of {@link
   * AsyncObjectCodec#deserializeAsync}.
   */
  abstract void generateDeserializeCode(MethodSpec.Builder deserialize);
}
