// Code generated by protoc-gen-go. DO NOT EDIT.
// source: recipes/example.proto

package recipes

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package

type Example struct {
	FieldA               *Example_FieldA `protobuf:"bytes,1,opt,name=field_a,json=fieldA,proto3" json:"field_a,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

func (m *Example) Reset()         { *m = Example{} }
func (m *Example) String() string { return proto.CompactTextString(m) }
func (*Example) ProtoMessage()    {}
func (*Example) Descriptor() ([]byte, []int) {
	return fileDescriptor_a131720fbcb681f7, []int{0}
}
func (m *Example) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Example.Unmarshal(m, b)
}
func (m *Example) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Example.Marshal(b, m, deterministic)
}
func (dst *Example) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Example.Merge(dst, src)
}
func (m *Example) XXX_Size() int {
	return xxx_messageInfo_Example.Size(m)
}
func (m *Example) XXX_DiscardUnknown() {
	xxx_messageInfo_Example.DiscardUnknown(m)
}

var xxx_messageInfo_Example proto.InternalMessageInfo

func (m *Example) GetFieldA() *Example_FieldA {
	if m != nil {
		return m.FieldA
	}
	return nil
}

type Example_FieldA struct {
	Value                int64    `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *Example_FieldA) Reset()         { *m = Example_FieldA{} }
func (m *Example_FieldA) String() string { return proto.CompactTextString(m) }
func (*Example_FieldA) ProtoMessage()    {}
func (*Example_FieldA) Descriptor() ([]byte, []int) {
	return fileDescriptor_a131720fbcb681f7, []int{0, 0}
}
func (m *Example_FieldA) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Example_FieldA.Unmarshal(m, b)
}
func (m *Example_FieldA) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Example_FieldA.Marshal(b, m, deterministic)
}
func (dst *Example_FieldA) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Example_FieldA.Merge(dst, src)
}
func (m *Example_FieldA) XXX_Size() int {
	return xxx_messageInfo_Example_FieldA.Size(m)
}
func (m *Example_FieldA) XXX_DiscardUnknown() {
	xxx_messageInfo_Example_FieldA.DiscardUnknown(m)
}

var xxx_messageInfo_Example_FieldA proto.InternalMessageInfo

func (m *Example_FieldA) GetValue() int64 {
	if m != nil {
		return m.Value
	}
	return 0
}

func init() {
	proto.RegisterType((*Example)(nil), "recipes.example.Example")
	proto.RegisterType((*Example_FieldA)(nil), "recipes.example.Example.FieldA")
}

func init() { proto.RegisterFile("recipes/example.proto", fileDescriptor_a131720fbcb681f7) }

var fileDescriptor_a131720fbcb681f7 = []byte{
	// 128 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2d, 0x4a, 0x4d, 0xce,
	0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xad, 0x48, 0xcc, 0x2d, 0xc8, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f,
	0xc9, 0x17, 0xe2, 0x87, 0x0a, 0xeb, 0x41, 0x85, 0x95, 0x92, 0xb9, 0xd8, 0x5d, 0x21, 0x4c, 0x21,
	0x0b, 0x2e, 0xf6, 0xb4, 0xcc, 0xd4, 0x9c, 0x94, 0xf8, 0x44, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e,
	0x23, 0x79, 0x3d, 0x34, 0xd5, 0x7a, 0x50, 0xa5, 0x7a, 0x6e, 0x20, 0x75, 0x8e, 0x41, 0x6c, 0x60,
	0xf5, 0x8e, 0x52, 0x72, 0x5c, 0x6c, 0x10, 0x11, 0x21, 0x11, 0x2e, 0xd6, 0xb2, 0xc4, 0x9c, 0xd2,
	0x54, 0xb0, 0x09, 0xcc, 0x41, 0x10, 0x8e, 0x13, 0x67, 0x14, 0x3b, 0xd4, 0xa4, 0x24, 0x36, 0xb0,
	0x3b, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x20, 0x5f, 0x15, 0xa0, 0x00, 0x00, 0x00,
}
