func FieldByNameWithMeta(msgD *pbmeta.Descriptor, name string) *pbmeta.FieldDescriptor { for i := 0; i < msgD.FieldCount(); i++ { fd := msgD.Field(i) if fd.Name() == name { return fd } meta, ok := data.GetFieldMeta(fd) if !ok { return nil } if meta != nil && meta.Alias == name { return fd } } return nil }
func findMapperField(msg *data.DynamicMessage) (fdset []*pbmeta.FieldDescriptor, lineFieldName string) { var lineMsgDesc *pbmeta.Descriptor // 找到行描述符 for i := 0; i < msg.Desc.FieldCount(); i++ { fd := msg.Desc.Field(i) if fd.IsRepeated() { lineMsgDesc = fd.MessageDesc() lineFieldName = fd.Name() break } } // 在结构中寻找需要导出的lua字段 for i := 0; i < lineMsgDesc.FieldCount(); i++ { fd := lineMsgDesc.Field(i) meta, ok := data.GetFieldMeta(fd) if !ok { return nil, "" } if meta == nil { continue } if !meta.LuaMapper { continue } fdset = append(fdset, fd) } return }
// 解析a.b.c字段,由给定的msg找到这些字段病返回字段访问器 func makeCompactAccessor(compactFieldName string, inputMsg *data.DynamicMessage) (*data.DynamicMessage, *pbmeta.FieldDescriptor) { // 将路径按点分割 fieldNameList := strings.Split(compactFieldName, ".") msg := inputMsg for _, fieldName := range fieldNameList { // 这个路径对应的描述器 fd := msg.Desc.FieldByName(fieldName) if fd == nil { log.Errorf("field type name not found, %s in %s", fieldName, compactFieldName) return nil, nil } // 消息进行添加并迭代 if fd.Type() == pbprotos.FieldDescriptorProto_TYPE_MESSAGE { // 字段中带repeated message的不支持, 使用string2struct解析字段 fdmeta, ok := data.GetFieldMeta(fd) if !ok { return nil, nil } if fd.IsRepeated() && fdmeta != nil && !fdmeta.String2Struct { log.Errorf("DO NOT support repeated message field, use 'string2struct' instead") return nil, nil } existMsg := msg.GetMessage(fd) if existMsg == nil { newMsg := data.NewDynamicMessage(fd.MessageDesc()) // 重复消息字段 if fd.IsRepeated() { if !msg.AddRepeatedMessage(fd, newMsg) { return nil, nil } } else { //普通值字段 if !msg.SetMessage(fd, newMsg) { return nil, nil } } msg = newMsg } else { msg = existMsg } } else { // 非消息返回当前层的反射器 return msg, fd } } // 纯消息, 字段使用父级 return msg, inputMsg.Desc.FieldByName(compactFieldName) }
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 }
func ValueConvetor(fd *pbmeta.FieldDescriptor, value string) (string, bool) { // 空单元格时, 给定一个这个类型对应的值 if value == "" { value = data.GetDefaultValue(fd) } switch fd.Type() { case pbprotos.FieldDescriptorProto_TYPE_FLOAT: _, err := strconv.ParseFloat(value, 32) if err != nil { return "", false } case pbprotos.FieldDescriptorProto_TYPE_INT64: _, err := strconv.ParseInt(value, 10, 64) if err != nil { return "", false } case pbprotos.FieldDescriptorProto_TYPE_UINT64: _, err := strconv.ParseUint(value, 10, 64) if err != nil { return "", false } case pbprotos.FieldDescriptorProto_TYPE_INT32: _, err := strconv.ParseInt(value, 10, 32) if err != nil { return "", false } case pbprotos.FieldDescriptorProto_TYPE_UINT32: _, err := strconv.ParseUint(value, 10, 32) if err != nil { return "", false } case pbprotos.FieldDescriptorProto_TYPE_BOOL: var final string for { if value == "是" { final = "true" break } else if value == "否" { final = "false" break } v, err := strconv.ParseBool(value) if err != nil { return "", false } if v { final = "true" } else { final = "false" } break } value = final case pbprotos.FieldDescriptorProto_TYPE_ENUM: ed := fd.EnumDesc() if ed.ValueCount() == 0 { return "", false } // 枚举值从表格读出时可能是中文枚举值, 需要根据meta信息转换为程序枚举值 var convValue string = value // 遍历这个枚举类型 for i := 0; i < ed.ValueCount(); i++ { evd := ed.Value(i) // 取出每个字段的meta meta, ok := data.GetFieldMeta(evd) if !ok { return "", false } if meta == nil { continue } // 这个枚举值的别名是否与给定的一致 if meta.Alias == value { convValue = evd.Name() break } } if ed.ValueByName(convValue) == nil { log.Errorf("enum doesn't contain this value, %s in %s", convValue, fd.Name()) return "", false } value = convValue } return value, true }