// 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 proto_test

import (
	"reflect"

	"google.golang.org/protobuf/encoding/prototext"
	"google.golang.org/protobuf/internal/encoding/pack"
	"google.golang.org/protobuf/internal/filedesc"
	"google.golang.org/protobuf/internal/flags"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protodesc"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/runtime/protoimpl"

	"google.golang.org/protobuf/types/descriptorpb"
)

func init() {
	if flags.ProtoLegacy {
		testValidMessages = append(testValidMessages, noEnforceUTF8TestProtos...)
	} else {
		testInvalidMessages = append(testInvalidMessages, noEnforceUTF8TestProtos...)
	}
}

var noEnforceUTF8TestProtos = []testProto{
	{
		desc: "invalid UTF-8 in optional string field",
		decodeTo: []proto.Message{&TestNoEnforceUTF8{
			OptionalString: string("abc\xff"),
		}},
		wire: pack.Message{
			pack.Tag{1, pack.BytesType}, pack.String("abc\xff"),
		}.Marshal(),
	},
	{
		desc: "invalid UTF-8 in optional string field of Go bytes",
		decodeTo: []proto.Message{&TestNoEnforceUTF8{
			OptionalBytes: []byte("abc\xff"),
		}},
		wire: pack.Message{
			pack.Tag{2, pack.BytesType}, pack.String("abc\xff"),
		}.Marshal(),
	},
	{
		desc: "invalid UTF-8 in repeated string field",
		decodeTo: []proto.Message{&TestNoEnforceUTF8{
			RepeatedString: []string{string("foo"), string("abc\xff")},
		}},
		wire: pack.Message{
			pack.Tag{3, pack.BytesType}, pack.String("foo"),
			pack.Tag{3, pack.BytesType}, pack.String("abc\xff"),
		}.Marshal(),
	},
	{
		desc: "invalid UTF-8 in repeated string field of Go bytes",
		decodeTo: []proto.Message{&TestNoEnforceUTF8{
			RepeatedBytes: [][]byte{[]byte("foo"), []byte("abc\xff")},
		}},
		wire: pack.Message{
			pack.Tag{4, pack.BytesType}, pack.String("foo"),
			pack.Tag{4, pack.BytesType}, pack.String("abc\xff"),
		}.Marshal(),
	},
	{
		desc: "invalid UTF-8 in oneof string field",
		decodeTo: []proto.Message{
			&TestNoEnforceUTF8{OneofField: &TestNoEnforceUTF8_OneofString{string("abc\xff")}},
		},
		wire: pack.Message{pack.Tag{5, pack.BytesType}, pack.String("abc\xff")}.Marshal(),
	},
	{
		desc: "invalid UTF-8 in oneof string field of Go bytes",
		decodeTo: []proto.Message{
			&TestNoEnforceUTF8{OneofField: &TestNoEnforceUTF8_OneofBytes{[]byte("abc\xff")}},
		},
		wire: pack.Message{pack.Tag{6, pack.BytesType}, pack.String("abc\xff")}.Marshal(),
	},
}

type TestNoEnforceUTF8 struct {
	OptionalString string       `protobuf:"bytes,1,opt,name=optional_string"`
	OptionalBytes  []byte       `protobuf:"bytes,2,opt,name=optional_bytes"`
	RepeatedString []string     `protobuf:"bytes,3,rep,name=repeated_string"`
	RepeatedBytes  [][]byte     `protobuf:"bytes,4,rep,name=repeated_bytes"`
	OneofField     isOneofField `protobuf_oneof:"oneof_field"`
}

type isOneofField interface{ isOneofField() }

type TestNoEnforceUTF8_OneofString struct {
	OneofString string `protobuf:"bytes,5,opt,name=oneof_string,oneof"`
}
type TestNoEnforceUTF8_OneofBytes struct {
	OneofBytes []byte `protobuf:"bytes,6,opt,name=oneof_bytes,oneof"`
}

func (*TestNoEnforceUTF8_OneofString) isOneofField() {}
func (*TestNoEnforceUTF8_OneofBytes) isOneofField()  {}

func (m *TestNoEnforceUTF8) ProtoReflect() protoreflect.Message {
	return messageInfo_TestNoEnforceUTF8.MessageOf(m)
}

var messageInfo_TestNoEnforceUTF8 = protoimpl.MessageInfo{
	GoReflectType: reflect.TypeOf((*TestNoEnforceUTF8)(nil)),
	Desc: func() protoreflect.MessageDescriptor {
		pb := new(descriptorpb.FileDescriptorProto)
		if err := prototext.Unmarshal([]byte(`
				syntax:  "proto3"
				name:    "test.proto"
				message_type: [{
					name: "TestNoEnforceUTF8"
					field: [
						{name:"optional_string" number:1 label:LABEL_OPTIONAL type:TYPE_STRING},
						{name:"optional_bytes"  number:2 label:LABEL_OPTIONAL type:TYPE_STRING},
						{name:"repeated_string" number:3 label:LABEL_REPEATED type:TYPE_STRING},
						{name:"repeated_bytes"  number:4 label:LABEL_REPEATED type:TYPE_STRING},
						{name:"oneof_string"    number:5 label:LABEL_OPTIONAL type:TYPE_STRING, oneof_index:0},
						{name:"oneof_bytes"     number:6 label:LABEL_OPTIONAL type:TYPE_STRING, oneof_index:0}
					]
					oneof_decl: [{name:"oneof_field"}]
				}]
			`), pb); err != nil {
			panic(err)
		}
		fd, err := protodesc.NewFile(pb, nil)
		if err != nil {
			panic(err)
		}
		md := fd.Messages().Get(0)
		for i := 0; i < md.Fields().Len(); i++ {
			md.Fields().Get(i).(*filedesc.Field).L1.HasEnforceUTF8 = true
			md.Fields().Get(i).(*filedesc.Field).L1.EnforceUTF8 = false
		}
		return md
	}(),
	OneofWrappers: []interface{}{
		(*TestNoEnforceUTF8_OneofString)(nil),
		(*TestNoEnforceUTF8_OneofBytes)(nil),
	},
}
