// Code generated by protoc-gen-go. DO NOT EDIT.
// source: config/replication_config.proto

package config

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	field_mask "google.golang.org/genproto/protobuf/field_mask"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// Describes different file types that can be replicated.
type FileType int32

const (
	FileType_FILE_TYPE_UNSPECIFIED FileType = 0
	// A JSON file. For protos encoded as JSON, FILE_TYPE_JSONPB should be used.
	FileType_FILE_TYPE_JSON FileType = 1
	// A proto encoded as a JSON file.
	FileType_FILE_TYPE_JSONPB FileType = 2
	// A file not described by the other types.
	FileType_FILE_TYPE_OTHER FileType = 3
)

var FileType_name = map[int32]string{
	0: "FILE_TYPE_UNSPECIFIED",
	1: "FILE_TYPE_JSON",
	2: "FILE_TYPE_JSONPB",
	3: "FILE_TYPE_OTHER",
}

var FileType_value = map[string]int32{
	"FILE_TYPE_UNSPECIFIED": 0,
	"FILE_TYPE_JSON":        1,
	"FILE_TYPE_JSONPB":      2,
	"FILE_TYPE_OTHER":       3,
}

func (x FileType) String() string {
	return proto.EnumName(FileType_name, int32(x))
}

func (FileType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_f9326e1353140a5f, []int{0}
}

type ReplicationType int32

const (
	ReplicationType_REPLICATION_TYPE_UNSPECIFIED ReplicationType = 0
	// Copy the entire file.
	ReplicationType_REPLICATION_TYPE_COPY ReplicationType = 1
	// Copy part of the file. When this type is used, a filtering mechanism must
	// be specified, e.g. a FieldMask. Not valid for some FileTypes, e.g.
	// FILE_TYPE_OTHER.
	ReplicationType_REPLICATION_TYPE_FILTER ReplicationType = 2
)

var ReplicationType_name = map[int32]string{
	0: "REPLICATION_TYPE_UNSPECIFIED",
	1: "REPLICATION_TYPE_COPY",
	2: "REPLICATION_TYPE_FILTER",
}

var ReplicationType_value = map[string]int32{
	"REPLICATION_TYPE_UNSPECIFIED": 0,
	"REPLICATION_TYPE_COPY":        1,
	"REPLICATION_TYPE_FILTER":      2,
}

func (x ReplicationType) String() string {
	return proto.EnumName(ReplicationType_name, int32(x))
}

func (ReplicationType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_f9326e1353140a5f, []int{1}
}

