func (b *Basic) Source() scanner.Type {
	return b.Src
}
Source returns the scanner source type for a given protobuf basic type
package protobuf  
import (
	"fmt"
	"path/filepath"
	"sort"
	"strings"
	"gopkg.in/src-d/proteus.v1/scanner"
)
type Package struct {
	Name     string
	Path     string
	Imports  []string
	Options  Options
	Messages []*Message
	Enums    []*Enum
	RPCs     []*RPC
}
func (p *Package) Import(typ *ProtoType) {
	if typ.Import != "" && !p.isImported(typ.Import) {
		p.Imports = append(p.Imports, typ.Import)
	}
}
func (p *Package) ImportFromPath(path string) {
	file := filepath.Join(path, "generated.proto")
	if path != p.Path && !p.isImported(file) {
		p.Imports = append(p.Imports, filepath.Join(path, "generated.proto"))
	}
}
func (p *Package) isImported(file string) bool {
	for _, i := range p.Imports {
		if i == file {
			return true
		}
	}
	return false
}
func (p *Package) ServiceName() string {
	parts := strings.Split(p.Name, ".")
	last := parts[len(parts)-1]
	return strings.ToUpper(string(last[0])) + last[1:] + "Service"
}
type Message struct {
	Docs     []string
	Name     string
	Reserved []uint
	Options  Options
	Fields   []*Field
}
func (m *Message) Reserve(pos uint) {
	if !m.isReserved(pos) {
		m.Reserved = append(m.Reserved, pos)
	}
}
func (m *Message) isReserved(pos uint) bool {
	for _, r := range m.Reserved {
		if r == pos {
			return true
		}
	}
	return false
}
type Field struct {
	Docs     []string
	Name     string
	Pos      int
	Repeated bool
	Type     Type
	Options  Options
}
type Options map[string]OptionValue
type Option struct {
	Name  string
	Value OptionValue
}
func (o Options) Sorted() []*Option {
	var names = make([]string, 0, len(o))
	for k := range o {
		names = append(names, k)
	}
	sort.Stable(sort.StringSlice(names))
	var opts = make([]*Option, len(o))
	for i, n := range names {
		opts[i] = &Option{Name: n, Value: o[n]}
	}
	return opts
}
type OptionValue interface {
	fmt.Stringer
	isOptionValue()
}
type LiteralValue struct {
	val string
}
func NewLiteralValue(val string) LiteralValue {
	return LiteralValue{val}
}
func (LiteralValue) isOptionValue() {}
func (v LiteralValue) String() string {
	return v.val
}
type StringValue struct {
	val string
}
func NewStringValue(val string) StringValue {
	return StringValue{val}
}
func (StringValue) isOptionValue() {}
func (v StringValue) String() string {
	return fmt.Sprintf("%q", v.val)
}
type Type interface {
	fmt.Stringer
	isType()
	SetSource(scanner.Type)
	Source() scanner.Type
	IsNullable() bool
}
type Named struct {
	Package string
	Name    string
	Generated bool
	Src       scanner.Type
}
func NewNamed(pkg, name string) *Named {
	return &Named{pkg, name, false, nil}
}
func NewGeneratedNamed(pkg, name string) *Named {
	return &Named{pkg, name, true, nil}
}
func (n Named) String() string {
	return fmt.Sprintf("%s.%s", n.Package, n.Name)
}
func (n *Named) SetSource(t scanner.Type) {
	n.Src = t
}
func (n *Named) Source() scanner.Type {
	return n.Src
}
func (n *Named) IsNullable() bool {
	if src := n.Source(); src != nil {
		return src.IsNullable()
	}
	return true  
}
type Alias struct {
	Type       Type
	Underlying Type
	Src        scanner.Type
}
func NewAlias(typ, underlying Type) *Alias {
	return &Alias{
		Type:       typ,
		Underlying: underlying,
	}
}
func (a *Alias) SetSource(t scanner.Type) {
	a.Src = t
}
func (a *Alias) Source() scanner.Type {
	return a.Src
}
func (a Alias) String() string {
	return a.Underlying.String()
}
func (a Alias) IsNullable() bool {
	if src := a.Source(); src != nil {
		return src.IsNullable()
	}
	return a.Type.IsNullable()
}
type Basic struct {
	Name string
	Src  scanner.Type
}
func NewBasic(name string) *Basic {
	b := Basic{Name: name}
	return &b
}
func (b Basic) String() string {
	return b.Name
}
func (b *Basic) SetSource(t scanner.Type) {
	b.Src = t
}