// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: src/proto/grpc/testing/empty_service.proto
// </auto-generated>
// Original file comments:
// Copyright 2018 gRPC authors.
//
// 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.
//
#pragma warning disable 0414, 1591
#region Designer generated code

using grpc = global::Grpc.Core;

namespace Grpc.Testing {
  /// <summary>
  /// A service that has zero methods.
  /// See https://github.com/grpc/grpc/issues/15574
  /// </summary>
  public static partial class EmptyService
  {
    static readonly string __ServiceName = "grpc.testing.EmptyService";


    /// <summary>Service descriptor</summary>
    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
    {
      get { return global::Grpc.Testing.EmptyServiceReflection.Descriptor.Services[0]; }
    }

    /// <summary>Base class for server-side implementations of EmptyService</summary>
    public abstract partial class EmptyServiceBase
    {
    }

    /// <summary>Client for EmptyService</summary>
    public partial class EmptyServiceClient : grpc::ClientBase<EmptyServiceClient>
    {
      /// <summary>Creates a new client for EmptyService</summary>
      /// <param name="channel">The channel to use to make remote calls.</param>
      public EmptyServiceClient(grpc::Channel channel) : base(channel)
      {
      }
      /// <summary>Creates a new client for EmptyService that uses a custom <c>CallInvoker</c>.</summary>
      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
      public EmptyServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
      {
      }
      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
      protected EmptyServiceClient() : base()
      {
      }
      /// <summary>Protected constructor to allow creation of configured clients.</summary>
      /// <param name="configuration">The client configuration.</param>
      protected EmptyServiceClient(ClientBaseConfiguration configuration) : base(configuration)
      {
      }

      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
      protected override EmptyServiceClient NewInstance(ClientBaseConfiguration configuration)
      {
        return new EmptyServiceClient(configuration);
      }
    }

    /// <summary>Creates service definition that can be registered with a server</summary>
    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
    public static grpc::ServerServiceDefinition BindService(EmptyServiceBase serviceImpl)
    {
      return grpc::ServerServiceDefinition.CreateBuilder().Build();
    }

  }
}
#endregion
