コード例 #1
0
ファイル: val2struct.go プロジェクト: davyxu/tabtoy
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

}
コード例 #2
0
ファイル: lua.go プロジェクト: davyxu/tabtoy
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
}
コード例 #3
0
ファイル: sheet.go プロジェクト: davyxu/tabtoy
// 解析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)
}
コード例 #4
0
ファイル: sheet.go プロジェクト: davyxu/tabtoy
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
}
コード例 #5
0
ファイル: valconv.go プロジェクト: davyxu/tabtoy
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
}