/*
 * Copyright 2017-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Code generated by protoc-gen-go.
// source: meta.proto
// DO NOT EDIT!

/*
Package voltha is a generated protocol buffer package.

It is generated from these files:
	meta.proto

It has these top-level messages:
	ChildNode
*/
package meta

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"

// 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.ProtoPackageIsVersion2 // please upgrade the proto package

type Access int32

const (
	// read-write, stored attribute
	Access_CONFIG Access = 0
	// read-only field, stored with the model, covered by its hash
	Access_READ_ONLY Access = 1
	// A read-only attribute that is not stored in the model, not covered
	// by its hash, its value is filled real-time upon each request.
	Access_REAL_TIME Access = 2
)

var Access_name = map[int32]string{
	0: "CONFIG",
	1: "READ_ONLY",
	2: "REAL_TIME",
}
var Access_value = map[string]int32{
	"CONFIG":    0,
	"READ_ONLY": 1,
	"REAL_TIME": 2,
}

func (x Access) String() string {
	return proto.EnumName(Access_name, int32(x))
}
func (Access) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

type ChildNode struct {
	Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"`
}

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

func (m *ChildNode) GetKey() string {
	if m != nil {
		return m.Key
	}
	return ""
}

var E_ChildNode = &proto.ExtensionDesc{
	ExtendedType:  (*google_protobuf.FieldOptions)(nil),
	ExtensionType: (*ChildNode)(nil),
	Field:         7761772,
	Name:          "voltha.child_node",
	Tag:           "bytes,7761772,opt,name=child_node,json=childNode",
	Filename:      "meta.proto",
}

var E_Access = &proto.ExtensionDesc{
	ExtendedType:  (*google_protobuf.FieldOptions)(nil),
	ExtensionType: (*Access)(nil),
	Field:         7761773,
	Name:          "voltha.access",
	Tag:           "varint,7761773,opt,name=access,enum=voltha.Access",
	Filename:      "meta.proto",
}

func init() {
	proto.RegisterType((*ChildNode)(nil), "voltha.ChildNode")
	proto.RegisterEnum("voltha.Access", Access_name, Access_value)
	proto.RegisterExtension(E_ChildNode)
	proto.RegisterExtension(E_Access)
}

func init() { proto.RegisterFile("meta.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
	// 229 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xca, 0x4d, 0x2d, 0x49,
	0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0xcb, 0xcf, 0x29, 0xc9, 0x48, 0x94, 0x52,
	0x48, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x07, 0x8b, 0x26, 0x95, 0xa6, 0xe9, 0xa7, 0xa4, 0x16,
	0x27, 0x17, 0x65, 0x16, 0x94, 0xe4, 0x17, 0x41, 0x54, 0x2a, 0xc9, 0x72, 0x71, 0x3a, 0x67, 0x64,
	0xe6, 0xa4, 0xf8, 0xe5, 0xa7, 0xa4, 0x0a, 0x09, 0x70, 0x31, 0x67, 0xa7, 0x56, 0x4a, 0x30, 0x2a,
	0x30, 0x6a, 0x70, 0x06, 0x81, 0x98, 0x5a, 0x46, 0x5c, 0x6c, 0x8e, 0xc9, 0xc9, 0xa9, 0xc5, 0xc5,
	0x42, 0x5c, 0x5c, 0x6c, 0xce, 0xfe, 0x7e, 0x6e, 0x9e, 0xee, 0x02, 0x0c, 0x42, 0xbc, 0x5c, 0x9c,
	0x41, 0xae, 0x8e, 0x2e, 0xf1, 0xfe, 0x7e, 0x3e, 0x91, 0x02, 0x8c, 0x50, 0xae, 0x4f, 0x7c, 0x88,
	0xa7, 0xaf, 0xab, 0x00, 0x93, 0x55, 0x10, 0x17, 0x57, 0x32, 0xc8, 0xc8, 0xf8, 0x3c, 0x90, 0x99,
	0xb2, 0x7a, 0x10, 0x37, 0xe8, 0xc1, 0xdc, 0xa0, 0xe7, 0x96, 0x99, 0x9a, 0x93, 0xe2, 0x5f, 0x50,
	0x92, 0x99, 0x9f, 0x57, 0x2c, 0xf1, 0xe6, 0xde, 0x4d, 0x66, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x41,
	0x3d, 0x88, 0x9b, 0xf5, 0xe0, 0xce, 0x09, 0xe2, 0x4c, 0x86, 0x31, 0xad, 0x3c, 0xb8, 0xd8, 0x12,
	0x21, 0xee, 0x20, 0x60, 0xde, 0x5b, 0x88, 0x79, 0x7c, 0x46, 0x7c, 0x30, 0xf3, 0x20, 0xee, 0x0f,
	0x82, 0xea, 0x4f, 0x62, 0x03, 0xeb, 0x33, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x55, 0xcc, 0xf1,
	0x90, 0x2f, 0x01, 0x00, 0x00,
}
