// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: greet.proto

package org.apache.dubbo.samples.proto;

public final class GreetProto {
  private GreetProto() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_samples_proto_GreetRequest_descriptor;
  static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_samples_proto_GreetRequest_fieldAccessorTable;
  static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_samples_proto_GreetResponse_descriptor;
  static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_samples_proto_GreetResponse_fieldAccessorTable;
  static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_samples_proto_SayHelloRequest_descriptor;
  static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_samples_proto_SayHelloRequest_fieldAccessorTable;
  static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_samples_proto_SayHelloResponse_descriptor;
  static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_samples_proto_SayHelloResponse_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\013greet.proto\022\036org.apache.dubbo.samples." +
      "proto\"\034\n\014GreetRequest\022\014\n\004name\030\001 \001(\t\"!\n\rG" +
      "reetResponse\022\020\n\010greeting\030\001 \001(\t\"\037\n\017SayHel" +
      "loRequest\022\014\n\004name\030\001 \001(\t\"!\n\020SayHelloRespo" +
      "nse\022\r\n\005hello\030\001 \001(\t2\347\001\n\014GreetService\022f\n\005G" +
      "reet\022,.org.apache.dubbo.samples.proto.Gr" +
      "eetRequest\032-.org.apache.dubbo.samples.pr" +
      "oto.GreetResponse\"\000\022o\n\010SayHello\022/.org.ap" +
      "ache.dubbo.samples.proto.SayHelloRequest" +
      "\0320.org.apache.dubbo.samples.proto.SayHel" +
      "loResponse\"\000B4\n\036org.apache.dubbo.samples" +
      ".protoB\nGreetProtoP\001\242\002\003HLWb\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        });
    internal_static_org_apache_dubbo_samples_proto_GreetRequest_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_org_apache_dubbo_samples_proto_GreetRequest_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_samples_proto_GreetRequest_descriptor,
        new java.lang.String[] { "Name", });
    internal_static_org_apache_dubbo_samples_proto_GreetResponse_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_org_apache_dubbo_samples_proto_GreetResponse_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_samples_proto_GreetResponse_descriptor,
        new java.lang.String[] { "Greeting", });
    internal_static_org_apache_dubbo_samples_proto_SayHelloRequest_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_org_apache_dubbo_samples_proto_SayHelloRequest_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_samples_proto_SayHelloRequest_descriptor,
        new java.lang.String[] { "Name", });
    internal_static_org_apache_dubbo_samples_proto_SayHelloResponse_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_org_apache_dubbo_samples_proto_SayHelloResponse_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_samples_proto_SayHelloResponse_descriptor,
        new java.lang.String[] { "Hello", });
  }

  // @@protoc_insertion_point(outer_class_scope)
}
