// Copyright 2019 The Chromium OS 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.
// versions:
// 	protoc-gen-go v1.25.0-devel
// 	protoc        v3.6.1
// source: device/config_id.proto

package device

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// These are the globally unique identifiers that determine what set of
// configuration data is used for a given device.
type ConfigId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Required.
	PlatformId *PlatformId `protobuf:"bytes,1,opt,name=platform_id,json=platformId,proto3" json:"platform_id,omitempty"`
	// Required.
	ModelId *ModelId `protobuf:"bytes,2,opt,name=model_id,json=modelId,proto3" json:"model_id,omitempty"`
	// Required.
	VariantId *VariantId `protobuf:"bytes,3,opt,name=variant_id,json=variantId,proto3" json:"variant_id,omitempty"`
	// Required.
	BrandId *BrandId `protobuf:"bytes,4,opt,name=brand_id,json=brandId,proto3" json:"brand_id,omitempty"`
}

func (x *ConfigId) Reset() {
	*x = ConfigId{}
	if protoimpl.UnsafeEnabled {
		mi := &file_device_config_id_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ConfigId) ProtoMessage() {}

func (x *ConfigId) ProtoReflect() protoreflect.Message {
	mi := &file_device_config_id_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 ConfigId.ProtoReflect.Descriptor instead.
func (*ConfigId) Descriptor() ([]byte, []int) {
	return file_device_config_id_proto_rawDescGZIP(), []int{0}
}

func (x *ConfigId) GetPlatformId() *PlatformId {
	if x != nil {
		return x.PlatformId
	}
	return nil
}

func (x *ConfigId) GetModelId() *ModelId {
	if x != nil {
		return x.ModelId
	}
	return nil
}

func (x *ConfigId) GetVariantId() *VariantId {
	if x != nil {
		return x.VariantId
	}
	return nil
}

func (x *ConfigId) GetBrandId() *BrandId {
	if x != nil {
		return x.BrandId
	}
	return nil
}

var File_device_config_id_proto protoreflect.FileDescriptor

var file_device_config_id_proto_rawDesc = []byte{
	0x0a, 0x16, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
	0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
	0x1a, 0x18, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
	0x6d, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x64, 0x65, 0x76, 0x69,
	0x63, 0x65, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74,
	0x6f, 0x1a, 0x15, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x5f,
	0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
	0x2f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74,
	0x6f, 0x22, 0xc9, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x33,
	0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
	0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x6c, 0x61,
	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x64, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
	0x6d, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18,
	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d,
	0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12,
	0x30, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20,
	0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x61, 0x72,
	0x69, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x49,
	0x64, 0x12, 0x2a, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20,
	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x72, 0x61,
	0x6e, 0x64, 0x49, 0x64, 0x52, 0x07, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x42, 0x32, 0x5a,
	0x30, 0x67, 0x6f, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2e, 0x6f, 0x72, 0x67,
	0x2f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x69, 0x6e, 0x66, 0x72,
	0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63,
	0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_device_config_id_proto_rawDescOnce sync.Once
	file_device_config_id_proto_rawDescData = file_device_config_id_proto_rawDesc
)

func file_device_config_id_proto_rawDescGZIP() []byte {
	file_device_config_id_proto_rawDescOnce.Do(func() {
		file_device_config_id_proto_rawDescData = protoimpl.X.CompressGZIP(file_device_config_id_proto_rawDescData)
	})
	return file_device_config_id_proto_rawDescData
}

var file_device_config_id_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_device_config_id_proto_goTypes = []interface{}{
	(*ConfigId)(nil),   // 0: device.ConfigId
	(*PlatformId)(nil), // 1: device.PlatformId
	(*ModelId)(nil),    // 2: device.ModelId
	(*VariantId)(nil),  // 3: device.VariantId
	(*BrandId)(nil),    // 4: device.BrandId
}
var file_device_config_id_proto_depIdxs = []int32{
	1, // 0: device.ConfigId.platform_id:type_name -> device.PlatformId
	2, // 1: device.ConfigId.model_id:type_name -> device.ModelId
	3, // 2: device.ConfigId.variant_id:type_name -> device.VariantId
	4, // 3: device.ConfigId.brand_id:type_name -> device.BrandId
	4, // [4:4] is the sub-list for method output_type
	4, // [4:4] is the sub-list for method input_type
	4, // [4:4] is the sub-list for extension type_name
	4, // [4:4] is the sub-list for extension extendee
	0, // [0:4] is the sub-list for field type_name
}

func init() { file_device_config_id_proto_init() }
func file_device_config_id_proto_init() {
	if File_device_config_id_proto != nil {
		return
	}
	file_device_platform_id_proto_init()
	file_device_model_id_proto_init()
	file_device_brand_id_proto_init()
	file_device_variant_id_proto_init()
	if !protoimpl.UnsafeEnabled {
		file_device_config_id_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ConfigId); 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_device_config_id_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_device_config_id_proto_goTypes,
		DependencyIndexes: file_device_config_id_proto_depIdxs,
		MessageInfos:      file_device_config_id_proto_msgTypes,
	}.Build()
	File_device_config_id_proto = out.File
	file_device_config_id_proto_rawDesc = nil
	file_device_config_id_proto_goTypes = nil
	file_device_config_id_proto_depIdxs = nil
}
