github.com/turingchain2020/turingchain@v1.1.21/cmd/tools/tasks/gen_dapp_util.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tasks
     6  
     7  import (
     8  	"fmt"
     9  	"regexp"
    10  	"strings"
    11  
    12  	sysutil "github.com/turingchain2020/turingchain/util"
    13  )
    14  
    15  type actionInfoItem struct {
    16  	memberName string
    17  	memberType string
    18  }
    19  
    20  /**
    21  通过正则获取Action的成员变量名和类型,其具体操作步骤如下:
    22  1. 读取需要解析的proto文件
    23  2. 通过搜索,定位到指定Action的起始为止
    24  3. 使用正则获取该Action中的oneof Value的内容
    25  4. 使用正则解析oneof Value中的内容,获取变量名和类型名
    26  5. 将获取到的变量名去除空格,并将首字母大写
    27  */
    28  func readDappActionFromProto(protoContent, actionName string) ([]*actionInfoItem, error) {
    29  
    30  	// 如果文件中含有与ActionName部分匹配的文字,则会造成搜索到多个
    31  	index := strings.Index(protoContent, actionName)
    32  	if index < 0 {
    33  		return nil, fmt.Errorf("action %s Not Existed", actionName)
    34  	}
    35  	expr := fmt.Sprintf(`\s*oneof\s+value\s*{\s+([\w\s=;]*)\}`)
    36  	reg := regexp.MustCompile(expr)
    37  	oneOfValueStrs := reg.FindAllStringSubmatch(protoContent, index)
    38  
    39  	expr = fmt.Sprintf(`\s+(\w+)([\s\w]+)=\s+(\d+);`)
    40  	reg = regexp.MustCompile(expr)
    41  	members := reg.FindAllStringSubmatch(oneOfValueStrs[0][0], -1)
    42  
    43  	actionInfos := make([]*actionInfoItem, 0)
    44  	for _, member := range members {
    45  		memberType := strings.Replace(member[1], " ", "", -1)
    46  		memberName := strings.Replace(member[2], " ", "", -1)
    47  		// 根据proto生成pb.go的规则,成员变量首字母必须大写
    48  		memberName, _ = sysutil.MakeStringToUpper(memberName, 0, 1)
    49  		actionInfos = append(actionInfos, &actionInfoItem{
    50  			memberName: memberName,
    51  			memberType: memberType,
    52  		})
    53  	}
    54  	if len(actionInfos) == 0 {
    55  		return nil, fmt.Errorf("can Not Find %s Member Info", actionName)
    56  	}
    57  	return actionInfos, nil
    58  }
    59  
    60  func formatExecContent(infos []*actionInfoItem, dappName string) string {
    61  
    62  	fnFmtStr := `func (${EXEC_OBJECT} *%s) Exec_%s(payload *%stypes.%s, tx *types.Transaction, index int) (*types.Receipt, error) {
    63  	receipt := &types.Receipt{Ty: types.ExecOk}
    64  	//implement code
    65  	return receipt, nil
    66  }
    67  
    68  `
    69  	content := ""
    70  	for _, info := range infos {
    71  		content += fmt.Sprintf(fnFmtStr, dappName, info.memberName, dappName, info.memberType)
    72  	}
    73  
    74  	return content
    75  }
    76  
    77  func formatExecLocalContent(infos []*actionInfoItem, dappName string) string {
    78  
    79  	fnFmtStr := `func (${EXEC_OBJECT} *%s) ExecLocal_%s(payload *%stypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
    80  	dbSet := &types.LocalDBSet{}
    81  	//implement code, add customize kv to dbSet...
    82  	
    83  	//auto gen for localdb auto rollback
    84  	return ${EXEC_OBJECT}.addAutoRollBack(tx, dbSet.KV), nil  
    85  }
    86  
    87  `
    88  	content := ""
    89  	for _, info := range infos {
    90  		content += fmt.Sprintf(fnFmtStr, dappName, info.memberName, dappName, info.memberType)
    91  	}
    92  
    93  	return content
    94  }
    95  
    96  func formatExecDelLocalContent(infos []*actionInfoItem, dappName string) string {
    97  
    98  	fnFmtStr := `func (${EXEC_OBJECT} *%s) ExecDelLocal_%s(payload *%stypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
    99  	var dbSet *types.LocalDBSet
   100  	//implement code
   101  	return dbSet, nil
   102  }
   103  
   104  `
   105  	content := ""
   106  	for _, info := range infos {
   107  		content += fmt.Sprintf(fnFmtStr, dappName, info.memberName, dappName, info.memberType)
   108  	}
   109  
   110  	return content
   111  }
   112  
   113  // 组成规则是 TyLog+ActionName + ActionMemberName
   114  func buildActionLogTypeText(infos []*actionInfoItem, className string) (text string) {
   115  	items := fmt.Sprintf("TyUnknownLog = iota + 100\n")
   116  	for _, info := range infos {
   117  		items += fmt.Sprintf("Ty%sLog\n", info.memberName)
   118  	}
   119  	text = fmt.Sprintf("const (\n%s)\n", items)
   120  	return
   121  }
   122  
   123  // 组成规则是 ActionName + ActionMemberName
   124  func buildActionIDText(infos []*actionInfoItem, className string) (text string) {
   125  
   126  	items := fmt.Sprintf("TyUnknowAction = iota + 100\n")
   127  	for _, info := range infos {
   128  		items += fmt.Sprintf("Ty%sAction\n", info.memberName)
   129  	}
   130  	items += "\n"
   131  	for _, info := range infos {
   132  		items += fmt.Sprintf("Name%sAction = \"%s\"\n", info.memberName, info.memberName)
   133  	}
   134  
   135  	text = fmt.Sprintf("const (\n%s)\n", items)
   136  	return
   137  }
   138  
   139  // 返回 map[string]int32
   140  func buildTypeMapText(infos []*actionInfoItem, className string) (text string) {
   141  	var items string
   142  	for _, info := range infos {
   143  		items += fmt.Sprintf("Name%sAction: Ty%sAction,\n", info.memberName, info.memberName)
   144  	}
   145  	text = fmt.Sprintf("map[string]int32{\n%s}", items)
   146  	return
   147  }
   148  
   149  // 返回 map[string]*types.LogInfo
   150  func buildLogMapText() (text string) {
   151  	text = fmt.Sprintf("map[int64]*types.LogInfo{\n\t//LogID:	{Ty: reflect.TypeOf(LogStruct), Name: LogName},\n}")
   152  	return
   153  }