// 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/model_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)
)

// Globally unique identifier.
type ModelId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Required. Source: 'mosys platform model'.
	Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}

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

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

func (*ModelId) ProtoMessage() {}

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

func (x *ModelId) GetValue() string {
	if x != nil {
		return x.Value
	}
	return ""
}

var File_device_model_id_proto protoreflect.FileDescriptor

var file_device_model_id_proto_rawDesc = []byte{
	0x0a, 0x15, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69,
	0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22,
	0x1f, 0x0a, 0x07, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
	0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
	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_model_id_proto_rawDescOnce sync.Once
	file_device_model_id_proto_rawDescData = file_device_model_id_proto_rawDesc
)

func file_device_model_id_proto_rawDescGZIP() []byte {
	file_device_model_id_proto_rawDescOnce.Do(func() {
		file_device_model_id_proto_rawDescData = protoimpl.X.CompressGZIP(file_device_model_id_proto_rawDescData)
	})
	return file_device_model_id_proto_rawDescData
}

var file_device_model_id_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_device_model_id_proto_goTypes = []interface{}{
	(*ModelId)(nil), // 0: device.ModelId
}
var file_device_model_id_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_device_model_id_proto_init() }
func file_device_model_id_proto_init() {
	if File_device_model_id_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_device_model_id_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ModelId); 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_model_id_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_device_model_id_proto_goTypes,
		DependencyIndexes: file_device_model_id_proto_depIdxs,
		MessageInfos:      file_device_model_id_proto_msgTypes,
	}.Build()
	File_device_model_id_proto = out.File
	file_device_model_id_proto_rawDesc = nil
	file_device_model_id_proto_goTypes = nil
	file_device_model_id_proto_depIdxs = nil
}
