// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: import_public/c.proto

package import_public

import (
	sub2 "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/import_public/sub2"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

type UsingPublicImport struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Local is declared in b.proto, which is a public import of a.proto.
	Local *Local `protobuf:"bytes,1,opt,name=local" json:"local,omitempty"`
	// Sub2Message is declared in sub2/a.proto, which is a public import of
	// sub/a.proto, which is a public import of a.proto.
	Sub2 *sub2.Sub2Message `protobuf:"bytes,2,opt,name=sub2" json:"sub2,omitempty"` // declared in sub2/a.proto
}

func (x *UsingPublicImport) Reset() {
	*x = UsingPublicImport{}
}

func (x *UsingPublicImport) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*UsingPublicImport) ProtoMessage() {}

func (x *UsingPublicImport) ProtoReflect() protoreflect.Message {
	mi := &file_import_public_c_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use UsingPublicImport.ProtoReflect.Descriptor instead.
func (*UsingPublicImport) Descriptor() ([]byte, []int) {
	return file_import_public_c_proto_rawDescGZIP(), []int{0}
}

func (x *UsingPublicImport) GetLocal() *Local {
	if x != nil {
		return x.Local
	}
	return nil
}

func (x *UsingPublicImport) GetSub2() *sub2.Sub2Message {
	if x != nil {
		return x.Sub2
	}
	return nil
}

var File_import_public_c_proto protoreflect.FileDescriptor

var file_import_public_c_proto_rawDesc = []byte{
	0x0a, 0x15, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f,
	0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70,
	0x75, 0x62, 0x6c, 0x69, 0x63, 0x1a, 0x15, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x75,
	0x62, 0x6c, 0x69, 0x63, 0x2f, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x01, 0x0a,
	0x11, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x6d, 0x70, 0x6f,
	0x72, 0x74, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
	0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
	0x6f, 0x63, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
	0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x42, 0x0a,
	0x04, 0x73, 0x75, 0x62, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x6f,
	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2e, 0x69, 0x6d, 0x70,
	0x6f, 0x72, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x73, 0x75, 0x62, 0x32, 0x2e,
	0x53, 0x75, 0x62, 0x32, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x73, 0x75, 0x62,
	0x32, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61,
	0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
	0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67,
	0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72,
	0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
}

var (
	file_import_public_c_proto_rawDescOnce sync.Once
	file_import_public_c_proto_rawDescData = file_import_public_c_proto_rawDesc
)

func file_import_public_c_proto_rawDescGZIP() []byte {
	file_import_public_c_proto_rawDescOnce.Do(func() {
		file_import_public_c_proto_rawDescData = protoimpl.X.CompressGZIP(file_import_public_c_proto_rawDescData)
	})
	return file_import_public_c_proto_rawDescData
}

var file_import_public_c_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_import_public_c_proto_goTypes = []interface{}{
	(*UsingPublicImport)(nil), // 0: goproto.protoc.import_public.UsingPublicImport
	(*Local)(nil),             // 1: goproto.protoc.import_public.Local
	(*sub2.Sub2Message)(nil),  // 2: goproto.protoc.import_public.sub2.Sub2Message
}
var file_import_public_c_proto_depIdxs = []int32{
	1, // goproto.protoc.import_public.UsingPublicImport.local:type_name -> goproto.protoc.import_public.Local
	2, // goproto.protoc.import_public.UsingPublicImport.sub2:type_name -> goproto.protoc.import_public.sub2.Sub2Message
	2, // starting offset of method output_type sub-list
	2, // starting offset of method input_type sub-list
	2, // starting offset of extension type_name sub-list
	2, // starting offset of extension extendee sub-list
	0, // starting offset of field type_name sub-list
}

func init() { file_import_public_c_proto_init() }
func file_import_public_c_proto_init() {
	if File_import_public_c_proto != nil {
		return
	}
	file_import_public_a_proto_init()
	if !protoimpl.UnsafeEnabled {
		file_import_public_c_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*UsingPublicImport); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_import_public_c_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_import_public_c_proto_goTypes,
		DependencyIndexes: file_import_public_c_proto_depIdxs,
		MessageInfos:      file_import_public_c_proto_msgTypes,
	}.Build()
	File_import_public_c_proto = out.File
	file_import_public_c_proto_rawDesc = nil
	file_import_public_c_proto_goTypes = nil
	file_import_public_c_proto_depIdxs = nil
}
