// Copyright 2020 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: test/custom_results/graphics/software_config_id.proto

package graphics

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

// Uniquely identifies a software configuration.
type SoftwareConfigId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}

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

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

func (*SoftwareConfigId) ProtoMessage() {}

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

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

var File_test_custom_results_graphics_software_config_id_proto protoreflect.FileDescriptor

var file_test_custom_results_graphics_software_config_id_proto_rawDesc = []byte{
	0x0a, 0x35, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72, 0x65,
	0x73, 0x75, 0x6c, 0x74, 0x73, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2f, 0x73,
	0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69,
	0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75,
	0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x67, 0x72, 0x61,
	0x70, 0x68, 0x69, 0x63, 0x73, 0x22, 0x28, 0x0a, 0x10, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72,
	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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,
	0x48, 0x5a, 0x46, 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, 0x74, 0x65, 0x73,
	0x74, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73,
	0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x33,
}

var (
	file_test_custom_results_graphics_software_config_id_proto_rawDescOnce sync.Once
	file_test_custom_results_graphics_software_config_id_proto_rawDescData = file_test_custom_results_graphics_software_config_id_proto_rawDesc
)

func file_test_custom_results_graphics_software_config_id_proto_rawDescGZIP() []byte {
	file_test_custom_results_graphics_software_config_id_proto_rawDescOnce.Do(func() {
		file_test_custom_results_graphics_software_config_id_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_custom_results_graphics_software_config_id_proto_rawDescData)
	})
	return file_test_custom_results_graphics_software_config_id_proto_rawDescData
}

var file_test_custom_results_graphics_software_config_id_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_test_custom_results_graphics_software_config_id_proto_goTypes = []interface{}{
	(*SoftwareConfigId)(nil), // 0: test.custom_results.graphics.SoftwareConfigId
}
var file_test_custom_results_graphics_software_config_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_test_custom_results_graphics_software_config_id_proto_init() }
func file_test_custom_results_graphics_software_config_id_proto_init() {
	if File_test_custom_results_graphics_software_config_id_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_test_custom_results_graphics_software_config_id_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*SoftwareConfigId); 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_test_custom_results_graphics_software_config_id_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_test_custom_results_graphics_software_config_id_proto_goTypes,
		DependencyIndexes: file_test_custom_results_graphics_software_config_id_proto_depIdxs,
		MessageInfos:      file_test_custom_results_graphics_software_config_id_proto_msgTypes,
	}.Build()
	File_test_custom_results_graphics_software_config_id_proto = out.File
	file_test_custom_results_graphics_software_config_id_proto_rawDesc = nil
	file_test_custom_results_graphics_software_config_id_proto_goTypes = nil
	file_test_custom_results_graphics_software_config_id_proto_depIdxs = nil
}
