func (c *CompleteItem) Icase() bool {
	return c.completeItems.Icase() != byte(0)
}
Icase return the more information about the item, can be displayed in a preview window.
package symbol
import (
	"path/filepath"
	"reflect"
	"time"
	"github.com/go-clang/v3.9/clang"
	flatbuffers "github.com/google/flatbuffers/go"
	"github.com/zchee/clang-server/internal/symbol"
)
type File struct {
	name            string
	flags           []string
	translationUnit []byte
	locations       map[Location]ID
	symbols         map[ID]*Info
	headers         []*Header
	builder *flatbuffers.Builder
	file *symbol.File
}
type SymbolFile = symbol.File
func NewFile(name string, flags []string) *File {
	return &File{
		name:      name,
		flags:     flags,
		locations: make(map[Location]ID),
		symbols:   make(map[ID]*Info),
		builder:   flatbuffers.NewBuilder(0),
	}
}
func GetRootAsFile(buf []byte, offset flatbuffers.UOffsetT) *File {
	return &File{
		file: symbol.GetRootAsFile(buf, offset),
	}
}
func (f *File) Name() string {
	if f.name != "" {
		return f.name
	}
	return string(f.file.Name())
}
func (f *File) Flags() []string {
	if len(f.flags) > 0 {
		return f.flags
	}
	n := f.file.FlagsLength()
	flags := make([]string, n)
	for i := 0; i < n; i++ {
		flags[i] = string(f.file.Flags(i))
	}
	return flags
}
func (f *File) TranslationUnit() []byte {
	if len(f.translationUnit) > 0 {
		return f.translationUnit
	}
	return f.file.TranslationUnit()
}
func (f *File) Symbols() []*Info {
	if len(f.symbols) > 0 {
		symbols := make([]*Info, len(f.symbols))
		for _, v := range f.symbols {
			symbols = append(symbols, v)
		}
		return symbols
	}
	n := f.file.SymbolsLength()
	symbols := make([]*Info, n)
	for i := 0; i < n; i++ {
		obj := new(symbol.Info)
		if f.file.Symbols(obj, i) {
			symbols[i] = &Info{info: obj}
		}
	}
	return symbols
}
func (f *File) Headers() []*Header {
	if len(f.headers) > 0 {
		return f.headers
	}
	n := f.file.HeadersLength()
	headers := make([]*Header, n)
	for i := 0; i < n; i++ {
		obj := new(symbol.Header)
		if f.file.Headers(obj, i) {
			headers[i] = &Header{header: obj}
		}
	}
	return headers
}
func (f *File) AddTranslationUnit(buf []byte) {
	f.translationUnit = buf
}
func (f *File) addSymbol(loc, def Location) {
	id := ToID(loc.usr)
	sym, ok := f.symbols[id]
	if !ok {
		sym = &Info{id: id}
	}
	sym.decls = append(sym.decls, loc)
	if def.isExist() {
		sym.def = def
	}
	f.locations[loc] = id
	f.symbols[id] = sym
}
func (f *File) AddDecl(loc Location) {
	f.addSymbol(loc, Location{})
}
func (f *File) AddDefinition(loc, def Location) {
	f.addSymbol(loc, def)
}
func notExistHeaderName(headPath string) string {
	return "IDoNotReallyExist-" + filepath.Base(headPath)
}
func (f *File) AddHeader(includePath string, headerFile clang.File) {
	hdr := new(Header)
	if headerFile.Name() == "" {
		hdr.fileid = ToFileID(notExistHeaderName(filepath.Clean(headerFile.Name())))
		hdr.mtime = time.Now()
	} else {
		hdr.fileid = ToFileID(filepath.Clean(headerFile.Name()))
		hdr.mtime = headerFile.Time()
	}
	f.headers = append(f.headers, hdr)
}
func (f *File) AddCaller(sym, def Location, funcCall bool) {
	id := ToID(sym.usr)
	syms, ok := f.symbols[id]
	if !ok {
		syms = &Info{id: id}
	}
	syms.callers = append(syms.callers, &Caller{
		location: sym,
		funcCall: funcCall,
	})
	f.symbols[id] = syms
}
func (f *File) Unmarshal() {
	f.name = string(f.file.Name())
	f.translationUnit = f.file.TranslationUnit()
	f.symbols = make(map[ID]*Info)
	for _, s := range f.Symbols() {
		f.symbols[s.ID()] = &Info{
			id:      s.ID(),
			decls:   s.Decls(),
			def:     s.Def(),
			callers: s.Callers(),
			info:    s.info,
		}
	}
	headers := f.Headers()
	f.headers = make([]*Header, len(headers))
	for _, hdr := range headers {
		f.headers = append(f.headers, hdr)
	}
}
func (f *File) Serialize() *flatbuffers.Builder {
	if f.builder == nil {
		f.builder = flatbuffers.NewBuilder(0)
	}
	fname := f.builder.CreateString(f.Name())
	tu := f.builder.CreateByteString(f.TranslationUnit())
	flagNum := len(f.flags)
	flagOffsets := make([]flatbuffers.UOffsetT, 0, flagNum)
	for _, flag := range f.flags {
		flagOffsets = append(flagOffsets, f.builder.CreateString(flag))
	}
	symbol.FileStartFlagsVector(f.builder, flagNum)
	for i := flagNum - 1; i >= 0; i-- {
		f.builder.PrependUOffsetT(flagOffsets[i])
	}
	flagVecOffset := f.builder.EndVector(flagNum)
	symbols := f.symbols
	symbolNum := len(symbols)
	symbolOffsets := make([]flatbuffers.UOffsetT, 0, symbolNum)
	for _, info := range symbols {
		symbolOffsets = append(symbolOffsets, info.serialize(f.builder))
	}
	symbol.FileStartSymbolsVector(f.builder, symbolNum)
	for i := symbolNum - 1; i >= 0; i-- {
		f.builder.PrependUOffsetT(symbolOffsets[i])
	}
	symbolVecOffset := f.builder.EndVector(symbolNum)
	hdrs := f.headers
	hdrNum := len(hdrs)
	hdrOffsets := make([]flatbuffers.UOffsetT, 0, hdrNum)
	for _, hdr := range hdrs {
		hdrOffsets = append(hdrOffsets, hdr.serialize(f.builder))
	}
	symbol.FileStartHeadersVector(f.builder, hdrNum)
	for i := hdrNum - 1; i >= 0; i-- {
		f.builder.PrependUOffsetT(hdrOffsets[i])
	}
	headerVecOffset := f.builder.EndVector(hdrNum)
	symbol.FileStart(f.builder)
	symbol.FileAddName(f.builder, fname)
	symbol.FileAddFlags(f.builder, flagVecOffset)
	symbol.FileAddTranslationUnit(f.builder, tu)
	symbol.FileAddSymbols(f.builder, symbolVecOffset)
	symbol.FileAddHeaders(f.builder, headerVecOffset)
	f.builder.Finish(symbol.FileEnd(f.builder))
	return f.builder
}
type Info struct {
	id      ID
	decls   []Location
	def     Location
	callers []*Caller
	info *symbol.Info
}
type SymbolInfo = symbol.Info
func (info *Info) serialize(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
	id := builder.CreateString(info.id.String())
	declsNum := len(info.decls)
	var declVecOffset flatbuffers.UOffsetT
	if declsNum > 0 {
		declsOffsets := make([]flatbuffers.UOffsetT, 0, declsNum)
		for _, decl := range info.decls {
			declsOffsets = append(declsOffsets, decl.serialize(builder))
		}
		symbol.InfoStartDeclsVector(builder, declsNum)
		for i := declsNum - 1; i >= 0; i-- {
			builder.PrependUOffsetT(declsOffsets[i])
		}
		declVecOffset = builder.EndVector(declsNum)
	}
	defOffset := info.def.serialize(builder)
	callersNum := len(info.callers)
	var callerVecOffset flatbuffers.UOffsetT
	if callersNum > 0 {
		callersOffsets := make([]flatbuffers.UOffsetT, 0, callersNum)
		for _, caller := range info.callers {
			callersOffsets = append(callersOffsets, caller.serialize(builder))
		}
		symbol.InfoStartCallersVector(builder, callersNum)
		for i := callersNum - 1; i >= 0; i-- {
			builder.PrependUOffsetT(callersOffsets[i])
		}
		callerVecOffset = builder.EndVector(callersNum)
	}
	symbol.InfoStart(builder)
	symbol.InfoAddID(builder, id)
	symbol.InfoAddDecls(builder, declVecOffset)
	symbol.InfoAddDef(builder, defOffset)
	symbol.InfoAddCallers(builder, callerVecOffset)
	return symbol.InfoEnd(builder)
}
func (info *Info) ID() ID {
	return ToID(string(info.info.ID()))
}
func (info *Info) Decls() []Location {
	n := info.info.DeclsLength()
	decls := make([]Location, n)
	for i := 0; i < n; i++ {
		obj := new(symbol.Location)
		if info.info.Decls(obj, i) {
			decls[i] = Location{location: obj}
		}
	}
	return decls
}
func (info *Info) Def() Location {
	obj := new(symbol.Location)
	info.info.Def(obj)
	return Location{location: obj}
}
func (info *Info) Callers() []*Caller {
	n := info.info.CallersLength()
	callers := make([]*Caller, n)
	for i := 0; i < n; i++ {
		obj := new(symbol.Caller)
		if info.info.Callers(obj, i) {
			callers[i] = &Caller{caller: obj}
		}
	}
	return callers
}
type Header struct {
	fileid FileID
	mtime  time.Time
	header *symbol.Header
}
type SymbolHeader = symbol.Header
func (h *Header) FileID() FileID {
	return ToFileID(string(h.header.FileID()))
}
func (h *Header) Mtime() int64 {
	return h.header.Mtime()
}
func (h *Header) serialize(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
	fid := builder.CreateString(h.fileid.String())
	symbol.HeaderStart(builder)
	symbol.HeaderAddFileID(builder, fid)
	symbol.HeaderAddMtime(builder, h.mtime.Unix())
	return symbol.HeaderEnd(builder)
}
type Caller struct {
	location Location
	funcCall bool
	caller *symbol.Caller
}
type SymbolCaller = symbol.Caller
func (c *Caller) Location() Location {
	obj := new(symbol.Location)
	c.caller.Location(obj)
	return Location{location: obj}
}
func (c *Caller) FuncCall() bool {
	return c.caller.FuncCall() != 0
}
func (c *Caller) serialize(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
	locOffset := c.location.serialize(builder)
	symbol.CallerStart(builder)
	symbol.CallerAddLocation(builder, locOffset)
	funcCall := byte(0)
	if c.funcCall {
		funcCall = byte(1)
	}
	symbol.CallerAddFuncCall(builder, funcCall)
	return symbol.CallerEnd(builder)
}
type Location struct {
	fileName string
	line     uint32
	col      uint32
	offset   uint32
	usr      string
	location *symbol.Location
}
type SymbolLocation = symbol.Location
func (l *Location) FileName() string {
	if l.location == nil {
		return l.fileName
	}
	return string(l.location.FileName())
}
func (l *Location) Line() uint32 {
	return l.location.Line()
}
func (l *Location) Col() uint32 {
	return l.location.Col()
}
func (l *Location) Offset() uint32 {
	return l.location.Offset()
}
func (l *Location) USR() string {
	if l.location == nil {
		return l.usr
	}
	return string(l.location.USR())
}
func (l *Location) serialize(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
	fname := builder.CreateString(l.fileName)
	usr := builder.CreateString(l.usr)
	symbol.LocationStart(builder)
	symbol.LocationAddFileName(builder, fname)
	symbol.LocationAddLine(builder, l.line)
	symbol.LocationAddCol(builder, l.col)
	symbol.LocationAddOffset(builder, l.offset)
	symbol.LocationAddUSR(builder, usr)
	return symbol.LocationEnd(builder)
}
func (l *Location) isExist() bool {
	return !reflect.DeepEqual(l, Location{})
}
func CreateLocation(filename string, line, col uint32) *flatbuffers.Builder {
	l := Location{
		fileName: filename,
		line:     line,
		col:      col,
	}
	builder := flatbuffers.NewBuilder(0)
	fname := builder.CreateString(l.fileName)
	symbol.LocationStart(builder)
	symbol.LocationAddFileName(builder, fname)
	symbol.LocationAddLine(builder, l.line)
	symbol.LocationAddCol(builder, l.col)
	builder.Finish(symbol.LocationEnd(builder))
	return builder
}
type CompleteItem struct {
	word  string
	abbr  string
	menu  string
	info  string
	kind  string
	icase bool
	dup   bool
	completeItems *symbol.CompleteItem
}
type SymbolCompleteItem = symbol.CompleteItem
func (c *CompleteItem) Word() string {
	return string(c.completeItems.Word())
}
func (c *CompleteItem) Abbr() string {
	return string(c.completeItems.Abbr())
}
func (c *CompleteItem) Menu() string {
	return string(c.completeItems.Menu())
}
func (c *CompleteItem) Info() string {
	return string(c.completeItems.Info())
}
func (c *CompleteItem) Kind() string {
	return string(c.completeItems.Kind())
}