You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: process_bind_info.go
    path of file: ./repos/bk-cmdb/src/common/metadata
    
    the code of the file until where you have to start completion: // Package metadata TODO
/*
 * Tencent is pleased to support the open source community by making 蓝鲸 available.,
 * Copyright (C) 2017,-2018 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the ",License",); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * http://opensource.org/licenses/MIT
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an ",AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */
package metadata

import (
	"encoding/json"
	"errors"
	"fmt"

	"configcenter/src/common"
	cErr "configcenter/src/common/errors"
	"configcenter/src/thirdparty/hooks/process"

	"go.mongodb.org/mongo-driver/bson"
)

/*
   version: 1.0 test
   description:  由于在不同的运行版本中,进程的绑定信息的二维结构中，数据的列是不一样的。 所以又下面的实现

   通过定义数据反序列化的方法来实现struct 的同一个属性在不同运行版本的环境上，实现进程绑定信息的多态。
   主要是利用interface 的特性来实现，

   defaultPropertyBindInfoHandle，defaultProcBindInfoHandle 是在使用反序列化 进程，进程模板中进程
   绑定信息实际结构的对象

   下面是defaultPrope
    
func (pbi *ProcPropertyBindInfo) Validate() (string, error) {
	maxRowID := int64(0)
	for idx, property := range pbi.Value {
		if property.Std == nil {
			return common.BKProcBindInfo, fmt.Errorf("not set value")
		}

		if property.Std.RowID > maxRowID {
			maxRowID = property.Std.RowID
		}

		if err := property.Std.IP.Validate(); err != nil {
			return fmt.Sprintf("%s[%d].%s", common.BKProcBindInfo, idx, common.BKIP), err
		}
		port := (*PropertyPortValue)(property.Std.Port.Value)

		if err := port.Validate(); err != nil {
			return fmt.Sprintf("%s[%d].%s", common.BKProcBindInfo, idx, common.BKPort), err
		}
		if err := property.Std.Protocol.Value.Validate(); err != nil {
			return fmt.Sprintf("%s[%d].%s", common.BKProcBindInfo, idx, common.BKProtocol), err
		}

		if property.Std.IP.Value != nil && *property.Std.IP.Value != "" {
			if err := ValidateBindIPMatchProtocol(*property.Std.IP.Value, *property.Std.Protocol.Value); err != nil {
				return fmt.Sprintf("%s[%d].(%s and %s)", common.BKProcBindInfo, idx, common.BKIP,
					common.BKProtocol), err
			}
		}

		if err := property.Std.Enable.Validate(); err != nil {
			return fmt.Sprintf("%s[%d].%s", common.BKProcBindInfo, idx, common.BKEnable), err
		}
		if property.extra != nil {
			if fieldName, err := property.extra.Validate(); err != nil {
				return fmt.Sprintf("%s[%d].%s", common.BKProcBindInfo, idx, fieldName), err
			}
		}

	}
	for idx, property := range pbi.Value {
		if property.Std.RowID == 0 {
			maxRowID += 1
			pbi.Value[idx].Std.RowID = maxRowID
		}
	}
	return "", nil
}