func (p *Properties) String() string {
	s := p.Wire
	s += "," + strconv.Itoa(p.Tag)
	if p.Required {
		s += ",req"
	}
	if p.Optional {
		s += ",opt"
	}
	if p.Repeated {
		s += ",rep"
	}
	if p.Packed {
		s += ",packed"
	}
	s += ",name=" + p.OrigName
	if p.JSONName != "" {
		s += ",json=" + p.JSONName
	}
	if len(p.Enum) > 0 {
		s += ",enum=" + p.Enum
	}
	if len(p.Weak) > 0 {
		s += ",weak=" + p.Weak
	}
	if p.Proto3 {
		s += ",proto3"
	}
	if p.Oneof {
		s += ",oneof"
	}
	if p.HasDefault {
		s += ",def=" + p.Default
	}
	return s
}
String formats the properties in the protobuf struct field tag style.
package proto
import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/runtime/protoimpl"
)
type StructProperties struct {
	Prop []*Properties
	OneofTypes map[string]*OneofProperties
}
type Properties struct {
	Name string
	OrigName string
	JSONName string
	Enum string  
	Weak string
	Wire string
	WireType int
	Tag int
	Required bool
	Optional bool
	Repeated bool
	Packed bool
	Proto3 bool
	Oneof bool
	Default string
	HasDefault bool
	MapKeyProp *Properties
	MapValProp *Properties
}
type OneofProperties struct {
	Type reflect.Type
	Field int
	Prop *Properties
}