// Copyright 2019 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.

package protodesc

import (
	
	

	
	
	
	

	
)

// ToFileDescriptorProto copies a protoreflect.FileDescriptor into a
// google.protobuf.FileDescriptorProto message.
func ( protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto {
	 := &descriptorpb.FileDescriptorProto{
		Name:    proto.String(.Path()),
		Options: proto.Clone(.Options()).(*descriptorpb.FileOptions),
	}
	if .Package() != "" {
		.Package = proto.String(string(.Package()))
	}
	for ,  := 0, .Imports();  < .Len(); ++ {
		 := .Get()
		.Dependency = append(.Dependency, .Path())
		if .IsPublic {
			.PublicDependency = append(.PublicDependency, int32())
		}
		if .IsWeak {
			.WeakDependency = append(.WeakDependency, int32())
		}
	}
	for ,  := 0, .SourceLocations();  < .Len(); ++ {
		 := .Get()
		 := &descriptorpb.SourceCodeInfo_Location{}
		.Path = append(.Path, .Path...)
		if .StartLine == .EndLine {
			.Span = []int32{int32(.StartLine), int32(.StartColumn), int32(.EndColumn)}
		} else {
			.Span = []int32{int32(.StartLine), int32(.StartColumn), int32(.EndLine), int32(.EndColumn)}
		}
		.LeadingDetachedComments = append([]string(nil), .LeadingDetachedComments...)
		if .LeadingComments != "" {
			.LeadingComments = proto.String(.LeadingComments)
		}
		if .TrailingComments != "" {
			.TrailingComments = proto.String(.TrailingComments)
		}
		if .SourceCodeInfo == nil {
			.SourceCodeInfo = &descriptorpb.SourceCodeInfo{}
		}
		.SourceCodeInfo.Location = append(.SourceCodeInfo.Location, )

	}
	for ,  := 0, .Messages();  < .Len(); ++ {
		.MessageType = append(.MessageType, ToDescriptorProto(.Get()))
	}
	for ,  := 0, .Enums();  < .Len(); ++ {
		.EnumType = append(.EnumType, ToEnumDescriptorProto(.Get()))
	}
	for ,  := 0, .Services();  < .Len(); ++ {
		.Service = append(.Service, ToServiceDescriptorProto(.Get()))
	}
	for ,  := 0, .Extensions();  < .Len(); ++ {
		.Extension = append(.Extension, ToFieldDescriptorProto(.Get()))
	}
	if  := .Syntax();  != protoreflect.Proto2 {
		.Syntax = proto.String(.Syntax().String())
	}
	return 
}

// ToDescriptorProto copies a protoreflect.MessageDescriptor into a
// google.protobuf.DescriptorProto message.
func ( protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto {
	 := &descriptorpb.DescriptorProto{
		Name:    proto.String(string(.Name())),
		Options: proto.Clone(.Options()).(*descriptorpb.MessageOptions),
	}
	for ,  := 0, .Fields();  < .Len(); ++ {
		.Field = append(.Field, ToFieldDescriptorProto(.Get()))
	}
	for ,  := 0, .Extensions();  < .Len(); ++ {
		.Extension = append(.Extension, ToFieldDescriptorProto(.Get()))
	}
	for ,  := 0, .Messages();  < .Len(); ++ {
		.NestedType = append(.NestedType, (.Get()))
	}
	for ,  := 0, .Enums();  < .Len(); ++ {
		.EnumType = append(.EnumType, ToEnumDescriptorProto(.Get()))
	}
	for ,  := 0, .ExtensionRanges();  < .Len(); ++ {
		 := .Get()
		.ExtensionRange = append(.ExtensionRange, &descriptorpb.DescriptorProto_ExtensionRange{
			Start:   proto.Int32(int32([0])),
			End:     proto.Int32(int32([1])),
			Options: proto.Clone(.ExtensionRangeOptions()).(*descriptorpb.ExtensionRangeOptions),
		})
	}
	for ,  := 0, .Oneofs();  < .Len(); ++ {
		.OneofDecl = append(.OneofDecl, ToOneofDescriptorProto(.Get()))
	}
	for ,  := 0, .ReservedRanges();  < .Len(); ++ {
		 := .Get()
		.ReservedRange = append(.ReservedRange, &descriptorpb.DescriptorProto_ReservedRange{
			Start: proto.Int32(int32([0])),
			End:   proto.Int32(int32([1])),
		})
	}
	for ,  := 0, .ReservedNames();  < .Len(); ++ {
		.ReservedName = append(.ReservedName, string(.Get()))
	}
	return 
}

// ToFieldDescriptorProto copies a protoreflect.FieldDescriptor into a
// google.protobuf.FieldDescriptorProto message.
func ( protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto {
	 := &descriptorpb.FieldDescriptorProto{
		Name:    proto.String(string(.Name())),
		Number:  proto.Int32(int32(.Number())),
		Label:   descriptorpb.FieldDescriptorProto_Label(.Cardinality()).Enum(),
		Options: proto.Clone(.Options()).(*descriptorpb.FieldOptions),
	}
	if .IsExtension() {
		.Extendee = fullNameOf(.ContainingMessage())
	}
	if .Kind().IsValid() {
		.Type = descriptorpb.FieldDescriptorProto_Type(.Kind()).Enum()
	}
	if .Enum() != nil {
		.TypeName = fullNameOf(.Enum())
	}
	if .Message() != nil {
		.TypeName = fullNameOf(.Message())
	}
	if .HasJSONName() {
		// A bug in older versions of protoc would always populate the
		// "json_name" option for extensions when it is meaningless.
		// When it did so, it would always use the camel-cased field name.
		if .IsExtension() {
			.JsonName = proto.String(strs.JSONCamelCase(string(.Name())))
		} else {
			.JsonName = proto.String(.JSONName())
		}
	}
	if .Syntax() == protoreflect.Proto3 && .HasOptionalKeyword() {
		.Proto3Optional = proto.Bool(true)
	}
	if .HasDefault() {
		,  := defval.Marshal(.Default(), .DefaultEnumValue(), .Kind(), defval.Descriptor)
		if  != nil && .DefaultEnumValue() != nil {
			 = string(.DefaultEnumValue().Name()) // occurs for unresolved enum values
		} else if  != nil {
			panic(fmt.Sprintf("%v: %v", .FullName(), ))
		}
		.DefaultValue = proto.String()
	}
	if  := .ContainingOneof();  != nil {
		.OneofIndex = proto.Int32(int32(.Index()))
	}
	return 
}

// ToOneofDescriptorProto copies a protoreflect.OneofDescriptor into a
// google.protobuf.OneofDescriptorProto message.
func ( protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto {
	return &descriptorpb.OneofDescriptorProto{
		Name:    proto.String(string(.Name())),
		Options: proto.Clone(.Options()).(*descriptorpb.OneofOptions),
	}
}

// ToEnumDescriptorProto copies a protoreflect.EnumDescriptor into a
// google.protobuf.EnumDescriptorProto message.
func ( protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto {
	 := &descriptorpb.EnumDescriptorProto{
		Name:    proto.String(string(.Name())),
		Options: proto.Clone(.Options()).(*descriptorpb.EnumOptions),
	}
	for ,  := 0, .Values();  < .Len(); ++ {
		.Value = append(.Value, ToEnumValueDescriptorProto(.Get()))
	}
	for ,  := 0, .ReservedRanges();  < .Len(); ++ {
		 := .Get()
		.ReservedRange = append(.ReservedRange, &descriptorpb.EnumDescriptorProto_EnumReservedRange{
			Start: proto.Int32(int32([0])),
			End:   proto.Int32(int32([1])),
		})
	}
	for ,  := 0, .ReservedNames();  < .Len(); ++ {
		.ReservedName = append(.ReservedName, string(.Get()))
	}
	return 
}

// ToEnumValueDescriptorProto copies a protoreflect.EnumValueDescriptor into a
// google.protobuf.EnumValueDescriptorProto message.
func ( protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto {
	return &descriptorpb.EnumValueDescriptorProto{
		Name:    proto.String(string(.Name())),
		Number:  proto.Int32(int32(.Number())),
		Options: proto.Clone(.Options()).(*descriptorpb.EnumValueOptions),
	}
}

// ToServiceDescriptorProto copies a protoreflect.ServiceDescriptor into a
// google.protobuf.ServiceDescriptorProto message.
func ( protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto {
	 := &descriptorpb.ServiceDescriptorProto{
		Name:    proto.String(string(.Name())),
		Options: proto.Clone(.Options()).(*descriptorpb.ServiceOptions),
	}
	for ,  := 0, .Methods();  < .Len(); ++ {
		.Method = append(.Method, ToMethodDescriptorProto(.Get()))
	}
	return 
}

// ToMethodDescriptorProto copies a protoreflect.MethodDescriptor into a
// google.protobuf.MethodDescriptorProto message.
func ( protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto {
	 := &descriptorpb.MethodDescriptorProto{
		Name:       proto.String(string(.Name())),
		InputType:  fullNameOf(.Input()),
		OutputType: fullNameOf(.Output()),
		Options:    proto.Clone(.Options()).(*descriptorpb.MethodOptions),
	}
	if .IsStreamingClient() {
		.ClientStreaming = proto.Bool(true)
	}
	if .IsStreamingServer() {
		.ServerStreaming = proto.Bool(true)
	}
	return 
}

func ( protoreflect.Descriptor) *string {
	if  == nil {
		return nil
	}
	if strings.HasPrefix(string(.FullName()), unknownPrefix) {
		return proto.String(string(.FullName()[len(unknownPrefix):]))
	}
	return proto.String("." + string(.FullName()))
}