// Describes how to replace a text with another text.
type StringReplacementRule struct {
	// The text before the transformation.
	Before string `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"`
	// The text after the transformation.
	After                string   `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *StringReplacementRule) Reset()         { *m = StringReplacementRule{} }
func (m *StringReplacementRule) String() string { return proto.CompactTextString(m) }
func (*StringReplacementRule) ProtoMessage()    {}
func (*StringReplacementRule) Descriptor() ([]byte, []int) {
	return fileDescriptor_f9326e1353140a5f, []int{0}
}

func (m *StringReplacementRule) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_StringReplacementRule.Unmarshal(m, b)
}
func (m *StringReplacementRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_StringReplacementRule.Marshal(b, m, deterministic)
}
func (m *StringReplacementRule) XXX_Merge(src proto.Message) {
	xxx_messageInfo_StringReplacementRule.Merge(m, src)
}
func (m *StringReplacementRule) XXX_Size() int {
	return xxx_messageInfo_StringReplacementRule.Size(m)
}
func (m *StringReplacementRule) XXX_DiscardUnknown() {
	xxx_messageInfo_StringReplacementRule.DiscardUnknown(m)
}

var xxx_messageInfo_StringReplacementRule proto.InternalMessageInfo

func (m *StringReplacementRule) GetBefore() string {
	if m != nil {
		return m.Before
	}
	return ""
}

func (m *StringReplacementRule) GetAfter() string {
	if m != nil {
		return m.After
	}
	return ""
}

// Describes how a single file should be replicated.
type FileReplicationRule struct {
	// Path to the original file. Should be relative to the source root,
	// e.g. "src/private-overlays/overlay-coral-private/chromeos-base/chromeos-config-bsp-coral-private/files/build_config.json"
	SourcePath string `protobuf:"bytes,1,opt,name=source_path,json=sourcePath,proto3" json:"source_path,omitempty"`
	// Path to output the file. Should be relative to the source root,
	// e.g. "src/overlays/overlay-coral/chromeos-base/chromeos-config-bsp-coral/files/build_config.json"
	DestinationPath string `protobuf:"bytes,2,opt,name=destination_path,json=destinationPath,proto3" json:"destination_path,omitempty"`
	// The type of file being replicated.
	FileType FileType `protobuf:"varint,3,opt,name=file_type,json=fileType,proto3,enum=config.FileType" json:"file_type,omitempty"`
	// The type of replication being done.
	ReplicationType ReplicationType `protobuf:"varint,4,opt,name=replication_type,json=replicationType,proto3,enum=config.ReplicationType" json:"replication_type,omitempty"`
	// Fields to replicate to destination config payloads. Only relevant for
	// REPLICATION_TYPE_FILTER. If set on other replication types a
	// reader of this rule may choose to ignore this field or throw an error.
	//
	// # Behavior Specific to ChromeOS Config Payloads
	//
	// The mask applies to each device config in the config payload, NOT to the
	// top-level payload; i.e. to copy the "audio" field to the destination,
	// the mask should be "audio", not "chromeos.configs.audio". This is
	// analogous to standard FieldMask behavior on a REST list operation, where
	// the mask applies to each individual message. Sub-fields are still
	// fully-qualified, as per standard FieldMasks, e.g.
	// "bluetooth.config.build-path"
	DestinationFields *field_mask.FieldMask `protobuf:"bytes,5,opt,name=destination_fields,json=destinationFields,proto3" json:"destination_fields,omitempty"`
	// String replacements to be done on the destination file. Replacements are
	// done in the order they appear in this list.
	//
	// Note that replacements are done after filtering. For example, say a
	// replacement rule changes the name of a field, "field1" -> "field2"; if
	// destination_fields specifies "field2", the renamed fields will not be
	// copied.
	StringReplacementRules []*StringReplacementRule `protobuf:"bytes,6,rep,name=string_replacement_rules,json=stringReplacementRules,proto3" json:"string_replacement_rules,omitempty"`
	XXX_NoUnkeyedLiteral   struct{}                 `json:"-"`
	XXX_unrecognized       []byte                   `json:"-"`
	XXX_sizecache          int32                    `json:"-"`
}

func (m *FileReplicationRule) Reset()         { *m = FileReplicationRule{} }
func (m *FileReplicationRule) String() string { return proto.CompactTextString(m) }
func (*FileReplicationRule) ProtoMessage()    {}
func (*FileReplicationRule) Descriptor() ([]byte, []int) {
	return fileDescriptor_f9326e1353140a5f, []int{1}
}

func (m *FileReplicationRule) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_FileReplicationRule.Unmarshal(m, b)
}
func (m *FileReplicationRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_FileReplicationRule.Marshal(b, m, deterministic)
}
func (m *FileReplicationRule) XXX_Merge(src proto.Message) {
	xxx_messageInfo_FileReplicationRule.Merge(m, src)
}
func (m *FileReplicationRule) XXX_Size() int {
	return xxx_messageInfo_FileReplicationRule.Size(m)
}
func (m *FileReplicationRule) XXX_DiscardUnknown() {
	xxx_messageInfo_FileReplicationRule.DiscardUnknown(m)
}

var xxx_messageInfo_FileReplicationRule proto.InternalMessageInfo

func (m *FileReplicationRule) GetSourcePath() string {
	if m != nil {
		return m.SourcePath
	}
	return ""
}

func (m *FileReplicationRule) GetDestinationPath() string {
	if m != nil {
		return m.DestinationPath
	}
	return ""
}

func (m *FileReplicationRule) GetFileType() FileType {
	if m != nil {
		return m.FileType
	}
	return FileType_FILE_TYPE_UNSPECIFIED
}

func (m *FileReplicationRule) GetReplicationType() ReplicationType {
	if m != nil {
		return m.ReplicationType
	}
	return ReplicationType_REPLICATION_TYPE_UNSPECIFIED
}

func (m *FileReplicationRule) GetDestinationFields() *field_mask.FieldMask {
	if m != nil {
		return m.DestinationFields
	}
	return nil
}

func (m *FileReplicationRule) GetStringReplacementRules() []*StringReplacementRule {
	if m != nil {
		return m.StringReplacementRules
	}
	return nil
}

// Describes how files should be replicated, e.g. from private to public.
type ReplicationConfig struct {
	// Files to be replicated.
	FileReplicationRules []*FileReplicationRule `protobuf:"bytes,1,rep,name=file_replication_rules,json=fileReplicationRules,proto3" json:"file_replication_rules,omitempty"`
	XXX_NoUnkeyedLiteral struct{}               `json:"-"`
	XXX_unrecognized     []byte                 `json:"-"`
	XXX_sizecache        int32                  `json:"-"`
}

func (m *ReplicationConfig) Reset()         { *m = ReplicationConfig{} }
func (m *ReplicationConfig) String() string { return proto.CompactTextString(m) }
func (*ReplicationConfig) ProtoMessage()    {}
func (*ReplicationConfig) Descriptor() ([]byte, []int) {
	return fileDescriptor_f9326e1353140a5f, []int{2}
}

func (m *ReplicationConfig) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ReplicationConfig.Unmarshal(m, b)
}
func (m *ReplicationConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ReplicationConfig.Marshal(b, m, deterministic)
}
func (m *ReplicationConfig) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ReplicationConfig.Merge(m, src)
}
func (m *ReplicationConfig) XXX_Size() int {
	return xxx_messageInfo_ReplicationConfig.Size(m)
}
func (m *ReplicationConfig) XXX_DiscardUnknown() {
	xxx_messageInfo_ReplicationConfig.DiscardUnknown(m)
}

var xxx_messageInfo_ReplicationConfig proto.InternalMessageInfo

func (m *ReplicationConfig) GetFileReplicationRules() []*FileReplicationRule {
	if m != nil {
		return m.FileReplicationRules
	}
	return nil
}

func init() {
	proto.RegisterEnum("config.FileType", FileType_name, FileType_value)
	proto.RegisterEnum("config.ReplicationType", ReplicationType_name, ReplicationType_value)
	proto.RegisterType((*StringReplacementRule)(nil), "config.StringReplacementRule")
	proto.RegisterType((*FileReplicationRule)(nil), "config.FileReplicationRule")
	proto.RegisterType((*ReplicationConfig)(nil), "config.ReplicationConfig")
}

func init() { proto.RegisterFile("config/replication_config.proto", fileDescriptor_f9326e1353140a5f) }

var fileDescriptor_f9326e1353140a5f = []byte{
	// 455 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x5f, 0x6f, 0xda, 0x3c,
	0x14, 0xc6, 0xdf, 0xc0, 0x5b, 0xd4, 0x1e, 0xa4, 0xe2, 0xba, 0x40, 0xd3, 0x76, 0x53, 0x23, 0xae,
	0x58, 0xa5, 0x05, 0x89, 0x7d, 0x82, 0x95, 0x25, 0x5a, 0x26, 0x06, 0x99, 0xc9, 0x34, 0xf5, 0x2a,
	0x0a, 0x70, 0x4c, 0x23, 0xd2, 0x24, 0xb2, 0xcd, 0x45, 0xbf, 0xf9, 0x2e, 0xa7, 0xda, 0x20, 0xd2,
	0xc2, 0x9d, 0xfd, 0x3b, 0xe7, 0x39, 0x7f, 0x9e, 0x03, 0x77, 0x8b, 0x22, 0xe7, 0xe9, 0x6a, 0x20,
	0xb0, 0xcc, 0xd2, 0x45, 0xa2, 0xd2, 0x22, 0x8f, 0x0d, 0x72, 0x4b, 0x51, 0xa8, 0x82, 0x36, 0xcc,
	0xef, 0xc6, 0x59, 0x15, 0xc5, 0x2a, 0xc3, 0x81, 0xa6, 0xf3, 0x0d, 0x1f, 0xf0, 0x14, 0xb3, 0x65,
	0xfc, 0x9c, 0xc8, 0xb5, 0xc9, 0xec, 0x79, 0xd0, 0x99, 0x29, 0x91, 0xe6, 0x2b, 0x86, 0x65, 0x96,
	0x2c, 0xf0, 0x19, 0x73, 0xc5, 0x36, 0x19, 0xd2, 0x2e, 0x34, 0xe6, 0xc8, 0x0b, 0x81, 0xb6, 0xe5,
	0x58, 0xfd, 0x33, 0xb6, 0xfd, 0xd1, 0x36, 0x9c, 0x24, 0x5c, 0xa1, 0xb0, 0x6b, 0x1a, 0x9b, 0x4f,
	0xef, 0x6f, 0x0d, 0x2e, 0xfd, 0x34, 0x43, 0xb6, 0x9f, 0x48, 0x57, 0xb9, 0x83, 0xa6, 0x2c, 0x36,
	0x62, 0x81, 0x71, 0x99, 0xa8, 0xa7, 0x6d, 0x29, 0x30, 0x28, 0x4c, 0xd4, 0x13, 0xfd, 0x04, 0x64,
	0x89, 0x52, 0xa5, 0xb9, 0xd9, 0x42, 0x67, 0x99, 0xca, 0xad, 0x0a, 0xd7, 0xa9, 0x9f, 0xe1, 0x8c,
	0xa7, 0x19, 0xc6, 0xea, 0xa5, 0x44, 0xbb, 0xee, 0x58, 0xfd, 0xf3, 0x21, 0x71, 0xb7, 0x6b, 0xbf,
	0xf6, 0x8e, 0x5e, 0x4a, 0x64, 0xa7, 0x7c, 0xfb, 0xa2, 0x0f, 0x40, 0xaa, 0xfe, 0x68, 0xd5, 0xff,
	0x5a, 0x75, 0xb5, 0x53, 0x55, 0xa6, 0xd5, 0xe2, 0x96, 0x78, 0x0b, 0x68, 0x00, 0xb4, 0x3a, 0x9d,
	0x76, 0x4f, 0xda, 0x27, 0x8e, 0xd5, 0x6f, 0x0e, 0x6f, 0x5c, 0x63, 0xae, 0xbb, 0x33, 0xd7, 0xf5,
	0x5f, 0xc3, 0x3f, 0x13, 0xb9, 0x66, 0x17, 0x15, 0x95, 0xa6, 0x92, 0xfe, 0x01, 0x5b, 0x6a, 0xa3,
	0x63, 0xb1, 0x77, 0x3a, 0x16, 0x9b, 0x0c, 0xa5, 0xdd, 0x70, 0xea, 0xfd, 0xe6, 0xf0, 0xe3, 0x6e,
	0xac, 0xa3, 0x07, 0x61, 0x5d, 0x79, 0x0c, 0xcb, 0x1e, 0x87, 0x8b, 0xca, 0x1e, 0x23, 0x5d, 0x82,
	0xfe, 0x82, 0xae, 0xf6, 0xaa, 0xea, 0x80, 0xe9, 0x65, 0xe9, 0x5e, 0xb7, 0x55, 0xe3, 0xde, 0x1d,
	0x8d, 0xb5, 0xf9, 0x21, 0x94, 0xf7, 0x4b, 0x38, 0xdd, 0xb9, 0x4c, 0xaf, 0xa1, 0xe3, 0x07, 0x63,
	0x2f, 0x8e, 0x1e, 0x43, 0x2f, 0xfe, 0x3d, 0x99, 0x85, 0xde, 0x28, 0xf0, 0x03, 0xef, 0x1b, 0xf9,
	0x8f, 0x52, 0x38, 0xdf, 0x87, 0x7e, 0xcc, 0xa6, 0x13, 0x62, 0xd1, 0x36, 0x90, 0xb7, 0x2c, 0x7c,
	0x20, 0x35, 0x7a, 0x09, 0xad, 0x3d, 0x9d, 0x46, 0xdf, 0x3d, 0x46, 0xea, 0xf7, 0x6b, 0x68, 0xbd,
	0xbb, 0x0a, 0x75, 0xe0, 0x03, 0xf3, 0xc2, 0x71, 0x30, 0xfa, 0x1a, 0x05, 0xd3, 0xc9, 0xb1, 0x9e,
	0xd7, 0xd0, 0x39, 0xc8, 0x18, 0x4d, 0xc3, 0x47, 0x62, 0xd1, 0x5b, 0xb8, 0x3a, 0x08, 0xf9, 0xc1,
	0x38, 0xf2, 0x18, 0xa9, 0xcd, 0x1b, 0xfa, 0x74, 0x5f, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0e,
	0xb7, 0xb1, 0x2d, 0x50, 0x03, 0x00, 0x00,
}
