func (self *TypeSheet) Parse(localFD *model.FileDescriptor, globalFD *model.FileDescriptor) bool { var root typeModelRoot if !self.ParseTable(&root) { goto ErrorStop } if !root.ParsePragma(localFD) { self.Row = TypeSheetRow_Pragma self.Column = 0 log.Errorf("%s", i18n.String(i18n.TypeSheet_PackageIsEmpty)) goto ErrorStop } if !root.ParseData(localFD, globalFD) { self.Row = root.Row self.Column = root.Col goto ErrorStop } if !root.SolveUnknownModel(localFD, globalFD) { self.Row = root.Row self.Column = root.Col goto ErrorStop } return self.checkProtobufCompatibility(localFD) ErrorStop: r, c := self.GetRC() log.Errorf("%s|%s(%s)", self.file.FileName, self.Name, util.ConvR1C1toA1(r, c)) return false }
// 检查字段行的长度 func (self *DataHeader) ParseProtoField(index int, sheet *Sheet, localFD *model.FileDescriptor, globalFD *model.FileDescriptor) bool { var def *model.FieldDescriptor // 遍历列 for sheet.Column = 0; ; sheet.Column++ { def = new(model.FieldDescriptor) // ====================解析字段==================== def.Name = sheet.GetCellData(DataSheetRow_FieldName, sheet.Column) if def.Name == "" { break } // #开头表示注释, 跳过 if strings.Index(def.Name, "#") != 0 { // ====================解析类型==================== testFileD := localFD rawFieldType := sheet.GetCellData(DataSheetRow_FieldType, sheet.Column) for { if def.ParseType(testFileD, rawFieldType) { break } if testFileD == localFD { testFileD = globalFD continue } break } // 依然找不到, 报错 if def.Type == model.FieldType_None { sheet.Row = DataSheetRow_FieldType log.Errorf("%s, '%s' (%s) raw: %s", i18n.String(i18n.DataHeader_TypeNotFound), def.Name, model.FieldTypeToString(def.Type), rawFieldType) goto ErrorStop } // ====================解析特性==================== metaString := sheet.GetCellData(DataSheetRow_FieldMeta, sheet.Column) if err := proto.UnmarshalText(metaString, &def.Meta); err != nil { sheet.Row = DataSheetRow_FieldMeta log.Errorf("%s '%s'", i18n.String(i18n.DataHeader_MetaParseFailed), err) goto ErrorStop } def.Comment = sheet.GetCellData(DataSheetRow_Comment, sheet.Column) // 根据字段名查找, 处理repeated字段case exist, ok := self.HeaderByName[def.Name] if ok { // 多个同名字段只允许repeated方式的字段 if !exist.IsRepeated { sheet.Row = DataSheetRow_FieldName log.Errorf("%s '%s'", i18n.String(i18n.DataHeader_DuplicateFieldName), def.Name) goto ErrorStop } // 多个repeated描述类型不一致 if exist.Type != def.Type { sheet.Row = DataSheetRow_FieldType log.Errorf("%s '%s' '%s' '%s'", i18n.String(i18n.DataHeader_RepeatedFieldTypeNotSameInMultiColumn), def.Name, model.FieldTypeToString(exist.Type), model.FieldTypeToString(def.Type)) goto ErrorStop } // 多个repeated描述内建类型不一致 if exist.Complex != def.Complex { sheet.Row = DataSheetRow_FieldType log.Errorf("%s '%s'", i18n.String(i18n.DataHeader_RepeatedFieldTypeNotSameInMultiColumn), def.Name) goto ErrorStop } // 多个repeated描述的meta不一致 if proto.CompactTextString(&exist.Meta) != proto.CompactTextString(&def.Meta) { sheet.Row = DataSheetRow_FieldMeta log.Errorf("%s '%s'", i18n.String(i18n.DataHeader_RepeatedFieldMetaNotSameInMultiColumn), def.Name) goto ErrorStop } def = exist } else { self.HeaderByName[def.Name] = def self.headerFields = append(self.headerFields, def) } } // 有注释字段, 但是依然要放到这里来进行索引 self.rawHeaderFields = append(self.rawHeaderFields, def) } if len(self.rawHeaderFields) == 0 { return false } if index == 0 { // 添加第一个数据表的定义 if !self.makeRowDescriptor(localFD, self.headerFields) { goto ErrorStop } } return true ErrorStop: r, c := sheet.GetRC() log.Errorf("%s|%s(%s)", sheet.file.FileName, sheet.Name, util.ConvR1C1toA1(r, c)) return false }
func (self *DataSheet) Export(file *File, tab *model.Table, dataHeader *DataHeader) bool { // 是否继续读行 var readingLine bool = true // 遍历每一行 for self.Row = DataSheetRow_DataBegin; readingLine; self.Row++ { // 第一列是空的,结束 if self.GetCellData(self.Row, 0) == "" { break } record := model.NewRecord() // 遍历每一列 for self.Column = 0; self.Column < dataHeader.RawFieldCount(); self.Column++ { fieldDef := dataHeader.RawField(self.Column) // 数据大于列头时, 结束这个列 if fieldDef == nil { break } // #开头表示注释, 跳过 if strings.Index(fieldDef.Name, "#") == 0 { continue } rawValue := self.GetCellData(self.Row, self.Column) // repeated的, 没有填充的, 直接跳过, 不生成数据 if rawValue == "" && fieldDef.Meta.Default == "" { continue } node := record.NewNodeByDefine(fieldDef) // 结构体要多添加一个节点, 处理repeated 结构体情况 if fieldDef.Type == model.FieldType_Struct { node.StructRoot = true node = node.AddKey(fieldDef) } if !dataProcessor(file, fieldDef, rawValue, node) { goto ErrorStop } } tab.Add(record) } return true ErrorStop: r, c := self.GetRC() log.Errorf("%s|%s(%s)", self.file.FileName, self.Name, util.ConvR1C1toA1(r, c)) return false }
func (self *Sheet) IterateData(callback func(*RecordInfo) bool) (*data.DynamicMessage, bool) { // 检查引导头 if !self.ParseProtoField() { return nil, true } // 是否继续读行 var readingLine bool = true // 检查引导Proto字段 sheetMsg, rowMsgDesc, lineFieldDesc := self.checkProtoHeader() if sheetMsg == nil { goto ErrorStop } // 遍历每一行 for self.cursor = DataIndex_DataBegin; readingLine; self.cursor++ { // 第一列是空的,结束 if self.GetCellData(self.cursor, 0) == "" { break } lineMsg := data.NewDynamicMessage(rowMsgDesc) if lineMsg == nil { break } // 遍历每一列 for self.index = 0; self.index < len(self.FieldHeader); self.index++ { ri := new(RecordInfo) // Proto字段头 ri.FieldName = self.FieldHeader[self.index] // 原始值 ri.CellValue = self.GetCellData(self.cursor, self.index) // #开头表示注释, 跳过 if strings.Index(ri.FieldName, "#") == 0 { continue } ri.FieldMsg, ri.FieldDesc = makeCompactAccessor(ri.FieldName, lineMsg) // 字段匹配错误 if ri.FieldMsg == nil || ri.FieldDesc == nil { goto ErrorStop } var ok bool // 取扩展元信息 ri.FieldMeta, ok = data.GetFieldMeta(ri.FieldDesc) if !ok { goto ErrorStop } if data.DebuggingLevel >= 1 { r, c := self.GetRC() log.Debugf("(%s) %s=%s", util.ConvR1C1toA1(r, c), ri.FieldName, ri.Value) } if !callback(ri) { goto ErrorStop } } sheetMsg.AddRepeatedMessage(lineFieldDesc, lineMsg) } return sheetMsg, true ErrorStop: r, c := self.GetRC() log.Errorf("%s|%s(%s)", self.file.FileName, self.Name, util.ConvR1C1toA1(r, c)) return nil, false }