diff --git a/descriptor.thrift b/descriptor.thrift index f86b5966..d4e9fbef 100644 --- a/descriptor.thrift +++ b/descriptor.thrift @@ -51,6 +51,7 @@ struct ConstValueDescriptor{ 6:optional list value_list // for list set 7:optional map value_map // for map 8:required string value_identifier // for identifier, such as another constant's name + 9:optional map extra // extra info } struct TypedefDescriptor{ diff --git a/extension/thrift_option/create_instance.go b/extension/thrift_option/create_instance.go new file mode 100644 index 00000000..d4295d1a --- /dev/null +++ b/extension/thrift_option/create_instance.go @@ -0,0 +1,292 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_option + +import ( + "encoding/hex" + "errors" + "github.com/cloudwego/thriftgo/thrift_reflection" + "github.com/cloudwego/thriftgo/utils" + "reflect" + "strconv" + "strings" +) + +func trimQuote(value string) string { + if strings.HasPrefix(value, "'") && strings.HasSuffix(value, "'") { + value = value[1 : len(value)-1] + } + if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") { + value = value[1 : len(value)-1] + } + return value +} + +func createInstance(td *thrift_reflection.TypeDescriptor, content string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + content = trimQuote(content) + if td.IsBasic() { + val, err := createBasic(td.GetName(), content) + return val, val, err + } + if td.IsContainer() { + return createContainer(td, content, mapMode) + } + if td.IsStruct() { + return creatStruct(td, content, mapMode) + } + if td.IsEnum() { + return createEnum(td, content, mapMode) + } + if td.IsTypedef() { + return createTypedef(td, content, mapMode) + } + return nil, nil, errors.New("unknown type") +} + +func createEnum(td *thrift_reflection.TypeDescriptor, content string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + enumDesc, err := td.GetEnumDescriptor() + if err != nil { + return nil, nil, err + } + for _, value := range enumDesc.GetValues() { + if content == value.GetName() { + val := value.GetValue() + if mapMode { + return val, nil, nil + } else { + enumGoType, er := td.GetGoType() + if er != nil { + return nil, nil, er + } + enumInstance := reflect.New(enumGoType).Elem() + enumVal := reflect.ValueOf(val) + enumInstance.Set(enumVal.Convert(enumGoType)) + return val, enumInstance.Interface(), nil + } + } + } + return nil, nil, errors.New("enum value " + content + " not found for" + enumDesc.GetName()) +} + +func createTypedef(td *thrift_reflection.TypeDescriptor, content string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + tdDesc, err := td.GetTypedefDescriptor() + if err != nil { + return nil, nil, err + } + return createInstance(tdDesc.GetType(), content, mapMode) +} + +type quadruple struct { + idx int + key string + mapValue interface{} + instanceValue interface{} +} + +func creatStruct(td *thrift_reflection.TypeDescriptor, content string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + des, err := td.GetStructDescriptor() + if err != nil { + return nil, nil, err + } + kv, err := utils.ParseKV(content) + if err != nil { + return nil, nil, err + } + // 检查 kv 里是否有非法字段 + for k := range kv { + if des.GetFieldByName(k) == nil { + return nil, nil, errors.New("field not exist:" + k) + } + } + triples := []*quadruple{} + for idx, fd := range des.GetFields() { + value, ok := kv[fd.GetName()] + if !ok { + // 当 option 里没对字段赋值时,使用 default value + if fd.GetDefaultValue() != nil { + value = fd.GetDefaultValue().GetValueAsString() + } else { + continue + } + } + mv, iv, er := createInstance(fd.GetType(), value, mapMode) + if er != nil { + return nil, nil, er + } + triples = append(triples, &quadruple{ + idx: idx, + key: fd.GetName(), + mapValue: mv, + instanceValue: iv, + }) + } + + resultMap := map[string]interface{}{} + for _, t := range triples { + resultMap[t.key] = t.mapValue + } + + if !mapMode { + goType := des.GetGoType() + structPtr := reflect.New(goType) + structEntity := structPtr.Elem() + if !structEntity.IsValid() { + return nil, nil, errors.New("invalid") + } + for _, t := range triples { + reflectField := structEntity.Field(t.idx) + reflectField.Set(reflect.ValueOf(t.instanceValue)) + } + return resultMap, structPtr.Interface(), nil + } + return resultMap, nil, nil +} + +func createBasic(name, value string) (interface{}, error) { + switch name { + case "bool": + i, er := strconv.ParseBool(value) + if er != nil { + return nil, er + } + return i, nil + case "byte": + i, er := strconv.ParseInt(value, 10, 8) + if er != nil { + return nil, er + } + return int8(i), nil + case "i8": + i, er := strconv.ParseInt(value, 10, 8) + if er != nil { + return nil, er + } + return int8(i), nil + case "i16": + i, er := strconv.ParseInt(value, 10, 16) + if er != nil { + return nil, er + } + return int16(i), nil + case "i32": + i, er := strconv.ParseInt(value, 10, 32) + if er != nil { + return nil, er + } + return int32(i), nil + case "i64": + i, er := strconv.ParseInt(value, 10, 64) + if er != nil { + return nil, er + } + return i, nil + case "double": + i, er := strconv.ParseFloat(value, 64) + if er != nil { + return nil, er + } + return i, nil + case "binary": + i, er := hex.DecodeString(value) + if er != nil { + return nil, er + } + return i, nil + case "string": + return value, nil + default: + return nil, errors.New("unsupported basic type: " + name) + } +} + +func createList(td *thrift_reflection.TypeDescriptor, value string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + arr, err := utils.ParseArr(value) + if err != nil { + return nil, nil, errors.New(err.Error() + " when parse " + td.Name) + } + + resultsMap := []interface{}{} + resultsInstance := []interface{}{} + for _, elm := range arr { + mv, iv, er := createInstance(td.GetValueType(), elm, mapMode) + if er != nil { + return nil, nil, er + } + resultsMap = append(resultsMap, mv) + resultsInstance = append(resultsInstance, iv) + } + + if mapMode { + return resultsMap, nil, nil + } else { + listType, er := td.GetGoType() + if er != nil { + return nil, nil, er + } + listValue := reflect.MakeSlice(listType, 0, 0) + for _, elmInstance := range resultsInstance { + listValue = reflect.Append(listValue, reflect.ValueOf(elmInstance)) + } + return resultsMap, listValue.Interface(), nil + } +} + +func createMap(td *thrift_reflection.TypeDescriptor, value string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + kvMap, err := utils.ParseKV(value) + if err != nil { + return nil, nil, errors.New(err.Error() + " when parse map " + td.Name) + } + + resultMap := map[interface{}]interface{}{} + resultInstances := map[interface{}]interface{}{} + for k, v := range kvMap { + kmv, kiv, er := createInstance(td.GetKeyType(), k, mapMode) + if er != nil { + return nil, nil, er + } + vmv, viv, er := createInstance(td.GetValueType(), v, mapMode) + if er != nil { + return nil, nil, er + } + resultMap[kmv] = vmv + resultInstances[kiv] = viv + } + + if mapMode { + return resultMap, nil, nil + } else { + mapType, er := td.GetGoType() + if er != nil { + return nil, nil, er + } + mapValue := reflect.MakeMap(mapType) + + for k, v := range resultInstances { + mapValue.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v)) + } + return resultMap, mapValue.Interface(), nil + } +} + +func createContainer(td *thrift_reflection.TypeDescriptor, value string, mapMode bool) (mapVal, instanceVal interface{}, e error) { + typeName := td.GetName() + if typeName == "map" { + return createMap(td, value, mapMode) + } + if typeName == "list" || typeName == "set" { + return createList(td, value, mapMode) + } + return nil, nil, errors.New("illegal container type") +} diff --git a/extension/thrift_option/option.go b/extension/thrift_option/option.go new file mode 100644 index 00000000..d40152da --- /dev/null +++ b/extension/thrift_option/option.go @@ -0,0 +1,222 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_option + +import ( + "strings" + + "github.com/cloudwego/thriftgo/thrift_reflection" + "github.com/cloudwego/thriftgo/utils" +) + +var optionDefMap = map[string]bool{ + "_FieldOptions": true, + "_StructOptions": true, + "_MethodOptions": true, + "_ServiceOptions": true, + "_EnumOptions": true, + "_EnumValueOptions": true, +} + +func parseOptionFromKey(in interface { + GetAnnotations() map[string][]string + GetFilepath() string + GetExtra() map[string]string +}, annotationName, optionType string) (option *OptionData, err error) { + // init FileDescriptor to enable reflection apis + + gd := thrift_reflection.GetGlobalDescriptor(in) + prefix, optionName := utils.ParseAlias(annotationName) + optionMeta := &commonOption{ + name: optionName, + optionType: optionType, + } + optionFD := gd.LookupFD(in.GetFilepath()).GetIncludeFD(prefix) + if optionFD != nil { + optionMeta.filepath = optionFD.GetFilepath() + } + + anno := &AnnotationMeta{ + filepath: in.GetFilepath(), + annotations: in.GetAnnotations(), + } + return parseOption(gd, anno, optionMeta, true) +} + +func parseOptionRuntime(in interface { + GetAnnotations() map[string][]string + GetFilepath() string + GetExtra() map[string]string +}, optionMeta OptionGetter) (val *OptionData, err error, +) { + anno := &AnnotationMeta{ + filepath: in.GetFilepath(), + annotations: in.GetAnnotations(), + } + gd := thrift_reflection.GetGlobalDescriptor(in) + optionData, err := parseOption(gd, anno, optionMeta, false) + if err != nil { + return nil, err + } + return optionData, nil +} + +// todo 添加缓存 +func parseOption(gd *thrift_reflection.GlobalDescriptor, anno *AnnotationMeta, optionMeta OptionGetter, mapMode bool) (option *OptionData, err error) { + optionName := optionMeta.GetName() + if optionMeta.GetType() == "_StructOptions" && optionDefMap[optionName] { + return nil, NotAllowError(optionName) + } + + if optionMeta.GetFilepath() == "" { + return nil, NotIncludedError(optionName) + } + + content := getOptionContent(gd, anno, optionMeta) + if content == "" { + // 传入的 Option 并不能在 Annotation 里找到 + return nil, KeyNotMatchError(optionMeta.GetName()) + } + + optionFilepath := optionMeta.GetFilepath() + optionType := optionMeta.GetType() + + fieldDesc := gd.LookupFD(optionFilepath).GetStructDescriptor(optionType).GetFieldByName(optionName) + if fieldDesc == nil || fieldDesc.GetType() == nil { + // 传入的 Option 和 Annotation 能匹配到,但并没有实际对应真正的 Option + return nil, NotExistError(optionName) + } + + typeDesc := fieldDesc.GetType() + + content = strings.ReplaceAll(content, "\n", " ") + content = strings.ReplaceAll(content, "\t", " ") + content = strings.TrimSpace(content) + mapVal, instanceVal, er := createInstance(typeDesc, content, mapMode) + if er != nil { + return nil, ParseFailedError(optionName, er) + } + + return &OptionData{optionName, typeDesc, mapVal, instanceVal}, nil +} + +type subValue struct { + path string + value string +} + +func getOptionContent(gd *thrift_reflection.GlobalDescriptor, annotation *AnnotationMeta, optionMeta OptionGetter) string { + + opts := []*subValue{} + for annotationKey, vals := range annotation.annotations { + if len(vals) < 1 { + continue + } + value := vals[len(vals)-1] + prefix, expectedOptionName, subpath, ok := parseOptionName(annotationKey) + if !ok { + continue + } + // check name + if expectedOptionName == optionMeta.GetName() { + match := false + if prefix == "" { + // option and current struct are in the same idl + // double check their idl filepath + match = optionMeta.GetFilepath() == annotation.filepath + } else { + // option and current struct are not in the same idl + currentFD := gd.LookupFD(annotation.filepath) + // check if current struct idl include the option's idl + match = optionMeta.GetFilepath() == currentFD.Includes[prefix] + } + if match { + if subpath == "" { + return value + } + opts = append(opts, &subValue{ + path: subpath, + value: value, + }) + } + } + } + + if len(opts) == 0 { + return "" + } + // todo 一个 prefix 的时候 panic + return buildTree(opts) +} + +func parseOptionName(tname string) (prefix, name, subpath string, ok bool) { + arr := strings.Split(tname, ".") + if len(arr) == 1 { + return "", tname, "", false + } + if len(arr) == 2 { + return arr[0], arr[1], "", true + } + return arr[0], arr[1], strings.Join(arr[2:], "."), true +} + +func buildTree(opts []*subValue) string { + tree := make(map[string]interface{}) + + for _, opt := range opts { + path := strings.Split(opt.path, ".") + value := opt.value + + current := tree + for i, comp := range path { + if i == len(path)-1 { + current[comp] = value + } else { + if _, ok := current[comp]; !ok { + current[comp] = make(map[string]interface{}) + } + if _, ok := current[comp].(map[string]interface{}); ok { + current = current[comp].(map[string]interface{}) + } else { + current[comp] = make(map[string]interface{}) + current = current[comp].(map[string]interface{}) + } + } + } + } + + return formatTree(tree) +} + +func formatTree(tree map[string]interface{}) string { + output := "{" + for key, value := range tree { + output += key + ":" + + switch v := value.(type) { + case string: + output += `"` + v + `"` + case map[string]interface{}: + output += formatTree(v) + } + + output += "," + } + + output = strings.TrimSuffix(output, ",") + output += "}" + + return output +} diff --git a/extension/thrift_option/option_error.go b/extension/thrift_option/option_error.go new file mode 100644 index 00000000..9aaeac29 --- /dev/null +++ b/extension/thrift_option/option_error.go @@ -0,0 +1,158 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_option + +import ( + "errors" + + "github.com/cloudwego/thriftgo/parser" + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +var ( + ErrKeyNotMatch = errors.New("key not matched") + ErrNotExistOption = errors.New("option does not exist") + ErrParseFailed = errors.New("failed to parse option") + ErrNotAllowOption = errors.New("not allowed to parse option") + ErrNotIncluded = errors.New("no such prefix found in the given include IDLs") +) + +type OptionError struct { + optionName string + detail error + reason error +} + +func ParseFailedError(optionName string, reason error) error { + return &OptionError{ + optionName: optionName, + detail: ErrParseFailed, + reason: reason, + } +} + +func NotIncludedError(optionName string) error { + return &OptionError{ + optionName: optionName, + detail: ErrNotIncluded, + } +} + +func NotAllowError(optionName string) error { + return &OptionError{ + optionName: optionName, + detail: ErrNotAllowOption, + } +} + +func KeyNotMatchError(optionName string) error { + return &OptionError{ + optionName: optionName, + detail: ErrKeyNotMatch, + } +} + +func NotExistError(optionName string) error { + return &OptionError{ + optionName: optionName, + detail: ErrNotExistOption, + } +} + +func (e *OptionError) Error() string { + if e.reason != nil { + return e.optionName + ":" + e.detail.Error() + ":" + e.reason.Error() + } + return e.optionName + ":" + e.detail.Error() +} + +func (e *OptionError) Unwrap() error { + return e.detail +} + +func hasOptionCompileError(err error) bool { + if err == nil { + return false + } + if errors.Is(err, ErrKeyNotMatch) { + return false + } + if errors.Is(err, ErrNotExistOption) { + return false + } + if errors.Is(err, ErrNotIncluded) { + return false + } + return true +} + +func CheckOptionGrammar(ast *parser.Thrift) error { + _, fd := thrift_reflection.RegisterAST(ast) + + for _, s := range fd.Structs { + if optionDefMap[s.Name] { + continue + } + for an := range s.Annotations { + _, err := ParseStructOption(s, an) + if hasOptionCompileError(err) { + return err + } + } + + for _, f := range s.Fields { + for fan := range f.Annotations { + _, err := ParseFieldOption(f, fan) + if hasOptionCompileError(err) { + return err + } + } + } + + } + for _, s := range fd.Services { + for san := range s.Annotations { + _, err := ParseServiceOption(s, san) + if hasOptionCompileError(err) { + return err + } + } + for _, f := range s.Methods { + for fa := range f.Annotations { + _, err := ParseMethodOption(f, fa) + if hasOptionCompileError(err) { + return err + } + } + } + } + for _, en := range fd.Enums { + for an := range en.Annotations { + _, err := ParseEnumOption(en, an) + if hasOptionCompileError(err) { + return err + } + } + for _, f := range en.Values { + for an := range f.Annotations { + _, err := ParseEnumValueOption(f, an) + if hasOptionCompileError(err) { + return err + } + } + } + } + return nil +} diff --git a/extension/thrift_option/option_error_test.go b/extension/thrift_option/option_error_test.go new file mode 100644 index 00000000..48cd7e3d --- /dev/null +++ b/extension/thrift_option/option_error_test.go @@ -0,0 +1,85 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_option + +import ( + "errors" + "testing" + + "github.com/cloudwego/thriftgo/parser" + "github.com/cloudwego/thriftgo/pkg/test" + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +// 检测各种报错提示场景 +func TestOptionError(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test_grammar_error.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + + p := fd.GetStructDescriptor("PersonA") + assert(t, p != nil) + + // 错误或者不存在的 Option 名称 + _, err = ParseStructOption(p, "abc") + // todo 这里需要展示前缀? + assert(t, err != nil && errors.Is(err, ErrKeyNotMatch), err) + + // 错误或者不存在的 Option 名称 + _, err = ParseStructOption(p, "entity.person_xxx_info") + // todo 这里需要展示前缀? + assert(t, err != nil && errors.Is(err, ErrNotExistOption), err) + + // 错误的 field value + p = fd.GetStructDescriptor("PersonB") + assert(t, p != nil) + _, err = ParseStructOption(p, "entity.person_basic_info") + assert(t, err != nil && errors.Is(err, ErrParseFailed), err) + + // 错误的 field name + p = fd.GetStructDescriptor("PersonC") + assert(t, p != nil) + _, err = ParseStructOption(p, "entity.person_struct_info") + // todo 具体的 parse field 可以以后增加测试校验 + assert(t, err != nil && errors.Is(err, ErrParseFailed), err) + + // 错误的 kv 语法 + p = fd.GetStructDescriptor("PersonE") + assert(t, p != nil) + _, err = ParseStructOption(p, "entity.person_container_info") + assert(t, err != nil && errors.Is(err, ErrParseFailed), err) + + // 没有 include 对应 option 的 IDL + p = fd.GetStructDescriptor("PersonF") + assert(t, p != nil) + _, err = ParseStructOption(p, "validation.person_string_info") + assert(t, err != nil && errors.Is(err, ErrNotIncluded), err) +} + +func TestGrammarCheck(t *testing.T) { + // 测试有 option 解析错误等各种情况的 IDL + ast, err := parser.ParseFile("option_idl/test_grammar_error.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + err = CheckOptionGrammar(ast) + test.Assert(t, err != nil) + + // 测试 option 写法都正常的 IDL (忽略 option 没有匹配到的情况) + ast, err = parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + err = CheckOptionGrammar(ast) + test.Assert(t, err == nil) +} diff --git a/extension/thrift_option/option_getter.go b/extension/thrift_option/option_getter.go new file mode 100644 index 00000000..597aa873 --- /dev/null +++ b/extension/thrift_option/option_getter.go @@ -0,0 +1,205 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_option + +import ( + "errors" + + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +type commonOption struct { + name string + filepath string + optionType string +} + +type OptionData struct { + name string + typeDescriptor *thrift_reflection.TypeDescriptor + mapVal interface{} + instanceVal interface{} +} + +func (o *OptionData) GetName() interface{} { + return o.name +} + +func (o *OptionData) GetValue() interface{} { + return o.mapVal +} + +func (o *OptionData) GetInstance() interface{} { + return o.instanceVal +} + +func (o *OptionData) GetFieldValue(name string) (interface{}, error) { + if !o.typeDescriptor.IsStruct() { + return nil, errors.New("not struct") + } + sd, err := o.typeDescriptor.GetStructDescriptor() + if err != nil { + return nil, errors.New("struct descriptor not found") + } + f := sd.GetFieldByName(name) + if f == nil { + return nil, errors.New("field name not match") + } + resultMap := o.mapVal.(map[string]interface{}) + return resultMap[name], nil +} + +func (o *OptionData) IsFieldSet(name string) (bool, error) { + if !o.typeDescriptor.IsStruct() { + return false, errors.New("not struct") + } + sd, err := o.typeDescriptor.GetStructDescriptor() + if err != nil { + return false, errors.New("struct descriptor not found") + } + f := sd.GetFieldByName(name) + if f == nil { + return false, errors.New("field name not match") + } + _, ok := o.mapVal.(map[string]interface{})[name] + return ok, nil +} + +type AnnotationMeta struct { + filepath string + annotations map[string][]string +} + +type OptionGetter interface { + GetName() string + GetFilepath() string + GetType() string +} + +func (o *commonOption) GetName() string { + return o.name +} + +func (o *commonOption) GetFilepath() string { + return o.filepath +} + +func (o *commonOption) GetType() string { + return o.optionType +} + +func newOption(filepath, name, optionType string) *commonOption { + return &commonOption{ + name: name, + filepath: filepath, + optionType: optionType, + } +} + +type EnumOption struct { + *commonOption +} + +func NewEnumOption(filepath, name string) *EnumOption { + return &EnumOption{newOption(filepath, name, "_EnumOptions")} +} + +type EnumValueOption struct { + *commonOption +} + +func NewEnumValueOption(filepath, name string) *EnumValueOption { + return &EnumValueOption{newOption(filepath, name, "_EnumValueOptions")} +} + +type MethodOption struct { + *commonOption +} + +func NewMethodOption(filepath, name string) *MethodOption { + return &MethodOption{newOption(filepath, name, "_MethodOptions")} +} + +type ServiceOption struct { + *commonOption +} + +func NewServiceOption(filepath, name string) *ServiceOption { + return &ServiceOption{newOption(filepath, name, "_ServiceOptions")} +} + +type StructOption struct { + *commonOption +} + +func NewStructOption(filepath, name string) *StructOption { + return &StructOption{newOption(filepath, name, "_StructOptions")} +} + +type FieldOption struct { + *commonOption +} + +func NewFieldOption(filepath, name string) *FieldOption { + return &FieldOption{newOption(filepath, name, "_FieldOptions")} +} + +func ParseFieldOption(field *thrift_reflection.FieldDescriptor, optionName string) (option *OptionData, err error) { + return parseOptionFromKey(field, optionName, "_FieldOptions") +} + +func ParseStructOption(structLike *thrift_reflection.StructDescriptor, annotationName string) (option *OptionData, err error) { + return parseOptionFromKey(structLike, annotationName, "_StructOptions") +} + +func ParseMethodOption(f *thrift_reflection.MethodDescriptor, optionName string) (option *OptionData, err error) { + return parseOptionFromKey(f, optionName, "_MethodOptions") +} + +func ParseServiceOption(s *thrift_reflection.ServiceDescriptor, optionName string) (option *OptionData, err error) { + return parseOptionFromKey(s, optionName, "_ServiceOptions") +} + +func ParseEnumOption(e *thrift_reflection.EnumDescriptor, optionName string) (option *OptionData, err error) { + return parseOptionFromKey(e, optionName, "_EnumOptions") +} + +func ParseEnumValueOption(ev *thrift_reflection.EnumValueDescriptor, optionName string) (option *OptionData, err error) { + return parseOptionFromKey(ev, optionName, "_EnumValueOptions") +} + +func GetFieldOption(s *thrift_reflection.FieldDescriptor, os *FieldOption) (val *OptionData, err error) { + return parseOptionRuntime(s, os) +} + +func GetEnumOption(s *thrift_reflection.EnumDescriptor, os *EnumOption) (val *OptionData, err error) { + return parseOptionRuntime(s, os) +} + +func GetEnumValueOption(s *thrift_reflection.EnumValueDescriptor, os *EnumValueOption) (val *OptionData, err error) { + return parseOptionRuntime(s, os) +} + +func GetServiceOption(s *thrift_reflection.ServiceDescriptor, os *ServiceOption) (val *OptionData, err error) { + return parseOptionRuntime(s, os) +} + +func GetMethodOption(s *thrift_reflection.MethodDescriptor, os *MethodOption) (val *OptionData, err error) { + return parseOptionRuntime(s, os) +} + +func GetStructOption(s *thrift_reflection.StructDescriptor, os *StructOption) (val *OptionData, err error) { + return parseOptionRuntime(s, os) +} diff --git a/extension/thrift_option/option_idl/annotations/entity/entity.thrift b/extension/thrift_option/option_idl/annotations/entity/entity.thrift new file mode 100644 index 00000000..db070344 --- /dev/null +++ b/extension/thrift_option/option_idl/annotations/entity/entity.thrift @@ -0,0 +1,70 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +namespace go option_gen.annotation.entity +include "entity_struct.thrift" + +struct _StructOptions { + 1:required PersonBasicInfo person_basic_info + 2:required PersonStructInfo person_struct_info + 3:required PersonContainerInfo person_container_info +} + +struct _FieldOptions { + 1:required string person_field_info +} + +struct PersonBasicInfo{ + 1:required i8 valuei8 + 2:required i16 valuei16; + 3:required i32 valuei32; + 4:required i64 valuei64; + 5:required string valuestring; + 6:required byte valuebyte; + 7:required double valuedouble; + 8:required binary valuebinary; + 9:required bool valuebool; +} + +struct PersonContainerInfo{ + 1:required map valuemap; + 2:required list valuelist; + 3:required set valueset; + 4:required list> valuelistset; + 5:required list> valuelistsetstruct; + 6:required map valuemapstruct; +} + +struct PersonStructInfo{ + 1:required TestStruct valueteststruct + 2:required entity_struct.InnerStruct valuestruct + 3:required TestEnum valueenum + 4:required TestStructTypedef valuestructtypedef + 5:required TestBasicTypedef valuebasictypedef +} + +enum TestEnum{ + A + B + C +} + +typedef entity_struct.InnerStruct TestStructTypedef +typedef string TestBasicTypedef + +struct TestStruct{ + 1:required string name + 2:required string age + 3:required entity_struct.InnerStruct innerStruct +} \ No newline at end of file diff --git a/extension/thrift_option/option_idl/annotations/entity/entity_struct.thrift b/extension/thrift_option/option_idl/annotations/entity/entity_struct.thrift new file mode 100644 index 00000000..fbdaf96f --- /dev/null +++ b/extension/thrift_option/option_idl/annotations/entity/entity_struct.thrift @@ -0,0 +1,19 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +namespace go option_gen.annotation.entity + +struct InnerStruct{ + 1:required string email +} \ No newline at end of file diff --git a/extension/thrift_option/option_idl/annotations/validation/validation.thrift b/extension/thrift_option/option_idl/annotations/validation/validation.thrift new file mode 100644 index 00000000..899b44dc --- /dev/null +++ b/extension/thrift_option/option_idl/annotations/validation/validation.thrift @@ -0,0 +1,74 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +namespace go option_gen.annotation.validation + +struct _StructOptions { + 1:required string person_string_info + 2:required map person_map_info + 3:required MyEnum person_enum_info + 4:required MyBasicTypedef person_basic_typedef_info + 5:required MyStructTypedef person_struct_typedef_info + 6:required MyStructWithDefaultVal person_struct_default_value_info +} + +struct MyStructWithDefaultVal{ + 1:required string v1 + 2:required string v2 = "v2" + 3:required i8 v3 = 8 + 4:required i16 v4 = 16 + 5:required i32 v5 = 32 + 6:required i64 v6 = 64 + 7:required bool v7 = true + 8:required double v8 = 3.1415926123456 + 9:required map v9 = {"k1":"v1"} + 10:required list v10 = ["k1","k2"] + 11:required string v11 = HELLO +} + +const string HELLO = "hello there" + +enum MyEnum{ + X + XL + XXL +} + +typedef string MyBasicTypedef +typedef TestInfo MyStructTypedef + +struct _FieldOptions { + 1:required string card_field_info +} + +struct TestInfo{ + 1:required string name + 2:required i16 number +} + +struct _ServiceOptions { + 1:required TestInfo svc_info +} + +struct _MethodOptions { + 1:required TestInfo method_info +} + +struct _EnumOptions { + 1:required TestInfo enum_info +} + +struct _EnumValueOptions { + 1:required TestInfo enum_value_info +} diff --git a/extension/thrift_option/option_idl/test.thrift b/extension/thrift_option/option_idl/test.thrift new file mode 100644 index 00000000..24ebb91f --- /dev/null +++ b/extension/thrift_option/option_idl/test.thrift @@ -0,0 +1,155 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +namespace go option_gen +include "annotations/entity/entity.thrift" +include "annotations/validation/validation.thrift" + +struct IDCard{ + 1:required string number + 2:required i8 age +} + + +struct Person{ + 1:required string name (entity.person_field_info='the name of this person') + 2:required IDCard id +}( + aaa.bbb = "hello" + entity.person_basic_info = '{ + valuei8:8 + valuei16:16 + valuei32:32 + valuei64:64 + valuestring:\'example@email.com\' + valuebyte: 1 + valuebinary: 12 + valuedouble:3.14159 + valuebool: true + }' + entity.person_struct_info = '{ + valuestruct:{email:"empty email"} + valueteststruct:{ + name: "lee" + innerStruct:{ + email:"no email" + } + } + valueenum: B + valuestructtypedef:{email:"empty email"} + valuebasictypedef: "hello there" + }' + entity.person_container_info = '{ + valuemap:{"hey1":"value1"} + valuelist:["list1","list2"] + valueset:["list3","list4"] + valuelistset:[[a,b,c],[d,e,f]] + valuelistsetstruct:[[{email:e1},{email:e2}],[{email:e3},{email:e4}]] + valuemapstruct:{k1:{email:e1} k2:{email:e2}} + }' + validation.person_string_info = 'hello' + validation.person_map_info = '{"hey1":"value1"}' + validation.person_enum_info = 'XXL' + validation.person_basic_typedef_info = '"hello there"' + validation.person_struct_typedef_info = '{name:"empty name"}' + validation.person_struct_default_value_info = '{v1:"v1 string"}' +) + +struct PersonB{ + +}( + entity.person_basic_info = '{ + valuei8:8,valuei16:16, + valuei32:32, + valuei64:64 , + valuestring:\'example@email.com\', + valuebyte: 1, + valuebinary: 12 , + valuedouble:3.14159, + valuebool: true, + }' + entity.person_struct_info = '{ + valuestruct:{email:"empty email"} + valueteststruct:{ + name: "lee", + innerStruct:{ + email:"no email", + } + } + valueenum: B valuestructtypedef:{email:"empty email"} , valuebasictypedef: "hello there" + }' + entity.person_container_info = '{ + valuemap:{"hey1":"value1"},valuelist:["list1","list2"] valueset:["list3","list4"] ,valuelistset:[[a,b,c],[d,e,f]] + valuelistsetstruct:[[{email:e1},{email:e2}],[{email:e3},{email:e4}]], + valuemapstruct:{k1:{email:e1} k2:{email:e2}} + }' +) + + +struct PersonC{ + +}( + entity.person_basic_info.valuei8 = '8' + entity.person_basic_info.valuei16 = '16' + entity.person_struct_info.valuestruct = '{email:"empty email"}' + // 简写不建议这样写,而且这行会被下面那行覆盖掉 + entity.person_struct_info.valueteststruct.innerStruct = "{name: '123'},innerStruct:{email:'456'}" + entity.person_struct_info.valueteststruct.innerStruct.email = "no email" + entity.person_struct_info.valueteststruct.name = "lee" +) + +enum MyEnum{ + A + ( + validation.enum_value_info = '{ + name: EnumValueInfoName + number: 222 + }' + ) + B +}( + validation.enum_info = '{ + name: EnumInfoName + number: 333 + }' +) + +service MyService{ + string M1() + ( + validation.method_info = '{ + name: MethodInfoName + number: 555 + }' + ) + string M2() + ( + validation.method_info = '{ + name: MethodInfoName + number: 444 + }' + ) +}( + validation.svc_info = '{ + name: ServiceInfoName + number: 666 + }' + +) + +struct TinyStruct{ + 1:required bool b1 + 2:required bool b2 +} + diff --git a/extension/thrift_option/option_idl/test_grammar_error.thrift b/extension/thrift_option/option_idl/test_grammar_error.thrift new file mode 100644 index 00000000..c0159c55 --- /dev/null +++ b/extension/thrift_option/option_idl/test_grammar_error.thrift @@ -0,0 +1,97 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +namespace go option_gen +include "annotations/entity/entity.thrift" + + +struct PersonA{ + 1:required string name +}( + // 错误的 option 名称 + entity.person_xxx_info = '{ + valuei16:16 + valuei32:32 + valuei64:64 + valuestring:\'example@email.com\' + valuebyte: 1 + valuebinary: 12 + valuedouble:3.14159 + valuebool: true + }' +) +struct PersonB{ + 1:required string name +}( + // 错误的 field value + entity.person_basic_info = '{ + valuei16:hellostring + valuei32:32 + valuei64:64 + valuestring:\'example@email.com\' + valuebyte: 1 + valuebinary: 12 + valuedouble:3.14159 + valuebool: true + }' +) + +struct PersonC{ + 1:required string name +}( + // 错误的 field 名称 + entity.person_struct_info = '{ + value_xxx:{ + name: "lee" + innerStruct:{ + email:"no email" + } + } + }' +) + +struct PersonD{ + 1:required string name +}//( + // 错误的 option 语法 +// option = 'entity.person_struct_info := { +// valueteststruct:{ +// name: "lee" +// innerStruct:{ +// email:"no email" +// } +// } +// }' +//) +struct PersonE{ + 1:required string name +}( + // 错误的 kv 语法 + entity.person_container_info = '{ + valuemap:{{"hey1":"value1"} + valuelist:["list1","list2"] + valueset:["list3","list4"] + valuelistset:[[a,b,c],[d,e,f]] + valuelistsetstruct:[[{email:e1},{email:e2}],[{email:e3},{email:e4}]] + valuemapstruct:{k1:{email:e1} k2:{email:e2}} + }' +) +struct PersonF{ + 1:required string name (entity.person_field_info="'the name of this person'") +}( + // 没有 include 对应 IDL + validation.person_string_info = 'hello' +) + + diff --git a/extension/thrift_option/option_test.go b/extension/thrift_option/option_test.go new file mode 100644 index 00000000..01a69a89 --- /dev/null +++ b/extension/thrift_option/option_test.go @@ -0,0 +1,664 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_option + +import ( + "fmt" + "testing" + + "github.com/cloudwego/thriftgo/parser" + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +func TestStructOptionWithStructBasic(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test basic option + opt, err := ParseStructOption(p, "entity.person_basic_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err := opt.GetFieldValue("valuei100") + assert(t, err != nil) + + v, err = opt.GetFieldValue("valuei8") + assert(t, err == nil) + val0, ok := v.(int8) + assert(t, ok && val0 == 8) + + v, err = opt.GetFieldValue("valuei16") + assert(t, err == nil) + val1, ok := v.(int16) + assert(t, ok && val1 == 16) + + v, err = opt.GetFieldValue("valuei32") + assert(t, err == nil) + val2, ok := v.(int32) + assert(t, ok && val2 == 32) + + v, err = opt.GetFieldValue("valuei64") + assert(t, err == nil) + val3, ok := v.(int64) + assert(t, ok && val3 == 64) + + v, err = opt.GetFieldValue("valuestring") + assert(t, err == nil) + val4, ok := v.(string) + assert(t, ok && val4 == "example@email.com") + + v, err = opt.GetFieldValue("valuebyte") + assert(t, err == nil) + val5, ok := v.(int8) + assert(t, ok && val5 == 1) + + v, err = opt.GetFieldValue("valuebinary") + assert(t, err == nil) + val6, ok := v.([]uint8) + assert(t, ok && len(val6) == 1 && val6[0] == 18) + + v, err = opt.GetFieldValue("valuedouble") + assert(t, err == nil) + val7, ok := v.(float64) + assert(t, ok && val7 == 3.14159) + + v, err = opt.GetFieldValue("valuebool") + assert(t, err == nil) + val8, ok := v.(bool) + assert(t, ok && val8 == true) +} + +func TestStructOptionWithStructStruct(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test struct option + opt, err := ParseStructOption(p, "entity.person_struct_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err := opt.GetFieldValue("valuestruct") + assert(t, err == nil) + val0, ok := v.(map[string]interface{}) + assert(t, ok && val0["email"] == "empty email") + + v, err = opt.GetFieldValue("valueteststruct") + assert(t, err == nil) + val1, ok := v.(map[string]interface{}) + assert(t, ok && val1["name"] == "lee") + val2, ok := val1["innerStruct"].(map[string]interface{}) + assert(t, ok && val2["email"] == "no email") + + v, err = opt.GetFieldValue("valueenum") + assert(t, err == nil) + val3, ok := v.(int64) + assert(t, ok && val3 == 1) + + v, err = opt.GetFieldValue("valuestructtypedef") + assert(t, err == nil) + val4, ok := v.(map[string]interface{}) + assert(t, ok && val4["email"] == "empty email") + + v, err = opt.GetFieldValue("valuebasictypedef") + assert(t, err == nil) + val5, ok := v.(string) + assert(t, ok && val5 == "hello there") +} + +func TestStructOptionWithStructContainer(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test container option + opt, err := ParseStructOption(p, "entity.person_container_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err := opt.GetFieldValue("valuemap") + assert(t, err == nil) + valuemap, ok := v.(map[interface{}]interface{}) + assert(t, ok) + assert(t, len(valuemap) == 1) + assert(t, valuemap["hey1"] == "value1") + + v, err = opt.GetFieldValue("valuelist") + assert(t, err == nil) + valuelist, ok := v.([]interface{}) + assert(t, ok) + assert(t, len(valuelist) == 2) + assert(t, valuelist[0] == "list1") + assert(t, valuelist[1] == "list2") + + v, err = opt.GetFieldValue("valueset") + assert(t, err == nil) + valueset, ok := v.([]interface{}) + assert(t, ok) + assert(t, len(valuelist) == 2) + assert(t, valueset[0] == "list3") + assert(t, valueset[1] == "list4") + + v, err = opt.GetFieldValue("valuelistsetstruct") + assert(t, err == nil) + valuelistsetstruct, ok := v.([]interface{}) + assert(t, ok) + assert(t, len(valuelist) == 2) + + valuelistsetstruct0, ok := valuelistsetstruct[0].([]interface{}) + assert(t, ok) + assert(t, len(valuelistsetstruct0) == 2) + + valuelistsetstruct1, ok := valuelistsetstruct[1].([]interface{}) + assert(t, ok) + assert(t, len(valuelistsetstruct1) == 2) + + v, err = opt.GetFieldValue("valuemapstruct") + assert(t, err == nil) + valuemapstruct, ok := v.(map[interface{}]interface{}) + assert(t, ok) + assert(t, len(valuemapstruct) == 2) + valuemapstructk1, ok := valuemapstruct["k1"].(map[string]interface{}) + assert(t, ok && valuemapstructk1["email"] == "e1") + valuemapstructk2, ok := valuemapstruct["k2"].(map[string]interface{}) + assert(t, ok && valuemapstructk2["email"] == "e2") +} + +func TestStructOptionWithBasic(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test basic option + opt, err := ParseStructOption(p, "validation.person_string_info") + assert(t, err == nil) + assert(t, opt != nil) + + v := opt.GetValue() + assert(t, err == nil) + valuestring, ok := v.(string) + assert(t, ok) + assert(t, valuestring == "hello") +} + +func TestStructOptionWithContainer(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test container option + opt, err := ParseStructOption(p, "validation.person_map_info") + assert(t, err == nil) + assert(t, opt != nil) + + v := opt.GetValue() + assert(t, err == nil) + valuemap, ok := v.(map[interface{}]interface{}) + assert(t, ok) + assert(t, len(valuemap) == 1) + assert(t, valuemap["hey1"] == "value1") +} + +func TestStructOptionWithEnum(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test enum option + opt, err := ParseStructOption(p, "validation.person_enum_info") + assert(t, err == nil) + assert(t, opt != nil) + + v := opt.GetValue() + assert(t, err == nil) + valueenum, ok := v.(int64) + assert(t, ok) + assert(t, valueenum == 2) +} + +func TestStructOptionWithTypedef(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test basic typedef option + opt1, err := ParseStructOption(p, "validation.person_basic_typedef_info") + assert(t, err == nil) + assert(t, opt1 != nil) + + v := opt1.GetValue() + assert(t, err == nil) + valuestring, ok := v.(string) + assert(t, ok) + assert(t, valuestring == "hello there") + + // test struct typedef option + opt2, err := ParseStructOption(p, "validation.person_struct_typedef_info") + assert(t, err == nil) + assert(t, opt2 != nil) + + v = opt2.GetValue() + assert(t, err == nil) + valuestruct, ok := v.(map[string]interface{}) + assert(t, ok) + assert(t, valuestruct["name"] == "empty name") +} + +func TestStructOptionWithDefaultValue(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + + // test basic option + opt, err := ParseStructOption(p, "validation.person_struct_default_value_info") + assert(t, err == nil) + assert(t, opt != nil) + + v1, err := opt.GetFieldValue("v1") + assert(t, err == nil && v1.(string) == "v1 string") + + v2, err := opt.GetFieldValue("v2") + assert(t, err == nil && v2.(string) == "v2") + + v3, err := opt.GetFieldValue("v3") + assert(t, err == nil && v3.(int8) == 8) + + v4, err := opt.GetFieldValue("v4") + assert(t, err == nil && v4.(int16) == 16) + + v5, err := opt.GetFieldValue("v5") + assert(t, err == nil && v5.(int32) == 32) + + v6, err := opt.GetFieldValue("v6") + assert(t, err == nil && v6.(int64) == 64) + + v7, err := opt.GetFieldValue("v7") + assert(t, err == nil && v7.(bool) == true) + + v8, err := opt.GetFieldValue("v8") + assert(t, err == nil && v8.(float64) == 3.1415926123456) + + v9, err := opt.GetFieldValue("v9") + assert(t, err == nil && v9.(map[interface{}]interface{})["k1"].(string) == "v1") + + v10, err := opt.GetFieldValue("v10") + assert(t, err == nil && v10.([]interface{})[0].(string) == "k1" && v10.([]interface{})[1].(string) == "k2") + + v11, err := opt.GetFieldValue("v11") + assert(t, err == nil && v11.(string) == "hello there") +} + +func TestFieldOption(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("Person") + assert(t, p != nil) + f := p.GetFieldByName("name") + assert(t, f != nil) + + opt, err := ParseFieldOption(f, "entity.person_field_info") + assert(t, err == nil) + assert(t, opt != nil) + + v := opt.GetValue() + assert(t, err == nil) + valuestring, ok := v.(string) + assert(t, ok) + assert(t, valuestring == "the name of this person") +} + +func TestServiceAndMethodOption(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + // service option + svc := fd.GetServiceDescriptor("MyService") + assert(t, svc != nil) + + opt, err := ParseServiceOption(svc, "validation.svc_info") + assert(t, err == nil, err) + assert(t, opt != nil) + + v := opt.GetValue() + assert(t, err == nil) + valueInfo, ok := v.(map[string]interface{}) + assert(t, ok) + assert(t, valueInfo["name"] == "ServiceInfoName") + number, ok := valueInfo["number"].(int16) + assert(t, ok && number == 666) + + // method option + method := svc.GetMethodByName("M1") + assert(t, method != nil) + + methodOption, err := ParseMethodOption(method, "validation.method_info") + assert(t, err == nil, err) + assert(t, methodOption != nil) + + mv := methodOption.GetValue() + assert(t, err == nil) + methodValueInfo, ok := mv.(map[string]interface{}) + assert(t, ok) + assert(t, methodValueInfo["name"] == "MethodInfoName") + methodNumber, ok := methodValueInfo["number"].(int16) + assert(t, ok && methodNumber == 555) +} + +func TestEnumAndEnumValueOption(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + // enum option + e := fd.GetEnumDescriptor("MyEnum") + assert(t, e != nil) + + opt, err := ParseEnumOption(e, "validation.enum_info") + assert(t, err == nil, err) + assert(t, opt != nil) + + v := opt.GetValue() + assert(t, err == nil) + valueInfo, ok := v.(map[string]interface{}) + assert(t, ok) + assert(t, valueInfo["name"] == "EnumInfoName") + number, ok := valueInfo["number"].(int16) + assert(t, ok && number == 333) + + // enum value option + ev := e.GetValues()[0] + + enumValueOption, err := ParseEnumValueOption(ev, "validation.enum_value_info") + assert(t, err == nil, err) + assert(t, enumValueOption != nil) + + evv := enumValueOption.GetValue() + assert(t, err == nil) + enumValueInfo, ok := evv.(map[string]interface{}) + assert(t, ok) + assert(t, enumValueInfo["name"] == "EnumValueInfoName") + enumValueNumber, ok := enumValueInfo["number"].(int16) + assert(t, ok && enumValueNumber == 222) +} + +func TestCommaGrammar(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("PersonB") + assert(t, p != nil) + + // test basic option + opt, err := ParseStructOption(p, "entity.person_basic_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err := opt.GetFieldValue("valuei100") + assert(t, err != nil) + + v, err = opt.GetFieldValue("valuei8") + assert(t, err == nil) + val0, ok := v.(int8) + assert(t, ok && val0 == 8) + + v, err = opt.GetFieldValue("valuei16") + assert(t, err == nil) + val1, ok := v.(int16) + assert(t, ok && val1 == 16) + + v, err = opt.GetFieldValue("valuei32") + assert(t, err == nil) + val2, ok := v.(int32) + assert(t, ok && val2 == 32) + + v, err = opt.GetFieldValue("valuei64") + assert(t, err == nil) + val3, ok := v.(int64) + assert(t, ok && val3 == 64) + + v, err = opt.GetFieldValue("valuestring") + assert(t, err == nil) + val4, ok := v.(string) + assert(t, ok && val4 == "example@email.com") + + v, err = opt.GetFieldValue("valuebyte") + assert(t, err == nil) + val5, ok := v.(int8) + assert(t, ok && val5 == 1) + + v, err = opt.GetFieldValue("valuebinary") + assert(t, err == nil) + val6, ok := v.([]uint8) + assert(t, ok && len(val6) == 1 && val6[0] == 18) + + v, err = opt.GetFieldValue("valuedouble") + assert(t, err == nil) + val7, ok := v.(float64) + assert(t, ok && val7 == 3.14159) + + v, err = opt.GetFieldValue("valuebool") + assert(t, err == nil) + val8, ok := v.(bool) + assert(t, ok && val8 == true) + + // test struct option + opt, err = ParseStructOption(p, "entity.person_struct_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err = opt.GetFieldValue("valuestruct") + assert(t, err == nil) + val00, ok := v.(map[string]interface{}) + assert(t, ok && val00["email"] == "empty email") + + vs, err := opt.GetFieldValue("valueteststruct") + assert(t, err == nil) + val11, ok := vs.(map[string]interface{}) + assert(t, ok && val11["name"] == "lee") + val22, ok := val11["innerStruct"].(map[string]interface{}) + assert(t, ok && val22["email"] == "no email") + + v, err = opt.GetFieldValue("valueenum") + assert(t, err == nil) + val33, ok := v.(int64) + assert(t, ok && val33 == 1) + + v, err = opt.GetFieldValue("valuestructtypedef") + assert(t, err == nil) + val44, ok := v.(map[string]interface{}) + assert(t, ok && val44["email"] == "empty email") + + v, err = opt.GetFieldValue("valuebasictypedef") + assert(t, err == nil) + val55, ok := v.(string) + assert(t, ok && val55 == "hello there") + + // test container option + opt, err = ParseStructOption(p, "entity.person_container_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err = opt.GetFieldValue("valuemap") + assert(t, err == nil) + valuemap, ok := v.(map[interface{}]interface{}) + assert(t, ok) + assert(t, len(valuemap) == 1) + assert(t, valuemap["hey1"] == "value1") + + v, err = opt.GetFieldValue("valuelist") + assert(t, err == nil) + valuelist, ok := v.([]interface{}) + assert(t, ok) + assert(t, len(valuelist) == 2) + assert(t, valuelist[0] == "list1") + assert(t, valuelist[1] == "list2") + + v, err = opt.GetFieldValue("valueset") + assert(t, err == nil) + valueset, ok := v.([]interface{}) + assert(t, ok) + assert(t, len(valuelist) == 2) + assert(t, valueset[0] == "list3") + assert(t, valueset[1] == "list4") + + v, err = opt.GetFieldValue("valuelistsetstruct") + assert(t, err == nil) + valuelistsetstruct, ok := v.([]interface{}) + assert(t, ok) + assert(t, len(valuelist) == 2) + + valuelistsetstruct0, ok := valuelistsetstruct[0].([]interface{}) + assert(t, ok) + assert(t, len(valuelistsetstruct0) == 2) + + valuelistsetstruct1, ok := valuelistsetstruct[1].([]interface{}) + assert(t, ok) + assert(t, len(valuelistsetstruct1) == 2) + + v, err = opt.GetFieldValue("valuemapstruct") + assert(t, err == nil) + valuemapstruct, ok := v.(map[interface{}]interface{}) + assert(t, ok) + assert(t, len(valuemapstruct) == 2) + valuemapstructk1, ok := valuemapstruct["k1"].(map[string]interface{}) + assert(t, ok && valuemapstructk1["email"] == "e1") + valuemapstructk2, ok := valuemapstruct["k2"].(map[string]interface{}) + assert(t, ok && valuemapstructk2["email"] == "e2") +} + +func TestSimpleGrammar(t *testing.T) { + ast, err := parser.ParseFile("option_idl/test.thrift", []string{"option_idl"}, true) + assert(t, err == nil) + + _, fd := thrift_reflection.RegisterAST(ast) + assert(t, fd != nil) + + p := fd.GetStructDescriptor("PersonC") + assert(t, p != nil) + + // test basic option + opt, err := ParseStructOption(p, "entity.person_basic_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err := opt.GetFieldValue("valuei100") + assert(t, err != nil) + + v, err = opt.GetFieldValue("valuei8") + assert(t, err == nil) + val0, ok := v.(int8) + assert(t, ok && val0 == 8) + + v, err = opt.GetFieldValue("valuei16") + assert(t, err == nil) + val1, ok := v.(int16) + assert(t, ok && val1 == 16) + + // test struct option + opt, err = ParseStructOption(p, "entity.person_struct_info") + assert(t, err == nil) + assert(t, opt != nil) + + v, err = opt.GetFieldValue("valuestruct") + assert(t, err == nil) + val00, ok := v.(map[string]interface{}) + assert(t, ok && val00["email"] == "empty email") + + vs, err := opt.GetFieldValue("valueteststruct") + assert(t, err == nil) + val11, ok := vs.(map[string]interface{}) + assert(t, ok && val11["name"] == "lee") + val22, ok := val11["innerStruct"].(map[string]interface{}) + assert(t, ok && val22["email"] == "no email") + +} + +func TestBuildTree(t *testing.T) { + opts := []*subValue{ + {path: "aa.bb.cc", value: "v1"}, + //{path: "aa.bb.dd", value: "v2"}, + //{path: "cc", value: "v3"}, + {path: "aa.dd", value: "v4"}, + {path: "aa.dd.ee.ff.gg", value: "v5"}, + } + + result := buildTree(opts) + fmt.Println(result) +} + +func assert(t *testing.T, cond bool, val ...interface{}) { + t.Helper() + if !cond { + if len(val) > 0 { + val = append([]interface{}{"assertion failed:"}, val...) + t.Fatal(val...) + } else { + t.Fatal("assertion failed") + } + } +} diff --git a/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity-reflection.go b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity-reflection.go new file mode 100644 index 00000000..812d33ad --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity-reflection.go @@ -0,0 +1,125 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package entity + +import ( + "reflect" + + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +// IDL Name: entity +// IDL Path: ../option_idl/annotations/entity/entity.thrift + +var file_entity_thrift_go_types = []interface{}{ + (*_StructOptions)(nil), // Struct 0: entity._StructOptions + (*_FieldOptions)(nil), // Struct 1: entity._FieldOptions + (*PersonBasicInfo)(nil), // Struct 2: entity.PersonBasicInfo + (*PersonContainerInfo)(nil), // Struct 3: entity.PersonContainerInfo + (*PersonStructInfo)(nil), // Struct 4: entity.PersonStructInfo + (*TestStruct)(nil), // Struct 5: entity.TestStruct + (*TestEnum)(nil), // Enum 0: entity.TestEnum + (*TestStructTypedef)(nil), // Enum 0: entity.TestStructTypedef + (*TestBasicTypedef)(nil), // Enum 1: entity.TestBasicTypedef +} +var file_entity_thrift *thrift_reflection.FileDescriptor +var file_idl_entity_rawDesc = []byte{ + 0x1f, 0x8b, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xdc, 0x59, 0x5f, 0x6f, 0xda, 0x3e, + 0x14, 0xbd, 0x24, 0x1, 0x42, 0x3, 0x4d, 0xdb, 0x9f, 0x7e, 0xf, 0x93, 0xf6, 0x19, 0x82, 0xfa, + 0x67, 0xa8, 0xaf, 0x6b, 0xb5, 0x49, 0x7d, 0xda, 0xb4, 0xf6, 0x3d, 0xa, 0x60, 0x98, 0xa5, 0x60, + 0xb3, 0xc4, 0x99, 0xc4, 0xb7, 0x9f, 0x12, 0x1b, 0x42, 0x47, 0x8a, 0x32, 0xee, 0x4d, 0x34, 0xad, + 0x2f, 0x56, 0x5b, 0xf9, 0x70, 0xce, 0xf1, 0xfd, 0x63, 0x5f, 0x3c, 0xe8, 0x0, 0x40, 0x10, 0x4, + 0x63, 0xb9, 0x56, 0x5c, 0x8a, 0x90, 0xcf, 0xe3, 0x71, 0x24, 0x84, 0x54, 0x51, 0xfe, 0x6b, 0x3a, + 0x66, 0x42, 0x71, 0xb5, 0x31, 0x4b, 0xa0, 0xbe, 0x27, 0x7c, 0xa1, 0x46, 0x60, 0x79, 0x1e, 0x40, + 0xb1, 0x75, 0xa4, 0xff, 0x13, 0xa6, 0x2a, 0xc9, 0x66, 0xa, 0x0, 0x3e, 0xd4, 0xc4, 0x32, 0x3b, + 0x76, 0x90, 0xf6, 0xe, 0xd2, 0x5a, 0x4a, 0x0, 0x78, 0x6f, 0x40, 0x96, 0x4c, 0x4, 0x25, 0x48, + 0xa0, 0x37, 0xfb, 0xe0, 0xc, 0x1, 0x0, 0x7c, 0xe8, 0xe6, 0x6b, 0xef, 0x24, 0x19, 0x1e, 0x58, + 0x0, 0x70, 0x1e, 0x3e, 0x17, 0x44, 0xbe, 0x14, 0x1b, 0x53, 0x1f, 0xec, 0x1c, 0xd1, 0x46, 0x20, + 0x5e, 0xae, 0x59, 0x92, 0x4a, 0x11, 0x4e, 0xa3, 0x94, 0xcf, 0x42, 0x2e, 0x16, 0x72, 0x88, 0xc2, + 0xf3, 0xbf, 0x16, 0x78, 0xf, 0x39, 0xdc, 0x93, 0x58, 0x48, 0xf0, 0xc0, 0x1, 0x0, 0xf7, 0x1b, + 0xfb, 0x91, 0xf1, 0x84, 0xcd, 0x5d, 0xe8, 0xe6, 0xce, 0x8d, 0xa0, 0xef, 0xf9, 0xb9, 0x29, 0x1e, + 0xb8, 0xa0, 0xd7, 0x93, 0x3f, 0xf2, 0xca, 0x48, 0xd0, 0x67, 0x44, 0xa0, 0xe1, 0x42, 0x6b, 0xd0, + 0x56, 0xbf, 0x2d, 0xc2, 0xa2, 0x14, 0xf1, 0xbf, 0x11, 0x31, 0x93, 0x42, 0x45, 0x5c, 0xb0, 0x84, + 0x40, 0xc7, 0x7f, 0x5a, 0xc7, 0xe3, 0x16, 0xf2, 0x6d, 0x29, 0xf6, 0x81, 0x94, 0x11, 0x38, 0xdb, + 0x3f, 0x74, 0xb1, 0xda, 0x46, 0xe1, 0x67, 0xce, 0xe2, 0xf9, 0xeb, 0xa0, 0xed, 0x10, 0x4, 0xed, + 0x22, 0x87, 0x25, 0x30, 0xaa, 0x97, 0xaa, 0x84, 0x8b, 0x65, 0xdd, 0x58, 0xa5, 0xf4, 0xe6, 0xf7, + 0x7c, 0x31, 0xee, 0xc, 0x10, 0x90, 0xfd, 0x9f, 0x51, 0x9c, 0x31, 0x7e, 0x8f, 0xf3, 0xc4, 0xe2, + 0xf7, 0x2d, 0xe4, 0xae, 0xab, 0xb9, 0x5e, 0x4f, 0x70, 0x64, 0x6d, 0x7e, 0x3d, 0x69, 0x21, 0x49, + 0xd, 0xdb, 0xdb, 0x1b, 0x2c, 0xdb, 0xdb, 0x9b, 0xba, 0x79, 0x88, 0x67, 0x3b, 0xb9, 0xc3, 0xb2, + 0x9d, 0xdc, 0x55, 0xb3, 0x75, 0x28, 0xd9, 0x7a, 0x5, 0x5b, 0x9d, 0x88, 0xd, 0x66, 0x73, 0x97, + 0x92, 0xf3, 0xa0, 0xe0, 0x3c, 0xdd, 0x28, 0x86, 0x63, 0xec, 0xe4, 0x10, 0xd5, 0x7c, 0x7b, 0xf4, + 0x1e, 0xcf, 0x65, 0x36, 0x8d, 0x91, 0x8c, 0x7b, 0x1a, 0xa4, 0x9a, 0x73, 0x9f, 0x9e, 0xf3, 0x94, + 0x8b, 0x28, 0xd9, 0x20, 0x39, 0x6b, 0x90, 0x6a, 0xce, 0x6e, 0x3, 0x71, 0x21, 0x65, 0x8c, 0x8d, + 0xb, 0x29, 0xe3, 0x6a, 0xbe, 0x83, 0x46, 0xbb, 0x52, 0xd5, 0xcd, 0xc1, 0x74, 0x26, 0xcc, 0xf5, + 0x55, 0x57, 0xa4, 0x55, 0xb4, 0x46, 0x56, 0x24, 0x34, 0xc2, 0xb6, 0x44, 0xc, 0xc1, 0x21, 0x40, + 0x69, 0xa1, 0x4f, 0xea, 0x88, 0x8a, 0x79, 0xaa, 0x90, 0x11, 0xa5, 0x21, 0x9a, 0x53, 0xdd, 0x40, + 0xbf, 0x4d, 0x19, 0x52, 0xb4, 0x5d, 0x20, 0x34, 0xa7, 0x99, 0xb4, 0x6b, 0xf, 0x77, 0x27, 0x8d, + 0xd6, 0x4d, 0x70, 0xd8, 0x84, 0xd6, 0xb5, 0x70, 0x87, 0xb8, 0xda, 0xf7, 0x4e, 0x3f, 0x7, 0xff, + 0x1, 0x7, 0xdf, 0xbd, 0x9e, 0x41, 0x3c, 0x9, 0xc1, 0x92, 0xe7, 0xed, 0x4, 0xa3, 0xf9, 0x4b, + 0xce, 0xf9, 0xb6, 0x68, 0x53, 0x18, 0xfa, 0xb7, 0x94, 0xee, 0x63, 0x9e, 0xd6, 0xbc, 0x87, 0x51, + 0xf6, 0xdb, 0x83, 0x89, 0x83, 0x69, 0xb6, 0x5d, 0xcc, 0xcb, 0xb2, 0x38, 0x37, 0xc5, 0x52, 0x92, + 0x4c, 0x38, 0x7b, 0x61, 0xa9, 0x32, 0xe, 0x35, 0xdf, 0xee, 0x76, 0x8f, 0x1, 0x34, 0xef, 0x23, + 0x7, 0xdd, 0x7c, 0xff, 0xd2, 0x5d, 0x9b, 0x89, 0x6c, 0x85, 0x13, 0xe1, 0xe6, 0xe6, 0x7f, 0x12, + 0xd9, 0xaa, 0x85, 0xfe, 0x73, 0xb5, 0x67, 0xbd, 0xda, 0xac, 0xd9, 0x9c, 0x2d, 0x70, 0xe4, 0x2f, + 0xcb, 0xc8, 0x79, 0xd1, 0x78, 0x2d, 0x74, 0x82, 0x4b, 0x7d, 0x3, 0x8f, 0x52, 0x3e, 0x23, 0x11, + 0x71, 0x91, 0x8b, 0x28, 0x86, 0x34, 0x47, 0x35, 0x1c, 0x16, 0x5e, 0xca, 0x2a, 0xb1, 0x97, 0x83, + 0x4, 0x93, 0x5f, 0x47, 0x44, 0x2b, 0xec, 0x2b, 0xf0, 0xcf, 0xe6, 0x66, 0x98, 0xbe, 0x11, 0x2d, + 0x9b, 0xe4, 0x4a, 0x9a, 0xf5, 0x1e, 0x2f, 0x8b, 0x4c, 0xbb, 0xc5, 0xab, 0xc6, 0x18, 0xd7, 0x87, + 0x9e, 0xf9, 0x32, 0xa2, 0x8f, 0x9d, 0xc2, 0xee, 0xaa, 0x12, 0x41, 0x30, 0x76, 0x3e, 0x9e, 0x81, + 0xd, 0xe6, 0x87, 0x32, 0x67, 0x3a, 0xf, 0x25, 0x70, 0x87, 0x14, 0xf8, 0xb1, 0x4, 0xb6, 0xe, + 0x80, 0x2b, 0x7c, 0x77, 0x73, 0x8f, 0xac, 0x93, 0x3e, 0x71, 0x78, 0xe2, 0xbe, 0x1a, 0x51, 0x64, + 0x57, 0x56, 0x68, 0x1a, 0xa3, 0x70, 0xb4, 0xcb, 0x84, 0xb5, 0xab, 0xa, 0x70, 0x85, 0xc3, 0x3, + 0x13, 0xd9, 0x67, 0xc5, 0xa, 0xbf, 0x2, 0x0, 0x0, 0xff, 0xff, 0x34, 0x81, 0xb0, 0x4, 0x2f, + 0x1c, 0x0, 0x0, +} + +func init() { + if file_entity_thrift != nil { + return + } + type x struct{} + builder := &thrift_reflection.FileDescriptorBuilder{ + Bytes: file_idl_entity_rawDesc, + GoTypes: file_entity_thrift_go_types, + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + } + file_entity_thrift = thrift_reflection.BuildFileDescriptor(builder) +} + +func GetFileDescriptorForEntity() *thrift_reflection.FileDescriptor { + return file_entity_thrift +} +func (p *_StructOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_thrift.GetStructDescriptor("_StructOptions") +} +func (p *_FieldOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_thrift.GetStructDescriptor("_FieldOptions") +} +func (p *PersonBasicInfo) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_thrift.GetStructDescriptor("PersonBasicInfo") +} +func (p *PersonContainerInfo) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_thrift.GetStructDescriptor("PersonContainerInfo") +} +func (p *PersonStructInfo) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_thrift.GetStructDescriptor("PersonStructInfo") +} +func (p *TestStruct) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_thrift.GetStructDescriptor("TestStruct") +} +func (p TestEnum) GetDescriptor() *thrift_reflection.EnumDescriptor { + return file_entity_thrift.GetEnumDescriptor("TestEnum") +} diff --git a/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity.go b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity.go new file mode 100644 index 00000000..aaf828a1 --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity.go @@ -0,0 +1,2332 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package entity + +import ( + "database/sql" + "database/sql/driver" + "fmt" + "github.com/apache/thrift/lib/go/thrift" + "github.com/cloudwego/thriftgo/extension/thrift_option" + "reflect" +) + +type TestEnum int64 + +const ( + TestEnum_A TestEnum = 0 + TestEnum_B TestEnum = 1 + TestEnum_C TestEnum = 2 +) + +func (p TestEnum) String() string { + switch p { + case TestEnum_A: + return "A" + case TestEnum_B: + return "B" + case TestEnum_C: + return "C" + } + return "" +} + +func TestEnumFromString(s string) (TestEnum, error) { + switch s { + case "A": + return TestEnum_A, nil + case "B": + return TestEnum_B, nil + case "C": + return TestEnum_C, nil + } + return TestEnum(0), fmt.Errorf("not a valid TestEnum string") +} + +func TestEnumPtr(v TestEnum) *TestEnum { return &v } +func (p *TestEnum) Scan(value interface{}) (err error) { + var result sql.NullInt64 + err = result.Scan(value) + *p = TestEnum(result.Int64) + return +} + +func (p *TestEnum) Value() (driver.Value, error) { + if p == nil { + return nil, nil + } + return int64(*p), nil +} + +type TestStructTypedef = InnerStruct + +func NewTestStructTypedef() *TestStructTypedef { + return (*TestStructTypedef)(NewInnerStruct()) +} + +type TestBasicTypedef = string + +type _StructOptions struct { + PersonBasicInfo *PersonBasicInfo `thrift:"person_basic_info,1,required" json:"person_basic_info"` + PersonStructInfo *PersonStructInfo `thrift:"person_struct_info,2,required" json:"person_struct_info"` + PersonContainerInfo *PersonContainerInfo `thrift:"person_container_info,3,required" json:"person_container_info"` +} + +func New_StructOptions() *_StructOptions { + return &_StructOptions{} +} + +var _StructOptions_PersonBasicInfo_DEFAULT *PersonBasicInfo + +func (p *_StructOptions) GetPersonBasicInfo() (v *PersonBasicInfo) { + if !p.IsSetPersonBasicInfo() { + return _StructOptions_PersonBasicInfo_DEFAULT + } + return p.PersonBasicInfo +} + +var _StructOptions_PersonStructInfo_DEFAULT *PersonStructInfo + +func (p *_StructOptions) GetPersonStructInfo() (v *PersonStructInfo) { + if !p.IsSetPersonStructInfo() { + return _StructOptions_PersonStructInfo_DEFAULT + } + return p.PersonStructInfo +} + +var _StructOptions_PersonContainerInfo_DEFAULT *PersonContainerInfo + +func (p *_StructOptions) GetPersonContainerInfo() (v *PersonContainerInfo) { + if !p.IsSetPersonContainerInfo() { + return _StructOptions_PersonContainerInfo_DEFAULT + } + return p.PersonContainerInfo +} + +var fieldIDToName__StructOptions = map[int16]string{ + 1: "person_basic_info", + 2: "person_struct_info", + 3: "person_container_info", +} + +func (p *_StructOptions) IsSetPersonBasicInfo() bool { + return p.PersonBasicInfo != nil +} + +func (p *_StructOptions) IsSetPersonStructInfo() bool { + return p.PersonStructInfo != nil +} + +func (p *_StructOptions) IsSetPersonContainerInfo() bool { + return p.PersonContainerInfo != nil +} + +func (p *_StructOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetPersonBasicInfo bool = false + var issetPersonStructInfo bool = false + var issetPersonContainerInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetPersonBasicInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetPersonStructInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetPersonContainerInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetPersonBasicInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetPersonStructInfo { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetPersonContainerInfo { + fieldId = 3 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__StructOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__StructOptions[fieldId])) +} + +func (p *_StructOptions) ReadField1(iprot thrift.TProtocol) error { + p.PersonBasicInfo = NewPersonBasicInfo() + if err := p.PersonBasicInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_StructOptions) ReadField2(iprot thrift.TProtocol) error { + p.PersonStructInfo = NewPersonStructInfo() + if err := p.PersonStructInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_StructOptions) ReadField3(iprot thrift.TProtocol) error { + p.PersonContainerInfo = NewPersonContainerInfo() + if err := p.PersonContainerInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_StructOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_StructOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_StructOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_basic_info", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.PersonBasicInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_StructOptions) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_struct_info", thrift.STRUCT, 2); err != nil { + goto WriteFieldBeginError + } + if err := p.PersonStructInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *_StructOptions) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_container_info", thrift.STRUCT, 3); err != nil { + goto WriteFieldBeginError + } + if err := p.PersonContainerInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *_StructOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_StructOptions(%+v)", *p) +} + +type _FieldOptions struct { + PersonFieldInfo string `thrift:"person_field_info,1,required" json:"person_field_info"` +} + +func New_FieldOptions() *_FieldOptions { + return &_FieldOptions{} +} + +func (p *_FieldOptions) GetPersonFieldInfo() (v string) { + return p.PersonFieldInfo +} + +var fieldIDToName__FieldOptions = map[int16]string{ + 1: "person_field_info", +} + +func (p *_FieldOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetPersonFieldInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetPersonFieldInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetPersonFieldInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__FieldOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__FieldOptions[fieldId])) +} + +func (p *_FieldOptions) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.PersonFieldInfo = v + } + return nil +} + +func (p *_FieldOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_FieldOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_FieldOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_field_info", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.PersonFieldInfo); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_FieldOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_FieldOptions(%+v)", *p) +} + +type PersonBasicInfo struct { + Valuei8 int8 `thrift:"valuei8,1,required" json:"valuei8"` + Valuei16 int16 `thrift:"valuei16,2,required" json:"valuei16"` + Valuei32 int32 `thrift:"valuei32,3,required" json:"valuei32"` + Valuei64 int64 `thrift:"valuei64,4,required" json:"valuei64"` + Valuestring string `thrift:"valuestring,5,required" json:"valuestring"` + Valuebyte int8 `thrift:"valuebyte,6,required" json:"valuebyte"` + Valuedouble float64 `thrift:"valuedouble,7,required" json:"valuedouble"` + Valuebinary []byte `thrift:"valuebinary,8,required" json:"valuebinary"` + Valuebool bool `thrift:"valuebool,9,required" json:"valuebool"` +} + +func NewPersonBasicInfo() *PersonBasicInfo { + return &PersonBasicInfo{} +} + +func (p *PersonBasicInfo) GetValuei8() (v int8) { + return p.Valuei8 +} + +func (p *PersonBasicInfo) GetValuei16() (v int16) { + return p.Valuei16 +} + +func (p *PersonBasicInfo) GetValuei32() (v int32) { + return p.Valuei32 +} + +func (p *PersonBasicInfo) GetValuei64() (v int64) { + return p.Valuei64 +} + +func (p *PersonBasicInfo) GetValuestring() (v string) { + return p.Valuestring +} + +func (p *PersonBasicInfo) GetValuebyte() (v int8) { + return p.Valuebyte +} + +func (p *PersonBasicInfo) GetValuedouble() (v float64) { + return p.Valuedouble +} + +func (p *PersonBasicInfo) GetValuebinary() (v []byte) { + return p.Valuebinary +} + +func (p *PersonBasicInfo) GetValuebool() (v bool) { + return p.Valuebool +} + +var fieldIDToName_PersonBasicInfo = map[int16]string{ + 1: "valuei8", + 2: "valuei16", + 3: "valuei32", + 4: "valuei64", + 5: "valuestring", + 6: "valuebyte", + 7: "valuedouble", + 8: "valuebinary", + 9: "valuebool", +} + +func (p *PersonBasicInfo) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetValuei8 bool = false + var issetValuei16 bool = false + var issetValuei32 bool = false + var issetValuei64 bool = false + var issetValuestring bool = false + var issetValuebyte bool = false + var issetValuedouble bool = false + var issetValuebinary bool = false + var issetValuebool bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.BYTE { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetValuei8 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.I16 { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetValuei16 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.I32 { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetValuei32 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 4: + if fieldTypeId == thrift.I64 { + if err = p.ReadField4(iprot); err != nil { + goto ReadFieldError + } + issetValuei64 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 5: + if fieldTypeId == thrift.STRING { + if err = p.ReadField5(iprot); err != nil { + goto ReadFieldError + } + issetValuestring = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 6: + if fieldTypeId == thrift.BYTE { + if err = p.ReadField6(iprot); err != nil { + goto ReadFieldError + } + issetValuebyte = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 7: + if fieldTypeId == thrift.DOUBLE { + if err = p.ReadField7(iprot); err != nil { + goto ReadFieldError + } + issetValuedouble = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 8: + if fieldTypeId == thrift.STRING { + if err = p.ReadField8(iprot); err != nil { + goto ReadFieldError + } + issetValuebinary = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 9: + if fieldTypeId == thrift.BOOL { + if err = p.ReadField9(iprot); err != nil { + goto ReadFieldError + } + issetValuebool = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetValuei8 { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetValuei16 { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetValuei32 { + fieldId = 3 + goto RequiredFieldNotSetError + } + + if !issetValuei64 { + fieldId = 4 + goto RequiredFieldNotSetError + } + + if !issetValuestring { + fieldId = 5 + goto RequiredFieldNotSetError + } + + if !issetValuebyte { + fieldId = 6 + goto RequiredFieldNotSetError + } + + if !issetValuedouble { + fieldId = 7 + goto RequiredFieldNotSetError + } + + if !issetValuebinary { + fieldId = 8 + goto RequiredFieldNotSetError + } + + if !issetValuebool { + fieldId = 9 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_PersonBasicInfo[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_PersonBasicInfo[fieldId])) +} + +func (p *PersonBasicInfo) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadByte(); err != nil { + return err + } else { + p.Valuei8 = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI16(); err != nil { + return err + } else { + p.Valuei16 = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return err + } else { + p.Valuei32 = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return err + } else { + p.Valuei64 = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField5(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Valuestring = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField6(iprot thrift.TProtocol) error { + if v, err := iprot.ReadByte(); err != nil { + return err + } else { + p.Valuebyte = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField7(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return err + } else { + p.Valuedouble = v + } + return nil +} + +func (p *PersonBasicInfo) ReadField8(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBinary(); err != nil { + return err + } else { + p.Valuebinary = []byte(v) + } + return nil +} + +func (p *PersonBasicInfo) ReadField9(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return err + } else { + p.Valuebool = v + } + return nil +} + +func (p *PersonBasicInfo) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("PersonBasicInfo"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + if err = p.writeField4(oprot); err != nil { + fieldId = 4 + goto WriteFieldError + } + if err = p.writeField5(oprot); err != nil { + fieldId = 5 + goto WriteFieldError + } + if err = p.writeField6(oprot); err != nil { + fieldId = 6 + goto WriteFieldError + } + if err = p.writeField7(oprot); err != nil { + fieldId = 7 + goto WriteFieldError + } + if err = p.writeField8(oprot); err != nil { + fieldId = 8 + goto WriteFieldError + } + if err = p.writeField9(oprot); err != nil { + fieldId = 9 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuei8", thrift.BYTE, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteByte(p.Valuei8); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuei16", thrift.I16, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI16(p.Valuei16); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuei32", thrift.I32, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI32(p.Valuei32); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField4(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuei64", thrift.I64, 4); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI64(p.Valuei64); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField5(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuestring", thrift.STRING, 5); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Valuestring); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField6(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuebyte", thrift.BYTE, 6); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteByte(p.Valuebyte); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField7(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuedouble", thrift.DOUBLE, 7); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteDouble(p.Valuedouble); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 7 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 7 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField8(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuebinary", thrift.STRING, 8); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBinary([]byte(p.Valuebinary)); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 8 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 8 end error: ", p), err) +} + +func (p *PersonBasicInfo) writeField9(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuebool", thrift.BOOL, 9); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBool(p.Valuebool); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 9 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 9 end error: ", p), err) +} + +func (p *PersonBasicInfo) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PersonBasicInfo(%+v)", *p) +} + +type PersonContainerInfo struct { + Valuemap map[string]string `thrift:"valuemap,1,required" json:"valuemap"` + Valuelist []string `thrift:"valuelist,2,required" json:"valuelist"` + Valueset []string `thrift:"valueset,3,required" json:"valueset"` + Valuelistset [][]string `thrift:"valuelistset,4,required" json:"valuelistset"` + Valuelistsetstruct [][]*InnerStruct `thrift:"valuelistsetstruct,5,required" json:"valuelistsetstruct"` + Valuemapstruct map[string]*InnerStruct `thrift:"valuemapstruct,6,required" json:"valuemapstruct"` +} + +func NewPersonContainerInfo() *PersonContainerInfo { + return &PersonContainerInfo{} +} + +func (p *PersonContainerInfo) GetValuemap() (v map[string]string) { + return p.Valuemap +} + +func (p *PersonContainerInfo) GetValuelist() (v []string) { + return p.Valuelist +} + +func (p *PersonContainerInfo) GetValueset() (v []string) { + return p.Valueset +} + +func (p *PersonContainerInfo) GetValuelistset() (v [][]string) { + return p.Valuelistset +} + +func (p *PersonContainerInfo) GetValuelistsetstruct() (v [][]*InnerStruct) { + return p.Valuelistsetstruct +} + +func (p *PersonContainerInfo) GetValuemapstruct() (v map[string]*InnerStruct) { + return p.Valuemapstruct +} + +var fieldIDToName_PersonContainerInfo = map[int16]string{ + 1: "valuemap", + 2: "valuelist", + 3: "valueset", + 4: "valuelistset", + 5: "valuelistsetstruct", + 6: "valuemapstruct", +} + +func (p *PersonContainerInfo) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetValuemap bool = false + var issetValuelist bool = false + var issetValueset bool = false + var issetValuelistset bool = false + var issetValuelistsetstruct bool = false + var issetValuemapstruct bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.MAP { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetValuemap = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.LIST { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetValuelist = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.SET { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetValueset = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 4: + if fieldTypeId == thrift.LIST { + if err = p.ReadField4(iprot); err != nil { + goto ReadFieldError + } + issetValuelistset = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 5: + if fieldTypeId == thrift.LIST { + if err = p.ReadField5(iprot); err != nil { + goto ReadFieldError + } + issetValuelistsetstruct = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 6: + if fieldTypeId == thrift.MAP { + if err = p.ReadField6(iprot); err != nil { + goto ReadFieldError + } + issetValuemapstruct = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetValuemap { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetValuelist { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetValueset { + fieldId = 3 + goto RequiredFieldNotSetError + } + + if !issetValuelistset { + fieldId = 4 + goto RequiredFieldNotSetError + } + + if !issetValuelistsetstruct { + fieldId = 5 + goto RequiredFieldNotSetError + } + + if !issetValuemapstruct { + fieldId = 6 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_PersonContainerInfo[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_PersonContainerInfo[fieldId])) +} + +func (p *PersonContainerInfo) ReadField1(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + p.Valuemap = make(map[string]string, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + + var _val string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _val = v + } + + p.Valuemap[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + return nil +} + +func (p *PersonContainerInfo) ReadField2(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + p.Valuelist = make([]string, 0, size) + for i := 0; i < size; i++ { + var _elem string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _elem = v + } + + p.Valuelist = append(p.Valuelist, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + return nil +} + +func (p *PersonContainerInfo) ReadField3(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadSetBegin() + if err != nil { + return err + } + p.Valueset = make([]string, 0, size) + for i := 0; i < size; i++ { + var _elem string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _elem = v + } + + p.Valueset = append(p.Valueset, _elem) + } + if err := iprot.ReadSetEnd(); err != nil { + return err + } + return nil +} + +func (p *PersonContainerInfo) ReadField4(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + p.Valuelistset = make([][]string, 0, size) + for i := 0; i < size; i++ { + _, size, err := iprot.ReadSetBegin() + if err != nil { + return err + } + _elem := make([]string, 0, size) + for i := 0; i < size; i++ { + var _elem1 string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _elem1 = v + } + + _elem = append(_elem, _elem1) + } + if err := iprot.ReadSetEnd(); err != nil { + return err + } + + p.Valuelistset = append(p.Valuelistset, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + return nil +} + +func (p *PersonContainerInfo) ReadField5(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + p.Valuelistsetstruct = make([][]*InnerStruct, 0, size) + for i := 0; i < size; i++ { + _, size, err := iprot.ReadSetBegin() + if err != nil { + return err + } + _elem := make([]*InnerStruct, 0, size) + for i := 0; i < size; i++ { + _elem1 := NewInnerStruct() + if err := _elem1.Read(iprot); err != nil { + return err + } + + _elem = append(_elem, _elem1) + } + if err := iprot.ReadSetEnd(); err != nil { + return err + } + + p.Valuelistsetstruct = append(p.Valuelistsetstruct, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + return nil +} + +func (p *PersonContainerInfo) ReadField6(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + p.Valuemapstruct = make(map[string]*InnerStruct, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + _val := NewInnerStruct() + if err := _val.Read(iprot); err != nil { + return err + } + + p.Valuemapstruct[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + return nil +} + +func (p *PersonContainerInfo) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("PersonContainerInfo"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + if err = p.writeField4(oprot); err != nil { + fieldId = 4 + goto WriteFieldError + } + if err = p.writeField5(oprot); err != nil { + fieldId = 5 + goto WriteFieldError + } + if err = p.writeField6(oprot); err != nil { + fieldId = 6 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PersonContainerInfo) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuemap", thrift.MAP, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRING, len(p.Valuemap)); err != nil { + return err + } + for k, v := range p.Valuemap { + + if err := oprot.WriteString(k); err != nil { + return err + } + + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *PersonContainerInfo) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuelist", thrift.LIST, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.STRING, len(p.Valuelist)); err != nil { + return err + } + for _, v := range p.Valuelist { + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *PersonContainerInfo) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valueset", thrift.SET, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteSetBegin(thrift.STRING, len(p.Valueset)); err != nil { + return err + } + for i := 0; i < len(p.Valueset); i++ { + for j := i + 1; j < len(p.Valueset); j++ { + if reflect.DeepEqual(p.Valueset[i], p.Valueset[j]) { + return thrift.PrependError("", fmt.Errorf("%T error writing set field: slice is not unique", p.Valueset[i])) + } + } + } + for _, v := range p.Valueset { + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteSetEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *PersonContainerInfo) writeField4(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuelistset", thrift.LIST, 4); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.SET, len(p.Valuelistset)); err != nil { + return err + } + for _, v := range p.Valuelistset { + if err := oprot.WriteSetBegin(thrift.STRING, len(v)); err != nil { + return err + } + for i := 0; i < len(v); i++ { + for j := i + 1; j < len(v); j++ { + if reflect.DeepEqual(v[i], v[j]) { + return thrift.PrependError("", fmt.Errorf("%T error writing set field: slice is not unique", v[i])) + } + } + } + for _, v := range v { + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteSetEnd(); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err) +} + +func (p *PersonContainerInfo) writeField5(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuelistsetstruct", thrift.LIST, 5); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.SET, len(p.Valuelistsetstruct)); err != nil { + return err + } + for _, v := range p.Valuelistsetstruct { + if err := oprot.WriteSetBegin(thrift.STRUCT, len(v)); err != nil { + return err + } + for i := 0; i < len(v); i++ { + for j := i + 1; j < len(v); j++ { + if reflect.DeepEqual(v[i], v[j]) { + return thrift.PrependError("", fmt.Errorf("%T error writing set field: slice is not unique", v[i])) + } + } + } + for _, v := range v { + if err := v.Write(oprot); err != nil { + return err + } + } + if err := oprot.WriteSetEnd(); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err) +} + +func (p *PersonContainerInfo) writeField6(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuemapstruct", thrift.MAP, 6); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRUCT, len(p.Valuemapstruct)); err != nil { + return err + } + for k, v := range p.Valuemapstruct { + + if err := oprot.WriteString(k); err != nil { + return err + } + + if err := v.Write(oprot); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err) +} + +func (p *PersonContainerInfo) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PersonContainerInfo(%+v)", *p) +} + +type PersonStructInfo struct { + Valueteststruct *TestStruct `thrift:"valueteststruct,1,required" json:"valueteststruct"` + Valuestruct *InnerStruct `thrift:"valuestruct,2,required" json:"valuestruct"` + Valueenum TestEnum `thrift:"valueenum,3,required" json:"valueenum"` + Valuestructtypedef *TestStructTypedef `thrift:"valuestructtypedef,4,required" json:"valuestructtypedef"` + Valuebasictypedef TestBasicTypedef `thrift:"valuebasictypedef,5,required" json:"valuebasictypedef"` +} + +func NewPersonStructInfo() *PersonStructInfo { + return &PersonStructInfo{} +} + +var PersonStructInfo_Valueteststruct_DEFAULT *TestStruct + +func (p *PersonStructInfo) GetValueteststruct() (v *TestStruct) { + if !p.IsSetValueteststruct() { + return PersonStructInfo_Valueteststruct_DEFAULT + } + return p.Valueteststruct +} + +var PersonStructInfo_Valuestruct_DEFAULT *InnerStruct + +func (p *PersonStructInfo) GetValuestruct() (v *InnerStruct) { + if !p.IsSetValuestruct() { + return PersonStructInfo_Valuestruct_DEFAULT + } + return p.Valuestruct +} + +func (p *PersonStructInfo) GetValueenum() (v TestEnum) { + return p.Valueenum +} + +var PersonStructInfo_Valuestructtypedef_DEFAULT *TestStructTypedef + +func (p *PersonStructInfo) GetValuestructtypedef() (v *TestStructTypedef) { + if !p.IsSetValuestructtypedef() { + return PersonStructInfo_Valuestructtypedef_DEFAULT + } + return p.Valuestructtypedef +} + +func (p *PersonStructInfo) GetValuebasictypedef() (v TestBasicTypedef) { + return p.Valuebasictypedef +} + +var fieldIDToName_PersonStructInfo = map[int16]string{ + 1: "valueteststruct", + 2: "valuestruct", + 3: "valueenum", + 4: "valuestructtypedef", + 5: "valuebasictypedef", +} + +func (p *PersonStructInfo) IsSetValueteststruct() bool { + return p.Valueteststruct != nil +} + +func (p *PersonStructInfo) IsSetValuestruct() bool { + return p.Valuestruct != nil +} + +func (p *PersonStructInfo) IsSetValuestructtypedef() bool { + return p.Valuestructtypedef != nil +} + +func (p *PersonStructInfo) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetValueteststruct bool = false + var issetValuestruct bool = false + var issetValueenum bool = false + var issetValuestructtypedef bool = false + var issetValuebasictypedef bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetValueteststruct = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetValuestruct = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.I32 { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetValueenum = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 4: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField4(iprot); err != nil { + goto ReadFieldError + } + issetValuestructtypedef = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 5: + if fieldTypeId == thrift.STRING { + if err = p.ReadField5(iprot); err != nil { + goto ReadFieldError + } + issetValuebasictypedef = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetValueteststruct { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetValuestruct { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetValueenum { + fieldId = 3 + goto RequiredFieldNotSetError + } + + if !issetValuestructtypedef { + fieldId = 4 + goto RequiredFieldNotSetError + } + + if !issetValuebasictypedef { + fieldId = 5 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_PersonStructInfo[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_PersonStructInfo[fieldId])) +} + +func (p *PersonStructInfo) ReadField1(iprot thrift.TProtocol) error { + p.Valueteststruct = NewTestStruct() + if err := p.Valueteststruct.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *PersonStructInfo) ReadField2(iprot thrift.TProtocol) error { + p.Valuestruct = NewInnerStruct() + if err := p.Valuestruct.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *PersonStructInfo) ReadField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return err + } else { + p.Valueenum = TestEnum(v) + } + return nil +} + +func (p *PersonStructInfo) ReadField4(iprot thrift.TProtocol) error { + p.Valuestructtypedef = NewTestStructTypedef() + if err := p.Valuestructtypedef.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *PersonStructInfo) ReadField5(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Valuebasictypedef = v + } + return nil +} + +func (p *PersonStructInfo) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("PersonStructInfo"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + if err = p.writeField4(oprot); err != nil { + fieldId = 4 + goto WriteFieldError + } + if err = p.writeField5(oprot); err != nil { + fieldId = 5 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PersonStructInfo) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valueteststruct", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.Valueteststruct.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *PersonStructInfo) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuestruct", thrift.STRUCT, 2); err != nil { + goto WriteFieldBeginError + } + if err := p.Valuestruct.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *PersonStructInfo) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valueenum", thrift.I32, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI32(int32(p.Valueenum)); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *PersonStructInfo) writeField4(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuestructtypedef", thrift.STRUCT, 4); err != nil { + goto WriteFieldBeginError + } + if err := p.Valuestructtypedef.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err) +} + +func (p *PersonStructInfo) writeField5(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("valuebasictypedef", thrift.STRING, 5); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Valuebasictypedef); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err) +} + +func (p *PersonStructInfo) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PersonStructInfo(%+v)", *p) +} + +type TestStruct struct { + Name string `thrift:"name,1,required" json:"name"` + Age string `thrift:"age,2,required" json:"age"` + InnerStruct *InnerStruct `thrift:"innerStruct,3,required" json:"innerStruct"` +} + +func NewTestStruct() *TestStruct { + return &TestStruct{} +} + +func (p *TestStruct) GetName() (v string) { + return p.Name +} + +func (p *TestStruct) GetAge() (v string) { + return p.Age +} + +var TestStruct_InnerStruct_DEFAULT *InnerStruct + +func (p *TestStruct) GetInnerStruct() (v *InnerStruct) { + if !p.IsSetInnerStruct() { + return TestStruct_InnerStruct_DEFAULT + } + return p.InnerStruct +} + +var fieldIDToName_TestStruct = map[int16]string{ + 1: "name", + 2: "age", + 3: "innerStruct", +} + +func (p *TestStruct) IsSetInnerStruct() bool { + return p.InnerStruct != nil +} + +func (p *TestStruct) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetName bool = false + var issetAge bool = false + var issetInnerStruct bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetName = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.STRING { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetAge = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetInnerStruct = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetName { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetAge { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetInnerStruct { + fieldId = 3 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_TestStruct[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_TestStruct[fieldId])) +} + +func (p *TestStruct) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Name = v + } + return nil +} + +func (p *TestStruct) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Age = v + } + return nil +} + +func (p *TestStruct) ReadField3(iprot thrift.TProtocol) error { + p.InnerStruct = NewInnerStruct() + if err := p.InnerStruct.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *TestStruct) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("TestStruct"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *TestStruct) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("name", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Name); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *TestStruct) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("age", thrift.STRING, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Age); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *TestStruct) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("innerStruct", thrift.STRUCT, 3); err != nil { + goto WriteFieldBeginError + } + if err := p.InnerStruct.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *TestStruct) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("TestStruct(%+v)", *p) +} + +var ( + STRUCT_OPTION_PERSON_BASIC_INFO = thrift_option.NewStructOption("../option_idl/annotations/entity/entity.thrift", "person_basic_info") + STRUCT_OPTION_PERSON_STRUCT_INFO = thrift_option.NewStructOption("../option_idl/annotations/entity/entity.thrift", "person_struct_info") + STRUCT_OPTION_PERSON_CONTAINER_INFO = thrift_option.NewStructOption("../option_idl/annotations/entity/entity.thrift", "person_container_info") + FIELD_OPTION_PERSON_FIELD_INFO = thrift_option.NewFieldOption("../option_idl/annotations/entity/entity.thrift", "person_field_info") +) diff --git a/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity_struct-reflection.go b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity_struct-reflection.go new file mode 100644 index 00000000..3c51a8b7 --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity_struct-reflection.go @@ -0,0 +1,65 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package entity + +import ( + "reflect" + + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +// IDL Name: entity_struct +// IDL Path: ../option_idl/annotations/entity/entity_struct.thrift + +var file_entity_struct_thrift_go_types = []interface{}{ + (*InnerStruct)(nil), // Struct 0: entity.InnerStruct +} +var file_entity_struct_thrift *thrift_reflection.FileDescriptor +var file_idl_entity_struct_rawDesc = []byte{ + 0x1f, 0x8b, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xac, 0x90, 0x4b, 0x4e, 0xc3, 0x30, + 0x10, 0x40, 0x5f, 0xf3, 0x69, 0x3, 0xd3, 0x28, 0x17, 0xe0, 0xc, 0xce, 0x8a, 0x43, 0xb0, 0x85, + 0x3, 0x54, 0x11, 0x35, 0xc1, 0x52, 0x19, 0x83, 0x33, 0x5d, 0x70, 0x7b, 0xe4, 0xc4, 0x88, 0x3, + 0x94, 0xd5, 0xf3, 0x47, 0xf3, 0x34, 0x7a, 0xc2, 0xe, 0x78, 0x74, 0x6e, 0x8c, 0x9f, 0x16, 0xa2, + 0x9e, 0xc2, 0xf9, 0x32, 0x4e, 0xaa, 0xd1, 0xa6, 0x7c, 0x5d, 0x46, 0xaf, 0x16, 0xec, 0xbb, 0xe0, + 0xb4, 0x58, 0xba, 0xbe, 0x9a, 0xb3, 0xf7, 0x14, 0xde, 0xac, 0xa7, 0x12, 0x1, 0xe8, 0xa9, 0xd7, + 0x43, 0x56, 0x55, 0x73, 0x4, 0x1e, 0x8a, 0x6d, 0xf6, 0xea, 0xfe, 0x6c, 0x6e, 0xb3, 0xc, 0x34, + 0xc7, 0x3c, 0x36, 0xd0, 0x66, 0xee, 0x6e, 0xd9, 0x41, 0xa8, 0x0, 0x79, 0x52, 0xf5, 0xe9, 0x65, + 0xfd, 0x18, 0xa8, 0xff, 0xc9, 0xda, 0xfa, 0x8f, 0x29, 0x5c, 0x8e, 0xd4, 0xb7, 0xab, 0xf6, 0x8b, + 0xa5, 0xa0, 0x33, 0x42, 0x3, 0x74, 0xcf, 0xfe, 0xeb, 0x1a, 0x92, 0x3f, 0x77, 0xb4, 0x79, 0xd5, + 0x9e, 0x83, 0xc, 0xb9, 0x88, 0xd0, 0xb1, 0x5, 0x6d, 0x7e, 0x1f, 0x5a, 0xb6, 0x54, 0xfb, 0x92, + 0xec, 0x50, 0xd8, 0x15, 0xde, 0x15, 0xde, 0xaf, 0xe4, 0x27, 0x0, 0x0, 0xff, 0xff, 0x88, 0x5f, + 0x20, 0x80, 0xd0, 0x1, 0x0, 0x0, +} + +func init() { + if file_entity_struct_thrift != nil { + return + } + type x struct{} + builder := &thrift_reflection.FileDescriptorBuilder{ + Bytes: file_idl_entity_struct_rawDesc, + GoTypes: file_entity_struct_thrift_go_types, + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + } + file_entity_struct_thrift = thrift_reflection.BuildFileDescriptor(builder) +} + +func GetFileDescriptorForEntityStruct() *thrift_reflection.FileDescriptor { + return file_entity_struct_thrift +} +func (p *InnerStruct) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_entity_struct_thrift.GetStructDescriptor("InnerStruct") +} diff --git a/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity_struct.go b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity_struct.go new file mode 100644 index 00000000..70b0514b --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/annotation/entity/entity_struct.go @@ -0,0 +1,166 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package entity + +import ( + "fmt" + "github.com/apache/thrift/lib/go/thrift" +) + +type InnerStruct struct { + Email string `thrift:"email,1,required" json:"email"` +} + +func NewInnerStruct() *InnerStruct { + return &InnerStruct{} +} + +func (p *InnerStruct) GetEmail() (v string) { + return p.Email +} + +var fieldIDToName_InnerStruct = map[int16]string{ + 1: "email", +} + +func (p *InnerStruct) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetEmail bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetEmail = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetEmail { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_InnerStruct[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_InnerStruct[fieldId])) +} + +func (p *InnerStruct) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Email = v + } + return nil +} + +func (p *InnerStruct) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("InnerStruct"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *InnerStruct) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("email", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Email); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *InnerStruct) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("InnerStruct(%+v)", *p) +} diff --git a/extension/thrift_option/runtime_test/option_gen/annotation/validation/validation-reflection.go b/extension/thrift_option/runtime_test/option_gen/annotation/validation/validation-reflection.go new file mode 100644 index 00000000..a9d6e0cd --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/annotation/validation/validation-reflection.go @@ -0,0 +1,138 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package validation + +import ( + "reflect" + + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +// IDL Name: validation +// IDL Path: ../option_idl/annotations/validation/validation.thrift + +var file_validation_thrift_go_types = []interface{}{ + (*_StructOptions)(nil), // Struct 0: validation._StructOptions + (*MyStructWithDefaultVal)(nil), // Struct 1: validation.MyStructWithDefaultVal + (*_FieldOptions)(nil), // Struct 2: validation._FieldOptions + (*TestInfo)(nil), // Struct 3: validation.TestInfo + (*_ServiceOptions)(nil), // Struct 4: validation._ServiceOptions + (*_MethodOptions)(nil), // Struct 5: validation._MethodOptions + (*_EnumOptions)(nil), // Struct 6: validation._EnumOptions + (*_EnumValueOptions)(nil), // Struct 7: validation._EnumValueOptions + (*MyEnum)(nil), // Enum 0: validation.MyEnum + (*MyBasicTypedef)(nil), // Enum 0: validation.MyBasicTypedef + (*MyStructTypedef)(nil), // Enum 1: validation.MyStructTypedef +} +var file_validation_thrift *thrift_reflection.FileDescriptor +var file_idl_validation_rawDesc = []byte{ + 0x1f, 0x8b, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xe4, 0x99, 0xdf, 0x6e, 0xda, 0x3e, + 0x14, 0xc7, 0xf, 0x4e, 0x42, 0x43, 0x3, 0x4d, 0x7f, 0xbf, 0x8b, 0x49, 0xdb, 0x15, 0x7b, 0x1, + 0x3a, 0x68, 0xc7, 0xba, 0xbb, 0x6a, 0x5a, 0xa7, 0x4d, 0x2a, 0xab, 0xb4, 0x56, 0x5d, 0xef, 0xa2, + 0x40, 0x4c, 0xb1, 0x9a, 0x3f, 0x2c, 0x71, 0x22, 0xf1, 0x6c, 0x7b, 0xb4, 0xdd, 0x4c, 0x4e, 0x42, + 0x0, 0x11, 0x4a, 0x25, 0x8e, 0xd3, 0x75, 0xeb, 0x4d, 0x5c, 0x14, 0x1f, 0xfb, 0xf3, 0x3d, 0x3e, + 0xc7, 0xc7, 0x8e, 0x1, 0x35, 0x0, 0xe8, 0x77, 0x3a, 0x47, 0xc1, 0x94, 0xb3, 0xc0, 0xb7, 0x98, + 0xe3, 0x1e, 0xd9, 0xbe, 0x1f, 0x70, 0x5b, 0xfc, 0x1b, 0x1d, 0x25, 0xb6, 0xcb, 0x9c, 0xb4, 0xbd, + 0xd4, 0xec, 0xf0, 0x49, 0xc8, 0xc6, 0xbc, 0x5, 0xc4, 0x30, 0x0, 0x0, 0x5a, 0xa0, 0xa4, 0xd, + 0x61, 0x8b, 0xdc, 0x5, 0x0, 0xd0, 0xce, 0xcd, 0xdd, 0x51, 0xbf, 0xb3, 0x30, 0xd7, 0x59, 0x98, + 0x30, 0x41, 0x6d, 0x8a, 0xae, 0x26, 0x68, 0xe2, 0xa9, 0xef, 0x34, 0x11, 0x3, 0x8, 0x0, 0x1c, + 0x58, 0x57, 0x3c, 0x8c, 0x47, 0xfc, 0x32, 0x35, 0x10, 0x99, 0xa0, 0x8, 0xcb, 0x75, 0x4, 0xcb, + 0xff, 0x4f, 0x69, 0x18, 0x5, 0xbe, 0x15, 0xf1, 0x90, 0xf9, 0x77, 0x16, 0xf3, 0xc7, 0x41, 0x13, + 0x14, 0x4, 0xc3, 0xf5, 0xcc, 0x22, 0x18, 0xa0, 0xa, 0x11, 0xbe, 0xd1, 0x1f, 0x31, 0xb, 0xa9, + 0xa3, 0x83, 0x26, 0xd4, 0x6c, 0xc1, 0x9e, 0x61, 0xa, 0x91, 0xc, 0xd0, 0x21, 0x7b, 0xee, 0x3c, + 0xa2, 0x99, 0xa3, 0x78, 0xf6, 0x14, 0x91, 0x43, 0xf1, 0xec, 0x29, 0xae, 0x22, 0x4d, 0x50, 0x11, + 0xad, 0x95, 0xb, 0x4c, 0x64, 0x8, 0x7c, 0x98, 0xb, 0x4c, 0xfd, 0xd8, 0xc3, 0x5c, 0x29, 0x83, + 0xd9, 0xb9, 0x1f, 0x7b, 0xe5, 0x20, 0x8a, 0xc, 0x90, 0x97, 0x39, 0xc8, 0xd0, 0x8e, 0xd8, 0xc8, + 0xe2, 0xb3, 0x29, 0x75, 0xe8, 0x18, 0x91, 0xe8, 0x60, 0x30, 0xfb, 0x20, 0x4c, 0x5f, 0x67, 0x96, + 0xcb, 0xc9, 0x54, 0x19, 0x64, 0xaf, 0x16, 0xe1, 0x1c, 0x8f, 0xb8, 0x4, 0x34, 0x73, 0x30, 0xcb, + 0x52, 0xd1, 0x83, 0x6c, 0x9a, 0xc, 0xb6, 0xf6, 0x2a, 0x9b, 0x43, 0xc7, 0x76, 0xec, 0x72, 0x2b, + 0xb1, 0xdd, 0x98, 0x22, 0x12, 0xbe, 0x98, 0x13, 0x7e, 0x67, 0x7c, 0xf2, 0x31, 0x1b, 0xe4, 0xc6, + 0x76, 0xcb, 0x41, 0xeb, 0x6b, 0xa0, 0x2d, 0x50, 0xe7, 0x3f, 0x68, 0x58, 0xe4, 0x1b, 0xa6, 0x94, + 0x6f, 0x3, 0x6, 0xc2, 0x8, 0x24, 0xe9, 0x3e, 0xd7, 0xb4, 0x4f, 0x92, 0x5e, 0x5, 0x53, 0x27, + 0x4d, 0xa8, 0xeb, 0x59, 0x15, 0xa0, 0xa6, 0x6f, 0xa7, 0x7f, 0xfb, 0xa0, 0xcc, 0x9b, 0x59, 0x2f, + 0x92, 0xf4, 0x8, 0x68, 0x4b, 0x8b, 0x41, 0x6, 0xef, 0x31, 0xe, 0x2f, 0x61, 0xa7, 0x1b, 0x72, + 0x6e, 0xc1, 0x5a, 0x2b, 0x65, 0xd5, 0xb3, 0x5e, 0x20, 0x9f, 0xf4, 0x4, 0x69, 0xf, 0x67, 0xdd, + 0xfe, 0x86, 0x24, 0xbc, 0x5, 0xf5, 0xb0, 0x32, 0xd4, 0xb7, 0x58, 0xa8, 0xc7, 0xbd, 0xd, 0x39, + 0x79, 0xb, 0x6a, 0xbb, 0x32, 0xd4, 0x3e, 0x16, 0x6a, 0xff, 0x64, 0x43, 0x56, 0xde, 0x82, 0x7a, + 0x56, 0x19, 0xea, 0x3b, 0x1c, 0x54, 0x75, 0x18, 0x4, 0x1b, 0x76, 0xa0, 0xbd, 0x82, 0x55, 0x79, + 0x28, 0x31, 0x9, 0xd6, 0x9a, 0x5c, 0xd6, 0x53, 0xa4, 0x34, 0xec, 0x4, 0xf1, 0xd0, 0xa5, 0xe5, + 0xb4, 0x7a, 0x41, 0xb, 0x2a, 0x90, 0xb3, 0xc6, 0xeb, 0x5f, 0x5f, 0x7f, 0x36, 0x6e, 0x4a, 0x69, + 0x25, 0x7b, 0xf6, 0xfd, 0xbf, 0x7c, 0xbc, 0x68, 0x14, 0x6e, 0xd0, 0xb6, 0x2d, 0x3a, 0x21, 0x7f, + 0x53, 0x94, 0x29, 0xb5, 0xc7, 0x6c, 0x9f, 0xf7, 0xdd, 0x65, 0xcf, 0x3d, 0x6a, 0xc3, 0x5d, 0xe9, + 0x21, 0xd3, 0xe7, 0x4a, 0xd2, 0x7d, 0x83, 0x14, 0xce, 0x2e, 0x8b, 0x78, 0x15, 0x7e, 0xda, 0x2f, + 0xfc, 0xa4, 0x6e, 0xf5, 0x93, 0x29, 0xd2, 0x26, 0x0, 0x91, 0xe3, 0xa6, 0xfb, 0x5e, 0x85, 0x6e, + 0xaa, 0xa2, 0x96, 0x35, 0xa, 0x69, 0xeb, 0x5b, 0xa5, 0xcd, 0xe8, 0xb4, 0xcf, 0xe7, 0x17, 0x17, + 0x97, 0xeb, 0xcc, 0x32, 0x4e, 0xc, 0x2d, 0xeb, 0x13, 0xa3, 0xae, 0xb3, 0x7a, 0x5f, 0x54, 0xc3, + 0x38, 0xff, 0x8d, 0xec, 0xd0, 0xb1, 0xc6, 0xc2, 0xf8, 0xd3, 0x5d, 0x16, 0xc9, 0x50, 0x4c, 0xbf, + 0xa6, 0x11, 0xff, 0xe2, 0x8f, 0x83, 0x5c, 0x2c, 0x82, 0x11, 0xe7, 0xbe, 0xed, 0xd1, 0xe7, 0x7a, + 0xae, 0xaa, 0xfb, 0xb1, 0x37, 0xa4, 0xa1, 0xec, 0xa, 0x7c, 0xfd, 0xa6, 0x4a, 0x86, 0x77, 0x4d, + 0xeb, 0x8a, 0x86, 0x9, 0x1b, 0x51, 0xfc, 0x88, 0xd0, 0xa3, 0x64, 0x84, 0x18, 0xa, 0xc5, 0x3a, + 0x7c, 0xca, 0x60, 0x38, 0xb0, 0x6, 0x94, 0x4f, 0x2, 0x9, 0xf9, 0xc3, 0xf0, 0x52, 0xc3, 0x7f, + 0x9b, 0x60, 0x4d, 0xeb, 0xdc, 0x8f, 0x3d, 0x7c, 0xb9, 0x1a, 0xc8, 0x77, 0xad, 0x7f, 0x84, 0x58, + 0xff, 0xa5, 0x62, 0xdd, 0xd8, 0x6e, 0x2c, 0x21, 0x1c, 0xcd, 0x54, 0x31, 0xec, 0x4b, 0xc1, 0xdd, + 0x75, 0xcb, 0xcb, 0x2b, 0x30, 0xc5, 0x89, 0xd, 0x7, 0x35, 0xbf, 0x38, 0xcf, 0xc5, 0xc3, 0xc0, + 0xac, 0xdd, 0x2e, 0x15, 0x30, 0x32, 0x5c, 0x4f, 0x6e, 0x2f, 0x16, 0x23, 0xd4, 0x64, 0x8c, 0xa0, + 0xdc, 0x2e, 0xf, 0x41, 0xd6, 0x86, 0x28, 0x71, 0x8c, 0xbe, 0xfb, 0x7e, 0xdf, 0x44, 0xa9, 0x17, + 0x16, 0x9b, 0xbc, 0xb2, 0xfe, 0x15, 0x1, 0x57, 0x2c, 0x9c, 0x9, 0x2f, 0x87, 0x85, 0x52, 0xf2, + 0x75, 0xa0, 0x44, 0xec, 0x46, 0x1e, 0x5, 0xfb, 0x58, 0x51, 0x90, 0x95, 0xd5, 0xe8, 0x67, 0xe8, + 0x47, 0x1c, 0x6a, 0x8c, 0x9, 0x75, 0xdd, 0xa0, 0xcd, 0x27, 0x34, 0xa4, 0xab, 0x17, 0xe, 0xda, + 0x9c, 0xba, 0x9e, 0xbd, 0xff, 0x3b, 0x0, 0x0, 0xff, 0xff, 0xe5, 0x36, 0x93, 0x4d, 0x8c, 0x1e, + 0x0, 0x0, +} + +func init() { + if file_validation_thrift != nil { + return + } + type x struct{} + builder := &thrift_reflection.FileDescriptorBuilder{ + Bytes: file_idl_validation_rawDesc, + GoTypes: file_validation_thrift_go_types, + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + } + file_validation_thrift = thrift_reflection.BuildFileDescriptor(builder) +} + +func GetFileDescriptorForValidation() *thrift_reflection.FileDescriptor { + return file_validation_thrift +} +func (p *_StructOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("_StructOptions") +} +func (p *MyStructWithDefaultVal) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("MyStructWithDefaultVal") +} +func (p *_FieldOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("_FieldOptions") +} +func (p *TestInfo) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("TestInfo") +} +func (p *_ServiceOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("_ServiceOptions") +} +func (p *_MethodOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("_MethodOptions") +} +func (p *_EnumOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("_EnumOptions") +} +func (p *_EnumValueOptions) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_validation_thrift.GetStructDescriptor("_EnumValueOptions") +} +func (p MyEnum) GetDescriptor() *thrift_reflection.EnumDescriptor { + return file_validation_thrift.GetEnumDescriptor("MyEnum") +} diff --git a/extension/thrift_option/runtime_test/option_gen/annotation/validation/validation.go b/extension/thrift_option/runtime_test/option_gen/annotation/validation/validation.go new file mode 100644 index 00000000..bb5ab558 --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/annotation/validation/validation.go @@ -0,0 +1,2257 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package validation + +import ( + "database/sql" + "database/sql/driver" + "fmt" + "github.com/apache/thrift/lib/go/thrift" + "github.com/cloudwego/thriftgo/extension/thrift_option" +) + +const ( + HELLO = "hello there" +) + +type MyEnum int64 + +const ( + MyEnum_X MyEnum = 0 + MyEnum_XL MyEnum = 1 + MyEnum_XXL MyEnum = 2 +) + +func (p MyEnum) String() string { + switch p { + case MyEnum_X: + return "X" + case MyEnum_XL: + return "XL" + case MyEnum_XXL: + return "XXL" + } + return "" +} + +func MyEnumFromString(s string) (MyEnum, error) { + switch s { + case "X": + return MyEnum_X, nil + case "XL": + return MyEnum_XL, nil + case "XXL": + return MyEnum_XXL, nil + } + return MyEnum(0), fmt.Errorf("not a valid MyEnum string") +} + +func MyEnumPtr(v MyEnum) *MyEnum { return &v } +func (p *MyEnum) Scan(value interface{}) (err error) { + var result sql.NullInt64 + err = result.Scan(value) + *p = MyEnum(result.Int64) + return +} + +func (p *MyEnum) Value() (driver.Value, error) { + if p == nil { + return nil, nil + } + return int64(*p), nil +} + +type MyBasicTypedef = string + +type MyStructTypedef = TestInfo + +func NewMyStructTypedef() *MyStructTypedef { + return (*MyStructTypedef)(NewTestInfo()) +} + +type _StructOptions struct { + PersonStringInfo string `thrift:"person_string_info,1,required" json:"person_string_info"` + PersonMapInfo map[string]string `thrift:"person_map_info,2,required" json:"person_map_info"` + PersonEnumInfo MyEnum `thrift:"person_enum_info,3,required" json:"person_enum_info"` + PersonBasicTypedefInfo MyBasicTypedef `thrift:"person_basic_typedef_info,4,required" json:"person_basic_typedef_info"` + PersonStructTypedefInfo *MyStructTypedef `thrift:"person_struct_typedef_info,5,required" json:"person_struct_typedef_info"` + PersonStructDefaultValueInfo *MyStructWithDefaultVal `thrift:"person_struct_default_value_info,6,required" json:"person_struct_default_value_info"` +} + +func New_StructOptions() *_StructOptions { + return &_StructOptions{} +} + +func (p *_StructOptions) GetPersonStringInfo() (v string) { + return p.PersonStringInfo +} + +func (p *_StructOptions) GetPersonMapInfo() (v map[string]string) { + return p.PersonMapInfo +} + +func (p *_StructOptions) GetPersonEnumInfo() (v MyEnum) { + return p.PersonEnumInfo +} + +func (p *_StructOptions) GetPersonBasicTypedefInfo() (v MyBasicTypedef) { + return p.PersonBasicTypedefInfo +} + +var _StructOptions_PersonStructTypedefInfo_DEFAULT *MyStructTypedef + +func (p *_StructOptions) GetPersonStructTypedefInfo() (v *MyStructTypedef) { + if !p.IsSetPersonStructTypedefInfo() { + return _StructOptions_PersonStructTypedefInfo_DEFAULT + } + return p.PersonStructTypedefInfo +} + +var _StructOptions_PersonStructDefaultValueInfo_DEFAULT *MyStructWithDefaultVal + +func (p *_StructOptions) GetPersonStructDefaultValueInfo() (v *MyStructWithDefaultVal) { + if !p.IsSetPersonStructDefaultValueInfo() { + return _StructOptions_PersonStructDefaultValueInfo_DEFAULT + } + return p.PersonStructDefaultValueInfo +} + +var fieldIDToName__StructOptions = map[int16]string{ + 1: "person_string_info", + 2: "person_map_info", + 3: "person_enum_info", + 4: "person_basic_typedef_info", + 5: "person_struct_typedef_info", + 6: "person_struct_default_value_info", +} + +func (p *_StructOptions) IsSetPersonStructTypedefInfo() bool { + return p.PersonStructTypedefInfo != nil +} + +func (p *_StructOptions) IsSetPersonStructDefaultValueInfo() bool { + return p.PersonStructDefaultValueInfo != nil +} + +func (p *_StructOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetPersonStringInfo bool = false + var issetPersonMapInfo bool = false + var issetPersonEnumInfo bool = false + var issetPersonBasicTypedefInfo bool = false + var issetPersonStructTypedefInfo bool = false + var issetPersonStructDefaultValueInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetPersonStringInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.MAP { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetPersonMapInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.I32 { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetPersonEnumInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 4: + if fieldTypeId == thrift.STRING { + if err = p.ReadField4(iprot); err != nil { + goto ReadFieldError + } + issetPersonBasicTypedefInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 5: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField5(iprot); err != nil { + goto ReadFieldError + } + issetPersonStructTypedefInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 6: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField6(iprot); err != nil { + goto ReadFieldError + } + issetPersonStructDefaultValueInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetPersonStringInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetPersonMapInfo { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetPersonEnumInfo { + fieldId = 3 + goto RequiredFieldNotSetError + } + + if !issetPersonBasicTypedefInfo { + fieldId = 4 + goto RequiredFieldNotSetError + } + + if !issetPersonStructTypedefInfo { + fieldId = 5 + goto RequiredFieldNotSetError + } + + if !issetPersonStructDefaultValueInfo { + fieldId = 6 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__StructOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__StructOptions[fieldId])) +} + +func (p *_StructOptions) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.PersonStringInfo = v + } + return nil +} + +func (p *_StructOptions) ReadField2(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + p.PersonMapInfo = make(map[string]string, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + + var _val string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _val = v + } + + p.PersonMapInfo[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + return nil +} + +func (p *_StructOptions) ReadField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return err + } else { + p.PersonEnumInfo = MyEnum(v) + } + return nil +} + +func (p *_StructOptions) ReadField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.PersonBasicTypedefInfo = v + } + return nil +} + +func (p *_StructOptions) ReadField5(iprot thrift.TProtocol) error { + p.PersonStructTypedefInfo = NewMyStructTypedef() + if err := p.PersonStructTypedefInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_StructOptions) ReadField6(iprot thrift.TProtocol) error { + p.PersonStructDefaultValueInfo = NewMyStructWithDefaultVal() + if err := p.PersonStructDefaultValueInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_StructOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_StructOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + if err = p.writeField4(oprot); err != nil { + fieldId = 4 + goto WriteFieldError + } + if err = p.writeField5(oprot); err != nil { + fieldId = 5 + goto WriteFieldError + } + if err = p.writeField6(oprot); err != nil { + fieldId = 6 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_StructOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_string_info", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.PersonStringInfo); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_StructOptions) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_map_info", thrift.MAP, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRING, len(p.PersonMapInfo)); err != nil { + return err + } + for k, v := range p.PersonMapInfo { + + if err := oprot.WriteString(k); err != nil { + return err + } + + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *_StructOptions) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_enum_info", thrift.I32, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI32(int32(p.PersonEnumInfo)); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *_StructOptions) writeField4(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_basic_typedef_info", thrift.STRING, 4); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.PersonBasicTypedefInfo); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err) +} + +func (p *_StructOptions) writeField5(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_struct_typedef_info", thrift.STRUCT, 5); err != nil { + goto WriteFieldBeginError + } + if err := p.PersonStructTypedefInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err) +} + +func (p *_StructOptions) writeField6(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("person_struct_default_value_info", thrift.STRUCT, 6); err != nil { + goto WriteFieldBeginError + } + if err := p.PersonStructDefaultValueInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err) +} + +func (p *_StructOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_StructOptions(%+v)", *p) +} + +type MyStructWithDefaultVal struct { + V1 string `thrift:"v1,1,required" json:"v1"` + V2 string `thrift:"v2,2,required" json:"v2"` + V3 int8 `thrift:"v3,3,required" json:"v3"` + V4 int16 `thrift:"v4,4,required" json:"v4"` + V5 int32 `thrift:"v5,5,required" json:"v5"` + V6 int64 `thrift:"v6,6,required" json:"v6"` + V7 bool `thrift:"v7,7,required" json:"v7"` + V8 float64 `thrift:"v8,8,required" json:"v8"` + V9 map[string]string `thrift:"v9,9,required" json:"v9"` + V10 []string `thrift:"v10,10,required" json:"v10"` + V11 string `thrift:"v11,11,required" json:"v11"` +} + +func NewMyStructWithDefaultVal() *MyStructWithDefaultVal { + return &MyStructWithDefaultVal{ + + V2: "v2", + V3: 8, + V4: 16, + V5: 32, + V6: 64, + V7: true, + V8: 3.1415926123456, + V9: map[string]string{ + "k1": "v1", + }, + V10: []string{ + "k1", + "k2", + }, + V11: HELLO, + } +} + +func (p *MyStructWithDefaultVal) GetV1() (v string) { + return p.V1 +} + +func (p *MyStructWithDefaultVal) GetV2() (v string) { + return p.V2 +} + +func (p *MyStructWithDefaultVal) GetV3() (v int8) { + return p.V3 +} + +func (p *MyStructWithDefaultVal) GetV4() (v int16) { + return p.V4 +} + +func (p *MyStructWithDefaultVal) GetV5() (v int32) { + return p.V5 +} + +func (p *MyStructWithDefaultVal) GetV6() (v int64) { + return p.V6 +} + +func (p *MyStructWithDefaultVal) GetV7() (v bool) { + return p.V7 +} + +func (p *MyStructWithDefaultVal) GetV8() (v float64) { + return p.V8 +} + +func (p *MyStructWithDefaultVal) GetV9() (v map[string]string) { + return p.V9 +} + +func (p *MyStructWithDefaultVal) GetV10() (v []string) { + return p.V10 +} + +func (p *MyStructWithDefaultVal) GetV11() (v string) { + return p.V11 +} + +var fieldIDToName_MyStructWithDefaultVal = map[int16]string{ + 1: "v1", + 2: "v2", + 3: "v3", + 4: "v4", + 5: "v5", + 6: "v6", + 7: "v7", + 8: "v8", + 9: "v9", + 10: "v10", + 11: "v11", +} + +func (p *MyStructWithDefaultVal) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetV1 bool = false + var issetV2 bool = false + var issetV3 bool = false + var issetV4 bool = false + var issetV5 bool = false + var issetV6 bool = false + var issetV7 bool = false + var issetV8 bool = false + var issetV9 bool = false + var issetV10 bool = false + var issetV11 bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetV1 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.STRING { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetV2 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 3: + if fieldTypeId == thrift.BYTE { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + issetV3 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 4: + if fieldTypeId == thrift.I16 { + if err = p.ReadField4(iprot); err != nil { + goto ReadFieldError + } + issetV4 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 5: + if fieldTypeId == thrift.I32 { + if err = p.ReadField5(iprot); err != nil { + goto ReadFieldError + } + issetV5 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 6: + if fieldTypeId == thrift.I64 { + if err = p.ReadField6(iprot); err != nil { + goto ReadFieldError + } + issetV6 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 7: + if fieldTypeId == thrift.BOOL { + if err = p.ReadField7(iprot); err != nil { + goto ReadFieldError + } + issetV7 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 8: + if fieldTypeId == thrift.DOUBLE { + if err = p.ReadField8(iprot); err != nil { + goto ReadFieldError + } + issetV8 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 9: + if fieldTypeId == thrift.MAP { + if err = p.ReadField9(iprot); err != nil { + goto ReadFieldError + } + issetV9 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 10: + if fieldTypeId == thrift.LIST { + if err = p.ReadField10(iprot); err != nil { + goto ReadFieldError + } + issetV10 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 11: + if fieldTypeId == thrift.STRING { + if err = p.ReadField11(iprot); err != nil { + goto ReadFieldError + } + issetV11 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetV1 { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetV2 { + fieldId = 2 + goto RequiredFieldNotSetError + } + + if !issetV3 { + fieldId = 3 + goto RequiredFieldNotSetError + } + + if !issetV4 { + fieldId = 4 + goto RequiredFieldNotSetError + } + + if !issetV5 { + fieldId = 5 + goto RequiredFieldNotSetError + } + + if !issetV6 { + fieldId = 6 + goto RequiredFieldNotSetError + } + + if !issetV7 { + fieldId = 7 + goto RequiredFieldNotSetError + } + + if !issetV8 { + fieldId = 8 + goto RequiredFieldNotSetError + } + + if !issetV9 { + fieldId = 9 + goto RequiredFieldNotSetError + } + + if !issetV10 { + fieldId = 10 + goto RequiredFieldNotSetError + } + + if !issetV11 { + fieldId = 11 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_MyStructWithDefaultVal[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_MyStructWithDefaultVal[fieldId])) +} + +func (p *MyStructWithDefaultVal) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.V1 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.V2 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadByte(); err != nil { + return err + } else { + p.V3 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI16(); err != nil { + return err + } else { + p.V4 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField5(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return err + } else { + p.V5 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField6(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return err + } else { + p.V6 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField7(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return err + } else { + p.V7 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField8(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return err + } else { + p.V8 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField9(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + p.V9 = make(map[string]string, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + + var _val string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _val = v + } + + p.V9[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField10(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + p.V10 = make([]string, 0, size) + for i := 0; i < size; i++ { + var _elem string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _elem = v + } + + p.V10 = append(p.V10, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + return nil +} + +func (p *MyStructWithDefaultVal) ReadField11(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.V11 = v + } + return nil +} + +func (p *MyStructWithDefaultVal) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("MyStructWithDefaultVal"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + if err = p.writeField4(oprot); err != nil { + fieldId = 4 + goto WriteFieldError + } + if err = p.writeField5(oprot); err != nil { + fieldId = 5 + goto WriteFieldError + } + if err = p.writeField6(oprot); err != nil { + fieldId = 6 + goto WriteFieldError + } + if err = p.writeField7(oprot); err != nil { + fieldId = 7 + goto WriteFieldError + } + if err = p.writeField8(oprot); err != nil { + fieldId = 8 + goto WriteFieldError + } + if err = p.writeField9(oprot); err != nil { + fieldId = 9 + goto WriteFieldError + } + if err = p.writeField10(oprot); err != nil { + fieldId = 10 + goto WriteFieldError + } + if err = p.writeField11(oprot); err != nil { + fieldId = 11 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v1", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.V1); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v2", thrift.STRING, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.V2); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v3", thrift.BYTE, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteByte(p.V3); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField4(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v4", thrift.I16, 4); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI16(p.V4); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField5(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v5", thrift.I32, 5); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI32(p.V5); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField6(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v6", thrift.I64, 6); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI64(p.V6); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField7(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v7", thrift.BOOL, 7); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBool(p.V7); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 7 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 7 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField8(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v8", thrift.DOUBLE, 8); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteDouble(p.V8); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 8 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 8 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField9(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v9", thrift.MAP, 9); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRING, len(p.V9)); err != nil { + return err + } + for k, v := range p.V9 { + + if err := oprot.WriteString(k); err != nil { + return err + } + + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 9 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 9 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField10(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v10", thrift.LIST, 10); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.STRING, len(p.V10)); err != nil { + return err + } + for _, v := range p.V10 { + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 10 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 10 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) writeField11(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("v11", thrift.STRING, 11); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.V11); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 11 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 11 end error: ", p), err) +} + +func (p *MyStructWithDefaultVal) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("MyStructWithDefaultVal(%+v)", *p) +} + +type _FieldOptions struct { + CardFieldInfo string `thrift:"card_field_info,1,required" json:"card_field_info"` +} + +func New_FieldOptions() *_FieldOptions { + return &_FieldOptions{} +} + +func (p *_FieldOptions) GetCardFieldInfo() (v string) { + return p.CardFieldInfo +} + +var fieldIDToName__FieldOptions = map[int16]string{ + 1: "card_field_info", +} + +func (p *_FieldOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetCardFieldInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetCardFieldInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetCardFieldInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__FieldOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__FieldOptions[fieldId])) +} + +func (p *_FieldOptions) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.CardFieldInfo = v + } + return nil +} + +func (p *_FieldOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_FieldOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_FieldOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("card_field_info", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.CardFieldInfo); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_FieldOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_FieldOptions(%+v)", *p) +} + +type TestInfo struct { + Name string `thrift:"name,1,required" json:"name"` + Number int16 `thrift:"number,2,required" json:"number"` +} + +func NewTestInfo() *TestInfo { + return &TestInfo{} +} + +func (p *TestInfo) GetName() (v string) { + return p.Name +} + +func (p *TestInfo) GetNumber() (v int16) { + return p.Number +} + +var fieldIDToName_TestInfo = map[int16]string{ + 1: "name", + 2: "number", +} + +func (p *TestInfo) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetName bool = false + var issetNumber bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetName = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.I16 { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetNumber = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetName { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetNumber { + fieldId = 2 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_TestInfo[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_TestInfo[fieldId])) +} + +func (p *TestInfo) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Name = v + } + return nil +} + +func (p *TestInfo) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI16(); err != nil { + return err + } else { + p.Number = v + } + return nil +} + +func (p *TestInfo) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("TestInfo"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *TestInfo) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("name", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Name); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *TestInfo) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("number", thrift.I16, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI16(p.Number); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *TestInfo) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("TestInfo(%+v)", *p) +} + +type _ServiceOptions struct { + SvcInfo *TestInfo `thrift:"svc_info,1,required" json:"svc_info"` +} + +func New_ServiceOptions() *_ServiceOptions { + return &_ServiceOptions{} +} + +var _ServiceOptions_SvcInfo_DEFAULT *TestInfo + +func (p *_ServiceOptions) GetSvcInfo() (v *TestInfo) { + if !p.IsSetSvcInfo() { + return _ServiceOptions_SvcInfo_DEFAULT + } + return p.SvcInfo +} + +var fieldIDToName__ServiceOptions = map[int16]string{ + 1: "svc_info", +} + +func (p *_ServiceOptions) IsSetSvcInfo() bool { + return p.SvcInfo != nil +} + +func (p *_ServiceOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetSvcInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetSvcInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetSvcInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__ServiceOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__ServiceOptions[fieldId])) +} + +func (p *_ServiceOptions) ReadField1(iprot thrift.TProtocol) error { + p.SvcInfo = NewTestInfo() + if err := p.SvcInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_ServiceOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_ServiceOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_ServiceOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("svc_info", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.SvcInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_ServiceOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_ServiceOptions(%+v)", *p) +} + +type _MethodOptions struct { + MethodInfo *TestInfo `thrift:"method_info,1,required" json:"method_info"` +} + +func New_MethodOptions() *_MethodOptions { + return &_MethodOptions{} +} + +var _MethodOptions_MethodInfo_DEFAULT *TestInfo + +func (p *_MethodOptions) GetMethodInfo() (v *TestInfo) { + if !p.IsSetMethodInfo() { + return _MethodOptions_MethodInfo_DEFAULT + } + return p.MethodInfo +} + +var fieldIDToName__MethodOptions = map[int16]string{ + 1: "method_info", +} + +func (p *_MethodOptions) IsSetMethodInfo() bool { + return p.MethodInfo != nil +} + +func (p *_MethodOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetMethodInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetMethodInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetMethodInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__MethodOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__MethodOptions[fieldId])) +} + +func (p *_MethodOptions) ReadField1(iprot thrift.TProtocol) error { + p.MethodInfo = NewTestInfo() + if err := p.MethodInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_MethodOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_MethodOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_MethodOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("method_info", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.MethodInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_MethodOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_MethodOptions(%+v)", *p) +} + +type _EnumOptions struct { + EnumInfo *TestInfo `thrift:"enum_info,1,required" json:"enum_info"` +} + +func New_EnumOptions() *_EnumOptions { + return &_EnumOptions{} +} + +var _EnumOptions_EnumInfo_DEFAULT *TestInfo + +func (p *_EnumOptions) GetEnumInfo() (v *TestInfo) { + if !p.IsSetEnumInfo() { + return _EnumOptions_EnumInfo_DEFAULT + } + return p.EnumInfo +} + +var fieldIDToName__EnumOptions = map[int16]string{ + 1: "enum_info", +} + +func (p *_EnumOptions) IsSetEnumInfo() bool { + return p.EnumInfo != nil +} + +func (p *_EnumOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetEnumInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetEnumInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetEnumInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__EnumOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__EnumOptions[fieldId])) +} + +func (p *_EnumOptions) ReadField1(iprot thrift.TProtocol) error { + p.EnumInfo = NewTestInfo() + if err := p.EnumInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_EnumOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_EnumOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_EnumOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("enum_info", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.EnumInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_EnumOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_EnumOptions(%+v)", *p) +} + +type _EnumValueOptions struct { + EnumValueInfo *TestInfo `thrift:"enum_value_info,1,required" json:"enum_value_info"` +} + +func New_EnumValueOptions() *_EnumValueOptions { + return &_EnumValueOptions{} +} + +var _EnumValueOptions_EnumValueInfo_DEFAULT *TestInfo + +func (p *_EnumValueOptions) GetEnumValueInfo() (v *TestInfo) { + if !p.IsSetEnumValueInfo() { + return _EnumValueOptions_EnumValueInfo_DEFAULT + } + return p.EnumValueInfo +} + +var fieldIDToName__EnumValueOptions = map[int16]string{ + 1: "enum_value_info", +} + +func (p *_EnumValueOptions) IsSetEnumValueInfo() bool { + return p.EnumValueInfo != nil +} + +func (p *_EnumValueOptions) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetEnumValueInfo bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetEnumValueInfo = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetEnumValueInfo { + fieldId = 1 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName__EnumValueOptions[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName__EnumValueOptions[fieldId])) +} + +func (p *_EnumValueOptions) ReadField1(iprot thrift.TProtocol) error { + p.EnumValueInfo = NewTestInfo() + if err := p.EnumValueInfo.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *_EnumValueOptions) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("_EnumValueOptions"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *_EnumValueOptions) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("enum_value_info", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.EnumValueInfo.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *_EnumValueOptions) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("_EnumValueOptions(%+v)", *p) +} + +var ( + STRUCT_OPTION_PERSON_STRING_INFO = thrift_option.NewStructOption("../option_idl/annotations/validation/validation.thrift", "person_string_info") + STRUCT_OPTION_PERSON_MAP_INFO = thrift_option.NewStructOption("../option_idl/annotations/validation/validation.thrift", "person_map_info") + STRUCT_OPTION_PERSON_ENUM_INFO = thrift_option.NewStructOption("../option_idl/annotations/validation/validation.thrift", "person_enum_info") + STRUCT_OPTION_PERSON_BASIC_TYPEDEF_INFO = thrift_option.NewStructOption("../option_idl/annotations/validation/validation.thrift", "person_basic_typedef_info") + STRUCT_OPTION_PERSON_STRUCT_TYPEDEF_INFO = thrift_option.NewStructOption("../option_idl/annotations/validation/validation.thrift", "person_struct_typedef_info") + STRUCT_OPTION_PERSON_STRUCT_DEFAULT_VALUE_INFO = thrift_option.NewStructOption("../option_idl/annotations/validation/validation.thrift", "person_struct_default_value_info") + FIELD_OPTION_CARD_FIELD_INFO = thrift_option.NewFieldOption("../option_idl/annotations/validation/validation.thrift", "card_field_info") + SERVICE_OPTION_SVC_INFO = thrift_option.NewServiceOption("../option_idl/annotations/validation/validation.thrift", "svc_info") + METHOD_OPTION_METHOD_INFO = thrift_option.NewMethodOption("../option_idl/annotations/validation/validation.thrift", "method_info") + ENUM_OPTION_ENUM_INFO = thrift_option.NewEnumOption("../option_idl/annotations/validation/validation.thrift", "enum_info") + ENUM_VALUE_OPTION_ENUM_VALUE_INFO = thrift_option.NewEnumValueOption("../option_idl/annotations/validation/validation.thrift", "enum_value_info") +) diff --git a/extension/thrift_option/runtime_test/option_gen/test-reflection.go b/extension/thrift_option/runtime_test/option_gen/test-reflection.go new file mode 100644 index 00000000..f92c1c43 --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/test-reflection.go @@ -0,0 +1,146 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package option_gen + +import ( + "reflect" + + "github.com/cloudwego/thriftgo/thrift_reflection" +) + +// IDL Name: test +// IDL Path: ../option_idl/test.thrift + +var file_test_thrift_go_types = []interface{}{ + (*IDCard)(nil), // Struct 0: option_gen.IDCard + (*Person)(nil), // Struct 1: option_gen.Person + (*PersonB)(nil), // Struct 2: option_gen.PersonB + (*PersonC)(nil), // Struct 3: option_gen.PersonC + (*TinyStruct)(nil), // Struct 4: option_gen.TinyStruct + (*MyEnum)(nil), // Enum 0: option_gen.MyEnum +} +var file_test_thrift *thrift_reflection.FileDescriptor +var file_idl_test_rawDesc = []byte{ + 0x1f, 0x8b, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xcc, 0x58, 0xed, 0x6b, 0xe3, 0x36, + 0x18, 0x7f, 0xe2, 0xb4, 0x69, 0x2f, 0x69, 0xe9, 0x8d, 0xdb, 0xdb, 0xed, 0x5, 0x3c, 0xb3, 0x91, + 0xf, 0x33, 0x2e, 0x76, 0x12, 0xd3, 0xf3, 0xbe, 0x6c, 0xbd, 0x1b, 0xe3, 0x60, 0x1d, 0x63, 0x37, + 0xc6, 0x41, 0x29, 0x45, 0x49, 0x94, 0x46, 0x9c, 0x2d, 0x67, 0x8e, 0x12, 0x16, 0x4a, 0xfe, 0xf7, + 0x21, 0x59, 0x4e, 0xac, 0x58, 0x4e, 0xed, 0xee, 0x38, 0x96, 0x2f, 0x4e, 0xa4, 0xe7, 0xe5, 0xf7, + 0x3c, 0xfa, 0xe9, 0xe7, 0x48, 0x1d, 0x68, 0x0, 0xc0, 0x73, 0xc7, 0x39, 0x8f, 0x67, 0x8c, 0xc4, + 0xf4, 0x96, 0x8c, 0xc3, 0x73, 0x86, 0xe7, 0xcc, 0x61, 0xd3, 0x84, 0x4c, 0xd8, 0x29, 0x18, 0x9d, + 0xe, 0x0, 0x18, 0x0, 0xd0, 0xc2, 0x94, 0x11, 0xb6, 0x2, 0x0, 0x47, 0xb5, 0x47, 0x94, 0xc6, + 0xc, 0xf1, 0x9f, 0xf3, 0xf3, 0xd4, 0x46, 0x3e, 0x64, 0x10, 0x0, 0x68, 0x2f, 0x51, 0x48, 0xc6, + 0xc2, 0x6, 0x0, 0xfc, 0x72, 0xff, 0xad, 0x5d, 0xee, 0xeb, 0x6, 0x4c, 0x53, 0x80, 0xe1, 0x90, + 0x8d, 0xbb, 0x98, 0x87, 0x95, 0x51, 0xee, 0x30, 0x3d, 0x83, 0x83, 0x13, 0x3e, 0xf7, 0x50, 0x45, + 0x1d, 0x51, 0xcb, 0x93, 0xab, 0xd5, 0x1b, 0x9c, 0x2c, 0xc9, 0x8, 0x9f, 0x41, 0x93, 0xfb, 0x19, + 0xd5, 0xfc, 0x8c, 0x2b, 0xf7, 0x4, 0x9a, 0xd5, 0x6c, 0x5b, 0x73, 0x96, 0x10, 0x7a, 0x7, 0x12, + 0x19, 0x9c, 0xc2, 0x61, 0xe7, 0x4c, 0xc2, 0xff, 0x34, 0x57, 0x5c, 0x84, 0xd9, 0x34, 0x1e, 0xdf, + 0x12, 0x3a, 0x89, 0xb3, 0xea, 0x5e, 0xdd, 0xb7, 0xcd, 0xdc, 0x87, 0xa2, 0x8, 0x7, 0xe6, 0x95, + 0xb0, 0x7b, 0x4d, 0x27, 0xf1, 0x6f, 0x28, 0xc2, 0xaa, 0xc1, 0x22, 0x1a, 0xe2, 0x24, 0x30, 0x7, + 0x83, 0xc1, 0x66, 0x7c, 0xdd, 0x81, 0x16, 0x4f, 0x7b, 0x6, 0x47, 0x22, 0xbd, 0x1, 0xc7, 0x0, + 0x55, 0xab, 0xf4, 0xfe, 0xcf, 0x55, 0xf6, 0xfb, 0xfd, 0xfd, 0x55, 0x9e, 0xc2, 0xc1, 0x6, 0xc3, + 0xb3, 0x1c, 0x86, 0xf9, 0x72, 0xa4, 0x0, 0x78, 0xb1, 0x5, 0x90, 0x26, 0x97, 0x9c, 0x28, 0x64, + 0xcf, 0x32, 0xfb, 0xbe, 0xdf, 0x96, 0x59, 0xf, 0x21, 0x4d, 0x7b, 0xc8, 0xd3, 0x1e, 0x56, 0xec, + 0xd5, 0xeb, 0x57, 0x2f, 0x51, 0x32, 0xae, 0x47, 0xb9, 0x56, 0x9a, 0xbc, 0xf6, 0x82, 0x74, 0xe0, + 0x0, 0x0, 0x8e, 0xff, 0xc0, 0x7f, 0x2f, 0x48, 0x82, 0xc7, 0xc7, 0x2, 0x71, 0xe3, 0x14, 0x8e, + 0x44, 0x6b, 0xa0, 0xc3, 0x1b, 0x5, 0x55, 0x19, 0xd1, 0x44, 0x77, 0xb8, 0x32, 0x2, 0x83, 0x5c, + 0xe8, 0xb3, 0x1b, 0x85, 0xec, 0xd9, 0x4a, 0x41, 0xd6, 0xd0, 0x8a, 0x35, 0xfe, 0x8e, 0x93, 0x79, + 0x4c, 0xeb, 0x35, 0xf2, 0x80, 0xaf, 0xf1, 0x7b, 0x6e, 0x23, 0x8f, 0xf4, 0xb9, 0x14, 0xbb, 0x99, + 0xc0, 0x74, 0x3b, 0x21, 0x38, 0x54, 0x79, 0xfe, 0x19, 0x9b, 0x62, 0x41, 0x30, 0x33, 0x9e, 0x98, + 0x6c, 0x4a, 0xe6, 0x66, 0x6a, 0x5a, 0x6f, 0x9, 0xc, 0x32, 0xae, 0xe, 0x3e, 0x25, 0x5a, 0xdd, + 0x55, 0x68, 0x3, 0xc0, 0xf7, 0xb9, 0xfd, 0x22, 0x2b, 0x9a, 0xb3, 0x64, 0x31, 0x62, 0xb7, 0x63, + 0x3c, 0x41, 0x8b, 0x90, 0xdd, 0x2e, 0x51, 0xb8, 0xc0, 0x4a, 0x81, 0x4f, 0xef, 0x97, 0x6e, 0x60, + 0x2d, 0x5d, 0x33, 0xed, 0x99, 0xb5, 0x2e, 0x76, 0x65, 0x88, 0xe6, 0x44, 0xd9, 0x7c, 0xd, 0x43, + 0xdd, 0xfd, 0x22, 0x2a, 0xb9, 0x8, 0x2e, 0x34, 0xa3, 0xae, 0x1f, 0xb8, 0xbe, 0x66, 0xbc, 0xe7, + 0x5, 0x3d, 0x4f, 0x33, 0xee, 0xf7, 0x3, 0xbf, 0x5f, 0x1c, 0x4f, 0xd1, 0x5, 0x5d, 0xfc, 0xf, + 0x8a, 0x66, 0x21, 0xfe, 0x11, 0x47, 0x88, 0x84, 0xce, 0x28, 0x8e, 0xba, 0x45, 0xdb, 0xe1, 0x8a, + 0xe1, 0xc0, 0x74, 0x35, 0x13, 0x84, 0xa2, 0x64, 0x15, 0x98, 0xae, 0x26, 0xf1, 0x38, 0x5e, 0xc, + 0x43, 0x1c, 0xf4, 0x1c, 0xb7, 0xef, 0xe, 0x5e, 0x68, 0x7c, 0xe3, 0x38, 0xc, 0x4c, 0x96, 0x2c, + 0x52, 0x65, 0xe1, 0x6d, 0x7a, 0xae, 0xb6, 0x49, 0xb6, 0x3a, 0xdf, 0xa7, 0x4b, 0x4d, 0x9f, 0x52, + 0xb3, 0xe0, 0x5e, 0x54, 0x10, 0x58, 0x38, 0x9a, 0xb1, 0x95, 0x29, 0x7e, 0x58, 0xeb, 0xa2, 0x35, + 0xa7, 0x47, 0xe6, 0xa1, 0xcc, 0x4a, 0xd5, 0xb3, 0x42, 0x8c, 0x2d, 0x75, 0x82, 0x50, 0x8a, 0x93, + 0x37, 0x5a, 0x1f, 0xfe, 0x91, 0x79, 0x69, 0x2c, 0x93, 0xee, 0x58, 0xa8, 0x18, 0x34, 0x88, 0x30, + 0x5d, 0x44, 0x81, 0x79, 0x59, 0x56, 0x18, 0x5b, 0xcd, 0xf0, 0x18, 0x4f, 0xaa, 0xd6, 0x27, 0xb8, + 0x95, 0xf9, 0x98, 0xd6, 0x14, 0x87, 0x61, 0x6c, 0xb2, 0x29, 0x4e, 0x64, 0x55, 0xbc, 0xcf, 0xdf, + 0x95, 0xd2, 0x5a, 0x3a, 0x2a, 0x84, 0x7e, 0x76, 0x2f, 0x3a, 0x23, 0x13, 0xf3, 0xef, 0x82, 0xd3, + 0x5f, 0x14, 0x83, 0x44, 0x68, 0xa6, 0x78, 0x7e, 0x74, 0x6f, 0x4d, 0xf1, 0xca, 0xb5, 0x2, 0x4b, + 0x40, 0x73, 0x85, 0xdf, 0x97, 0x45, 0x3f, 0xde, 0x1, 0xc5, 0xb1, 0xf9, 0xf6, 0xed, 0xaf, 0x0, + 0xf0, 0x6d, 0xd1, 0x34, 0xdd, 0x3a, 0x3a, 0x98, 0xa7, 0x4a, 0xad, 0x0, 0x70, 0x84, 0x10, 0x72, + 0x86, 0xc3, 0x61, 0x66, 0x70, 0x28, 0xe6, 0x1, 0xe0, 0x2b, 0x95, 0x66, 0xa3, 0x98, 0x32, 0x44, + 0x28, 0x4e, 0x14, 0xa6, 0x79, 0x1a, 0xa6, 0x45, 0x68, 0x16, 0x14, 0x4a, 0x2a, 0x9a, 0x85, 0x64, + 0xce, 0x82, 0x6b, 0x8b, 0x3f, 0x5c, 0xcb, 0x16, 0x4f, 0xcf, 0xba, 0xd1, 0xac, 0x2f, 0xce, 0xcc, + 0x7a, 0xd2, 0xac, 0xaf, 0x33, 0xe3, 0x13, 0xc2, 0xf4, 0x1a, 0xd9, 0x43, 0x7b, 0x74, 0x63, 0x5f, + 0x8f, 0x6d, 0x6c, 0x4f, 0x6e, 0xca, 0x4d, 0x25, 0xbf, 0xaf, 0xaf, 0x25, 0x67, 0xb0, 0xbb, 0xb6, + 0xb3, 0xaf, 0xde, 0xfa, 0xc6, 0xde, 0x8c, 0xf7, 0xb6, 0xe3, 0xfd, 0xb5, 0x2e, 0x60, 0x84, 0x66, + 0xd9, 0x66, 0x79, 0xe7, 0x6, 0xdb, 0x70, 0xe6, 0x3b, 0x2f, 0xd8, 0x46, 0x5c, 0x6f, 0x98, 0xf5, + 0xb5, 0x96, 0x59, 0x84, 0xde, 0x29, 0x4b, 0x95, 0xae, 0x44, 0xbd, 0xb7, 0xdc, 0x51, 0xfa, 0x96, + 0xbb, 0x94, 0xaf, 0xb9, 0x8d, 0x4c, 0x37, 0xab, 0xc8, 0x2b, 0x94, 0xc8, 0xab, 0x9d, 0x93, 0x54, + 0xbb, 0x4c, 0x53, 0x75, 0x13, 0x42, 0x54, 0x4d, 0xcd, 0x4c, 0xb9, 0xac, 0x6a, 0x8c, 0xa5, 0xae, + 0xea, 0x66, 0x36, 0xc2, 0xaa, 0x4b, 0xa2, 0x4a, 0xab, 0xce, 0x7d, 0xa3, 0xad, 0x76, 0xd, 0x71, + 0x75, 0x3e, 0x8c, 0xb8, 0xda, 0xff, 0x49, 0x5d, 0xed, 0x47, 0xca, 0x6b, 0x65, 0x49, 0x35, 0xed, + 0xea, 0x42, 0x5a, 0x49, 0x49, 0x9e, 0x56, 0x55, 0x12, 0x7b, 0x8f, 0x7a, 0xec, 0x51, 0xc, 0xd3, + 0xfe, 0xc0, 0x32, 0xa1, 0x21, 0x5c, 0x2d, 0x9d, 0x78, 0xd4, 0xc6, 0x7f, 0xb9, 0xbb, 0xf1, 0xf9, + 0x49, 0xe7, 0x87, 0x52, 0x4e, 0x3b, 0x3b, 0x7c, 0x74, 0x72, 0x34, 0x73, 0x4, 0xa0, 0x4c, 0x8c, + 0x8e, 0x33, 0x6a, 0xf1, 0xb3, 0x7c, 0xf5, 0x78, 0x9c, 0xd0, 0x9b, 0xd7, 0x55, 0x88, 0x31, 0x0, + 0x98, 0x65, 0x32, 0xe4, 0x48, 0xc1, 0xc9, 0xec, 0x1b, 0x17, 0x0, 0xf0, 0xcd, 0x3, 0xd6, 0xae, + 0xbf, 0x39, 0xde, 0xbb, 0x3e, 0x7f, 0x69, 0x3f, 0x80, 0x2d, 0x1d, 0xc8, 0x7c, 0x3e, 0xd1, 0x72, + 0x1b, 0x0, 0x6, 0x8f, 0x6a, 0x59, 0x16, 0xb6, 0x9b, 0xfe, 0x17, 0x30, 0xbb, 0xae, 0xd7, 0xeb, + 0xae, 0x6d, 0x65, 0xef, 0xa6, 0x9, 0xbb, 0xfd, 0x81, 0xdf, 0xad, 0xb9, 0xc4, 0xed, 0x3f, 0x9, + 0x5d, 0xa5, 0x61, 0x6a, 0xde, 0x40, 0xc, 0xab, 0xdf, 0x40, 0x1c, 0x70, 0x51, 0x7c, 0xbf, 0x7, + 0x41, 0x63, 0x58, 0xfd, 0x6a, 0x60, 0x4f, 0xfa, 0xa, 0x27, 0xc1, 0x33, 0x68, 0x9d, 0xe4, 0x4e, + 0xf6, 0x15, 0x2f, 0x76, 0x5a, 0x57, 0xab, 0x9f, 0xe9, 0x22, 0xaa, 0xd7, 0xd3, 0xc6, 0x4f, 0x6d, + 0xf1, 0x52, 0x55, 0x80, 0x34, 0x76, 0xfe, 0xf0, 0x89, 0x7f, 0x6c, 0xc5, 0xb3, 0xcf, 0x2f, 0xba, + 0x4b, 0xc, 0xe, 0xe1, 0x2f, 0x6e, 0xba, 0xf7, 0x1e, 0xc3, 0xf3, 0xbc, 0xfc, 0x3d, 0x46, 0x1d, + 0xfa, 0x34, 0x2e, 0xb7, 0x88, 0x1b, 0x85, 0xd6, 0xe5, 0x4b, 0xf8, 0x78, 0xb7, 0x84, 0x3c, 0x78, + 0x7f, 0xf7, 0x2, 0x84, 0x3, 0x2f, 0xbd, 0xfd, 0xe8, 0xf5, 0x7a, 0xbb, 0xb7, 0x1f, 0xc7, 0x72, + 0x89, 0x9e, 0xc8, 0x67, 0x5b, 0x3c, 0xe1, 0xdf, 0x0, 0x0, 0x0, 0xff, 0xff, 0xe1, 0x8e, 0x5e, + 0x71, 0x57, 0x14, 0x0, 0x0, +} + +func init() { + if file_test_thrift != nil { + return + } + type x struct{} + builder := &thrift_reflection.FileDescriptorBuilder{ + Bytes: file_idl_test_rawDesc, + GoTypes: file_test_thrift_go_types, + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + } + file_test_thrift = thrift_reflection.BuildFileDescriptor(builder) +} + +func GetFileDescriptorForTest() *thrift_reflection.FileDescriptor { + return file_test_thrift +} +func (p *IDCard) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_test_thrift.GetStructDescriptor("IDCard") +} +func (p *Person) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_test_thrift.GetStructDescriptor("Person") +} +func (p *PersonB) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_test_thrift.GetStructDescriptor("PersonB") +} +func (p *PersonC) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_test_thrift.GetStructDescriptor("PersonC") +} +func (p *TinyStruct) GetDescriptor() *thrift_reflection.StructDescriptor { + return file_test_thrift.GetStructDescriptor("TinyStruct") +} +func (p MyEnum) GetDescriptor() *thrift_reflection.EnumDescriptor { + return file_test_thrift.GetEnumDescriptor("MyEnum") +} diff --git a/extension/thrift_option/runtime_test/option_gen/test.go b/extension/thrift_option/runtime_test/option_gen/test.go new file mode 100644 index 00000000..fd257dfd --- /dev/null +++ b/extension/thrift_option/runtime_test/option_gen/test.go @@ -0,0 +1,1475 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// Code generated by thriftgo (0.3.2-option-exp). DO NOT EDIT. + +package option_gen + +import ( + "context" + "database/sql" + "database/sql/driver" + "fmt" + "github.com/apache/thrift/lib/go/thrift" +) + +type MyEnum int64 + +const ( + MyEnum_A MyEnum = 0 + MyEnum_B MyEnum = 1 +) + +func (p MyEnum) String() string { + switch p { + case MyEnum_A: + return "A" + case MyEnum_B: + return "B" + } + return "" +} + +func MyEnumFromString(s string) (MyEnum, error) { + switch s { + case "A": + return MyEnum_A, nil + case "B": + return MyEnum_B, nil + } + return MyEnum(0), fmt.Errorf("not a valid MyEnum string") +} + +func MyEnumPtr(v MyEnum) *MyEnum { return &v } +func (p *MyEnum) Scan(value interface{}) (err error) { + var result sql.NullInt64 + err = result.Scan(value) + *p = MyEnum(result.Int64) + return +} + +func (p *MyEnum) Value() (driver.Value, error) { + if p == nil { + return nil, nil + } + return int64(*p), nil +} + +type IDCard struct { + Number string `thrift:"number,1,required" json:"number"` + Age int8 `thrift:"age,2,required" json:"age"` +} + +func NewIDCard() *IDCard { + return &IDCard{} +} + +func (p *IDCard) GetNumber() (v string) { + return p.Number +} + +func (p *IDCard) GetAge() (v int8) { + return p.Age +} + +var fieldIDToName_IDCard = map[int16]string{ + 1: "number", + 2: "age", +} + +func (p *IDCard) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetNumber bool = false + var issetAge bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetNumber = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.BYTE { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetAge = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetNumber { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetAge { + fieldId = 2 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_IDCard[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_IDCard[fieldId])) +} + +func (p *IDCard) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Number = v + } + return nil +} + +func (p *IDCard) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadByte(); err != nil { + return err + } else { + p.Age = v + } + return nil +} + +func (p *IDCard) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("IDCard"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *IDCard) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("number", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Number); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *IDCard) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("age", thrift.BYTE, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteByte(p.Age); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *IDCard) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("IDCard(%+v)", *p) +} + +type Person struct { + Name string `thrift:"name,1,required" json:"name"` + ID *IDCard `thrift:"id,2,required" json:"id"` +} + +func NewPerson() *Person { + return &Person{} +} + +func (p *Person) GetName() (v string) { + return p.Name +} + +var Person_ID_DEFAULT *IDCard + +func (p *Person) GetID() (v *IDCard) { + if !p.IsSetID() { + return Person_ID_DEFAULT + } + return p.ID +} + +var fieldIDToName_Person = map[int16]string{ + 1: "name", + 2: "id", +} + +func (p *Person) IsSetID() bool { + return p.ID != nil +} + +func (p *Person) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetName bool = false + var issetID bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetName = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetID = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetName { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetID { + fieldId = 2 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_Person[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_Person[fieldId])) +} + +func (p *Person) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Name = v + } + return nil +} + +func (p *Person) ReadField2(iprot thrift.TProtocol) error { + p.ID = NewIDCard() + if err := p.ID.Read(iprot); err != nil { + return err + } + return nil +} + +func (p *Person) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Person"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *Person) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("name", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Name); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *Person) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("id", thrift.STRUCT, 2); err != nil { + goto WriteFieldBeginError + } + if err := p.ID.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *Person) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Person(%+v)", *p) +} + +type PersonB struct { +} + +func NewPersonB() *PersonB { + return &PersonB{} +} + +var fieldIDToName_PersonB = map[int16]string{} + +func (p *PersonB) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *PersonB) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("PersonB"); err != nil { + goto WriteStructBeginError + } + if p != nil { + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PersonB) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PersonB(%+v)", *p) +} + +type PersonC struct { +} + +func NewPersonC() *PersonC { + return &PersonC{} +} + +var fieldIDToName_PersonC = map[int16]string{} + +func (p *PersonC) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *PersonC) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("PersonC"); err != nil { + goto WriteStructBeginError + } + if p != nil { + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PersonC) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PersonC(%+v)", *p) +} + +type TinyStruct struct { + B1 bool `thrift:"b1,1,required" json:"b1"` + B2 bool `thrift:"b2,2,required" json:"b2"` +} + +func NewTinyStruct() *TinyStruct { + return &TinyStruct{} +} + +func (p *TinyStruct) GetB1() (v bool) { + return p.B1 +} + +func (p *TinyStruct) GetB2() (v bool) { + return p.B2 +} + +var fieldIDToName_TinyStruct = map[int16]string{ + 1: "b1", + 2: "b2", +} + +func (p *TinyStruct) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + var issetB1 bool = false + var issetB2 bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.BOOL { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetB1 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + case 2: + if fieldTypeId == thrift.BOOL { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetB2 = true + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetB1 { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetB2 { + fieldId = 2 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_TinyStruct[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_TinyStruct[fieldId])) +} + +func (p *TinyStruct) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return err + } else { + p.B1 = v + } + return nil +} + +func (p *TinyStruct) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return err + } else { + p.B2 = v + } + return nil +} + +func (p *TinyStruct) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("TinyStruct"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *TinyStruct) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("b1", thrift.BOOL, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBool(p.B1); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *TinyStruct) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("b2", thrift.BOOL, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBool(p.B2); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *TinyStruct) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("TinyStruct(%+v)", *p) +} + +type MyService interface { + M1(ctx context.Context) (r string, err error) + + M2(ctx context.Context) (r string, err error) +} + +type MyServiceClient struct { + c thrift.TClient +} + +func NewMyServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *MyServiceClient { + return &MyServiceClient{ + c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)), + } +} + +func NewMyServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *MyServiceClient { + return &MyServiceClient{ + c: thrift.NewTStandardClient(iprot, oprot), + } +} + +func NewMyServiceClient(c thrift.TClient) *MyServiceClient { + return &MyServiceClient{ + c: c, + } +} + +func (p *MyServiceClient) Client_() thrift.TClient { + return p.c +} + +func (p *MyServiceClient) M1(ctx context.Context) (r string, err error) { + var _args MyServiceM1Args + var _result MyServiceM1Result + if err = p.Client_().Call(ctx, "M1", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *MyServiceClient) M2(ctx context.Context) (r string, err error) { + var _args MyServiceM2Args + var _result MyServiceM2Result + if err = p.Client_().Call(ctx, "M2", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} + +type MyServiceProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler MyService +} + +func (p *MyServiceProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *MyServiceProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *MyServiceProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewMyServiceProcessor(handler MyService) *MyServiceProcessor { + self := &MyServiceProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self.AddToProcessorMap("M1", &myServiceProcessorM1{handler: handler}) + self.AddToProcessorMap("M2", &myServiceProcessorM2{handler: handler}) + return self +} +func (p *MyServiceProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(ctx, seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, x +} + +type myServiceProcessorM1 struct { + handler MyService +} + +func (p *myServiceProcessorM1) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := MyServiceM1Args{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("M1", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := MyServiceM1Result{} + var retval string + if retval, err2 = p.handler.M1(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing M1: "+err2.Error()) + oprot.WriteMessageBegin("M1", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = &retval + } + if err2 = oprot.WriteMessageBegin("M1", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type myServiceProcessorM2 struct { + handler MyService +} + +func (p *myServiceProcessorM2) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := MyServiceM2Args{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("M2", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := MyServiceM2Result{} + var retval string + if retval, err2 = p.handler.M2(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing M2: "+err2.Error()) + oprot.WriteMessageBegin("M2", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = &retval + } + if err2 = oprot.WriteMessageBegin("M2", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type MyServiceM1Args struct { +} + +func NewMyServiceM1Args() *MyServiceM1Args { + return &MyServiceM1Args{} +} + +var fieldIDToName_MyServiceM1Args = map[int16]string{} + +func (p *MyServiceM1Args) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *MyServiceM1Args) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("M1_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *MyServiceM1Args) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("MyServiceM1Args(%+v)", *p) +} + +type MyServiceM1Result struct { + Success *string `thrift:"success,0,optional" json:"success,omitempty"` +} + +func NewMyServiceM1Result() *MyServiceM1Result { + return &MyServiceM1Result{} +} + +var MyServiceM1Result_Success_DEFAULT string + +func (p *MyServiceM1Result) GetSuccess() (v string) { + if !p.IsSetSuccess() { + return MyServiceM1Result_Success_DEFAULT + } + return *p.Success +} + +var fieldIDToName_MyServiceM1Result = map[int16]string{ + 0: "success", +} + +func (p *MyServiceM1Result) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *MyServiceM1Result) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRING { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_MyServiceM1Result[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *MyServiceM1Result) ReadField0(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Success = &v + } + return nil +} + +func (p *MyServiceM1Result) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("M1_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *MyServiceM1Result) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRING, 0); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(*p.Success); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *MyServiceM1Result) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("MyServiceM1Result(%+v)", *p) +} + +type MyServiceM2Args struct { +} + +func NewMyServiceM2Args() *MyServiceM2Args { + return &MyServiceM2Args{} +} + +var fieldIDToName_MyServiceM2Args = map[int16]string{} + +func (p *MyServiceM2Args) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *MyServiceM2Args) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("M2_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *MyServiceM2Args) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("MyServiceM2Args(%+v)", *p) +} + +type MyServiceM2Result struct { + Success *string `thrift:"success,0,optional" json:"success,omitempty"` +} + +func NewMyServiceM2Result() *MyServiceM2Result { + return &MyServiceM2Result{} +} + +var MyServiceM2Result_Success_DEFAULT string + +func (p *MyServiceM2Result) GetSuccess() (v string) { + if !p.IsSetSuccess() { + return MyServiceM2Result_Success_DEFAULT + } + return *p.Success +} + +var fieldIDToName_MyServiceM2Result = map[int16]string{ + 0: "success", +} + +func (p *MyServiceM2Result) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *MyServiceM2Result) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRING { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_MyServiceM2Result[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *MyServiceM2Result) ReadField0(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return err + } else { + p.Success = &v + } + return nil +} + +func (p *MyServiceM2Result) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("M2_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *MyServiceM2Result) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRING, 0); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(*p.Success); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *MyServiceM2Result) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("MyServiceM2Result(%+v)", *p) +} diff --git a/extension/thrift_option/runtime_test/option_runtime_codegen.sh b/extension/thrift_option/runtime_test/option_runtime_codegen.sh new file mode 100644 index 00000000..3d2b49aa --- /dev/null +++ b/extension/thrift_option/runtime_test/option_runtime_codegen.sh @@ -0,0 +1,15 @@ +# Copyright 2024 CloudWeGo Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. + +go run ../../../. -g go:with_reflection,use_option -o . -r ../option_idl/test.thrift \ No newline at end of file diff --git a/extension/thrift_option/runtime_test/option_runtime_test.go b/extension/thrift_option/runtime_test/option_runtime_test.go new file mode 100644 index 00000000..b55b4c3d --- /dev/null +++ b/extension/thrift_option/runtime_test/option_runtime_test.go @@ -0,0 +1,262 @@ +// Copyright 2024 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 runtime_test + +import ( + "testing" + + "github.com/cloudwego/thriftgo/extension/thrift_option" + "github.com/cloudwego/thriftgo/extension/thrift_option/runtime_test/option_gen" + "github.com/cloudwego/thriftgo/extension/thrift_option/runtime_test/option_gen/annotation/entity" + "github.com/cloudwego/thriftgo/extension/thrift_option/runtime_test/option_gen/annotation/validation" +) + +func TestRuntimeSimpleGrammarOption(t *testing.T) { + // test basic option + option, err := thrift_option.GetStructOption(option_gen.NewPersonC().GetDescriptor(), entity.STRUCT_OPTION_PERSON_BASIC_INFO) + assert(t, err == nil && option != nil) + opt, ok := option.GetInstance().(*entity.PersonBasicInfo) + assert(t, ok) + + assert(t, opt.GetValuei8() == 8) + assert(t, opt.GetValuei16() == 16) + + // test struct option + option2, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), entity.STRUCT_OPTION_PERSON_STRUCT_INFO) + assert(t, err == nil && option != nil) + opt2, ok := option2.GetInstance().(*entity.PersonStructInfo) + assert(t, ok) + + innerStruct := opt2.GetValuestruct() + assert(t, innerStruct != nil && innerStruct.GetEmail() == "empty email") + + testStruct := opt2.GetValueteststruct() + assert(t, testStruct != nil) + assert(t, testStruct.GetName() == "lee") + innerStruct = testStruct.GetInnerStruct() + assert(t, innerStruct != nil && innerStruct.GetEmail() == "no email") + +} + +func TestRuntimeBasicStructOption(t *testing.T) { + // test basic option + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), entity.STRUCT_OPTION_PERSON_BASIC_INFO) + assert(t, err == nil && option != nil) + opt, ok := option.GetInstance().(*entity.PersonBasicInfo) + assert(t, ok) + + assert(t, opt.GetValuei8() == 8) + assert(t, opt.GetValuei16() == 16) + assert(t, opt.GetValuei32() == 32) + assert(t, opt.GetValuei64() == 64) + assert(t, opt.GetValuestring() == "example@email.com") + assert(t, opt.GetValuebyte() == 1) + assert(t, len(opt.GetValuebinary()) == 1 && opt.GetValuebinary()[0] == 18) + assert(t, opt.GetValuedouble() == 3.14159) + assert(t, opt.GetValuebool() == true) +} + +func TestRuntimeStructStructOption(t *testing.T) { + // test struct option + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), entity.STRUCT_OPTION_PERSON_STRUCT_INFO) + assert(t, err == nil && option != nil) + opt, ok := option.GetInstance().(*entity.PersonStructInfo) + assert(t, ok) + + innerStruct := opt.GetValuestruct() + assert(t, innerStruct != nil && innerStruct.GetEmail() == "empty email") + + testStruct := opt.GetValueteststruct() + assert(t, testStruct != nil) + assert(t, testStruct.GetName() == "lee") + innerStruct = testStruct.GetInnerStruct() + assert(t, innerStruct != nil && innerStruct.GetEmail() == "no email") + + // test enum option + valueenum := opt.GetValueenum() + assert(t, valueenum == entity.TestEnum_B) + + // test basic typedef option + valuebasicTypedef := opt.GetValuebasictypedef() + assert(t, ok && valuebasicTypedef == "hello there") + + // test struct typedef option + valuestructTypedef := opt.GetValuestructtypedef() + assert(t, valuestructTypedef != nil) + assert(t, ok && valuestructTypedef.GetEmail() == "empty email") +} + +func TestRuntimeContainerStructOption(t *testing.T) { + // test container option + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), entity.STRUCT_OPTION_PERSON_CONTAINER_INFO) + assert(t, err == nil && option != nil) + opt, ok := option.GetInstance().(*entity.PersonContainerInfo) + assert(t, ok) + + valuemap := opt.GetValuemap() + assert(t, len(valuemap) == 1) + assert(t, valuemap["hey1"] == "value1") + + valuelist := opt.GetValuelist() + assert(t, len(valuelist) == 2) + assert(t, valuelist[0] == "list1") + assert(t, valuelist[1] == "list2") + + valueset := opt.GetValueset() + assert(t, len(valuelist) == 2) + assert(t, valueset[0] == "list3") + assert(t, valueset[1] == "list4") + + valuelistsetstruct := opt.GetValuelistsetstruct() + valuelistsetstruct0 := valuelistsetstruct[0] + assert(t, len(valuelistsetstruct0) == 2) + valuelistsetstruct1 := valuelistsetstruct[1] + assert(t, len(valuelistsetstruct1) == 2) + + valuemapstruct := opt.GetValuemapstruct() + assert(t, len(valuemapstruct) == 2) + valuemapstructk1 := valuemapstruct["k1"] + assert(t, ok && valuemapstructk1.GetEmail() == "e1") + valuemapstructk2 := valuemapstruct["k2"] + assert(t, ok && valuemapstructk2.GetEmail() == "e2") +} + +func TestRuntimeBasicOption(t *testing.T) { + // test basic string option + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), validation.STRUCT_OPTION_PERSON_STRING_INFO) + assert(t, err == nil && option != nil) + valuestring, ok := option.GetInstance().(string) + assert(t, ok) + assert(t, valuestring == "hello") +} + +func TestRuntimeContainerOption(t *testing.T) { + // test container + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), validation.STRUCT_OPTION_PERSON_MAP_INFO) + assert(t, err == nil && option != nil) + valuemap, ok := option.GetInstance().(map[string]string) + assert(t, ok) + assert(t, len(valuemap) == 1) + assert(t, valuemap["hey1"] == "value1") +} + +func TestRuntimeEnumOption(t *testing.T) { + // test enum option + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), validation.STRUCT_OPTION_PERSON_ENUM_INFO) + assert(t, err == nil && option.GetInstance() == validation.MyEnum_XXL) +} + +func TestRuntimeTypedefOption(t *testing.T) { + // test basic typedef option + option1, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), validation.STRUCT_OPTION_PERSON_BASIC_TYPEDEF_INFO) + assert(t, err == nil && option1 != nil) + valuebasicTypedef, ok := option1.GetInstance().(validation.MyBasicTypedef) + assert(t, ok && valuebasicTypedef == "hello there") + + // test struct typedef option + option2, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), validation.STRUCT_OPTION_PERSON_STRUCT_TYPEDEF_INFO) + assert(t, err == nil && option2 != nil) + valuestructTypedef, ok := option2.GetInstance().(*validation.MyStructTypedef) + assert(t, ok && valuestructTypedef.GetName() == "empty name") +} + +func TestRuntimeStructOptionWithDefaultValue(t *testing.T) { + option, err := thrift_option.GetStructOption(option_gen.NewPerson().GetDescriptor(), validation.STRUCT_OPTION_PERSON_STRUCT_DEFAULT_VALUE_INFO) + assert(t, err == nil) + + opt := option.GetInstance().(*validation.MyStructWithDefaultVal) + assert(t, opt.GetV1() == "v1 string") + assert(t, opt.GetV2() == "v2") + assert(t, opt.GetV3() == 8) + assert(t, opt.GetV4() == 16) + assert(t, opt.GetV5() == 32) + assert(t, opt.GetV6() == 64) + assert(t, opt.GetV7() == true) + assert(t, opt.GetV8() == 3.1415926123456) + assert(t, opt.GetV9()["k1"] == "v1") + assert(t, opt.GetV10()[0] == "k1" && opt.GetV10()[1] == "k2") + assert(t, opt.GetV11() == "hello there") +} + +func TestRuntimeFieldOption(t *testing.T) { + pd := option_gen.NewPerson().GetDescriptor() + fd := pd.GetFieldByName("name") + // test basic string option + opt, err := thrift_option.GetFieldOption(fd, entity.FIELD_OPTION_PERSON_FIELD_INFO) + assert(t, err == nil && opt != nil) + valuestring, ok := opt.GetInstance().(string) + assert(t, ok) + assert(t, valuestring == "the name of this person") +} + +func TestRuntimeServiceAndMethodOption(t *testing.T) { + // service option + svc := option_gen.GetFileDescriptorForTest().GetServiceDescriptor("MyService") + opt, err := thrift_option.GetServiceOption(svc, validation.SERVICE_OPTION_SVC_INFO) + assert(t, err == nil, err) + + valueInfo, ok := opt.GetInstance().(*validation.TestInfo) + assert(t, ok) + assert(t, valueInfo.GetName() == "ServiceInfoName") + assert(t, valueInfo.GetNumber() == 666) + + // method option + + // method := option_gen.GetMethodDescriptorForMyServiceM1() + method := svc.GetMethodByName("M1") + assert(t, method != nil) + methodOption, err := thrift_option.GetMethodOption(method, validation.METHOD_OPTION_METHOD_INFO) + assert(t, err == nil, err) + + methodValueInfo, ok := methodOption.GetInstance().(*validation.TestInfo) + assert(t, ok) + assert(t, methodValueInfo.GetName() == "MethodInfoName") + assert(t, methodValueInfo.GetNumber() == 555) +} + +func TestRuntimeEnumAndEnumValueOption(t *testing.T) { + // enum option + e := option_gen.MyEnum(0).GetDescriptor() + assert(t, e != nil) + opt, err := thrift_option.GetEnumOption(e, validation.ENUM_OPTION_ENUM_INFO) + assert(t, err == nil, err) + + valueInfo, ok := opt.GetInstance().(*validation.TestInfo) + assert(t, ok) + assert(t, valueInfo.GetName() == "EnumInfoName") + assert(t, valueInfo.GetNumber() == 333) + + // enum value option + ev := e.GetValues()[0] + enumValueOption, err := thrift_option.GetEnumValueOption(ev, validation.ENUM_VALUE_OPTION_ENUM_VALUE_INFO) + assert(t, err == nil, err) + + enumValueInfo, ok := enumValueOption.GetInstance().(*validation.TestInfo) + assert(t, ok) + assert(t, enumValueInfo.GetName() == "EnumValueInfoName") + assert(t, enumValueInfo.GetNumber() == 222) +} + +func assert(t *testing.T, cond bool, val ...interface{}) { + t.Helper() + if !cond { + if len(val) > 0 { + val = append([]interface{}{"assertion failed:"}, val...) + t.Fatal(val...) + } else { + t.Fatal("assertion failed") + } + } +} diff --git a/fieldmask/api_test.go b/fieldmask/api_test.go index f0904869..664b4e0c 100644 --- a/fieldmask/api_test.go +++ b/fieldmask/api_test.go @@ -101,11 +101,12 @@ func GetDescriptor(IDL string, root string) *thrift_reflection.TypeDescriptor { if err != nil { panic(err.Error()) } - fd := thrift_reflection.RegisterAST(ast) + _, fd := thrift_reflection.RegisterAST(ast) st := fd.GetStructDescriptor(root) return &thrift_reflection.TypeDescriptor{ Filepath: st.Filepath, Name: st.Name, + Extra: map[string]string{thrift_reflection.GLOBAL_UUID_EXTRA_KEY: st.Extra[thrift_reflection.GLOBAL_UUID_EXTRA_KEY]}, } } diff --git a/generator/golang/imports.go b/generator/golang/imports.go index 754aadda..229f2ac9 100644 --- a/generator/golang/imports.go +++ b/generator/golang/imports.go @@ -90,6 +90,7 @@ func (im *importManager) init(cu *CodeUtils, ast *parser.Thrift) { "json_utils": ThriftJSONUtilLib, "fieldmask": ThriftFieldMaskLib, "streaming": KitexStreamingLib, + "thrift_option": ThriftOptionLib, } for pkg, path := range std { ns.Add(pkg, path) diff --git a/generator/golang/option.go b/generator/golang/option.go index 09e5ad84..b839f92f 100644 --- a/generator/golang/option.go +++ b/generator/golang/option.go @@ -64,6 +64,8 @@ type Features struct { NoDefaultSerdes bool `no_default_serdes:"Do not generate default thrift serdes code."` NoAliasTypeReflectionMethod bool `no_alias_type_reflection_method:"Do not generate type related methods in _reflection.go when 'thrift.is_alias=\"true\"' annotation is set to types."` EnableRefInterface bool `enable_ref_interface:"Generate Interface field without pointer type when 'thrift.is_interface=\"true\"' annotation is set to types in referred thrift."` + UseOption bool `use_option:"Parse specific Thrift annotations into struct-style option fields. If key not match, thriftgo will just ignore it."` + // ForceUseOption bool `use_option:"Forcefully parse all Thrift annotations into struct-style option fields. If parsing is not possible, an error will be thrown."` } var defaultFeatures = Features{ diff --git a/generator/golang/scope.go b/generator/golang/scope.go index 47c230f3..5a9093ca 100644 --- a/generator/golang/scope.go +++ b/generator/golang/scope.go @@ -726,3 +726,40 @@ func buildSynthesized(v *parser.Function) (argType, resType *parser.StructLike) } return } + +func (s *Scope) GetOption(filepath string) []string { + ods := []string{} + for _, st := range s.ast.Structs { + if st.Name == "_StructOptions" { + for _, f := range st.Fields { + ods = append(ods, fmt.Sprintf("STRUCT_OPTION_%s = thrift_option.NewStructOption(\"%s\",\"%s\")", strings.ToUpper(f.GetName()), filepath, f.GetName())) + } + } + if st.Name == "_EnumOptions" { + for _, f := range st.Fields { + ods = append(ods, fmt.Sprintf("ENUM_OPTION_%s = thrift_option.NewEnumOption(\"%s\",\"%s\")", strings.ToUpper(f.GetName()), filepath, f.GetName())) + } + } + if st.Name == "_FieldOptions" { + for _, f := range st.Fields { + ods = append(ods, fmt.Sprintf("FIELD_OPTION_%s = thrift_option.NewFieldOption(\"%s\",\"%s\")", strings.ToUpper(f.GetName()), filepath, f.GetName())) + } + } + if st.Name == "_MethodOptions" { + for _, f := range st.Fields { + ods = append(ods, fmt.Sprintf("METHOD_OPTION_%s = thrift_option.NewMethodOption(\"%s\",\"%s\")", strings.ToUpper(f.GetName()), filepath, f.GetName())) + } + } + if st.Name == "_ServiceOptions" { + for _, f := range st.Fields { + ods = append(ods, fmt.Sprintf("SERVICE_OPTION_%s = thrift_option.NewServiceOption(\"%s\",\"%s\")", strings.ToUpper(f.GetName()), filepath, f.GetName())) + } + } + if st.Name == "_EnumValueOptions" { + for _, f := range st.Fields { + ods = append(ods, fmt.Sprintf("ENUM_VALUE_OPTION_%s = thrift_option.NewEnumValueOption(\"%s\",\"%s\")", strings.ToUpper(f.GetName()), filepath, f.GetName())) + } + } + } + return ods +} diff --git a/generator/golang/scope_internal.go b/generator/golang/scope_internal.go index 2d33f7bf..365fd766 100644 --- a/generator/golang/scope_internal.go +++ b/generator/golang/scope_internal.go @@ -21,6 +21,8 @@ import ( "strconv" "strings" + thrift_option "github.com/cloudwego/thriftgo/extension/thrift_option" + "github.com/cloudwego/thriftgo/generator/golang/common" "github.com/cloudwego/thriftgo/generator/golang/streaming" "github.com/cloudwego/thriftgo/parser" @@ -56,6 +58,16 @@ func (s *Scope) init(cu *CodeUtils) (err error) { err = fmt.Errorf("err = %v, stack = %s", r, debug.Stack()) } }() + + if cu.Features().UseOption { + for ast := range s.AST().DepthFirstSearch() { + er := thrift_option.CheckOptionGrammar(ast) + if er != nil { + return er + } + } + } + if cu.Features().ReorderFields { for _, x := range s.ast.GetStructLikes() { diff := reorderFields(x) diff --git a/generator/golang/templates/file.go b/generator/golang/templates/file.go index c4b9ab4f..dbe71266 100644 --- a/generator/golang/templates/file.go +++ b/generator/golang/templates/file.go @@ -56,6 +56,18 @@ import ( {{template "ThriftProcessor" .}} {{- end}} +{{- if Features.UseOption}} +{{- $Options := .GetOption .AST.Filename }} +{{- if $Options}} +{{- UseStdLibrary "thrift_option"}} +var ( + {{- range $Line := $Options}} + {{$Line}} + {{- end}} +) +{{- end}} +{{- end}} + {{- if Features.GenerateReflectionInfo}} var file_{{.IDLName}}_rawDesc = {{.IDLMeta}} func init(){ diff --git a/generator/golang/templates/reflection/reflection_tpl.go b/generator/golang/templates/reflection/reflection_tpl.go index 734aefb0..e7e45997 100644 --- a/generator/golang/templates/reflection/reflection_tpl.go +++ b/generator/golang/templates/reflection/reflection_tpl.go @@ -88,7 +88,6 @@ func (p *{{.GoName}}) GetTypeDescriptor() *thrift_reflection.TypeDescriptor{ {{- end}} {{- end}} {{- range .Enums}} -{{- if not .IsAlias}} func (p {{.GoName}}) GetDescriptor() *thrift_reflection.EnumDescriptor{ return file_{{$IDLName}}_thrift.GetEnumDescriptor("{{.Name}}") } @@ -100,7 +99,6 @@ func (p *{{.GoName}}) GetTypeDescriptor() *thrift_reflection.TypeDescriptor{ return ret } {{- end}} -{{- end}} {{- range .Unions}} {{- if not .IsAlias}} func (p *{{.GoName}}) GetDescriptor() *thrift_reflection.StructDescriptor{ diff --git a/generator/golang/util.go b/generator/golang/util.go index 9f169b96..47488582 100644 --- a/generator/golang/util.go +++ b/generator/golang/util.go @@ -44,7 +44,7 @@ const ( DefaultMetaLib = "github.com/cloudwego/thriftgo/generator/golang/extension/meta" ThriftReflectionLib = "github.com/cloudwego/thriftgo/thrift_reflection" ThriftFieldMaskLib = "github.com/cloudwego/thriftgo/fieldmask" - ThriftOptionLib = "github.com/cloudwego/thriftgo/option" + ThriftOptionLib = "github.com/cloudwego/thriftgo/extension/thrift_option" defaultTemplate = "default" ThriftJSONUtilLib = "github.com/cloudwego/thriftgo/utils/json_utils" KitexStreamingLib = "github.com/cloudwego/kitex/pkg/streaming" diff --git a/go.mod b/go.mod index d148f8af..123d2cb7 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,9 @@ go 1.13 require ( github.com/apache/thrift v0.13.0 - github.com/dlclark/regexp2 v1.10.0 - golang.org/x/text v0.6.0 + github.com/dlclark/regexp2 v1.11.0 + github.com/kr/pretty v0.1.0 // indirect + golang.org/x/text v0.7.0 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 6bf2817b..9147184b 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,12 @@ github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= -github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -21,13 +26,14 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/parser/parser_test.go b/parser/parser_test.go index eb882f51..14ea0d2d 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -38,6 +38,8 @@ struct s { 2: string f2 ( a = "a", b = "" ); 3: string (str = "str") f3; 4: string f4; + 5: string f5 (); + 6: string f6 ( ); } ( xxx = "", yyy = "y", @@ -104,7 +106,7 @@ func TestAnnotation(t *testing.T) { test.Assert(t, has(ast.Structs[0].Annotations, "xxx", "")) test.Assert(t, has(ast.Structs[0].Annotations, "yyy", "y")) test.Assert(t, has(ast.Structs[0].Annotations, "zzz", "zzz")) - test.Assert(t, len(ast.Structs[0].Fields) == 4) + test.Assert(t, len(ast.Structs[0].Fields) == 6) test.Assert(t, len(ast.Structs[0].Fields[0].Annotations) == 1) test.Assert(t, len(ast.Structs[0].Fields[1].Annotations) == 2) test.Assert(t, len(ast.Structs[0].Fields[2].Annotations) == 0) @@ -113,6 +115,8 @@ func TestAnnotation(t *testing.T) { test.Assert(t, has(ast.Structs[0].Fields[1].Annotations, "a", "a")) test.Assert(t, has(ast.Structs[0].Fields[1].Annotations, "b", "")) test.Assert(t, has(ast.Structs[0].Fields[2].Type.Annotations, "str", "str")) + test.Assert(t, ast.Structs[0].Fields[4].Annotations == nil) + test.Assert(t, ast.Structs[0].Fields[5].Annotations == nil) test.Assert(t, len(ast.Exceptions) == 1) test.Assert(t, len(ast.Exceptions[0].Annotations) == 1) diff --git a/parser/thrift.peg b/parser/thrift.peg index d8c685ee..f37842f5 100644 --- a/parser/thrift.peg +++ b/parser/thrift.peg @@ -72,7 +72,7 @@ DoubleConstant <- Skip <[+\-]? ( Exponent <- ('e' / 'E') IntConstant -Annotations <- LPAR Annotation+ RPAR +Annotations <- LPAR Annotation* RPAR Annotation <- Identifier EQUAL Literal ListSeparator? diff --git a/parser/thrift.peg.go b/parser/thrift.peg.go index cc943377..f0790708 100644 --- a/parser/thrift.peg.go +++ b/parser/thrift.peg.go @@ -2011,7 +2011,7 @@ func (p *ThriftIDL) Init(options ...func(*ThriftIDL) error) error { position, tokenIndex = position203, tokenIndex203 return false }, - /* 31 Annotations <- <(LPAR Annotation+ RPAR)> */ + /* 31 Annotations <- <(LPAR Annotation* RPAR)> */ func() bool { position207, tokenIndex207 := position, tokenIndex { @@ -2019,9 +2019,6 @@ func (p *ThriftIDL) Init(options ...func(*ThriftIDL) error) error { if !_rules[ruleLPAR]() { goto l207 } - if !_rules[ruleAnnotation]() { - goto l207 - } l209: { position210, tokenIndex210 := position, tokenIndex diff --git a/thrift_reflection/descriptor-extend.go b/thrift_reflection/descriptor-extend.go index 21e5d908..21f47527 100644 --- a/thrift_reflection/descriptor-extend.go +++ b/thrift_reflection/descriptor-extend.go @@ -32,7 +32,7 @@ func (f *FileDescriptor) GetIncludeFD(alias string) *FileDescriptor { } includePath := f.Includes[alias] if includePath != "" { - return LookupFD(includePath) + return GetGlobalDescriptor(f).LookupFD(includePath) } return nil } @@ -249,7 +249,11 @@ func (sd *ServiceDescriptor) GetMethodByName(name string) *MethodDescriptor { } func (ed *EnumDescriptor) GetGoType() reflect.Type { - return enumDes2goType[ed] + gd := GetGlobalDescriptor(ed) + if gd != nil && gd.enumDes2goType != nil { + return gd.enumDes2goType[ed] + } + return nil } func (td *TypeDescriptor) IsBasic() bool { @@ -272,7 +276,7 @@ func (td *TypeDescriptor) GetExceptionDescriptor() (*StructDescriptor, error) { if td.IsContainer() || td.IsBasic() { return nil, errors.New("not exception") } - stDesc := LookupFD(td.Filepath).GetExceptionDescriptor(td.GetName()) + stDesc := GetGlobalDescriptor(td).LookupFD(td.Filepath).GetExceptionDescriptor(td.GetName()) if stDesc != nil { return stDesc, nil } @@ -283,7 +287,7 @@ func (td *TypeDescriptor) GetUnionDescriptor() (*StructDescriptor, error) { if td.IsContainer() || td.IsBasic() { return nil, errors.New("not union") } - stDesc := LookupFD(td.Filepath).GetUnionDescriptor(td.GetName()) + stDesc := GetGlobalDescriptor(td).LookupFD(td.Filepath).GetUnionDescriptor(td.GetName()) if stDesc != nil { return stDesc, nil } @@ -294,7 +298,7 @@ func (td *TypeDescriptor) GetStructDescriptor() (*StructDescriptor, error) { if td.IsContainer() || td.IsBasic() { return nil, errors.New("not struct") } - stDesc := LookupFD(td.Filepath).GetStructDescriptor(td.GetName()) + stDesc := GetGlobalDescriptor(td).LookupFD(td.Filepath).GetStructDescriptor(td.GetName()) if stDesc != nil { return stDesc, nil } @@ -370,7 +374,7 @@ func (td *TypeDescriptor) GetEnumDescriptor() (*EnumDescriptor, error) { return nil, errors.New("not enum") } prefix, name := utils.ParseAlias(td.GetName()) - fd := LookupFD(td.Filepath) + fd := GetGlobalDescriptor(td).LookupFD(td.Filepath) if fd != nil { targetFd := fd.GetIncludeFD(prefix) if targetFd != nil { @@ -388,23 +392,12 @@ func (td *TypeDescriptor) IsTypedef() bool { if ok { return cacheType == "typedef" } - if td.IsContainer() || td.IsBasic() { - return false - } - prefix, name := utils.ParseAlias(td.GetName()) - fd := LookupFD(td.Filepath) - if fd == nil { - return false - } - targetFd := fd.GetIncludeFD(prefix) - if targetFd == nil { - return false - } - if targetFd.GetTypedefDescriptor(name) == nil { - return false + sd, err := td.GetTypedefDescriptor() + isStruct := err == nil && sd != nil + if isStruct { + td.Extra["type"] = "typedef" } - td.Extra["type"] = "typedef" - return true + return isStruct } func (td *TypeDescriptor) GetTypedefDescriptor() (*TypedefDescriptor, error) { @@ -412,7 +405,7 @@ func (td *TypeDescriptor) GetTypedefDescriptor() (*TypedefDescriptor, error) { return nil, errors.New("not typedef") } prefix, name := utils.ParseAlias(td.GetName()) - fd := LookupFD(td.Filepath) + fd := GetGlobalDescriptor(td).LookupFD(td.Filepath) if fd != nil { targetFd := fd.GetIncludeFD(prefix) if targetFd != nil { @@ -496,11 +489,19 @@ func (td *TypeDescriptor) GetGoType() (reflect.Type, error) { } func (s *StructDescriptor) GetGoType() reflect.Type { - return structDes2goType[s] + gd := GetGlobalDescriptor(s) + if gd != nil && gd.structDes2goType != nil { + return gd.structDes2goType[s] + } + return nil } func (s *TypedefDescriptor) GetGoType() reflect.Type { - return typedefDes2goType[s] + gd := GetGlobalDescriptor(s) + if gd != nil && gd.typedefDes2goType != nil { + return gd.typedefDes2goType[s] + } + return nil } func (s *StructDescriptor) GetFieldByName(name string) *FieldDescriptor { @@ -556,10 +557,54 @@ func (s *ConstValueDescriptor) GetValueAsString() string { return fmt.Sprintf("[%v]", strings.Join(valueList, ",")) } if t == ConstValueType_IDENTIFIER { - targetConst := LookupConst(s.GetValueIdentifier(), "") + targetConst := GetGlobalDescriptor(s).LookupConst(s.GetValueIdentifier(), "") if targetConst != nil { return targetConst.GetValue().GetValueAsString() } } return "" } + +func (d *ServiceDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *MethodDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *FieldDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *StructDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *EnumDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *FileDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *TypedefDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *EnumValueDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *ConstDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *ConstValueDescriptor) setExtra(m map[string]string) { + d.Extra = m +} + +func (d *TypeDescriptor) setExtra(m map[string]string) { + d.Extra = m +} diff --git a/thrift_reflection/descriptor.go b/thrift_reflection/descriptor.go index 3c4f4bde..56b95caa 100644 --- a/thrift_reflection/descriptor.go +++ b/thrift_reflection/descriptor.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Code generated by thriftgo (0.3.0). DO NOT EDIT. +// Code generated by thriftgo (0.3.2). DO NOT EDIT. package thrift_reflection @@ -1119,13 +1119,14 @@ type ConstValueDescriptor struct { ValueList []*ConstValueDescriptor `thrift:"value_list,6,optional" json:"value_list,omitempty"` ValueMap map[*ConstValueDescriptor]*ConstValueDescriptor `thrift:"value_map,7,optional" json:"value_map,omitempty"` ValueIdentifier string `thrift:"value_identifier,8,required" json:"value_identifier"` + Extra map[string]string `thrift:"extra,9,optional" json:"extra,omitempty"` } func init() { meta.RegisterStruct(NewConstValueDescriptor, []byte{ 0xb, 0x0, 0x1, 0x0, 0x0, 0x0, 0x14, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0xb, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x6, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0xf, 0x0, 0x3, 0xc, 0x0, 0x0, 0x0, 0x8, + 0x0, 0x6, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0xf, 0x0, 0x3, 0xc, 0x0, 0x0, 0x0, 0x9, 0x6, 0x0, 0x1, 0x0, 0x1, 0xb, 0x0, 0x2, 0x0, 0x0, 0x0, 0x4, 0x74, 0x79, 0x70, 0x65, 0x8, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0xc, 0x0, 0x4, 0x8, 0x0, 0x1, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x6, 0x0, 0x1, 0x0, 0x2, 0xb, 0x0, 0x2, 0x0, 0x0, 0x0, 0xc, 0x76, @@ -1148,7 +1149,11 @@ func init() { 0x0, 0x3, 0x8, 0x0, 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x6, 0x0, 0x1, 0x0, 0x8, 0xb, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x8, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0xc, - 0x0, 0x4, 0x8, 0x0, 0x1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x8, 0x0, 0x1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x6, 0x0, 0x1, 0x0, 0x9, + 0xb, 0x0, 0x2, 0x0, 0x0, 0x0, 0x5, 0x65, 0x78, 0x74, 0x72, 0x61, 0x8, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x2, 0xc, 0x0, 0x4, 0x8, 0x0, 0x1, 0x0, 0x0, 0x0, 0xd, 0xc, 0x0, 0x2, + 0x8, 0x0, 0x1, 0x0, 0x0, 0x0, 0xb, 0x0, 0xc, 0x0, 0x3, 0x8, 0x0, 0x1, 0x0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, }) } @@ -1198,6 +1203,15 @@ func (p *ConstValueDescriptor) GetValueIdentifier() (v string) { return p.ValueIdentifier } +var ConstValueDescriptor_Extra_DEFAULT map[string]string + +func (p *ConstValueDescriptor) GetExtra() (v map[string]string) { + if !p.IsSetExtra() { + return ConstValueDescriptor_Extra_DEFAULT + } + return p.Extra +} + var fieldIDToName_ConstValueDescriptor = map[int16]string{ 1: "type", 2: "value_double", @@ -1207,6 +1221,7 @@ var fieldIDToName_ConstValueDescriptor = map[int16]string{ 6: "value_list", 7: "value_map", 8: "value_identifier", + 9: "extra", } func (p *ConstValueDescriptor) IsSetValueList() bool { @@ -1217,6 +1232,10 @@ func (p *ConstValueDescriptor) IsSetValueMap() bool { return p.ValueMap != nil } +func (p *ConstValueDescriptor) IsSetExtra() bool { + return p.Extra != nil +} + func (p *ConstValueDescriptor) Read(iprot thrift.TProtocol) (err error) { var fieldTypeId thrift.TType @@ -1328,6 +1347,16 @@ func (p *ConstValueDescriptor) Read(iprot thrift.TProtocol) (err error) { goto SkipFieldError } } + case 9: + if fieldTypeId == thrift.MAP { + if err = p.ReadField9(iprot); err != nil { + goto ReadFieldError + } + } else { + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } default: if err = iprot.Skip(fieldTypeId); err != nil { goto SkipFieldError @@ -1487,6 +1516,35 @@ func (p *ConstValueDescriptor) ReadField8(iprot thrift.TProtocol) error { return nil } +func (p *ConstValueDescriptor) ReadField9(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + p.Extra = make(map[string]string, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + + var _val string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _val = v + } + + p.Extra[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + return nil +} + func (p *ConstValueDescriptor) Write(oprot thrift.TProtocol) (err error) { var fieldId int16 if err = oprot.WriteStructBegin("ConstValueDescriptor"); err != nil { @@ -1525,6 +1583,10 @@ func (p *ConstValueDescriptor) Write(oprot thrift.TProtocol) (err error) { fieldId = 8 goto WriteFieldError } + if err = p.writeField9(oprot); err != nil { + fieldId = 9 + goto WriteFieldError + } } if err = oprot.WriteFieldStop(); err != nil { @@ -1705,6 +1767,38 @@ WriteFieldEndError: return thrift.PrependError(fmt.Sprintf("%T write field 8 end error: ", p), err) } +func (p *ConstValueDescriptor) writeField9(oprot thrift.TProtocol) (err error) { + if p.IsSetExtra() { + if err = oprot.WriteFieldBegin("extra", thrift.MAP, 9); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRING, len(p.Extra)); err != nil { + return err + } + for k, v := range p.Extra { + + if err := oprot.WriteString(k); err != nil { + return err + } + + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 9 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 9 end error: ", p), err) +} + func (p *ConstValueDescriptor) String() string { if p == nil { return "" diff --git a/thrift_reflection/descriptor_lookup.go b/thrift_reflection/descriptor_lookup.go index ad43622d..a228edd0 100644 --- a/thrift_reflection/descriptor_lookup.go +++ b/thrift_reflection/descriptor_lookup.go @@ -14,15 +14,23 @@ package thrift_reflection -func LookupFD(filepath string) *FileDescriptor { - return globalFD[filepath] +import "errors" + +func (gd *GlobalDescriptor) LookupFD(filepath string) *FileDescriptor { + if gd == nil { + return nil + } + return gd.globalFD[filepath] } -func LookupEnum(name, filepath string) *EnumDescriptor { +func (gd *GlobalDescriptor) LookupEnum(name, filepath string) *EnumDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetEnumDescriptor(name) + return gd.LookupFD(filepath).GetEnumDescriptor(name) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetEnumDescriptor(name) if val != nil { return val @@ -31,11 +39,14 @@ func LookupEnum(name, filepath string) *EnumDescriptor { return nil } -func LookupConst(name, filepath string) *ConstDescriptor { +func (gd *GlobalDescriptor) LookupConst(name, filepath string) *ConstDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetConstDescriptor(name) + return gd.LookupFD(filepath).GetConstDescriptor(name) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetConstDescriptor(name) if val != nil { return val @@ -44,11 +55,14 @@ func LookupConst(name, filepath string) *ConstDescriptor { return nil } -func LookupTypedef(alias, filepath string) *TypedefDescriptor { +func (gd *GlobalDescriptor) LookupTypedef(alias, filepath string) *TypedefDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetTypedefDescriptor(alias) + return gd.LookupFD(filepath).GetTypedefDescriptor(alias) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetTypedefDescriptor(alias) if val != nil { return val @@ -57,11 +71,14 @@ func LookupTypedef(alias, filepath string) *TypedefDescriptor { return nil } -func LookupStruct(name, filepath string) *StructDescriptor { +func (gd *GlobalDescriptor) LookupStruct(name, filepath string) *StructDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetStructDescriptor(name) + return gd.LookupFD(filepath).GetStructDescriptor(name) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetStructDescriptor(name) if val != nil { return val @@ -70,11 +87,14 @@ func LookupStruct(name, filepath string) *StructDescriptor { return nil } -func LookupUnion(name, filepath string) *StructDescriptor { +func (gd *GlobalDescriptor) LookupUnion(name, filepath string) *StructDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetUnionDescriptor(name) + return gd.LookupFD(filepath).GetUnionDescriptor(name) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetUnionDescriptor(name) if val != nil { return val @@ -83,11 +103,14 @@ func LookupUnion(name, filepath string) *StructDescriptor { return nil } -func LookupException(name, filepath string) *StructDescriptor { +func (gd *GlobalDescriptor) LookupException(name, filepath string) *StructDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetExceptionDescriptor(name) + return gd.LookupFD(filepath).GetExceptionDescriptor(name) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetExceptionDescriptor(name) if val != nil { return val @@ -96,11 +119,14 @@ func LookupException(name, filepath string) *StructDescriptor { return nil } -func LookupService(name, filepath string) *ServiceDescriptor { +func (gd *GlobalDescriptor) LookupService(name, filepath string) *ServiceDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetServiceDescriptor(name) + return gd.LookupFD(filepath).GetServiceDescriptor(name) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetServiceDescriptor(name) if val != nil { return val @@ -109,11 +135,14 @@ func LookupService(name, filepath string) *ServiceDescriptor { return nil } -func LookupMethod(method, service, filepath string) *MethodDescriptor { +func (gd *GlobalDescriptor) LookupMethod(method, service, filepath string) *MethodDescriptor { + if gd == nil { + return nil + } if filepath != "" { - return LookupFD(filepath).GetMethodDescriptor(service, method) + return gd.LookupFD(filepath).GetMethodDescriptor(service, method) } - for _, fd := range globalFD { + for _, fd := range gd.globalFD { val := fd.GetMethodDescriptor(service, method) if val != nil { return val @@ -122,7 +151,10 @@ func LookupMethod(method, service, filepath string) *MethodDescriptor { return nil } -func LookupIncludedStructsFromMethod(method *MethodDescriptor) ([]*StructDescriptor, error) { +func (gd *GlobalDescriptor) LookupIncludedStructsFromMethod(method *MethodDescriptor) ([]*StructDescriptor, error) { + if gd == nil { + return nil, errors.New("global descriptor is nil") + } structMap := map[*StructDescriptor]bool{} typeArr := []*TypeDescriptor{} typeArr = append(typeArr, method.GetResponse()) @@ -130,7 +162,7 @@ func LookupIncludedStructsFromMethod(method *MethodDescriptor) ([]*StructDescrip typeArr = append(typeArr, arg.GetType()) } for _, typeDesc := range typeArr { - err := lookupIncludedStructsFromType(typeDesc, structMap) + err := gd.lookupIncludedStructsFromType(typeDesc, structMap) if err != nil { return nil, err } @@ -143,9 +175,12 @@ func LookupIncludedStructsFromMethod(method *MethodDescriptor) ([]*StructDescrip } // LookupIncludedStructsFromStruct finds all struct descriptor included by this structDescriptor (and current struct descriptor is also included in the return result) -func LookupIncludedStructsFromStruct(sd *StructDescriptor) ([]*StructDescriptor, error) { +func (gd *GlobalDescriptor) LookupIncludedStructsFromStruct(sd *StructDescriptor) ([]*StructDescriptor, error) { + if gd == nil { + return nil, errors.New("global descriptor is nil") + } structMap := map[*StructDescriptor]bool{} - err := lookupIncludedStructsFromStruct(sd, structMap) + err := gd.lookupIncludedStructsFromStruct(sd, structMap) if err != nil { return nil, err } @@ -156,9 +191,12 @@ func LookupIncludedStructsFromStruct(sd *StructDescriptor) ([]*StructDescriptor, return structArr, nil } -func LookupIncludedStructsFromType(td *TypeDescriptor) ([]*StructDescriptor, error) { +func (gd *GlobalDescriptor) LookupIncludedStructsFromType(td *TypeDescriptor) ([]*StructDescriptor, error) { + if gd == nil { + return nil, errors.New("global descriptor is nil") + } structMap := map[*StructDescriptor]bool{} - err := lookupIncludedStructsFromType(td, structMap) + err := gd.lookupIncludedStructsFromType(td, structMap) if err != nil { return nil, err } @@ -169,21 +207,24 @@ func LookupIncludedStructsFromType(td *TypeDescriptor) ([]*StructDescriptor, err return structArr, nil } -func lookupIncludedStructsFromType(typeDesc *TypeDescriptor, structMap map[*StructDescriptor]bool) error { +func (gd *GlobalDescriptor) lookupIncludedStructsFromType(typeDesc *TypeDescriptor, structMap map[*StructDescriptor]bool) error { + if gd == nil { + return errors.New("global descriptor is nil") + } if typeDesc.IsStruct() { stDesc, err := typeDesc.GetStructDescriptor() if err != nil { return err } - return lookupIncludedStructsFromStruct(stDesc, structMap) + return gd.lookupIncludedStructsFromStruct(stDesc, structMap) } if typeDesc.IsContainer() { - err := lookupIncludedStructsFromType(typeDesc.GetValueType(), structMap) + err := gd.lookupIncludedStructsFromType(typeDesc.GetValueType(), structMap) if err != nil { return err } if typeDesc.IsMap() { - er := lookupIncludedStructsFromType(typeDesc.GetKeyType(), structMap) + er := gd.lookupIncludedStructsFromType(typeDesc.GetKeyType(), structMap) if er != nil { return er } @@ -192,17 +233,69 @@ func lookupIncludedStructsFromType(typeDesc *TypeDescriptor, structMap map[*Stru return nil } -func lookupIncludedStructsFromStruct(sd *StructDescriptor, structMap map[*StructDescriptor]bool) error { +func (gd *GlobalDescriptor) lookupIncludedStructsFromStruct(sd *StructDescriptor, structMap map[*StructDescriptor]bool) error { + if gd == nil { + return errors.New("global descriptor is nil") + } if structMap[sd] { return nil } structMap[sd] = true for _, f := range sd.GetFields() { typeDesc := f.GetType() - err := lookupIncludedStructsFromType(typeDesc, structMap) + err := gd.lookupIncludedStructsFromType(typeDesc, structMap) if err != nil { return err } } return nil } + +func LookupFD(filepath string) *FileDescriptor { + return defaultGlobalDescriptor.LookupFD(filepath) +} + +func LookupEnum(name, filepath string) *EnumDescriptor { + return defaultGlobalDescriptor.LookupEnum(name, filepath) +} + +func LookupConst(name, filepath string) *ConstDescriptor { + return defaultGlobalDescriptor.LookupConst(name, filepath) +} + +func LookupTypedef(alias, filepath string) *TypedefDescriptor { + return defaultGlobalDescriptor.LookupTypedef(alias, filepath) +} + +func LookupStruct(name, filepath string) *StructDescriptor { + return defaultGlobalDescriptor.LookupStruct(name, filepath) +} + +func LookupUnion(name, filepath string) *StructDescriptor { + return defaultGlobalDescriptor.LookupUnion(name, filepath) +} + +func LookupException(name, filepath string) *StructDescriptor { + return defaultGlobalDescriptor.LookupException(name, filepath) +} + +func LookupService(name, filepath string) *ServiceDescriptor { + return defaultGlobalDescriptor.LookupService(name, filepath) +} + +func LookupMethod(method, service, filepath string) *MethodDescriptor { + return defaultGlobalDescriptor.LookupMethod(method, service, filepath) +} + +func LookupIncludedStructsFromMethod(method *MethodDescriptor) ([]*StructDescriptor, error) { + return defaultGlobalDescriptor.LookupIncludedStructsFromMethod(method) +} + +// LookupIncludedStructsFromStruct finds all struct descriptor included by this structDescriptor (and current struct descriptor is also included in the return result) +func LookupIncludedStructsFromStruct(sd *StructDescriptor) ([]*StructDescriptor, error) { + return defaultGlobalDescriptor.LookupIncludedStructsFromStruct(sd) +} + +func LookupIncludedStructsFromType(td *TypeDescriptor) ([]*StructDescriptor, error) { + return defaultGlobalDescriptor.LookupIncludedStructsFromType(td) +} diff --git a/thrift_reflection/descriptor_register.go b/thrift_reflection/descriptor_register.go index 6d5e57f8..afea4c97 100644 --- a/thrift_reflection/descriptor_register.go +++ b/thrift_reflection/descriptor_register.go @@ -15,19 +15,151 @@ package thrift_reflection import ( + "encoding/hex" "fmt" + "math/rand" "reflect" + "sync" "github.com/cloudwego/thriftgo/parser" ) -var globalFD = map[string]*FileDescriptor{} +type GlobalDescriptor struct { + uuid string + globalFD map[string]*FileDescriptor -func checkDuplicateAndRegister(f *FileDescriptor, currentGoPkgPath string) { + structDes2goType map[*StructDescriptor]reflect.Type + enumDes2goType map[*EnumDescriptor]reflect.Type + typedefDes2goType map[*TypedefDescriptor]reflect.Type + + goType2StructDes map[reflect.Type]*StructDescriptor + goType2EnumDes map[reflect.Type]*EnumDescriptor + goType2TypedefDes map[reflect.Type]*TypedefDescriptor +} + +var defaultGlobalDescriptor = &GlobalDescriptor{ + uuid: DEFAULT_GLOBAL_DESCRIPTOR_UUID, + globalFD: map[string]*FileDescriptor{}, + structDes2goType: map[*StructDescriptor]reflect.Type{}, + enumDes2goType: map[*EnumDescriptor]reflect.Type{}, + typedefDes2goType: map[*TypedefDescriptor]reflect.Type{}, + goType2StructDes: map[reflect.Type]*StructDescriptor{}, + goType2EnumDes: map[reflect.Type]*EnumDescriptor{}, + goType2TypedefDes: map[reflect.Type]*TypedefDescriptor{}, +} + +var globalDescriptorMap = map[string]*GlobalDescriptor{ + DEFAULT_GLOBAL_DESCRIPTOR_UUID: defaultGlobalDescriptor, +} +var lock sync.RWMutex + +const ( + DEFAULT_GLOBAL_DESCRIPTOR_UUID = "default" + GLOBAL_UUID_EXTRA_KEY = "global_descriptor_uuid" +) + +func GetGlobalDescriptor(v interface{ GetExtra() map[string]string }) *GlobalDescriptor { + uuid := v.GetExtra()[GLOBAL_UUID_EXTRA_KEY] + if uuid == "" { + return defaultGlobalDescriptor + } + lock.RLock() + defer lock.RUnlock() + return globalDescriptorMap[uuid] +} + +func addExtraToDescriptor(uuid string, v interface { + GetExtra() map[string]string + setExtra(m map[string]string) +}) { + if v == nil || isNil(v) { + return + } + if v.GetExtra() == nil { + v.setExtra(map[string]string{}) + } + v.GetExtra()[GLOBAL_UUID_EXTRA_KEY] = uuid +} + +func isNil(i interface{}) bool { + if i == nil { + return true + } + + vi := reflect.ValueOf(i) + + if vi.Kind() == reflect.Ptr { + return vi.IsNil() + } + + return false +} + +func addExtraToTypeDescriptor(uuid string, td *TypeDescriptor) { + if td == nil { + return + } + if td.GetExtra() == nil { + td.setExtra(map[string]string{}) + } + td.GetExtra()[GLOBAL_UUID_EXTRA_KEY] = uuid + addExtraToTypeDescriptor(uuid, td.KeyType) + addExtraToTypeDescriptor(uuid, td.ValueType) +} + +func registerGlobalUUID(fd *FileDescriptor, uuid string) { + addExtraToDescriptor(uuid, fd) + + for _, service := range fd.Services { + addExtraToDescriptor(uuid, service) + for _, method := range service.Methods { + addExtraToDescriptor(uuid, method) + addExtraToTypeDescriptor(uuid, method.Response) + for _, arg := range method.Args { + addExtraToDescriptor(uuid, arg) + addExtraToTypeDescriptor(uuid, arg.Type) + } + for _, e := range method.ThrowExceptions { + addExtraToDescriptor(uuid, e) + addExtraToTypeDescriptor(uuid, e.Type) + } + } + } + structs := []*StructDescriptor{} + structs = append(structs, fd.Structs...) + structs = append(structs, fd.Unions...) + structs = append(structs, fd.Exceptions...) + for _, strct := range fd.Structs { + addExtraToDescriptor(uuid, strct) + for _, f := range strct.Fields { + addExtraToDescriptor(uuid, f) + addExtraToTypeDescriptor(uuid, f.Type) + addExtraToDescriptor(uuid, f.DefaultValue) + } + } + + for _, enum := range fd.Enums { + addExtraToDescriptor(uuid, enum) + for _, ev := range enum.Values { + addExtraToDescriptor(uuid, ev) + } + } + + for _, typedef := range fd.Typedefs { + addExtraToDescriptor(uuid, typedef) + addExtraToTypeDescriptor(uuid, typedef.Type) + } + for _, c := range fd.Consts { + addExtraToDescriptor(uuid, c) + addExtraToDescriptor(uuid, c.Value) + } +} + +func (gd *GlobalDescriptor) checkDuplicateAndRegister(f *FileDescriptor, currentGoPkgPath string) { f.setGoPkgPath(currentGoPkgPath) - previous, ok := globalFD[f.Filepath] + previous, ok := gd.globalFD[f.Filepath] if !ok { - globalFD[f.Filepath] = f + gd.globalFD[f.Filepath] = f return } @@ -48,8 +180,8 @@ func checkDuplicateAndRegister(f *FileDescriptor, currentGoPkgPath string) { func BuildFileDescriptor(builder *FileDescriptorBuilder) *FileDescriptor { fd := MustUnmarshal(builder.Bytes) - checkDuplicateAndRegister(fd, builder.GoPackagePath) - registerGoTypes(fd, builder.GoTypes) + defaultGlobalDescriptor.checkDuplicateAndRegister(fd, builder.GoPackagePath) + defaultGlobalDescriptor.registerGoTypes(fd, builder.GoTypes) return fd } @@ -59,9 +191,9 @@ type FileDescriptorBuilder struct { GoPackagePath string } -func ShowRegisterInfo() map[string]string { +func (gd *GlobalDescriptor) ShowRegisterInfo() map[string]string { info := map[string]string{} - for _, fd := range globalFD { + for _, fd := range gd.globalFD { info[fd.Filepath] = fd.getGoPkgPath() } return info @@ -85,7 +217,25 @@ func (f *FileDescriptor) setGoPkgPath(path string) { f.Extra["GoPkgPath"] = path } -func RegisterAST(ast *parser.Thrift) *FileDescriptor { +func RegisterAST(ast *parser.Thrift) (*GlobalDescriptor, *FileDescriptor) { + gd := &GlobalDescriptor{globalFD: map[string]*FileDescriptor{}} + gd.uuid = generateShortUUID() + fd := doRegisterAST(ast, gd.globalFD, gd.uuid) + lock.Lock() + defer lock.Unlock() + globalDescriptorMap[gd.uuid] = gd + return gd, fd +} + +func generateShortUUID() string { + uuid := make([]byte, 4) + _, _ = rand.Read(uuid) + // 将随机生成的字节转换为十六进制字符串 + shortUUID := hex.EncodeToString(uuid) + return shortUUID +} + +func doRegisterAST(ast *parser.Thrift, globalFD map[string]*FileDescriptor, globalUUID string) *FileDescriptor { fd, ok := globalFD[ast.Filename] if ok { return fd @@ -93,7 +243,8 @@ func RegisterAST(ast *parser.Thrift) *FileDescriptor { fd = GetFileDescriptor(ast) globalFD[fd.Filepath] = fd for _, inc := range ast.Includes { - RegisterAST(inc.GetReference()) + doRegisterAST(inc.GetReference(), globalFD, globalUUID) } + registerGlobalUUID(fd, globalUUID) return fd } diff --git a/thrift_reflection/descriptor_register_go_type.go b/thrift_reflection/descriptor_register_go_type.go index eaddbced..54ab3202 100644 --- a/thrift_reflection/descriptor_register_go_type.go +++ b/thrift_reflection/descriptor_register_go_type.go @@ -16,59 +16,70 @@ package thrift_reflection import "reflect" -var ( - structDes2goType = map[*StructDescriptor]reflect.Type{} - enumDes2goType = map[*EnumDescriptor]reflect.Type{} - typedefDes2goType = map[*TypedefDescriptor]reflect.Type{} - - goType2StructDes = map[reflect.Type]*StructDescriptor{} - goType2EnumDes = map[reflect.Type]*EnumDescriptor{} - goType2TypedefDes = map[reflect.Type]*TypedefDescriptor{} -) - func getReflect(in interface{}) reflect.Type { return reflect.TypeOf(in).Elem() } -func registerGoTypes(fd *FileDescriptor, goTypes []interface{}) { +func (gd *GlobalDescriptor) registerGoTypes(fd *FileDescriptor, goTypes []interface{}) { structList := []*StructDescriptor{} structList = append(structList, fd.Structs...) structList = append(structList, fd.Unions...) structList = append(structList, fd.Exceptions...) for idx, s := range structList { - registerStructGoType(s, getReflect(goTypes[idx])) + gd.registerStructGoType(s, getReflect(goTypes[idx])) } for idx, e := range fd.Enums { - registerEnumGoType(e, getReflect(goTypes[len(structList)+idx])) + gd.registerEnumGoType(e, getReflect(goTypes[len(structList)+idx])) } for idx, t := range fd.Typedefs { - registerTypedefGoType(t, getReflect(goTypes[len(structList)+len(fd.Enums)+idx])) + gd.registerTypedefGoType(t, getReflect(goTypes[len(structList)+len(fd.Enums)+idx])) } } -func registerStructGoType(s *StructDescriptor, t reflect.Type) { - structDes2goType[s] = t - goType2StructDes[t] = s +func (gd *GlobalDescriptor) registerStructGoType(s *StructDescriptor, t reflect.Type) { + gd.structDes2goType[s] = t + gd.goType2StructDes[t] = s +} + +func (gd *GlobalDescriptor) registerEnumGoType(s *EnumDescriptor, t reflect.Type) { + gd.enumDes2goType[s] = t + gd.goType2EnumDes[t] = s } -func registerEnumGoType(s *EnumDescriptor, t reflect.Type) { - enumDes2goType[s] = t - goType2EnumDes[t] = s +func (gd *GlobalDescriptor) registerTypedefGoType(s *TypedefDescriptor, t reflect.Type) { + gd.typedefDes2goType[s] = t + gd.goType2TypedefDes[t] = s } -func registerTypedefGoType(s *TypedefDescriptor, t reflect.Type) { - typedefDes2goType[s] = t - goType2TypedefDes[t] = s +func (gd *GlobalDescriptor) GetStructDescriptorByGoType(in interface{}) *StructDescriptor { + if gd.goType2StructDes == nil { + return nil + } + return gd.goType2StructDes[getReflect(in)] +} + +func (gd *GlobalDescriptor) GetEnumDescriptorByGoType(in interface{}) *EnumDescriptor { + if gd.goType2EnumDes == nil { + return nil + } + return gd.goType2EnumDes[getReflect(in)] +} + +func (gd *GlobalDescriptor) GetTypedefDescriptorByGoType(in interface{}) *TypedefDescriptor { + if gd.goType2TypedefDes == nil { + return nil + } + return gd.goType2TypedefDes[getReflect(in)] } func GetStructDescriptorByGoType(in interface{}) *StructDescriptor { - return goType2StructDes[getReflect(in)] + return defaultGlobalDescriptor.GetStructDescriptorByGoType(in) } func GetEnumDescriptorByGoType(in interface{}) *EnumDescriptor { - return goType2EnumDes[getReflect(in)] + return defaultGlobalDescriptor.GetEnumDescriptorByGoType(in) } func GetTypedefDescriptorByGoType(in interface{}) *TypedefDescriptor { - return goType2TypedefDes[getReflect(in)] + return defaultGlobalDescriptor.GetTypedefDescriptorByGoType(in) } diff --git a/thrift_reflection/descriptor_register_relacer.go b/thrift_reflection/descriptor_register_relacer.go index 461e5918..2720077a 100644 --- a/thrift_reflection/descriptor_register_relacer.go +++ b/thrift_reflection/descriptor_register_relacer.go @@ -36,7 +36,7 @@ func ReplaceFileDescriptor(replacer *FileDescriptorReplacer) *FileDescriptor { currentGoPkgPath := replacer.CurrentGoPkgPath currentFilepath := replacer.CurrentFilepath matcher := replacer.Matcher - remoteDesc := matchRemoteFileDescriptor(remoteGoPkgPath, matcher) + remoteDesc := defaultGlobalDescriptor.matchRemoteFileDescriptor(remoteGoPkgPath, matcher) if remoteDesc == nil { panic("not found remote fd") } @@ -50,15 +50,15 @@ func ReplaceFileDescriptor(replacer *FileDescriptorReplacer) *FileDescriptor { shadowDesc.setGoPkgPathRef(currentGoPkgPath) if remoteDesc.Filepath != currentFilepath { - checkDuplicateAndRegister(shadowDesc, currentGoPkgPath) + defaultGlobalDescriptor.checkDuplicateAndRegister(shadowDesc, currentGoPkgPath) } return shadowDesc } -func matchRemoteFileDescriptor(remoteGoPkgPath, matcher string) *FileDescriptor { - for k, fd := range globalFD { +func (g *GlobalDescriptor) matchRemoteFileDescriptor(remoteGoPkgPath, matcher string) *FileDescriptor { + for k, fd := range g.globalFD { if fd.checkGoPkgPathWithRef(remoteGoPkgPath) && checkMatch(matcher, fd) { - return globalFD[k] + return g.globalFD[k] } } return nil diff --git a/thrift_reflection/descriptor_register_test.go b/thrift_reflection/descriptor_register_test.go index 8fffb485..484c1616 100644 --- a/thrift_reflection/descriptor_register_test.go +++ b/thrift_reflection/descriptor_register_test.go @@ -29,7 +29,7 @@ func Test_checkDuplicateAndRegister(t *testing.T) { } type x struct{} pkgPath := reflect.TypeOf(x{}).PkgPath() - checkDuplicateAndRegister(testDesc, pkgPath) + defaultGlobalDescriptor.checkDuplicateAndRegister(testDesc, pkgPath) // register the FileDescriptor with the same content and Filepath sameDesc := &FileDescriptor{ @@ -38,7 +38,7 @@ func Test_checkDuplicateAndRegister(t *testing.T) { "testKey": "testValue", }, } - checkDuplicateAndRegister(sameDesc, pkgPath) + defaultGlobalDescriptor.checkDuplicateAndRegister(sameDesc, pkgPath) // register the FileDescriptor with the same Filepath and different content anotherDesc := &FileDescriptor{ @@ -52,5 +52,5 @@ func Test_checkDuplicateAndRegister(t *testing.T) { t.Fatal("Register FileDescriptor with the same Filepath and different content should panic") } }() - checkDuplicateAndRegister(anotherDesc, pkgPath) + defaultGlobalDescriptor.checkDuplicateAndRegister(anotherDesc, pkgPath) } diff --git a/thrift_reflection/descriptor_test.go b/thrift_reflection/descriptor_test.go new file mode 100644 index 00000000..7a9d7fe1 --- /dev/null +++ b/thrift_reflection/descriptor_test.go @@ -0,0 +1,129 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 thrift_reflection + +import ( + "reflect" + "testing" + + "github.com/cloudwego/thriftgo/parser" +) + +func TestDescriptor(t *testing.T) { + // file descriptor + ast, err := parser.ParseFile("reflection_test_idl.thrift", []string{"reflection_test_idl"}, true) + assert(t, err == nil) + _, fd := RegisterAST(ast) + assert(t, fd != nil) + assert(t, fd.Namespaces["go"] == "thrift_reflection_test") + + // struct descriptor + pd := fd.GetStructDescriptor("Person") + + assert(t, pd != nil) + assert(t, pd.GetName() == "Person") + assert(t, pd.GetComments() == "// Person Comment") + assert(t, pd.GetAnnotations()["k1"][0] == "hello") + assert(t, pd.GetAnnotations()["k2"][0] == "hey") + assert(t, pd.GetFilepath() == "reflection_test_idl.thrift") + assert(t, len(pd.GetFields()) == 8) + + // file descriptor getter test + personDesc := fd.GetStructDescriptor("Person") + assert(t, personDesc == pd) + personUnknownDesc := fd.GetStructDescriptor("person_unknown") + assert(t, personUnknownDesc == nil) + + // struct descriptor reflection api, currently no go type registered + assert(t, pd.GetGoType() == nil) + + // field descriptor + basicField := pd.GetFieldByName("name") + assert(t, basicField != nil) + assert(t, basicField.GetName() == "name") + assert(t, basicField.GetRequiredness() == "Required") + assert(t, basicField.GetID() == 1) + + // type descriptor + basicType := basicField.GetType() + assert(t, basicType != nil) + assert(t, basicType.IsBasic()) + assert(t, basicType.Name == "string") + + basicGoType, err := basicType.GetGoType() + assert(t, err == nil) + assert(t, basicGoType == reflect.TypeOf(string(""))) + + // get struct descriptor from type descriptor + structField := pd.GetFieldByName("id") + structTypeDesc := structField.GetType() + assert(t, structTypeDesc.IsStruct()) + stDesc, err := structTypeDesc.GetStructDescriptor() + assert(t, err == nil) + assert(t, stDesc.GetName() == "IDCard") + assert(t, stDesc.GetGoType() == nil) +} + +func TestLookup(t *testing.T) { + ast, err := parser.ParseFile("reflection_test_idl.thrift", []string{"reflection_test_idl"}, true) + assert(t, err == nil) + gd, fd := RegisterAST(ast) + // lookup struct + pd := fd.GetStructDescriptor("Person") + assert(t, pd == gd.LookupStruct(pd.GetName(), "")) + assert(t, pd == gd.LookupStruct(pd.GetName(), pd.GetFilepath())) + // lookup const + cs := fd.GetConstDescriptor("MY_CONST") + assert(t, cs == gd.LookupConst(cs.GetName(), "")) + assert(t, cs == gd.LookupConst(cs.GetName(), cs.GetFilepath())) + // lookup enum + en := fd.GetEnumDescriptor("Gender") + assert(t, en == gd.LookupEnum(en.GetName(), "")) + assert(t, en == gd.LookupEnum(en.GetName(), en.GetFilepath())) + // lookup typedef + td := fd.GetTypedefDescriptor("SpecialPerson") + assert(t, td == gd.LookupTypedef(td.GetAlias(), "")) + assert(t, td == gd.LookupTypedef(td.GetAlias(), td.GetFilepath())) + // lookup union + un := fd.GetUnionDescriptor("MyUnion") + assert(t, un == gd.LookupUnion(un.GetName(), "")) + assert(t, un == gd.LookupUnion(un.GetName(), td.GetFilepath())) + // lookup exception + ex := fd.GetExceptionDescriptor("MyException") + assert(t, ex == gd.LookupException(ex.GetName(), "")) + assert(t, ex == gd.LookupException(ex.GetName(), td.GetFilepath())) + // lookup service + svc := fd.GetServiceDescriptor("MyService") + assert(t, svc == gd.LookupService(svc.GetName(), "")) + assert(t, svc == gd.LookupService(svc.GetName(), svc.GetFilepath())) + // lookup method + md := fd.GetMethodDescriptor("MyService", "M1") + assert(t, md == gd.LookupMethod(md.GetName(), "", "")) + assert(t, md == gd.LookupMethod(md.GetName(), "", md.GetFilepath())) + assert(t, md == gd.LookupMethod(md.GetName(), svc.GetName(), "")) + assert(t, md == gd.LookupMethod(md.GetName(), svc.GetName(), md.GetFilepath())) +} + +func assert(t *testing.T, cond bool, val ...interface{}) { + t.Helper() + if !cond { + if len(val) > 0 { + val = append([]interface{}{"assertion failed:"}, val...) + t.Fatal(val...) + } else { + t.Fatal("assertion failed") + } + } +} diff --git a/utils/string_utils.go b/utils/string_utils.go index a1c06244..2303334f 100644 --- a/utils/string_utils.go +++ b/utils/string_utils.go @@ -83,7 +83,7 @@ func ParseArr(str string) ([]string, error) { if sb == 0 && cb == 0 && dq && sq { kend = len(str) if kstart >= kend { - return nil, errors.New("grammar error") + return nil, errors.New("grammar error for:" + str) } key = str[kstart:kend] result = append(result, key) @@ -99,6 +99,7 @@ func ParseArr(str string) ([]string, error) { // ParseKV parses a string such as {a:b,c:d} into a string map func ParseKV(str string) (map[string]string, error) { + str = strings.ReplaceAll(str, ",", ", ") for { newstr := strings.ReplaceAll(str, "\t", " ") newstr = strings.ReplaceAll(newstr, "\n", " ") @@ -106,6 +107,7 @@ func ParseKV(str string) (map[string]string, error) { newstr = strings.ReplaceAll(newstr, "{ ", "{") newstr = strings.ReplaceAll(newstr, " :", ":") newstr = strings.ReplaceAll(newstr, ": ", ":") + newstr = strings.ReplaceAll(newstr, " ,", ",") newstr = strings.ReplaceAll(newstr, " ", " ") newstr = strings.TrimSpace(newstr) if len(newstr) == len(str) { @@ -162,10 +164,13 @@ func ParseKV(str string) (map[string]string, error) { if sb == 0 && cb == 0 && dq && sq { vend = i if vstart >= vend { - return nil, errors.New("grammar error") + return nil, errors.New("grammar error for:" + str) } kstart = i + 1 - value = str[vstart:vend] + value = strings.TrimSpace(str[vstart:vend]) + if strings.HasSuffix(value, ",") { + value = strings.TrimSuffix(value, ",") + } result[strings.TrimSpace(key)] = strings.TrimSpace(value) } continue @@ -174,12 +179,16 @@ func ParseKV(str string) (map[string]string, error) { if sb == 0 && cb == 0 && dq && sq { vend = len(str) if vstart >= vend { - return nil, errors.New("grammar error") + return nil, errors.New("grammar error for:" + str) } if kstart >= kend { - return nil, errors.New("grammar error") + return nil, errors.New("grammar error for:" + str) } value = str[vstart:vend] + value = strings.TrimSpace(str[vstart:vend]) + if strings.HasSuffix(value, ",") { + value = strings.TrimSuffix(value, ",") + } result[strings.TrimSpace(key)] = strings.TrimSpace(value) return result, nil } else { diff --git a/utils/utils_test.go b/utils/utils_test.go index b3790a4b..33d2d061 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -24,7 +24,7 @@ func TestParseKV(t *testing.T) { kv, err := ParseKV(input) assert(t, err == nil && len(kv) == 5) assert(t, kv["k1"] == "v1") - assert(t, kv["k2"] == "[{kk1:vv1 kkk1:vvv1},{kk2:vv2}]") + assert(t, kv["k2"] == "[{kk1:vv1 kkk1:vvv1}, {kk2:vv2}]") assert(t, kv["k3"] == "v3") assert(t, kv["k4"] == "v4") assert(t, kv["k5"] == "{kkkk1:kvvvv1}") @@ -35,7 +35,7 @@ func TestParseKV(t *testing.T) { kv, err = ParseKV(input) assert(t, err == nil && len(kv) == 5) assert(t, kv["k1"] == "v1") - assert(t, kv["k2"] == "[{kk1:vv1 kkk1:vvv1},{kk2:v v2}]") + assert(t, kv["k2"] == "[{kk1:vv1 kkk1:vvv1}, {kk2:v v2}]") assert(t, kv["k3"] == "v3") assert(t, kv["k4"] == "v4") assert(t, kv["k5"] == "{kkkk1:kvvvv1}") diff --git a/version/version.go b/version/version.go index b1c4124f..5925891c 100644 --- a/version/version.go +++ b/version/version.go @@ -14,4 +14,4 @@ package version -const ThriftgoVersion = "0.3.7" +const ThriftgoVersion = "0.3.8"