// Copyright 2018 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;

import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;

/**
 * A codec for Java 8 serializable lambdas. Lambdas that are tagged as {@link Serializable} have a
 * generated method, {@code writeReplace}, that converts them into a {@link SerializedLambda}, which
 * can then be serialized like a normal object. On deserialization, we call {@link
 * SerializedLambda#readResolve}, which converts the object back into a lambda.
 *
 * <p>Since lambdas do not share a common base class, choosing this codec for serializing them must
 * be special-cased in {@link ObjectCodecRegistry}. We must also make a somewhat arbitrary choice
 * around the generic parameter. Since all of our lambdas are {@link Serializable}, we use that.
 * Because {@link Serializable} is an interface, not a class, this codec will never be chosen for
 * any object without special-casing.
 */
class LambdaCodec implements ObjectCodec<Serializable> {
  private final Method readResolveMethod;

  LambdaCodec() {
    try {
      this.readResolveMethod = SerializedLambda.class.getDeclaredMethod("readResolve");
    } catch (NoSuchMethodException e) {
      throw new IllegalStateException(e);
    }
    readResolveMethod.setAccessible(true);
  }

  static boolean isProbablyLambda(Class<?> type) {
    return type.isSynthetic() && !type.isLocalClass() && !type.isAnonymousClass();
  }

  @Override
  public Class<? extends Serializable> getEncodedClass() {
    return Serializable.class;
  }

  @Override
  public void serialize(SerializationContext context, Serializable obj, CodedOutputStream codedOut)
      throws SerializationException, IOException {
    Class<?> objClass = obj.getClass();
    if (!isProbablyLambda(objClass)) {
      throw new SerializationException(obj + " is not a lambda: " + objClass);
    }
    Method writeReplaceMethod;
    try {
      // TODO(janakr): We could cache these methods if retrieval shows up as a hotspot.
      writeReplaceMethod = objClass.getDeclaredMethod("writeReplace");
    } catch (NoSuchMethodException e) {
      throw new SerializationException(
          "No writeReplace method for " + obj + " with " + objClass, e);
    }
    writeReplaceMethod.setAccessible(true);
    SerializedLambda serializedLambda;
    try {
      serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(obj);
    } catch (ReflectiveOperationException e) {
      throw new SerializationException(
          "Exception invoking writeReplace for " + obj + " with " + objClass, e);
    }
    context.serialize(serializedLambda, codedOut);
  }

  @Override
  public Serializable deserialize(DeserializationContext context, CodedInputStream codedIn)
      throws SerializationException, IOException {
    SerializedLambda serializedLambda = context.deserialize(codedIn);
    try {
      return (Serializable) readResolveMethod.invoke(serializedLambda);
    } catch (ReflectiveOperationException e) {
      throw new IllegalStateException("Error read-resolving " + serializedLambda, e);
    }
  }
}
