/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * 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.facebook.thrift.legacy.server;

import com.facebook.swift.service.ThriftEventHandler;
import com.facebook.thrift.server.CompositeRpcServerHandler;
import com.facebook.thrift.server.RpcServerHandler;
import com.google.common.base.Throwables;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

public class GeneratedRpcServerHandlerBuilder {
  private static final String ASYNC_TYPE_NAME = "Async";
  private static final String REACTIVE_TYPE_NAME = "Reactive";
  private static final String GENERATED_RPC_SERVER_HANDLER_POSTFIX = "RpcServerHandler";

  public static RpcServerHandler generatedRpcServerHandler(
      List<Object> sources, List<ThriftEventHandler> eventHandlers) {
    List<RpcServerHandler> serverHandlers = new ArrayList<>();
    for (Object serviceImpl : sources) {
      Class<?> serviceImplClass = serviceImpl.getClass();
      Class<?>[] directInterfaces = serviceImplClass.getInterfaces();

      for (Class<?> directInterface : directInterfaces) {
        CodeFlavor flavor = getCodeFlavor(directInterface);
        String generatedRpcServerHandlerName =
            flavor == CodeFlavor.Blocking
                ? directInterface.getName() + GENERATED_RPC_SERVER_HANDLER_POSTFIX
                : directInterface.getEnclosingClass().getName()
                    + GENERATED_RPC_SERVER_HANDLER_POSTFIX;
        Class<?> rpcServerHandlerClass;
        try {
          rpcServerHandlerClass = Class.forName(generatedRpcServerHandlerName);
        } catch (ClassNotFoundException e) {
          throw new RuntimeException(
              "Unable to find generated RpcServerHandler class, We may using classes not generated by thrift compiler.",
              e);
        }

        Constructor<?> constructor;

        try {
          constructor = rpcServerHandlerClass.getConstructor(directInterface, List.class);
        } catch (NoSuchMethodException e) {
          throw new RuntimeException(
              "Unable to find constructor for generated RpcServerHandler class, We may using classes not generated by thrift compiler.",
              e);
        }

        RpcServerHandler handler;
        try {
          handler = (RpcServerHandler) constructor.newInstance(serviceImpl, eventHandlers);
        } catch (Exception e) {
          Throwable rootCause = Throwables.getRootCause(e);
          throw new RuntimeException("Error creating new RpcServerHandler instance.", rootCause);
        }

        serverHandlers.add(handler);
      }
    }

    return new CompositeRpcServerHandler(serverHandlers);
  }

  private static CodeFlavor getCodeFlavor(Class<?> sourceClass) {
    String classType = sourceClass.getSimpleName();
    if (ASYNC_TYPE_NAME.equals(classType)) {
      return CodeFlavor.Async;
    } else if (REACTIVE_TYPE_NAME.equals(classType)) {
      return CodeFlavor.Reactive;
    } else {
      return CodeFlavor.Blocking;
    }
  }

  private enum CodeFlavor {
    Blocking,
    Async,
    Reactive
  }
}

@@ -956,16 +956,28 @@
 .List;%0A%0A
+@Deprecated%0A
 public c

replace easy case of GeneratedRpcServerHandlerBuilder usage