From b51801e6bcd4c44e897f99d7ba27eace80a3f492 Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Fri, 4 Oct 2024 07:20:13 -0700 Subject: [PATCH 01/10] compiler/cpp/src/parse: Add virtual class to carry name and annotations --- compiler/cpp/Makefile.am | 1 + compiler/cpp/src/generate/t_as3_generator.cc | 2 +- compiler/cpp/src/generate/t_cpp_generator.cc | 9 +-- .../cpp/src/generate/t_csharp_generator.cc | 10 +-- .../cpp/src/generate/t_delphi_generator.cc | 2 +- compiler/cpp/src/generate/t_go_generator.cc | 7 +- compiler/cpp/src/generate/t_java_generator.cc | 4 +- .../cpp/src/generate/t_javame_generator.cc | 4 +- compiler/cpp/src/parse/t_annotated.h | 80 +++++++++++++++++++ compiler/cpp/src/parse/t_const.h | 7 +- compiler/cpp/src/parse/t_enum_value.h | 12 +-- compiler/cpp/src/parse/t_field.h | 15 ++-- compiler/cpp/src/parse/t_function.h | 16 ++-- compiler/cpp/src/parse/t_type.h | 19 +---- compiler/cpp/src/thrifty.yy | 52 +++++++----- 15 files changed, 149 insertions(+), 91 deletions(-) create mode 100644 compiler/cpp/src/parse/t_annotated.h diff --git a/compiler/cpp/Makefile.am b/compiler/cpp/Makefile.am index 559a83935df..96882e3bfe6 100644 --- a/compiler/cpp/Makefile.am +++ b/compiler/cpp/Makefile.am @@ -41,6 +41,7 @@ thrift_SOURCES = src/main.cc \ src/logging.h \ src/md5.h \ src/parse/t_doc.h \ + src/parse/t_annotated.h \ src/parse/t_type.h \ src/parse/t_base_type.h \ src/parse/t_enum.h \ diff --git a/compiler/cpp/src/generate/t_as3_generator.cc b/compiler/cpp/src/generate/t_as3_generator.cc index 2c4343028fe..3dfbb9b2ea6 100644 --- a/compiler/cpp/src/generate/t_as3_generator.cc +++ b/compiler/cpp/src/generate/t_as3_generator.cc @@ -679,7 +679,7 @@ void t_as3_generator::generate_as3_struct_definition(ofstream& out, bool is_result) { generate_as3_doc(out, tstruct); - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); bool bindable = !is_exception && !in_class && bindable_; indent(out) << (in_class ? "" : "public ") << (is_final ? "final " : "") << "class " diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc index 3edd7c8a383..8b17e61e913 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -1014,7 +1014,7 @@ void t_cpp_generator::generate_struct_declaration(ofstream& out, scope_down(out); } - if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { + if (!tstruct->has_legacy_annotation("final")) { out << endl << indent() << "virtual ~" << tstruct->get_name() << "() throw();" << endl; } @@ -1134,7 +1134,7 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, const vector& members = tstruct->get_members(); // Destructor - if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { + if (!tstruct->has_legacy_annotation("final")) { force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name() << "() throw() {" << endl; indent_up(); @@ -4017,9 +4017,8 @@ string t_cpp_generator::namespace_close(string ns) { string t_cpp_generator::type_name(t_type* ttype, bool in_typedef, bool arg) { if (ttype->is_base_type()) { string bname = base_type_name(((t_base_type*)ttype)->get_base()); - std::map::iterator it = ttype->annotations_.find("cpp.type"); - if (it != ttype->annotations_.end()) { - bname = it->second; + if (ttype->has_legacy_annotation("cpp.type")) { + bname = ttype->legacy_annotation_value("cpp.type"); } if (!arg) { diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc index 586ab753b6d..0f5eb736e11 100644 --- a/compiler/cpp/src/generate/t_csharp_generator.cc +++ b/compiler/cpp/src/generate/t_csharp_generator.cc @@ -695,7 +695,7 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream& out, << endl; // do not make exception classes directly WCF serializable, we provide a // separate "fault" for that } - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); indent(out) << "public " << (is_final ? "sealed " : "") << "partial class " << normalize_name(tstruct->get_name()) << " : "; @@ -881,7 +881,7 @@ void t_csharp_generator::generate_csharp_wcffault(ofstream& out, t_struct* tstru indent(out) << "[Serializable]" << endl; indent(out) << "#endif" << endl; indent(out) << "[DataContract]" << endl; - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); indent(out) << "public " << (is_final ? "sealed " : "") << "partial class " << tstruct->get_name() << "Fault" << endl; @@ -2512,11 +2512,11 @@ void t_csharp_generator::prepare_member_name_mapping(void* scope, // current C# generator policy: // - prop names are always rendered with an Uppercase first letter // - struct names are used as given - - + + // prevent name conflicts with struct (CS0542 error) used_member_names.insert(structname); - + // prevent name conflicts with known methods (THRIFT-2942) used_member_names.insert("Read"); used_member_names.insert("Write"); diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc index 2684811cf19..899c4d8cc60 100644 --- a/compiler/cpp/src/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/generate/t_delphi_generator.cc @@ -1623,7 +1623,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out, bool in_class, bool is_result, bool is_x_factory) { - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); string struct_intf_name; string struct_name; string isset_name; diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc index 48b3f4862f5..2e4ad3a3186 100644 --- a/compiler/cpp/src/generate/t_go_generator.cc +++ b/compiler/cpp/src/generate/t_go_generator.cc @@ -360,7 +360,7 @@ static bool type_need_reference(t_type* type) { // returns false if field could not use comparison to default value as !IsSet* bool t_go_generator::is_pointer_field(t_field* tfield, bool in_container_value) { (void)in_container_value; - if (tfield->annotations_.count("cpp.ref") != 0) { + if (tfield->has_legacy_annotation("cpp.ref")) { return true; } t_type* type = tfield->get_type()->get_true_type(); @@ -1201,9 +1201,8 @@ void t_go_generator::generate_go_struct_definition(ofstream& out, } else { gotag = "json:\"" + escape_string((*m_iter)->get_name()) + "\""; } - std::map::iterator it = (*m_iter)->annotations_.find("go.tag"); - if (it != (*m_iter)->annotations_.end()) { - gotag = it->second; + if ((*m_iter)->has_legacy_annotation("go.tag")) { + gotag = (*m_iter)->legacy_annotation_value("go.tag"); } indent(out) << publicize((*m_iter)->get_name()) << " " << goType << " `thrift:\"" << escape_string((*m_iter)->get_name()) << "," diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index 1b1963ab5fe..7031f366656 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -768,7 +768,7 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { generate_java_doc(f_struct, tstruct); - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); indent(f_struct) << "public " << (is_final ? "final " : "") << "class " << tstruct->get_name() << " extends org.apache.thrift.TUnion<" << tstruct->get_name() << ", " @@ -1325,7 +1325,7 @@ void t_java_generator::generate_java_struct_definition(ofstream& out, bool is_result) { generate_java_doc(out, tstruct); - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); if (!in_class) { generate_javax_generated_annotation(out); diff --git a/compiler/cpp/src/generate/t_javame_generator.cc b/compiler/cpp/src/generate/t_javame_generator.cc index b4a13fc043d..94e0f3baf5d 100644 --- a/compiler/cpp/src/generate/t_javame_generator.cc +++ b/compiler/cpp/src/generate/t_javame_generator.cc @@ -656,7 +656,7 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) { generate_java_doc(f_struct, tstruct); - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); indent(f_struct) << "public " << (is_final ? "final " : "") << "class " << tstruct->get_name() << " extends TUnion "; @@ -996,7 +996,7 @@ void t_javame_generator::generate_java_struct_definition(ofstream& out, bool is_result) { generate_java_doc(out, tstruct); - bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + bool is_final = tstruct->has_legacy_annotation("final"); indent(out) << "public " << (is_final ? "final " : "") << (in_class ? "static " : "") << "class " << tstruct->get_name() << " "; diff --git a/compiler/cpp/src/parse/t_annotated.h b/compiler/cpp/src/parse/t_annotated.h new file mode 100644 index 00000000000..ba6e38b7530 --- /dev/null +++ b/compiler/cpp/src/parse/t_annotated.h @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#ifndef T_ANNOTATED_H +#define T_ANNOTATED_H + +#include +#include +#include "t_doc.h" + +class t_type; +class t_const_value; + +class t_structured_annotation { +public: + t_structured_annotation() : type_(NULL), value_(NULL) {}; + t_type* type_; + t_const_value* value_; + +}; + +/** + * Placeholder struct for returning the key and value of an annotation + * during parsing. + */ +struct t_legacy_annotation { + std::string key; + std::string val; +}; + + +class t_annotated : public t_doc { +public: + void append_legacy_annotation(t_legacy_annotation* v) { legacy_annotations_[v->key] = v->val; } + void append_structured_annotation(t_structured_annotation* v) { structured_annotations_.push_back(v); } + + void merge(t_annotated* other) { + legacy_annotations_.insert(std::make_move_iterator(other->legacy_annotations_.begin()), std::make_move_iterator(other->legacy_annotations_.end())); + structured_annotations_.insert(structured_annotations_.end(), std::make_move_iterator(other->structured_annotations_.begin()), std::make_move_iterator(other->structured_annotations_.end())); + } + + const std::map& legacy_annotations() { return legacy_annotations_; } + + const std::string& get_name() const { return name_; } + + bool has_legacy_annotation(std::string key) { + return legacy_annotations_.find(key) != legacy_annotations_.end(); + } + + const std::string legacy_annotation_value(std::string key) { + return legacy_annotations_.find(key)->second; + } + + t_annotated() : name_("") {} +protected: + t_annotated(std::string name) : name_(name) {} + std::string name_; + +private: + std::map legacy_annotations_; + std::vector structured_annotations_; +}; + +#endif diff --git a/compiler/cpp/src/parse/t_const.h b/compiler/cpp/src/parse/t_const.h index 0f64bb14aff..e0739a89f2c 100644 --- a/compiler/cpp/src/parse/t_const.h +++ b/compiler/cpp/src/parse/t_const.h @@ -30,20 +30,17 @@ * whole thing out. * */ -class t_const : public t_doc { +class t_const : public t_annotated { public: t_const(t_type* type, std::string name, t_const_value* value) - : type_(type), name_(name), value_(value) {} + : t_annotated(name), type_(type), value_(value) {} t_type* get_type() const { return type_; } - std::string get_name() const { return name_; } - t_const_value* get_value() const { return value_; } private: t_type* type_; - std::string name_; t_const_value* value_; }; diff --git a/compiler/cpp/src/parse/t_enum_value.h b/compiler/cpp/src/parse/t_enum_value.h index 5979f06a7b7..3c2abfba19f 100644 --- a/compiler/cpp/src/parse/t_enum_value.h +++ b/compiler/cpp/src/parse/t_enum_value.h @@ -21,7 +21,7 @@ #define T_ENUM_VALUE_H #include -#include "t_doc.h" +#include "t_annotated.h" /** * A constant. These are used inside of enum definitions. Constants are just @@ -29,20 +29,14 @@ * with them. * */ -class t_enum_value : public t_doc { +class t_enum_value : public t_annotated { public: - t_enum_value(std::string name, int value) : name_(name), value_(value) {} + t_enum_value(std::string name, int value) : t_annotated(name), value_(value) {} ~t_enum_value() {} - const std::string& get_name() const { return name_; } - int get_value() const { return value_; } - - std::map annotations_; - private: - std::string name_; int value_; }; diff --git a/compiler/cpp/src/parse/t_field.h b/compiler/cpp/src/parse/t_field.h index c4e30e37d3e..7dce1389821 100644 --- a/compiler/cpp/src/parse/t_field.h +++ b/compiler/cpp/src/parse/t_field.h @@ -23,7 +23,7 @@ #include #include -#include "t_doc.h" +#include "t_annotated.h" // Forward declare for xsd_attrs class t_struct; @@ -33,11 +33,11 @@ class t_struct; * a symbolic name, and a numeric identifier. * */ -class t_field : public t_doc { +class t_field : public t_annotated { public: t_field(t_type* type, std::string name) - : type_(type), - name_(name), + : t_annotated(name), + type_(type), key_(0), value_(NULL), xsd_optional_(false), @@ -46,8 +46,8 @@ class t_field : public t_doc { reference_(false) {} t_field(t_type* type, std::string name, int32_t key) - : type_(type), - name_(name), + : t_annotated(name), + type_(type), key_(key), req_(T_OPT_IN_REQ_OUT), value_(NULL), @@ -106,15 +106,12 @@ class t_field : public t_doc { } }; - std::map annotations_; - bool get_reference() { return reference_; } void set_reference(bool reference) { reference_ = reference; } private: t_type* type_; - std::string name_; int32_t key_; e_req req_; t_const_value* value_; diff --git a/compiler/cpp/src/parse/t_function.h b/compiler/cpp/src/parse/t_function.h index 96886f3269c..756d9c21a7c 100644 --- a/compiler/cpp/src/parse/t_function.h +++ b/compiler/cpp/src/parse/t_function.h @@ -23,7 +23,7 @@ #include #include "t_type.h" #include "t_struct.h" -#include "t_doc.h" +#include "t_annotated.h" /** * Representation of a function. Key parts are return type, function name, @@ -31,10 +31,10 @@ * struct. * */ -class t_function : public t_doc { +class t_function : public t_annotated { public: t_function(t_type* returntype, std::string name, t_struct* arglist, bool oneway = false) - : returntype_(returntype), name_(name), arglist_(arglist), oneway_(oneway) { + : t_annotated(name), returntype_(returntype), arglist_(arglist), oneway_(oneway) { xceptions_ = new t_struct(NULL); if (oneway_ && (!returntype_->is_void())) { pwarning(1, "Oneway methods should return void.\n"); @@ -46,8 +46,8 @@ class t_function : public t_doc { t_struct* arglist, t_struct* xceptions, bool oneway = false) - : returntype_(returntype), - name_(name), + : t_annotated(name), + returntype_(returntype), arglist_(arglist), xceptions_(xceptions), oneway_(oneway) { @@ -63,19 +63,13 @@ class t_function : public t_doc { t_type* get_returntype() const { return returntype_; } - const std::string& get_name() const { return name_; } - t_struct* get_arglist() const { return arglist_; } t_struct* get_xceptions() const { return xceptions_; } bool is_oneway() const { return oneway_; } - - std::map annotations_; - private: t_type* returntype_; - std::string name_; t_struct* arglist_; t_struct* xceptions_; bool oneway_; diff --git a/compiler/cpp/src/parse/t_type.h b/compiler/cpp/src/parse/t_type.h index 20409f391f3..b56a837c497 100644 --- a/compiler/cpp/src/parse/t_type.h +++ b/compiler/cpp/src/parse/t_type.h @@ -25,6 +25,7 @@ #include #include #include "t_doc.h" +#include "t_annotated.h" class t_program; @@ -36,7 +37,7 @@ class t_program; * various types. * */ -class t_type : public t_doc { +class t_type : public t_annotated { public: virtual ~t_type() {} @@ -119,34 +120,22 @@ class t_type : public t_doc { return rv; } - std::map annotations_; - protected: t_type() : program_(NULL) { memset(fingerprint_, 0, sizeof(fingerprint_)); } t_type(t_program* program) : program_(program) { memset(fingerprint_, 0, sizeof(fingerprint_)); } - t_type(t_program* program, std::string name) : program_(program), name_(name) { + t_type(t_program* program, std::string name) : t_annotated(name), program_(program) { memset(fingerprint_, 0, sizeof(fingerprint_)); } - t_type(std::string name) : program_(NULL), name_(name) { + t_type(std::string name) : t_annotated(name), program_(NULL) { memset(fingerprint_, 0, sizeof(fingerprint_)); } t_program* program_; - std::string name_; uint8_t fingerprint_[fingerprint_len]; }; -/** - * Placeholder struct for returning the key and value of an annotation - * during parsing. - */ -struct t_annotation { - std::string key; - std::string val; -}; - #endif diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy index 61d4231c4a5..08a0dab774a 100644 --- a/compiler/cpp/src/thrifty.yy +++ b/compiler/cpp/src/thrifty.yy @@ -89,8 +89,11 @@ const int struct_is_union = 1; t_field* tfield; char* dtext; t_field::e_req ereq; - t_annotation* tannot; + t_annotated* tannotated; t_field_id tfieldid; + + t_legacy_annotation* tlannot; + t_structured_annotation* tsannot; } /** @@ -186,15 +189,21 @@ const int struct_is_union = 1; %type SetType %type ListType -%type Definition -%type TypeDefinition +%type Definition +%type TypeDefinition %type Typedef -%type TypeAnnotations -%type TypeAnnotationList -%type TypeAnnotation -%type TypeAnnotationValue +%type TypeAnnotations +%type TypeAnnotationList +%type TypeAnnotation +%type TypeAnnotationValue + +%type StructuredAnnotations +%type StructuredAnnotation +%type StructuredAnnotationScalarValue +%type StructuredAnnotationValue + %type Field %type FieldIdentifier @@ -561,7 +570,7 @@ Typedef: t_typedef *td = new t_typedef(g_program, $2, $3); $$ = td; if ($4 != NULL) { - $$->annotations_ = $4->annotations_; + $$->merge($4); delete $4; } } @@ -574,7 +583,7 @@ Enum: validate_simple_identifier( $2); $$->set_name($2); if ($6 != NULL) { - $$->annotations_ = $6->annotations_; + $$->merge($4); delete $6; } @@ -616,8 +625,8 @@ EnumDef: if ($1 != NULL) { $$->set_doc($1); } - if ($3 != NULL) { - $$->annotations_ = $3->annotations_; + if ($3 != NULL) { + $$->merge($3); delete $3; } } @@ -656,7 +665,7 @@ Senum: validate_simple_identifier( $2); $$ = new t_typedef(g_program, $4, $2); if ($6 != NULL) { - $$->annotations_ = $6->annotations_; + $$->merge($6); delete $6; } } @@ -795,13 +804,13 @@ Struct: StructHead tok_identifier XsdAll '{' FieldList '}' TypeAnnotations { pdebug("Struct -> tok_struct tok_identifier { FieldList }"); - validate_simple_identifier( $2); + validate_simple_identifier($2); $5->set_xsd_all($3); $5->set_union($1 == struct_is_union); $$ = $5; $$->set_name($2); if ($7 != NULL) { - $$->annotations_ = $7->annotations_; + $$->merge($7); delete $7; } } @@ -855,7 +864,7 @@ Xception: $4->set_xception(true); $$ = $4; if ($6 != NULL) { - $$->annotations_ = $6->annotations_; + $$->merge($6); delete $6; } } @@ -869,7 +878,7 @@ Service: $$->set_name($2); $$->set_extends($3); if ($9 != NULL) { - $$->annotations_ = $9->annotations_; + $$->merge($9); delete $9; } } @@ -1141,7 +1150,7 @@ BaseType: SimpleBaseType TypeAnnotations pdebug("BaseType -> SimpleBaseType TypeAnnotations"); if ($2 != NULL) { $$ = new t_base_type(*static_cast($1)); - $$->annotations_ = $2->annotations_; + $$->merge($2); delete $2; } else { $$ = $1; @@ -1200,7 +1209,7 @@ ContainerType: SimpleContainerType TypeAnnotations pdebug("ContainerType -> SimpleContainerType TypeAnnotations"); $$ = $1; if ($2 != NULL) { - $$->annotations_ = $2->annotations_; + $$->merge($2); delete $2; } } @@ -1279,20 +1288,19 @@ TypeAnnotationList: { pdebug("TypeAnnotationList -> TypeAnnotationList , TypeAnnotation"); $$ = $1; - $$->annotations_[$2->key] = $2->val; - delete $2; + $$->append_legacy_annotation($2); } | { /* Just use a dummy structure to hold the annotations. */ - $$ = new t_struct(g_program); + $$ = new t_annotated(); } TypeAnnotation: tok_identifier TypeAnnotationValue CommaOrSemicolonOptional { pdebug("TypeAnnotation -> TypeAnnotationValue"); - $$ = new t_annotation; + $$ = new t_legacy_annotation; $$->key = $1; $$->val = $2; } From bebd4fad1d88875d6abb4ece1a55235cc7088a0c Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Fri, 4 Oct 2024 07:21:49 -0700 Subject: [PATCH 02/10] compiler/cpp/src/thrifty: Add structured annotations on all types, fields and functions --- compiler/cpp/src/thriftl.ll | 1 + compiler/cpp/src/thrifty.yy | 141 +++++++++++++++++++++++++++++------- 2 files changed, 115 insertions(+), 27 deletions(-) diff --git a/compiler/cpp/src/thriftl.ll b/compiler/cpp/src/thriftl.ll index a8ffe57622c..8eeed03b5fb 100644 --- a/compiler/cpp/src/thriftl.ll +++ b/compiler/cpp/src/thriftl.ll @@ -188,6 +188,7 @@ literal_begin (['\"]) return tok_oneway; } "&" { return tok_reference; } +"@" { return tok_at; } "BEGIN" { thrift_reserved_keyword(yytext); } diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy index 08a0dab774a..d365a1fbd9b 100644 --- a/compiler/cpp/src/thrifty.yy +++ b/compiler/cpp/src/thrifty.yy @@ -177,6 +177,8 @@ const int struct_is_union = 1; %token tok_union %token tok_reference +%token tok_at + /** * Grammar nodes */ @@ -464,11 +466,15 @@ Include: } DefinitionList: - DefinitionList CaptureDocText Definition + DefinitionList CaptureDocText StructuredAnnotations Definition { pdebug("DefinitionList -> DefinitionList Definition"); - if ($2 != NULL && $3 != NULL) { - $3->set_doc($2); + if ($2 != NULL && $4 != NULL) { + $4->set_doc($2); + } + + if ($3 != NULL && $4 != NULL) { + $4->merge($3); } } | @@ -925,17 +931,21 @@ FunctionList: } Function: - CaptureDocText Oneway FunctionType tok_identifier '(' FieldList ')' Throws TypeAnnotations CommaOrSemicolonOptional + CaptureDocText StructuredAnnotations Oneway FunctionType tok_identifier '(' FieldList ')' Throws TypeAnnotations CommaOrSemicolonOptional { - validate_simple_identifier( $4); - $6->set_name(std::string($4) + "_args"); - $$ = new t_function($3, $4, $6, $8, $2); + validate_simple_identifier($5); + $7->set_name(std::string($5) + "_args"); + $$ = new t_function($4, $5, $7, $9, $3); if ($1 != NULL) { $$->set_doc($1); } - if ($9 != NULL) { - $$->annotations_ = $9->annotations_; - delete $9; + if ($10 != NULL) { + $$->merge($10); + delete $10; + } + if ($2 != NULL) { + $$->merge($2); + delete $2; } } @@ -982,36 +992,40 @@ FieldList: } Field: - CaptureDocText FieldIdentifier FieldRequiredness FieldType FieldReference tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes TypeAnnotations CommaOrSemicolonOptional + CaptureDocText StructuredAnnotations FieldIdentifier FieldRequiredness FieldType FieldReference tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes TypeAnnotations CommaOrSemicolonOptional { pdebug("tok_int_constant : Field -> FieldType tok_identifier"); - if ($2.auto_assigned) { + if ($3.auto_assigned) { pwarning(1, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $6); if (g_strict >= 192) { yyerror("Implicit field keys are deprecated and not allowed with -strict"); exit(1); } } - validate_simple_identifier($6); - $$ = new t_field($4, $6, $2.value); - $$->set_reference($5); - $$->set_req($3); - if ($7 != NULL) { - g_scope->resolve_const_value($7, $4); - validate_field_value($$, $7); - $$->set_value($7); + validate_simple_identifier($7); + $$ = new t_field($5, $7, $3.value); + $$->set_reference($6); + $$->set_req($4); + if ($8 != NULL) { + g_scope->resolve_const_value($8, $5); + validate_field_value($$, $8); + $$->set_value($8); } - $$->set_xsd_optional($8); - $$->set_xsd_nillable($9); + $$->set_xsd_optional($9); + $$->set_xsd_nillable($10); if ($1 != NULL) { $$->set_doc($1); } - if ($10 != NULL) { - $$->set_xsd_attrs($10); - } if ($11 != NULL) { - $$->annotations_ = $11->annotations_; - delete $11; + $$->set_xsd_attrs($11); + } + if ($12 != NULL) { + $$->merge($12); + delete $12; + } + if ($2 != NULL) { + $$->merge($2); + delete $2; } } @@ -1272,6 +1286,79 @@ CppType: $$ = NULL; } +StructuredAnnotation: + tok_at tok_identifier StructuredAnnotationValue + { + pdebug("StructuredAnnotation -> @ tok_identifier StructuredAnnotationValue"); + $$ = new t_structured_annotation(); + $$->type_ = g_scope->get_type($2); + + if (g_parse_mode == PROGRAM) { + if ($$->type_ == NULL) { + yyerror("Type \"%s\" does not exist.", $2); + exit(1); + } + + g_scope->resolve_const_value($3, $$->type_); + } + + $$->value_ = $3; + } + +StructuredAnnotationValue: + ConstMap + { + $$ = $1; + } +| ConstList + { + $$ = $1; + } +| '(' StructuredAnnotationScalarValue ')' + { + $$ = $2; + } + +StructuredAnnotationScalarValue: + tok_int_constant + { + pdebug("StructuredAnnotationScalarValue => tok_int_constant"); + $$ = new t_const_value(); + $$->set_integer($1); + if (!g_allow_64bit_consts && ($1 < INT32_MIN || $1 > INT32_MAX)) { + pwarning(1, "64-bit constant \"%" PRIi64"\" may not work in all languages.\n", $1); + } + } +| tok_dub_constant + { + pdebug("StructuredAnnotationScalarValue => tok_dub_constant"); + $$ = new t_const_value(); + $$->set_double($1); + } +| tok_literal + { + pdebug("StructuredAnnotationScalarValue => tok_literal"); + $$ = new t_const_value($1); + } +| tok_identifier + { + pdebug("StructuredAnnotationScalarValue => tok_identifier"); + $$ = new t_const_value(); + $$->set_identifier($1); + } + +StructuredAnnotations: + StructuredAnnotations StructuredAnnotation + { + pdebug("StructuredAnnotations -> StructuredAnnotations StructuredAnnotation"); + $$ = $1; + $$->append_structured_annotation($2); + } +| + { + $$ = new t_annotated(); + } + TypeAnnotations: '(' TypeAnnotationList ')' { From 032bede122173487f0954d632662580498812c2c Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Fri, 4 Oct 2024 11:51:44 -0700 Subject: [PATCH 03/10] compiler/cpp/src/generate/t_json_generator: Embed the annotations in the json payload --- compiler/cpp/src/generate/t_json_generator.cc | 67 +++++++++++-------- compiler/cpp/src/parse/t_annotated.h | 1 + 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/compiler/cpp/src/generate/t_json_generator.cc b/compiler/cpp/src/generate/t_json_generator.cc index 107f83fffa7..8f0a180174b 100644 --- a/compiler/cpp/src/generate/t_json_generator.cc +++ b/compiler/cpp/src/generate/t_json_generator.cc @@ -30,6 +30,7 @@ #include #include +#include "parse/t_annotated.h" #include "t_generator.h" #include "platform.h" @@ -114,6 +115,7 @@ class t_json_generator : public t_generator { void merge_includes(t_program*); void generate_constant(t_const* con); + void generate_annotated_fields(t_annotated* tannot); void write_type_spec_entry(const char* name, t_type* ttype); void write_type_spec_object(const char* name, t_type* ttype); @@ -445,12 +447,9 @@ void t_json_generator::generate_program() { void t_json_generator::generate_typedef(t_typedef* ttypedef) { start_object(); - write_key_and_string("name", get_qualified_name(ttypedef)); + generate_annotated_fields((t_annotated*)ttypedef); write_key_and_string("typeId", get_type_name(ttypedef->get_true_type())); write_type_spec_object("type", ttypedef->get_true_type()); - if (ttypedef->has_doc()) { - write_key_and_string("doc", ttypedef->get_doc()); - } end_object(); } @@ -544,11 +543,7 @@ void t_json_generator::generate_constant(t_const* con) { void t_json_generator::generate_enum(t_enum* tenum) { start_object(); - write_key_and_string("name", tenum->get_name()); - - if (tenum->has_doc()) { - write_key_and_string("doc", tenum->get_doc()); - } + generate_annotated_fields((t_annotated*)tenum); write_key_and("members"); start_array(); @@ -574,11 +569,7 @@ void t_json_generator::generate_enum(t_enum* tenum) { void t_json_generator::generate_struct(t_struct* tstruct) { start_object(); - write_key_and_string("name", tstruct->get_name()); - - if (tstruct->has_doc()) { - write_key_and_string("doc", tstruct->get_doc()); - } + generate_annotated_fields((t_annotated*)tstruct); write_key_and_bool("isException", tstruct->is_xception()); @@ -601,16 +592,12 @@ void t_json_generator::generate_struct(t_struct* tstruct) { void t_json_generator::generate_service(t_service* tservice) { start_object(); - write_key_and_string("name", get_qualified_name(tservice)); + generate_annotated_fields((t_annotated*)tservice); if (tservice->get_extends()) { write_key_and_string("extends", get_qualified_name(tservice->get_extends())); } - if (tservice->has_doc()) { - write_key_and_string("doc", tservice->get_doc()); - } - write_key_and("functions"); start_array(); vector functions = tservice->get_functions(); @@ -628,16 +615,13 @@ void t_json_generator::generate_service(t_service* tservice) { void t_json_generator::generate_function(t_function* tfunc) { start_object(); - write_key_and_string("name", tfunc->get_name()); + generate_annotated_fields((t_annotated*)tfunc); write_key_and_string("returnTypeId", get_type_name(tfunc->get_returntype())); write_type_spec_object("returnType", tfunc->get_returntype()); write_key_and_bool("oneway", tfunc->is_oneway()); - if (tfunc->has_doc()) { - write_key_and_string("doc", tfunc->get_doc()); - } write_key_and("arguments"); start_array(); @@ -664,17 +648,46 @@ void t_json_generator::generate_function(t_function* tfunc) { end_object(); } +void t_json_generator::generate_annotated_fields(t_annotated* tannot) { + write_key_and_string("name", tannot->get_name()); + + if (tannot->has_doc()) { + write_key_and_string("doc", tannot->get_doc()); + } + + write_key_and("legacy_annotations"); + start_object(); + const map& annotations = tannot->legacy_annotations(); + for (map::const_iterator ns_it = annotations.begin(); ns_it != annotations.end(); ++ns_it) { + write_comma_if_needed(); + write_key_and_string(ns_it->first, ns_it->second); + indicate_comma_needed(); + } + end_object(); + + write_key_and("structured_annotations"); + start_array(); + vector sannotations = tannot->structured_annotations(); + for (vector::const_iterator it = sannotations.begin(); it != sannotations.end(); it++) { + write_comma_if_needed(); + start_object(); + write_type_spec_object("type", (*it)->type_); + write_key_and("value"); + write_const_value((*it)->value_); + end_object(); + indicate_comma_needed(); + } + end_array(); +} + void t_json_generator::generate_field(t_field* field) { start_object(); + generate_annotated_fields((t_annotated*)field); write_key_and_integer("key", field->get_key()); - write_key_and_string("name", field->get_name()); write_key_and_string("typeId", get_type_name(field->get_type())); write_type_spec_object("type", field->get_type()); - if (field->has_doc()) { - write_key_and_string("doc", field->get_doc()); - } write_key_and("required"); switch (field->get_req()) { diff --git a/compiler/cpp/src/parse/t_annotated.h b/compiler/cpp/src/parse/t_annotated.h index ba6e38b7530..cd0a7c2fd07 100644 --- a/compiler/cpp/src/parse/t_annotated.h +++ b/compiler/cpp/src/parse/t_annotated.h @@ -56,6 +56,7 @@ class t_annotated : public t_doc { } const std::map& legacy_annotations() { return legacy_annotations_; } + const std::vector& structured_annotations() { return structured_annotations_; } const std::string& get_name() const { return name_; } From bb7f6ef89eb64af9f02b00800843febda384d271 Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Fri, 4 Oct 2024 15:38:16 -0700 Subject: [PATCH 04/10] compiler/cpp/src/generate/t_go_generator: Embed the annotations in the struct and service definitions --- compiler/cpp/src/generate/t_go_generator.cc | 124 ++++++++++++++++++-- lib/go/thrift/definition.go | 85 ++++++++++++-- 2 files changed, 189 insertions(+), 20 deletions(-) diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc index 2e4ad3a3186..d08d849f4e7 100644 --- a/compiler/cpp/src/generate/t_go_generator.cc +++ b/compiler/cpp/src/generate/t_go_generator.cc @@ -237,7 +237,7 @@ class t_go_generator : public t_generator { const char* subheader); void generate_go_docstring(std::ofstream& out, t_doc* tdoc); - + void generate_go_annotated_definition(ofstream& out, t_annotated* tannotated); /** * Helper rendering functions */ @@ -723,16 +723,9 @@ void t_go_generator::init_generator() { f_consts_ << go_autogen_comment() << go_package() << render_includes(); - f_const_values_ << endl << "func init() {" << endl; - + f_consts_ << "const Namespace = \"" << program_->get_namespace("*") << "\"" << endl << endl; - const vector& structs = program_->get_structs(); - - for (size_t i = 0; i < structs.size(); ++i) { - f_const_values_ << " thrift.RegisterStruct((*" - << publicize(structs[i]->get_name(), false) - << ")(nil))"<< endl; - } + f_const_values_ << endl << "func init() {" << endl; } /** @@ -1129,6 +1122,37 @@ void t_go_generator::generate_go_struct_initializer(ofstream& out, out << "}" << endl; } +void t_go_generator::generate_go_annotated_definition(ofstream& out, + t_annotated* tannotated) { + + out << indent() << "AnnotatedDefinition: thrift.AnnotatedDefinition{" << endl; + indent_up(); + out << indent() << "Name: \"" << tannotated->get_name() << "\"," << endl; + out << indent() << "LegacyAnnotations: map[string]string{" << endl; + + indent_up(); + const map& annotations = tannotated->legacy_annotations(); + for (map::const_iterator ns_it = annotations.begin(); ns_it != annotations.end(); ++ns_it) { + out << indent() << "\"" << escape_string(ns_it->first) << "\" : \"" << escape_string(ns_it->second)<< "\"," << endl; + } + indent_down(); + + out << indent() << "}," << endl; + out << indent() << "StructuredAnnotations: []thrift.RegistrableStruct{" << endl; + + indent_up(); + vector sannotations = tannotated->structured_annotations(); + for (vector::const_iterator it = sannotations.begin(); it != sannotations.end(); it++) { + out << indent() << render_const_value((*it)->type_, (*it)->value_, "") << "," << endl; + } + indent_down(); + + out << indent() << "}," << endl; + indent_down(); + + out << indent() << "}," << endl; +} + /** * Generates a struct definition for a thrift data type. * @@ -1145,6 +1169,11 @@ void t_go_generator::generate_go_struct_definition(ofstream& out, std::string tstruct_name(publicize(tstruct->get_name(), is_args || is_result)); generate_go_docstring(out, tstruct); + + f_const_values_ << " thrift.RegisterStruct((*" + << tstruct_name + << ")(nil))"<< endl; + out << indent() << "type " << tstruct_name << " struct {" << endl; /* Here we generate the structure specification for the fastbinary codec. @@ -1230,8 +1259,41 @@ void t_go_generator::generate_go_struct_definition(ofstream& out, generate_go_struct_initializer(out, tstruct, is_result || is_args); out << indent() << "}" << endl << endl; // Default values for optional fields + std::string def_name(privatize(tstruct_name + "StructDefinition")); + + out << indent() << "var " << def_name << " = thrift.StructDefinition{" << endl; + indent_up(); + + out << indent() << "Namespace: Namespace, " << endl; + + if (tstruct->is_xception()) { + out << indent() << "IsException: true," << endl; + } + + if (tstruct->is_union()) { + out << indent() << "IsUnion: true," << endl; + } + + generate_go_annotated_definition(out, tstruct); + + out << indent() << "Fields: []thrift.FieldDefinition{" << endl; + indent_up(); + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + out << indent() << "{" << endl; + indent_up(); + + generate_go_annotated_definition(out, *m_iter); + + indent_down(); + out << indent() << "}," << endl << endl; + } + indent_down(); + out << indent() << "}," << endl << endl; + + indent_down(); + out << indent() << "}" << endl << endl; out << indent() << "func (p *" << tstruct_name << ") StructDefinition() thrift.StructDefinition {" << endl; - out << indent() << " return thrift.StructDefinition{Namespace: \"" << tstruct->get_program()->get_namespace("*") << "\", Name: \"" << tstruct->get_name() << "\"}" << endl; + out << indent() << " return " << def_name << endl; out << indent() << "}" << endl << endl; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1818,6 +1880,46 @@ void t_go_generator::generate_service_interface(t_service* tservice) { indent_down(); f_service_ << indent() << "}" << endl << endl; + + + std::string def_name(privatize(serviceName + "ServiceDefinition")); + + f_service_ << indent() << "var " << def_name << " = thrift.ServiceDefinition{" << endl; + indent_up(); + + f_service_ << indent() << "Namespace: Namespace, " << endl; + + + generate_go_annotated_definition(f_service_, tservice); + + if (!functions.empty()) { + vector::iterator f_iter; + f_service_ << indent() << "Functions: []thrift.FunctionDefinition{" << endl; + + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + f_service_ << indent() << "{" << endl; + indent_up(); + if ((*f_iter)->is_oneway()) { + f_service_ << indent() << "IsOneway: true," << endl; + } else { + f_service_ << indent() << "Result: &" << privatize(publicize((*f_iter)->get_name() + "_result", true) + "StructDefinition") << "," << endl; + } + + f_service_ << indent() << "Args: " << privatize(publicize((*f_iter)->get_name() + "_args", true) + "StructDefinition") << "," << endl; + + generate_go_annotated_definition(f_service_, *f_iter); + + indent_down(); + f_service_ << indent() << "}," << endl << endl; + } + + indent_down(); + f_service_ << indent() << "}," << endl << endl; + } + indent_down(); + f_service_ << indent() << "}" << endl << endl; + + f_const_values_ << " thrift.RegisterService(" << def_name << ")" << endl; } /** diff --git a/lib/go/thrift/definition.go b/lib/go/thrift/definition.go index 3c9c891dc77..ab5892b2586 100644 --- a/lib/go/thrift/definition.go +++ b/lib/go/thrift/definition.go @@ -6,13 +6,32 @@ import ( "sync" ) -var defaultStructTypeRegistry = &structTypeRegistry{ - types: make(map[string]reflect.Type), - defs: make(map[string]StructDefinition), +var ( + defaultStructTypeRegistry = &structTypeRegistry{ + types: make(map[string]reflect.Type), + defs: make(map[string]StructDefinition), + } + + defaultServiceRegistry = &serviceRegistry{ + defs: make(map[string]ServiceDefinition), + } +) + +type serviceRegistry struct { + mu sync.RWMutex + + defs map[string]ServiceDefinition +} + +func (str *serviceRegistry) registerService(sd ServiceDefinition) { + str.mu.Lock() + defer str.mu.Unlock() + + str.defs[sd.CanonicalName()] = sd } type structTypeRegistry struct { - sync.RWMutex + mu sync.RWMutex defs map[string]StructDefinition types map[string]reflect.Type @@ -28,36 +47,84 @@ func (str *structTypeRegistry) registerStructType(rs RegistrableStruct) { sd := rs.StructDefinition() n := sd.CanonicalName() - str.Lock() - defer str.Unlock() + str.mu.Lock() + defer str.mu.Unlock() str.types[n] = t str.defs[n] = sd } func (str *structTypeRegistry) structType(n string) (reflect.Type, bool) { - str.Lock() - defer str.Unlock() + str.mu.Lock() + defer str.mu.Unlock() t, ok := str.types[n] return t, ok } +type AnnotatedDefintion struct { + Name string + + LegacyAnnotations map[string]string + SturcturedAnnotations []RegistrableStruct +} + +type FieldDefinition struct { + AnnotatedDefintion +} + type StructDefinition struct { + AnnotatedDefintion + Namespace string - Name string + + IsException bool + IsUnion bool + + Fields []FieldDefinition } func (sd StructDefinition) CanonicalName() string { return fmt.Sprintf("%s.%s", sd.Namespace, sd.Name) } +type FunctionDefinition struct { + AnnotatedDefintion + + IsOneway bool + + Args StructDefinition + Result *StructDefinition +} + +type ServiceDefinition struct { + AnnotatedDefintion + + Namespace string + + Functions []FunctionDefinition +} + +func (sd ServiceDefinition) CanonicalName() string { + return fmt.Sprintf("%s.%s", sd.Namespace, sd.Name) +} + type RegistrableStruct interface { TStruct StructDefinition() StructDefinition } +func RegisterService(def ServiceDefinition) { + defaultServiceRegistry.registerService(def) +} + +func GetServiceDefinition(n string) (ServiceDefinition, bool) { + def, ok := defaultServiceRegistry.defs[n] + + return def, ok +} + func RegisterStruct(rs RegistrableStruct) { defaultStructTypeRegistry.registerStructType(rs) } From e4f682fa0e4b81da906b9a42c6369c0fe98aecb6 Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Fri, 4 Oct 2024 16:23:05 -0700 Subject: [PATCH 05/10] compiler/cpp/src/generate/t_rb_generator: Embed the annotations in the struct and service definitions --- compiler/cpp/src/generate/t_rb_generator.cc | 41 ++++++++++++++++++++- lib/rb/lib/thrift/definition.rb | 18 +++++---- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/compiler/cpp/src/generate/t_rb_generator.cc b/compiler/cpp/src/generate/t_rb_generator.cc index e60bc529b2a..8269a5fa68b 100644 --- a/compiler/cpp/src/generate/t_rb_generator.cc +++ b/compiler/cpp/src/generate/t_rb_generator.cc @@ -184,6 +184,8 @@ class t_rb_generator : public t_oop_generator { void generate_rdoc(t_rb_ofstream& out, t_doc* tdoc); + void generate_rb_annotations(t_rb_ofstream& out, t_annotated* tannotated, std::string key_prefix); + /** * Helper rendering functions */ @@ -596,6 +598,7 @@ void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, out.indent() << "NAME = '" << tstruct->get_name() << "'.freeze" << endl; out.indent() << "NAMESPACE = '" << tstruct->get_program()->get_namespace("*") << "'.freeze" << endl << endl; + generate_rb_annotations(out, tstruct, ""); generate_field_constants(out, tstruct); generate_field_defns(out, tstruct); generate_rb_struct_required_validator(out, tstruct); @@ -607,6 +610,28 @@ void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, out.indent() << "end" << endl << endl; } + +void t_rb_generator::generate_rb_annotations(t_rb_ofstream& out, + t_annotated* tannotated, + std::string key_prefix) { + out.indent() << key_prefix << "LEGACY_ANNOTATIONS = {" << endl; + out.indent_up(); + const map& annotations = tannotated->legacy_annotations(); + for (map::const_iterator ns_it = annotations.begin(); ns_it != annotations.end(); ++ns_it) { + out << indent() << "%q\"" << escape_string(ns_it->first) << "\" => %q\"" << escape_string(ns_it->second)<< "\"," << endl; + } + out.indent_down(); + out.indent() << "}.freeze" << endl << endl; + + out.indent() << key_prefix << "STRUCTURED_ANNOTATIONS = [" << endl; + out.indent_up(); + vector sannotations = tannotated->structured_annotations(); + for (vector::const_iterator it = sannotations.begin(); it != sannotations.end(); it++) { + render_const_value(out.indent(), (*it)->type_, (*it)->value_) << "," << endl; + } + out.indent_down(); + out.indent() << "].freeze" << endl << endl; +} /** * Generates a ruby union */ @@ -623,8 +648,8 @@ void t_rb_generator::generate_rb_union(t_rb_ofstream& out, out.indent() << "NAME = '" << tstruct->get_name() << "'.freeze" << endl; out.indent() << "NAMESPACE = '" << tstruct->get_program()->get_namespace("*") << "'.freeze" << endl << endl; + generate_rb_annotations(out, tstruct, ""); generate_field_constructors(out, tstruct); - generate_field_constants(out, tstruct); generate_field_defns(out, tstruct); generate_rb_union_validator(out, tstruct); @@ -702,6 +727,10 @@ void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + generate_rb_annotations(out, *f_iter, "THRIFT_FIELD_" + upcase_string((*f_iter)->get_name()) + "_"); + } + out.indent() << "FIELDS = {" << endl; out.indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -775,6 +804,9 @@ void t_rb_generator::generate_field_data(t_rb_ofstream& out, out << ", enum_class: " << full_type_name(field_type); } + out << ", legacy_annotations: THRIFT_FIELD_" << upcase_string(field_name) << "_LEGACY_ANNOTATIONS"; + out << ", structured_annotations: THRIFT_FIELD_" << upcase_string(field_name) << "_STRUCTURED_ANNOTATIONS"; + // End of this field's defn out << "}"; } @@ -826,6 +858,7 @@ void t_rb_generator::generate_service(t_service* tservice) { f_service_.indent() << "NAMESPACE = '" << tservice->get_program()->get_namespace("*") << "'.freeze" << endl << endl; // Generate the three main parts of the service (well, two for now in PHP) + generate_rb_annotations(f_service_, tservice, ""); generate_service_helpers(tservice); generate_service_client(tservice); generate_service_server(tservice); @@ -1019,11 +1052,15 @@ void t_rb_generator::generate_service_server(t_service* tservice) { f_service_.indent_down(); f_service_.indent() << "end" << endl << endl; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + generate_rb_annotations(f_service_, *f_iter, "THRIFT_METHOD_" + upcase_string((*f_iter)->get_name()) + "_"); + } + f_service_.indent() << "METHODS = {" << endl; f_service_.indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_.indent() << "'" << (*f_iter)->get_name() << "' => { args_klass: " << capitalize((*f_iter)->get_name()) << "_args, oneway: " << ((*f_iter)->is_oneway() ? "true" : "false") << "}," << endl; + f_service_.indent() << "'" << (*f_iter)->get_name() << "' => { args_klass: " << capitalize((*f_iter)->get_name()) << "_args, oneway: " << ((*f_iter)->is_oneway() ? "true" : "false") << ", legacy_annotations: THRIFT_METHOD_" << upcase_string((*f_iter)->get_name()) << "_STRUCTURED_ANNOTATIONS, structured_annotations: THRIFT_METHOD_" << upcase_string((*f_iter)->get_name()) << "_STRUCTURED_ANNOTATIONS}," << endl; } f_service_.indent_down(); diff --git a/lib/rb/lib/thrift/definition.rb b/lib/rb/lib/thrift/definition.rb index 01dc58fac1f..75147d9d742 100644 --- a/lib/rb/lib/thrift/definition.rb +++ b/lib/rb/lib/thrift/definition.rb @@ -6,6 +6,14 @@ def initialize(klass) @klass = klass end + def structured_annotations + @klass::STRUCTURED_ANNOTATIONS + end + + def legacy_annotations + @klass::LEGACY_ANNOTATIONS + end + def namespace @klass::NAMESPACE end @@ -20,12 +28,6 @@ def struct_type end class ServiceDefinition < StructDefinition - attr_reader :klass - - def initialize(klass) - @klass = klass - end - def client_class @klass::Client end @@ -34,8 +36,8 @@ def processor_class @klass::Processor end - def namespace - @klass::NAMESPACE + def name + service end def service From 69fb5d5cb1831be1a67790c1fce02adeb4829620 Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Tue, 8 Oct 2024 15:33:42 -0700 Subject: [PATCH 06/10] types: Add two annotation types --- contrib/generate-types.sh | 3 +- lib/cpp/Makefile.am | 2 +- .../annotation/deprecation_constants.cpp | 17 ++ .../types/annotation/deprecation_constants.h | 24 ++ .../types/annotation/deprecation_types.cpp | 83 +++++++ .../types/annotation/deprecation_types.h | 58 +++++ .../types/annotation/naming_constants.cpp | 17 ++ .../types/annotation/naming_constants.h | 24 ++ .../thrift/types/annotation/naming_types.cpp | 130 +++++++++++ .../thrift/types/annotation/naming_types.h | 79 +++++++ lib/go/Makefile.am | 2 +- .../types/annotation/deprecation/constants.go | 21 ++ .../types/annotation/deprecation/ttypes.go | 85 ++++++++ .../types/annotation/naming/constants.go | 21 ++ .../thrift/types/annotation/naming/ttypes.go | 206 ++++++++++++++++++ lib/go/thrift/types/known/any/any.go | 9 +- lib/go/thrift/types/known/any/any_test.go | 5 +- lib/go/thrift/types/known/any/constants.go | 2 + lib/go/thrift/types/known/any/ttypes.go | 28 ++- .../thrift/types/known/duration/constants.go | 2 + lib/go/thrift/types/known/duration/ttypes.go | 28 ++- .../thrift/types/known/timestamp/constants.go | 2 + lib/go/thrift/types/known/timestamp/ttypes.go | 28 ++- lib/go/thrift/types/value/constants.go | 2 + lib/go/thrift/types/value/ttypes.go | 185 +++++++++++++++- lib/rb/Makefile.am | 2 +- .../types/annotation/deprecation_constants.rb | 17 ++ .../types/annotation/deprecation_types.rb | 44 ++++ .../types/annotation/naming_constants.rb | 17 ++ .../thrift/types/annotation/naming_types.rb | 59 +++++ lib/rb/lib/thrift/types/known/any_types.rb | 22 +- .../lib/thrift/types/known/duration_types.rb | 22 +- .../lib/thrift/types/known/timestamp_types.rb | 22 +- lib/rb/lib/thrift/types/value_types.rb | 148 +++++++++++-- types/annotation/deprecation.thrift | 3 + types/annotation/naming.thrift | 8 + 36 files changed, 1389 insertions(+), 38 deletions(-) create mode 100644 lib/cpp/src/thrift/types/annotation/deprecation_constants.cpp create mode 100644 lib/cpp/src/thrift/types/annotation/deprecation_constants.h create mode 100644 lib/cpp/src/thrift/types/annotation/deprecation_types.cpp create mode 100644 lib/cpp/src/thrift/types/annotation/deprecation_types.h create mode 100644 lib/cpp/src/thrift/types/annotation/naming_constants.cpp create mode 100644 lib/cpp/src/thrift/types/annotation/naming_constants.h create mode 100644 lib/cpp/src/thrift/types/annotation/naming_types.cpp create mode 100644 lib/cpp/src/thrift/types/annotation/naming_types.h create mode 100644 lib/go/thrift/types/annotation/deprecation/constants.go create mode 100644 lib/go/thrift/types/annotation/deprecation/ttypes.go create mode 100644 lib/go/thrift/types/annotation/naming/constants.go create mode 100644 lib/go/thrift/types/annotation/naming/ttypes.go create mode 100644 lib/rb/lib/thrift/types/annotation/deprecation_constants.rb create mode 100644 lib/rb/lib/thrift/types/annotation/deprecation_types.rb create mode 100644 lib/rb/lib/thrift/types/annotation/naming_constants.rb create mode 100644 lib/rb/lib/thrift/types/annotation/naming_types.rb create mode 100644 types/annotation/deprecation.thrift create mode 100644 types/annotation/naming.thrift diff --git a/contrib/generate-types.sh b/contrib/generate-types.sh index f84ae4f9100..8b1a6a56642 100644 --- a/contrib/generate-types.sh +++ b/contrib/generate-types.sh @@ -2,7 +2,8 @@ set -x -tag=$(git describe --tag) +git_tag=$(git describe --tag) +tag=${TAG:-$git_tag} ./bootstrap.sh diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am index 59ea4e85004..76d87fff54c 100755 --- a/lib/cpp/Makefile.am +++ b/lib/cpp/Makefile.am @@ -272,7 +272,7 @@ EXTRA_DIST = \ style-local: $(CPPSTYLE_CMD) -TYPE_FILES = ../../types/*.thrift ../../types/known/*.thrift +TYPE_FILES = ../../types/*.thrift ../../types/*/*.thrift $(TYPE_FILES): mkdir -p src/thrift/$(patsubst ../../%,%,$(dir $@)) diff --git a/lib/cpp/src/thrift/types/annotation/deprecation_constants.cpp b/lib/cpp/src/thrift/types/annotation/deprecation_constants.cpp new file mode 100644 index 00000000000..1c69c8a7beb --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/deprecation_constants.cpp @@ -0,0 +1,17 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include "deprecation_constants.h" + +namespace types { namespace annotation { namespace deprecation { + +const deprecationConstants g_deprecation_constants; + +deprecationConstants::deprecationConstants() { +} + +}}} // namespace + diff --git a/lib/cpp/src/thrift/types/annotation/deprecation_constants.h b/lib/cpp/src/thrift/types/annotation/deprecation_constants.h new file mode 100644 index 00000000000..00418a6e5b9 --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/deprecation_constants.h @@ -0,0 +1,24 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef deprecation_CONSTANTS_H +#define deprecation_CONSTANTS_H + +#include "deprecation_types.h" + +namespace types { namespace annotation { namespace deprecation { + +class deprecationConstants { + public: + deprecationConstants(); + +}; + +extern const deprecationConstants g_deprecation_constants; + +}}} // namespace + +#endif diff --git a/lib/cpp/src/thrift/types/annotation/deprecation_types.cpp b/lib/cpp/src/thrift/types/annotation/deprecation_types.cpp new file mode 100644 index 00000000000..e3419a63195 --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/deprecation_types.cpp @@ -0,0 +1,83 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include "deprecation_types.h" + +#include +#include + +#include + +namespace types { namespace annotation { namespace deprecation { + + +Deprecated::~Deprecated() throw() { +} + + +const char* Deprecated::ascii_fingerprint = "99914B932BD37A50B983C5E7C90AE93B"; +const uint8_t Deprecated::binary_fingerprint[16] = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + +uint32_t Deprecated::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + xfer += iprot->skip(ftype); + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t Deprecated::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + oprot->incrementRecursionDepth(); + xfer += oprot->writeStructBegin("Deprecated"); + + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + oprot->decrementRecursionDepth(); + return xfer; +} + +void swap(Deprecated &a, Deprecated &b) { + using ::std::swap; + (void) a; + (void) b; +} + +Deprecated::Deprecated(const Deprecated& other0) { + (void) other0; +} +Deprecated& Deprecated::operator=(const Deprecated& other1) { + (void) other1; + return *this; +} +std::ostream& operator<<(std::ostream& out, const Deprecated& obj) { + using apache::thrift::to_string; + (void) obj; + out << "Deprecated("; + out << ")"; + return out; +} + +}}} // namespace diff --git a/lib/cpp/src/thrift/types/annotation/deprecation_types.h b/lib/cpp/src/thrift/types/annotation/deprecation_types.h new file mode 100644 index 00000000000..92b23b9b518 --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/deprecation_types.h @@ -0,0 +1,58 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef deprecation_TYPES_H +#define deprecation_TYPES_H + +#include + +#include +#include +#include +#include + +#include + + +namespace types { namespace annotation { namespace deprecation { + +class Deprecated; + + +class Deprecated { + public: + + static const char* ascii_fingerprint; // = "99914B932BD37A50B983C5E7C90AE93B"; + static const uint8_t binary_fingerprint[16]; // = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B}; + + Deprecated(const Deprecated&); + Deprecated& operator=(const Deprecated&); + Deprecated() { + } + + virtual ~Deprecated() throw(); + + bool operator == (const Deprecated & /* rhs */) const + { + return true; + } + bool operator != (const Deprecated &rhs) const { + return !(*this == rhs); + } + + bool operator < (const Deprecated & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + + friend std::ostream& operator<<(std::ostream& out, const Deprecated& obj); +}; + +void swap(Deprecated &a, Deprecated &b); + +}}} // namespace + +#endif diff --git a/lib/cpp/src/thrift/types/annotation/naming_constants.cpp b/lib/cpp/src/thrift/types/annotation/naming_constants.cpp new file mode 100644 index 00000000000..9367dbd0290 --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/naming_constants.cpp @@ -0,0 +1,17 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include "naming_constants.h" + +namespace types { namespace annotation { namespace naming { + +const namingConstants g_naming_constants; + +namingConstants::namingConstants() { +} + +}}} // namespace + diff --git a/lib/cpp/src/thrift/types/annotation/naming_constants.h b/lib/cpp/src/thrift/types/annotation/naming_constants.h new file mode 100644 index 00000000000..f28feb89ced --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/naming_constants.h @@ -0,0 +1,24 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef naming_CONSTANTS_H +#define naming_CONSTANTS_H + +#include "naming_types.h" + +namespace types { namespace annotation { namespace naming { + +class namingConstants { + public: + namingConstants(); + +}; + +extern const namingConstants g_naming_constants; + +}}} // namespace + +#endif diff --git a/lib/cpp/src/thrift/types/annotation/naming_types.cpp b/lib/cpp/src/thrift/types/annotation/naming_types.cpp new file mode 100644 index 00000000000..0d09e2d5fc7 --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/naming_types.cpp @@ -0,0 +1,130 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#include "naming_types.h" + +#include +#include + +#include + +namespace types { namespace annotation { namespace naming { + + +PreviouslyKnownAs::~PreviouslyKnownAs() throw() { +} + + +void PreviouslyKnownAs::__set_namespace_(const std::string& val) { + this->namespace_ = val; +__isset.namespace_ = true; +} + +void PreviouslyKnownAs::__set_name(const std::string& val) { + this->name = val; +__isset.name = true; +} + +const char* PreviouslyKnownAs::ascii_fingerprint = "D0297FC5011701BD87898CC36146A565"; +const uint8_t PreviouslyKnownAs::binary_fingerprint[16] = {0xD0,0x29,0x7F,0xC5,0x01,0x17,0x01,0xBD,0x87,0x89,0x8C,0xC3,0x61,0x46,0xA5,0x65}; + +uint32_t PreviouslyKnownAs::read(::apache::thrift::protocol::TProtocol* iprot) { + + uint32_t xfer = 0; + std::string fname; + ::apache::thrift::protocol::TType ftype; + int16_t fid; + + xfer += iprot->readStructBegin(fname); + + using ::apache::thrift::protocol::TProtocolException; + + + while (true) + { + xfer += iprot->readFieldBegin(fname, ftype, fid); + if (ftype == ::apache::thrift::protocol::T_STOP) { + break; + } + switch (fid) + { + case 1: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->namespace_); + this->__isset.namespace_ = true; + } else { + xfer += iprot->skip(ftype); + } + break; + case 2: + if (ftype == ::apache::thrift::protocol::T_STRING) { + xfer += iprot->readString(this->name); + this->__isset.name = true; + } else { + xfer += iprot->skip(ftype); + } + break; + default: + xfer += iprot->skip(ftype); + break; + } + xfer += iprot->readFieldEnd(); + } + + xfer += iprot->readStructEnd(); + + return xfer; +} + +uint32_t PreviouslyKnownAs::write(::apache::thrift::protocol::TProtocol* oprot) const { + uint32_t xfer = 0; + oprot->incrementRecursionDepth(); + xfer += oprot->writeStructBegin("PreviouslyKnownAs"); + + if (this->__isset.namespace_) { + xfer += oprot->writeFieldBegin("namespace_", ::apache::thrift::protocol::T_STRING, 1); + xfer += oprot->writeString(this->namespace_); + xfer += oprot->writeFieldEnd(); + } + if (this->__isset.name) { + xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 2); + xfer += oprot->writeString(this->name); + xfer += oprot->writeFieldEnd(); + } + xfer += oprot->writeFieldStop(); + xfer += oprot->writeStructEnd(); + oprot->decrementRecursionDepth(); + return xfer; +} + +void swap(PreviouslyKnownAs &a, PreviouslyKnownAs &b) { + using ::std::swap; + swap(a.namespace_, b.namespace_); + swap(a.name, b.name); + swap(a.__isset, b.__isset); +} + +PreviouslyKnownAs::PreviouslyKnownAs(const PreviouslyKnownAs& other0) { + namespace_ = other0.namespace_; + name = other0.name; + __isset = other0.__isset; +} +PreviouslyKnownAs& PreviouslyKnownAs::operator=(const PreviouslyKnownAs& other1) { + namespace_ = other1.namespace_; + name = other1.name; + __isset = other1.__isset; + return *this; +} +std::ostream& operator<<(std::ostream& out, const PreviouslyKnownAs& obj) { + using apache::thrift::to_string; + out << "PreviouslyKnownAs("; + out << "namespace_="; (obj.__isset.namespace_ ? (out << to_string(obj.namespace_)) : (out << "")); + out << ", " << "name="; (obj.__isset.name ? (out << to_string(obj.name)) : (out << "")); + out << ")"; + return out; +} + +}}} // namespace diff --git a/lib/cpp/src/thrift/types/annotation/naming_types.h b/lib/cpp/src/thrift/types/annotation/naming_types.h new file mode 100644 index 00000000000..137abeb7942 --- /dev/null +++ b/lib/cpp/src/thrift/types/annotation/naming_types.h @@ -0,0 +1,79 @@ +/** + * Autogenerated by Thrift Compiler (2.5.4-upfluence) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +#ifndef naming_TYPES_H +#define naming_TYPES_H + +#include + +#include +#include +#include +#include + +#include + + +namespace types { namespace annotation { namespace naming { + +class PreviouslyKnownAs; + +typedef struct _PreviouslyKnownAs__isset { + _PreviouslyKnownAs__isset() : namespace_(false), name(false) {} + bool namespace_ :1; + bool name :1; +} _PreviouslyKnownAs__isset; + +class PreviouslyKnownAs { + public: + + static const char* ascii_fingerprint; // = "D0297FC5011701BD87898CC36146A565"; + static const uint8_t binary_fingerprint[16]; // = {0xD0,0x29,0x7F,0xC5,0x01,0x17,0x01,0xBD,0x87,0x89,0x8C,0xC3,0x61,0x46,0xA5,0x65}; + + PreviouslyKnownAs(const PreviouslyKnownAs&); + PreviouslyKnownAs& operator=(const PreviouslyKnownAs&); + PreviouslyKnownAs() : namespace_(), name() { + } + + virtual ~PreviouslyKnownAs() throw(); + std::string namespace_; + std::string name; + + _PreviouslyKnownAs__isset __isset; + + void __set_namespace_(const std::string& val); + + void __set_name(const std::string& val); + + bool operator == (const PreviouslyKnownAs & rhs) const + { + if (__isset.namespace_ != rhs.__isset.namespace_) + return false; + else if (__isset.namespace_ && !(namespace_ == rhs.namespace_)) + return false; + if (__isset.name != rhs.__isset.name) + return false; + else if (__isset.name && !(name == rhs.name)) + return false; + return true; + } + bool operator != (const PreviouslyKnownAs &rhs) const { + return !(*this == rhs); + } + + bool operator < (const PreviouslyKnownAs & ) const; + + uint32_t read(::apache::thrift::protocol::TProtocol* iprot); + uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; + + friend std::ostream& operator<<(std::ostream& out, const PreviouslyKnownAs& obj); +}; + +void swap(PreviouslyKnownAs &a, PreviouslyKnownAs &b); + +}}} // namespace + +#endif diff --git a/lib/go/Makefile.am b/lib/go/Makefile.am index a7073178d34..eebfa6d17f9 100644 --- a/lib/go/Makefile.am +++ b/lib/go/Makefile.am @@ -32,7 +32,7 @@ install: @echo '##############################################################' @echo '##############################################################' -TYPE_FILES = ../../types/*.thrift ../../types/known/*.thrift +TYPE_FILES = ../../types/*.thrift ../../types/*/*.thrift $(TYPE_FILES): $(THRIFT) -gen go --out thrift $@ diff --git a/lib/go/thrift/types/annotation/deprecation/constants.go b/lib/go/thrift/types/annotation/deprecation/constants.go new file mode 100644 index 00000000000..1786e6d511d --- /dev/null +++ b/lib/go/thrift/types/annotation/deprecation/constants.go @@ -0,0 +1,21 @@ +// Autogenerated by Thrift Compiler (2.5.4-upfluence) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package deprecation + +import ( + "bytes" + "fmt" + "github.com/upfluence/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +const Namespace = "types.annotation.deprecation" + +func init() { + thrift.RegisterStruct((*Deprecated)(nil)) +} diff --git a/lib/go/thrift/types/annotation/deprecation/ttypes.go b/lib/go/thrift/types/annotation/deprecation/ttypes.go new file mode 100644 index 00000000000..1b6cceaad32 --- /dev/null +++ b/lib/go/thrift/types/annotation/deprecation/ttypes.go @@ -0,0 +1,85 @@ +// Autogenerated by Thrift Compiler (2.5.4-upfluence) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package deprecation + +import ( + "bytes" + "fmt" + "github.com/upfluence/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal +var GoUnusedProtection__ int + +type Deprecated struct { +} + +func NewDeprecated() *Deprecated { + return &Deprecated{} +} + +var deprecatedStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "Deprecated", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{}, +} + +func (p *Deprecated) StructDefinition() thrift.StructDefinition { + return deprecatedStructDefinition +} + +func (p *Deprecated) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *Deprecated) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Deprecated"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Deprecated) String() string { + if p == nil { + return "" + } + return fmt.Sprintf( + "Deprecated({})", + ) +} diff --git a/lib/go/thrift/types/annotation/naming/constants.go b/lib/go/thrift/types/annotation/naming/constants.go new file mode 100644 index 00000000000..5acd4bbfcdc --- /dev/null +++ b/lib/go/thrift/types/annotation/naming/constants.go @@ -0,0 +1,21 @@ +// Autogenerated by Thrift Compiler (2.5.4-upfluence) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package naming + +import ( + "bytes" + "fmt" + "github.com/upfluence/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +const Namespace = "types.annotation.naming" + +func init() { + thrift.RegisterStruct((*PreviouslyKnownAs)(nil)) +} diff --git a/lib/go/thrift/types/annotation/naming/ttypes.go b/lib/go/thrift/types/annotation/naming/ttypes.go new file mode 100644 index 00000000000..b11af57faf3 --- /dev/null +++ b/lib/go/thrift/types/annotation/naming/ttypes.go @@ -0,0 +1,206 @@ +// Autogenerated by Thrift Compiler (2.5.4-upfluence) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package naming + +import ( + "bytes" + "fmt" + "github.com/upfluence/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal +var GoUnusedProtection__ int + +// Attributes: +// - Namespace_ +// - Name +type PreviouslyKnownAs struct { + Namespace_ *string `thrift:"namespace_,1" json:"namespace_,omitempty"` + Name *string `thrift:"name,2" json:"name,omitempty"` +} + +func NewPreviouslyKnownAs() *PreviouslyKnownAs { + return &PreviouslyKnownAs{} +} + +var previouslyKnownAsStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "PreviouslyKnownAs", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "namespace_", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "name", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + +func (p *PreviouslyKnownAs) StructDefinition() thrift.StructDefinition { + return previouslyKnownAsStructDefinition +} + +var PreviouslyKnownAs_Namespace__DEFAULT string + +func (p *PreviouslyKnownAs) GetNamespace_() string { + if !p.IsSetNamespace_() { + return PreviouslyKnownAs_Namespace__DEFAULT + } + return *p.Namespace_ +} + +func (p *PreviouslyKnownAs) SetNamespace_(v string) { + p.Namespace_ = &v +} + +var PreviouslyKnownAs_Name_DEFAULT string + +func (p *PreviouslyKnownAs) GetName() string { + if !p.IsSetName() { + return PreviouslyKnownAs_Name_DEFAULT + } + return *p.Name +} + +func (p *PreviouslyKnownAs) SetName(v string) { + p.Name = &v +} +func (p *PreviouslyKnownAs) IsSetNamespace_() bool { + return p.Namespace_ != nil +} + +func (p *PreviouslyKnownAs) IsSetName() bool { + return p.Name != nil +} + +func (p *PreviouslyKnownAs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.ReadField1(iprot); err != nil { + return err + } + case 2: + if err := p.ReadField2(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *PreviouslyKnownAs) ReadField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Namespace_ = &v + } + return nil +} + +func (p *PreviouslyKnownAs) ReadField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.Name = &v + } + return nil +} + +func (p *PreviouslyKnownAs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("PreviouslyKnownAs"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *PreviouslyKnownAs) writeField1(oprot thrift.TProtocol) (err error) { + if p.IsSetNamespace_() { + if err := oprot.WriteFieldBegin("namespace_", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:namespace_: ", p), err) + } + if err := oprot.WriteString(string(*p.Namespace_)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.namespace_ (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:namespace_: ", p), err) + } + } + return err +} + +func (p *PreviouslyKnownAs) writeField2(oprot thrift.TProtocol) (err error) { + if p.IsSetName() { + if err := oprot.WriteFieldBegin("name", thrift.STRING, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:name: ", p), err) + } + if err := oprot.WriteString(string(*p.Name)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.name (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:name: ", p), err) + } + } + return err +} + +func (p *PreviouslyKnownAs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf( + "PreviouslyKnownAs({namespace_: %v, name: %v})", + p.GetNamespace_(), + p.GetName(), + ) +} diff --git a/lib/go/thrift/types/known/any/any.go b/lib/go/thrift/types/known/any/any.go index c6475ed1b34..7383e511c16 100644 --- a/lib/go/thrift/types/known/any/any.go +++ b/lib/go/thrift/types/known/any/any.go @@ -9,11 +9,16 @@ import ( "github.com/upfluence/thrift/lib/go/thrift" ) -func New(s thrift.RegistrableStruct) (*Any, error) { +type RegistrableStruct interface { + thrift.RegistrableStruct + thrift.TStruct +} + +func New(s RegistrableStruct) (*Any, error) { return NewWithEncoding(s, "", DefaultEncoding) } -func NewWithEncoding(s thrift.RegistrableStruct, n string, e Encoding) (*Any, error) { +func NewWithEncoding(s RegistrableStruct, n string, e Encoding) (*Any, error) { var buf bytes.Buffer if err := e.Encoder(&buf).Encode(s); err != nil { diff --git a/lib/go/thrift/types/known/any/any_test.go b/lib/go/thrift/types/known/any/any_test.go index 96439c3e672..1a6f224d315 100644 --- a/lib/go/thrift/types/known/any/any_test.go +++ b/lib/go/thrift/types/known/any/any_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/upfluence/thrift/lib/go/thrift" "github.com/upfluence/thrift/lib/go/thrift/types/known/duration" "github.com/upfluence/thrift/lib/go/thrift/types/known/timestamp" ) @@ -14,7 +13,7 @@ func TestNew(t *testing.T) { for _, tt := range []struct { name string - in thrift.RegistrableStruct + in RegistrableStruct wantType string wantValue string @@ -54,7 +53,7 @@ func TestNewJSON(t *testing.T) { for _, tt := range []struct { name string - in thrift.RegistrableStruct + in RegistrableStruct wantType string wantValue string diff --git a/lib/go/thrift/types/known/any/constants.go b/lib/go/thrift/types/known/any/constants.go index 487d410cdec..1850752b7d4 100644 --- a/lib/go/thrift/types/known/any/constants.go +++ b/lib/go/thrift/types/known/any/constants.go @@ -14,6 +14,8 @@ var _ = thrift.ZERO var _ = fmt.Printf var _ = bytes.Equal +const Namespace = "types.known.any" + func init() { thrift.RegisterStruct((*Any)(nil)) } diff --git a/lib/go/thrift/types/known/any/ttypes.go b/lib/go/thrift/types/known/any/ttypes.go index 4a911fedb66..c5b0c351655 100644 --- a/lib/go/thrift/types/known/any/ttypes.go +++ b/lib/go/thrift/types/known/any/ttypes.go @@ -27,8 +27,34 @@ func NewAny() *Any { return &Any{} } +var anyStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "Any", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "type", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *Any) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.known.any", Name: "Any"} + return anyStructDefinition } func (p *Any) GetType() string { diff --git a/lib/go/thrift/types/known/duration/constants.go b/lib/go/thrift/types/known/duration/constants.go index 133e249d15e..c48f912b290 100644 --- a/lib/go/thrift/types/known/duration/constants.go +++ b/lib/go/thrift/types/known/duration/constants.go @@ -14,6 +14,8 @@ var _ = thrift.ZERO var _ = fmt.Printf var _ = bytes.Equal +const Namespace = "types.known.duration" + func init() { thrift.RegisterStruct((*Duration)(nil)) } diff --git a/lib/go/thrift/types/known/duration/ttypes.go b/lib/go/thrift/types/known/duration/ttypes.go index 28140a21099..73393d68716 100644 --- a/lib/go/thrift/types/known/duration/ttypes.go +++ b/lib/go/thrift/types/known/duration/ttypes.go @@ -27,8 +27,34 @@ func NewDuration() *Duration { return &Duration{} } +var durationStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "Duration", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "seconds", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "nanos", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *Duration) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.known.duration", Name: "Duration"} + return durationStructDefinition } func (p *Duration) GetSeconds() int64 { diff --git a/lib/go/thrift/types/known/timestamp/constants.go b/lib/go/thrift/types/known/timestamp/constants.go index ad94625c953..9b272761d43 100644 --- a/lib/go/thrift/types/known/timestamp/constants.go +++ b/lib/go/thrift/types/known/timestamp/constants.go @@ -14,6 +14,8 @@ var _ = thrift.ZERO var _ = fmt.Printf var _ = bytes.Equal +const Namespace = "types.known.timestamp" + func init() { thrift.RegisterStruct((*Timestamp)(nil)) } diff --git a/lib/go/thrift/types/known/timestamp/ttypes.go b/lib/go/thrift/types/known/timestamp/ttypes.go index 6973ab185a5..e4d8c1c88e0 100644 --- a/lib/go/thrift/types/known/timestamp/ttypes.go +++ b/lib/go/thrift/types/known/timestamp/ttypes.go @@ -27,8 +27,34 @@ func NewTimestamp() *Timestamp { return &Timestamp{} } +var timestampStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "Timestamp", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "seconds", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "nanos", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *Timestamp) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.known.timestamp", Name: "Timestamp"} + return timestampStructDefinition } func (p *Timestamp) GetSeconds() int64 { diff --git a/lib/go/thrift/types/value/constants.go b/lib/go/thrift/types/value/constants.go index 823b156902d..a5ca6cdba58 100644 --- a/lib/go/thrift/types/value/constants.go +++ b/lib/go/thrift/types/value/constants.go @@ -14,6 +14,8 @@ var _ = thrift.ZERO var _ = fmt.Printf var _ = bytes.Equal +const Namespace = "types.value" + func init() { thrift.RegisterStruct((*NullValue)(nil)) thrift.RegisterStruct((*ListValue)(nil)) diff --git a/lib/go/thrift/types/value/ttypes.go b/lib/go/thrift/types/value/ttypes.go index 1d3f64b3a30..f639ab3ee7b 100644 --- a/lib/go/thrift/types/value/ttypes.go +++ b/lib/go/thrift/types/value/ttypes.go @@ -22,8 +22,18 @@ func NewNullValue() *NullValue { return &NullValue{} } +var nullValueStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "NullValue", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{}, +} + func (p *NullValue) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.value", Name: "NullValue"} + return nullValueStructDefinition } func (p *NullValue) Read(iprot thrift.TProtocol) error { @@ -84,8 +94,26 @@ func NewListValue() *ListValue { return &ListValue{} } +var listValueStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "ListValue", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "values", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *ListValue) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.value", Name: "ListValue"} + return listValueStructDefinition } func (p *ListValue) GetValues() []*Value { @@ -213,8 +241,34 @@ func NewMapEntry() *MapEntry { return &MapEntry{} } +var mapEntryStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "MapEntry", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "key", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *MapEntry) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.value", Name: "MapEntry"} + return mapEntryStructDefinition } var MapEntry_Key_DEFAULT *Value @@ -380,8 +434,26 @@ func NewMapValue() *MapValue { return &MapValue{} } +var mapValueStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "MapValue", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "entries", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *MapValue) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.value", Name: "MapValue"} + return mapValueStructDefinition } func (p *MapValue) GetEntries() []*MapEntry { @@ -507,8 +579,26 @@ func NewStructValue() *StructValue { return &StructValue{} } +var structValueStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "StructValue", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "fields", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *StructValue) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.value", Name: "StructValue"} + return structValueStructDefinition } func (p *StructValue) GetFields() map[string]*Value { @@ -659,8 +749,91 @@ func NewValue() *Value { return &Value{} } +var valueStructDefinition = thrift.StructDefinition{ + Namespace: Namespace, + IsUnion: true, + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "Value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + Fields: []thrift.FieldDefinition{ + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "null_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "string_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "binary_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "integer_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "double_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "bool_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "list_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "map_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + + { + AnnotatedDefinition: thrift.AnnotatedDefinition{ + Name: "struct_value", + LegacyAnnotations: map[string]string{}, + StructuredAnnotations: []thrift.RegistrableStruct{}, + }, + }, + }, +} + func (p *Value) StructDefinition() thrift.StructDefinition { - return thrift.StructDefinition{Namespace: "types.value", Name: "Value"} + return valueStructDefinition } var Value_NullValue_DEFAULT *NullValue diff --git a/lib/rb/Makefile.am b/lib/rb/Makefile.am index 68d28633651..59e6ae7b667 100755 --- a/lib/rb/Makefile.am +++ b/lib/rb/Makefile.am @@ -38,7 +38,7 @@ check-local: all endif -TYPE_FILES = ../../types/*.thrift ../../types/known/*.thrift +TYPE_FILES = ../../types/*.thrift ../../types/*/*.thrift $(TYPE_FILES): mkdir -p lib/thrift/$(patsubst ../../%,%,$(dir $@)) diff --git a/lib/rb/lib/thrift/types/annotation/deprecation_constants.rb b/lib/rb/lib/thrift/types/annotation/deprecation_constants.rb new file mode 100644 index 00000000000..7915179b58c --- /dev/null +++ b/lib/rb/lib/thrift/types/annotation/deprecation_constants.rb @@ -0,0 +1,17 @@ +# +# Autogenerated by Thrift Compiler (2.5.4-upfluence) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# + +require 'thrift' +require 'deprecation_types' + +module Thrift + module Types + module Annotation + module Deprecation + end + end + end +end diff --git a/lib/rb/lib/thrift/types/annotation/deprecation_types.rb b/lib/rb/lib/thrift/types/annotation/deprecation_types.rb new file mode 100644 index 00000000000..2625f07cbc9 --- /dev/null +++ b/lib/rb/lib/thrift/types/annotation/deprecation_types.rb @@ -0,0 +1,44 @@ +# +# Autogenerated by Thrift Compiler (2.5.4-upfluence) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# + +require 'thrift' + +module Thrift + module Types + module Annotation + module Deprecation + class Deprecated; end + + class Deprecated + include ::Thrift::Struct, ::Thrift::Struct_Union + + NAME = 'Deprecated'.freeze + NAMESPACE = 'types.annotation.deprecation'.freeze + + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + + + FIELDS = { + + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + ::Thrift.register_struct_type self + end + + end + end + end +end diff --git a/lib/rb/lib/thrift/types/annotation/naming_constants.rb b/lib/rb/lib/thrift/types/annotation/naming_constants.rb new file mode 100644 index 00000000000..6bcccde02ad --- /dev/null +++ b/lib/rb/lib/thrift/types/annotation/naming_constants.rb @@ -0,0 +1,17 @@ +# +# Autogenerated by Thrift Compiler (2.5.4-upfluence) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# + +require 'thrift' +require 'naming_types' + +module Thrift + module Types + module Annotation + module Naming + end + end + end +end diff --git a/lib/rb/lib/thrift/types/annotation/naming_types.rb b/lib/rb/lib/thrift/types/annotation/naming_types.rb new file mode 100644 index 00000000000..a0b26fde0a7 --- /dev/null +++ b/lib/rb/lib/thrift/types/annotation/naming_types.rb @@ -0,0 +1,59 @@ +# +# Autogenerated by Thrift Compiler (2.5.4-upfluence) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# + +require 'thrift' + +module Thrift + module Types + module Annotation + module Naming + class PreviouslyKnownAs; end + + class PreviouslyKnownAs + include ::Thrift::Struct, ::Thrift::Struct_Union + + NAME = 'PreviouslyKnownAs'.freeze + NAMESPACE = 'types.annotation.naming'.freeze + + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_INDEX_NAMESPACE_ = 1 + THRIFT_FIELD_INDEX_NAME = 2 + + THRIFT_FIELD_NAMESPACE__LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_NAMESPACE__STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_NAME_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_NAME_STRUCTURED_ANNOTATIONS = [ + ].freeze + + FIELDS = { + THRIFT_FIELD_INDEX_NAMESPACE_ => {type: ::Thrift::Types::STRING, name: 'namespace_', optional: true, legacy_annotations: THRIFT_FIELD_NAMESPACE__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_NAMESPACE__STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_NAME => {type: ::Thrift::Types::STRING, name: 'name', optional: true, legacy_annotations: THRIFT_FIELD_NAME_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_NAME_STRUCTURED_ANNOTATIONS} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + ::Thrift.register_struct_type self + end + + end + end + end +end diff --git a/lib/rb/lib/thrift/types/known/any_types.rb b/lib/rb/lib/thrift/types/known/any_types.rb index 47b3cfe02e8..ce599b08ca3 100644 --- a/lib/rb/lib/thrift/types/known/any_types.rb +++ b/lib/rb/lib/thrift/types/known/any_types.rb @@ -18,12 +18,30 @@ class Any NAME = 'Any'.freeze NAMESPACE = 'types.known.any'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_TYPE = 1 THRIFT_FIELD_INDEX_VALUE = 2 + THRIFT_FIELD_TYPE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_TYPE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_TYPE => {type: ::Thrift::Types::STRING, name: 'type'}, - THRIFT_FIELD_INDEX_VALUE => {type: ::Thrift::Types::STRING, name: 'value', binary: true} + THRIFT_FIELD_INDEX_TYPE => {type: ::Thrift::Types::STRING, name: 'type', legacy_annotations: THRIFT_FIELD_TYPE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_TYPE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_VALUE => {type: ::Thrift::Types::STRING, name: 'value', binary: true, legacy_annotations: THRIFT_FIELD_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_VALUE_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end diff --git a/lib/rb/lib/thrift/types/known/duration_types.rb b/lib/rb/lib/thrift/types/known/duration_types.rb index 27dbf9f7e75..c0cc8f9ff48 100644 --- a/lib/rb/lib/thrift/types/known/duration_types.rb +++ b/lib/rb/lib/thrift/types/known/duration_types.rb @@ -18,12 +18,30 @@ class Duration NAME = 'Duration'.freeze NAMESPACE = 'types.known.duration'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_SECONDS = 1 THRIFT_FIELD_INDEX_NANOS = 2 + THRIFT_FIELD_SECONDS_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_SECONDS_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_NANOS_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_NANOS_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_SECONDS => {type: ::Thrift::Types::I64, name: 'seconds'}, - THRIFT_FIELD_INDEX_NANOS => {type: ::Thrift::Types::I32, name: 'nanos'} + THRIFT_FIELD_INDEX_SECONDS => {type: ::Thrift::Types::I64, name: 'seconds', legacy_annotations: THRIFT_FIELD_SECONDS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_SECONDS_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_NANOS => {type: ::Thrift::Types::I32, name: 'nanos', legacy_annotations: THRIFT_FIELD_NANOS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_NANOS_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end diff --git a/lib/rb/lib/thrift/types/known/timestamp_types.rb b/lib/rb/lib/thrift/types/known/timestamp_types.rb index 2f56b4d4e83..c9d89410f36 100644 --- a/lib/rb/lib/thrift/types/known/timestamp_types.rb +++ b/lib/rb/lib/thrift/types/known/timestamp_types.rb @@ -18,12 +18,30 @@ class Timestamp NAME = 'Timestamp'.freeze NAMESPACE = 'types.known.timestamp'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_SECONDS = 1 THRIFT_FIELD_INDEX_NANOS = 2 + THRIFT_FIELD_SECONDS_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_SECONDS_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_NANOS_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_NANOS_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_SECONDS => {type: ::Thrift::Types::I64, name: 'seconds'}, - THRIFT_FIELD_INDEX_NANOS => {type: ::Thrift::Types::I32, name: 'nanos'} + THRIFT_FIELD_INDEX_SECONDS => {type: ::Thrift::Types::I64, name: 'seconds', legacy_annotations: THRIFT_FIELD_SECONDS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_SECONDS_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_NANOS => {type: ::Thrift::Types::I32, name: 'nanos', legacy_annotations: THRIFT_FIELD_NANOS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_NANOS_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end diff --git a/lib/rb/lib/thrift/types/value_types.rb b/lib/rb/lib/thrift/types/value_types.rb index 612d716a3e8..e23b7671ea8 100644 --- a/lib/rb/lib/thrift/types/value_types.rb +++ b/lib/rb/lib/thrift/types/value_types.rb @@ -27,6 +27,12 @@ class NullValue NAME = 'NullValue'.freeze NAMESPACE = 'types.value'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { @@ -47,10 +53,22 @@ class ListValue NAME = 'ListValue'.freeze NAMESPACE = 'types.value'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_VALUES = 1 + THRIFT_FIELD_VALUES_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_VALUES_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_VALUES => {type: ::Thrift::Types::LIST, name: 'values', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value}} + THRIFT_FIELD_INDEX_VALUES => {type: ::Thrift::Types::LIST, name: 'values', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, legacy_annotations: THRIFT_FIELD_VALUES_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_VALUES_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end @@ -69,12 +87,30 @@ class MapEntry NAME = 'MapEntry'.freeze NAMESPACE = 'types.value'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_KEY = 1 THRIFT_FIELD_INDEX_VALUE = 2 + THRIFT_FIELD_KEY_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_KEY_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_KEY => {type: ::Thrift::Types::STRUCT, name: 'key', class: ::Thrift::Types::Value::Value}, - THRIFT_FIELD_INDEX_VALUE => {type: ::Thrift::Types::STRUCT, name: 'value', class: ::Thrift::Types::Value::Value} + THRIFT_FIELD_INDEX_KEY => {type: ::Thrift::Types::STRUCT, name: 'key', class: ::Thrift::Types::Value::Value, legacy_annotations: THRIFT_FIELD_KEY_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_KEY_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_VALUE => {type: ::Thrift::Types::STRUCT, name: 'value', class: ::Thrift::Types::Value::Value, legacy_annotations: THRIFT_FIELD_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_VALUE_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end @@ -94,10 +130,22 @@ class MapValue NAME = 'MapValue'.freeze NAMESPACE = 'types.value'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_ENTRIES = 1 + THRIFT_FIELD_ENTRIES_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_ENTRIES_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_ENTRIES => {type: ::Thrift::Types::LIST, name: 'entries', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::MapEntry}} + THRIFT_FIELD_INDEX_ENTRIES => {type: ::Thrift::Types::LIST, name: 'entries', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::MapEntry, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, legacy_annotations: THRIFT_FIELD_ENTRIES_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_ENTRIES_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end @@ -116,10 +164,22 @@ class StructValue NAME = 'StructValue'.freeze NAMESPACE = 'types.value'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + THRIFT_FIELD_INDEX_FIELDS = 1 + THRIFT_FIELD_FIELDS_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_FIELDS_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_FIELDS => {type: ::Thrift::Types::MAP, name: 'fields', key: {type: ::Thrift::Types::STRING}, value: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value}} + THRIFT_FIELD_INDEX_FIELDS => {type: ::Thrift::Types::MAP, name: 'fields', key: {type: ::Thrift::Types::STRING, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, value: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, legacy_annotations: THRIFT_FIELD_FIELDS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_FIELDS_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end @@ -138,6 +198,12 @@ class Value < ::Thrift::Union NAME = 'Value'.freeze NAMESPACE = 'types.value'.freeze + LEGACY_ANNOTATIONS = { + }.freeze + + STRUCTURED_ANNOTATIONS = [ + ].freeze + class << self def null_value(val) Value.new(:null_value, val) @@ -186,16 +252,70 @@ def struct_value(val) THRIFT_FIELD_INDEX_MAP_VALUE = 8 THRIFT_FIELD_INDEX_STRUCT_VALUE = 9 + THRIFT_FIELD_NULL_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_NULL_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_STRING_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_STRING_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_BINARY_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_BINARY_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_INTEGER_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_INTEGER_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_DOUBLE_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_DOUBLE_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_BOOL_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_BOOL_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_LIST_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_LIST_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_MAP_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_MAP_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + + THRIFT_FIELD_STRUCT_VALUE_LEGACY_ANNOTATIONS = { + }.freeze + + THRIFT_FIELD_STRUCT_VALUE_STRUCTURED_ANNOTATIONS = [ + ].freeze + FIELDS = { - THRIFT_FIELD_INDEX_NULL_VALUE => {type: ::Thrift::Types::STRUCT, name: 'null_value', class: ::Thrift::Types::Value::NullValue}, - THRIFT_FIELD_INDEX_STRING_VALUE => {type: ::Thrift::Types::STRING, name: 'string_value'}, - THRIFT_FIELD_INDEX_BINARY_VALUE => {type: ::Thrift::Types::STRING, name: 'binary_value', binary: true}, - THRIFT_FIELD_INDEX_INTEGER_VALUE => {type: ::Thrift::Types::I64, name: 'integer_value'}, - THRIFT_FIELD_INDEX_DOUBLE_VALUE => {type: ::Thrift::Types::DOUBLE, name: 'double_value'}, - THRIFT_FIELD_INDEX_BOOL_VALUE => {type: ::Thrift::Types::BOOL, name: 'bool_value'}, - THRIFT_FIELD_INDEX_LIST_VALUE => {type: ::Thrift::Types::STRUCT, name: 'list_value', class: ::Thrift::Types::Value::ListValue}, - THRIFT_FIELD_INDEX_MAP_VALUE => {type: ::Thrift::Types::STRUCT, name: 'map_value', class: ::Thrift::Types::Value::MapValue}, - THRIFT_FIELD_INDEX_STRUCT_VALUE => {type: ::Thrift::Types::STRUCT, name: 'struct_value', class: ::Thrift::Types::Value::StructValue} + THRIFT_FIELD_INDEX_NULL_VALUE => {type: ::Thrift::Types::STRUCT, name: 'null_value', class: ::Thrift::Types::Value::NullValue, legacy_annotations: THRIFT_FIELD_NULL_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_NULL_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_STRING_VALUE => {type: ::Thrift::Types::STRING, name: 'string_value', legacy_annotations: THRIFT_FIELD_STRING_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_STRING_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_BINARY_VALUE => {type: ::Thrift::Types::STRING, name: 'binary_value', binary: true, legacy_annotations: THRIFT_FIELD_BINARY_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_BINARY_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_INTEGER_VALUE => {type: ::Thrift::Types::I64, name: 'integer_value', legacy_annotations: THRIFT_FIELD_INTEGER_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_INTEGER_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_DOUBLE_VALUE => {type: ::Thrift::Types::DOUBLE, name: 'double_value', legacy_annotations: THRIFT_FIELD_DOUBLE_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_DOUBLE_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_BOOL_VALUE => {type: ::Thrift::Types::BOOL, name: 'bool_value', legacy_annotations: THRIFT_FIELD_BOOL_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_BOOL_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_LIST_VALUE => {type: ::Thrift::Types::STRUCT, name: 'list_value', class: ::Thrift::Types::Value::ListValue, legacy_annotations: THRIFT_FIELD_LIST_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_LIST_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_MAP_VALUE => {type: ::Thrift::Types::STRUCT, name: 'map_value', class: ::Thrift::Types::Value::MapValue, legacy_annotations: THRIFT_FIELD_MAP_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_MAP_VALUE_STRUCTURED_ANNOTATIONS}, + THRIFT_FIELD_INDEX_STRUCT_VALUE => {type: ::Thrift::Types::STRUCT, name: 'struct_value', class: ::Thrift::Types::Value::StructValue, legacy_annotations: THRIFT_FIELD_STRUCT_VALUE_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_STRUCT_VALUE_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end diff --git a/types/annotation/deprecation.thrift b/types/annotation/deprecation.thrift new file mode 100644 index 00000000000..fa3c4c062ff --- /dev/null +++ b/types/annotation/deprecation.thrift @@ -0,0 +1,3 @@ +namespace * types.annotation.deprecation + +struct Deprecated {} diff --git a/types/annotation/naming.thrift b/types/annotation/naming.thrift new file mode 100644 index 00000000000..e7a1984630c --- /dev/null +++ b/types/annotation/naming.thrift @@ -0,0 +1,8 @@ +namespace * types.annotation.naming + +struct PreviouslyKnownAs { + // If namespace is nil, the previous namespace is the current one + 1: optional string namespace_; + // If name is nil, the previous struct/service name is the current one + 2: optional string name; +} From b60279b4188f1fe62c8576f02056b5fe7c18530f Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Tue, 8 Oct 2024 15:38:22 -0700 Subject: [PATCH 07/10] lib/go: Handle the PreviouslyKnownAs annotation seamlessly --- lib/go/go.mod | 14 ++ lib/go/go.sum | 12 ++ lib/go/test/tests/go.mod | 3 + lib/go/thrift/definition.go | 130 ++--------- lib/go/thrift/exception_test.go | 10 +- lib/go/thrift/field.go | 4 +- .../thrift/internal/reflection/definition.go | 204 ++++++++++++++++++ lib/go/thrift/json_protocol_test.go | 2 +- lib/go/thrift/numeric.go | 2 +- lib/go/thrift/simple_json_protocol_test.go | 2 +- .../thrift/types/annotation/naming/naming.go | 30 +++ 11 files changed, 289 insertions(+), 124 deletions(-) create mode 100644 lib/go/go.mod create mode 100644 lib/go/go.sum create mode 100644 lib/go/test/tests/go.mod create mode 100644 lib/go/thrift/internal/reflection/definition.go create mode 100644 lib/go/thrift/types/annotation/naming/naming.go diff --git a/lib/go/go.mod b/lib/go/go.mod new file mode 100644 index 00000000000..9fd9f7c51c4 --- /dev/null +++ b/lib/go/go.mod @@ -0,0 +1,14 @@ +module github.com/upfluence/thrift/lib/go + +go 1.23.0 + +require ( + github.com/stretchr/testify v1.9.0 + github.com/upfluence/errors v0.2.11 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/lib/go/go.sum b/lib/go/go.sum new file mode 100644 index 00000000000..168d9624546 --- /dev/null +++ b/lib/go/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/upfluence/errors v0.2.11 h1:v0siQatgm/ovihotNy++k2AXYk136VLVi4cdxAIFo1s= +github.com/upfluence/errors v0.2.11/go.mod h1:XmrnFoB1O343aOni1tqU1wZNQuRhWNDHXa/cqnFzDzE= +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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib/go/test/tests/go.mod b/lib/go/test/tests/go.mod new file mode 100644 index 00000000000..1d7afab3e3e --- /dev/null +++ b/lib/go/test/tests/go.mod @@ -0,0 +1,3 @@ +module github.com/upfluence/thrift/lib/go/test/tests + +go 1.23.0 diff --git a/lib/go/thrift/definition.go b/lib/go/thrift/definition.go index ab5892b2586..2da2dd317e4 100644 --- a/lib/go/thrift/definition.go +++ b/lib/go/thrift/definition.go @@ -1,134 +1,34 @@ package thrift import ( - "fmt" "reflect" - "sync" -) - -var ( - defaultStructTypeRegistry = &structTypeRegistry{ - types: make(map[string]reflect.Type), - defs: make(map[string]StructDefinition), - } - defaultServiceRegistry = &serviceRegistry{ - defs: make(map[string]ServiceDefinition), - } + "github.com/upfluence/thrift/lib/go/thrift/internal/reflection" ) -type serviceRegistry struct { - mu sync.RWMutex - - defs map[string]ServiceDefinition -} - -func (str *serviceRegistry) registerService(sd ServiceDefinition) { - str.mu.Lock() - defer str.mu.Unlock() - - str.defs[sd.CanonicalName()] = sd -} - -type structTypeRegistry struct { - mu sync.RWMutex - - defs map[string]StructDefinition - types map[string]reflect.Type -} - -func (str *structTypeRegistry) registerStructType(rs RegistrableStruct) { - t := reflect.TypeOf(rs) - - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - - sd := rs.StructDefinition() - n := sd.CanonicalName() - - str.mu.Lock() - defer str.mu.Unlock() - - str.types[n] = t - str.defs[n] = sd -} - -func (str *structTypeRegistry) structType(n string) (reflect.Type, bool) { - str.mu.Lock() - defer str.mu.Unlock() - - t, ok := str.types[n] - - return t, ok -} - -type AnnotatedDefintion struct { - Name string - - LegacyAnnotations map[string]string - SturcturedAnnotations []RegistrableStruct -} - -type FieldDefinition struct { - AnnotatedDefintion -} - -type StructDefinition struct { - AnnotatedDefintion - - Namespace string - - IsException bool - IsUnion bool - - Fields []FieldDefinition -} - -func (sd StructDefinition) CanonicalName() string { - return fmt.Sprintf("%s.%s", sd.Namespace, sd.Name) -} - -type FunctionDefinition struct { - AnnotatedDefintion - - IsOneway bool - - Args StructDefinition - Result *StructDefinition -} - -type ServiceDefinition struct { - AnnotatedDefintion - - Namespace string - - Functions []FunctionDefinition -} - -func (sd ServiceDefinition) CanonicalName() string { - return fmt.Sprintf("%s.%s", sd.Namespace, sd.Name) -} - -type RegistrableStruct interface { - TStruct - StructDefinition() StructDefinition -} +type AnnotatedDefinition = reflection.AnnotatedDefinition +type FieldDefinition = reflection.FieldDefinition +type StructDefinition = reflection.StructDefinition +type FunctionDefinition = reflection.FunctionDefinition +type ServiceDefinition = reflection.ServiceDefinition +type RegistrableStruct = reflection.RegistrableStruct func RegisterService(def ServiceDefinition) { - defaultServiceRegistry.registerService(def) + reflection.RegisterService(def) } func GetServiceDefinition(n string) (ServiceDefinition, bool) { - def, ok := defaultServiceRegistry.defs[n] - - return def, ok + return reflection.GetServiceDefinition(n) } func RegisterStruct(rs RegistrableStruct) { - defaultStructTypeRegistry.registerStructType(rs) + reflection.RegisterStruct(rs) } func StructType(n string) (reflect.Type, bool) { - return defaultStructTypeRegistry.structType(n) + return reflection.StructType(n) +} + +func ExtractCanonicalNames(ns string, def AnnotatedDefinition) []string { + return reflection.ExtractCanonicalNames(ns, def) } diff --git a/lib/go/thrift/exception_test.go b/lib/go/thrift/exception_test.go index 71f5e2c7e79..11ed3303352 100644 --- a/lib/go/thrift/exception_test.go +++ b/lib/go/thrift/exception_test.go @@ -30,8 +30,8 @@ func TestPrependError(t *testing.T) { if !ok { t.Fatal("Couldn't cast error TApplicationException") } - if err2.Error() != "Prepend: original error" { - t.Fatal("Unexpected error string") + if err2.Error() != "Prepend: : original error" { + t.Fatalf("Unexpected error string, has %q", err2.Error()) } if err2.TypeId() != INTERNAL_ERROR { t.Fatal("Unexpected type error") @@ -42,7 +42,7 @@ func TestPrependError(t *testing.T) { if !ok { t.Fatal("Couldn't cast error TProtocolException") } - if err4.Error() != "Prepend: original error" { + if err4.Error() != "Prepend: : original error" { t.Fatal("Unexpected error string") } if err4.TypeId() != INVALID_DATA { @@ -54,7 +54,7 @@ func TestPrependError(t *testing.T) { if !ok { t.Fatal("Couldn't cast error TTransportException") } - if err6.Error() != "Prepend: original error" { + if err6.Error() != "Prepend: : original error" { t.Fatal("Unexpected error string") } if err6.TypeId() != TIMED_OUT { @@ -63,7 +63,7 @@ func TestPrependError(t *testing.T) { err7 := errors.New("original error") err8 := PrependError("Prepend: ", err7) - if err8.Error() != "Prepend: original error" { + if err8.Error() != "Prepend: : original error" { t.Fatal("Unexpected error string") } } diff --git a/lib/go/thrift/field.go b/lib/go/thrift/field.go index 9d665255097..98c5aa1292b 100644 --- a/lib/go/thrift/field.go +++ b/lib/go/thrift/field.go @@ -19,6 +19,8 @@ package thrift +import "strconv" + // Helper class that encapsulates field metadata. type field struct { name string @@ -55,7 +57,7 @@ func (p *field) String() string { if p == nil { return "" } - return "" + return "" } var ANONYMOUS_FIELD *field diff --git a/lib/go/thrift/internal/reflection/definition.go b/lib/go/thrift/internal/reflection/definition.go new file mode 100644 index 00000000000..71952177e68 --- /dev/null +++ b/lib/go/thrift/internal/reflection/definition.go @@ -0,0 +1,204 @@ +package reflection + +import ( + "fmt" + "reflect" + "sync" +) + +var ( + defaultCanonicalNameExtractor = &canonicalNameExtractors{ + es: []CanonicalNameExtractor{ + CanonicalNameExtractorFunc(func(ns string, def AnnotatedDefinition) []string { + return []string{fmt.Sprintf("%s.%s", ns, def.Name)} + }), + }, + } + + defaultStructTypeRegistry = &structTypeRegistry{ + types: make(map[string]reflect.Type), + ext: defaultCanonicalNameExtractor, + } + + defaultServiceRegistry = &serviceRegistry{ + defs: make(map[string]ServiceDefinition), + ext: defaultCanonicalNameExtractor, + } +) + +type CanonicalNameExtractor interface { + Extract(string, AnnotatedDefinition) []string +} + +type CanonicalNameExtractorFunc func(string, AnnotatedDefinition) []string + +func (fn CanonicalNameExtractorFunc) Extract(ns string, def AnnotatedDefinition) []string { + return fn(ns, def) +} + +type canonicalNameExtractors struct { + es []CanonicalNameExtractor + mu sync.RWMutex +} + +func (fns *canonicalNameExtractors) registerExtractor(e CanonicalNameExtractor) { + fns.mu.Lock() + defer fns.mu.Unlock() + + fns.es = append(fns.es, e) +} + +func (fns *canonicalNameExtractors) Extract(ns string, def AnnotatedDefinition) []string { + var res []string + + fns.mu.RLock() + defer fns.mu.RUnlock() + + for _, e := range fns.es { + res = append(res, e.Extract(ns, def)...) + } + + return res +} + +func RegisterCanonicalNameExtractor(e CanonicalNameExtractor) { + defaultCanonicalNameExtractor.registerExtractor(e) +} + +func ExtractCanonicalNames(ns string, def AnnotatedDefinition) []string { + return defaultCanonicalNameExtractor.Extract(ns, def) +} + +type serviceRegistry struct { + mu sync.RWMutex + + ext CanonicalNameExtractor + defs map[string]ServiceDefinition +} + +func (str *serviceRegistry) registerService(sd ServiceDefinition) { + ns := str.ext.Extract(sd.Namespace, sd.AnnotatedDefinition) + + str.mu.Lock() + defer str.mu.Unlock() + + for _, n := range ns { + str.defs[n] = sd + } +} + +type structTypeRegistry struct { + mu sync.RWMutex + + ext CanonicalNameExtractor + + types map[string]reflect.Type +} + +func (str *structTypeRegistry) registerStructType(rs RegistrableStruct) { + t := reflect.TypeOf(rs) + + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + sd := rs.StructDefinition() + ns := str.ext.Extract(sd.Namespace, sd.AnnotatedDefinition) + + str.mu.Lock() + defer str.mu.Unlock() + + for _, n := range ns { + str.types[n] = t + } +} + +func (str *structTypeRegistry) structType(n string) (reflect.Type, bool) { + str.mu.Lock() + defer str.mu.Unlock() + + t, ok := str.types[n] + + return t, ok +} + +type AnnotatedDefinition struct { + Name string + + LegacyAnnotations map[string]string + StructuredAnnotations []RegistrableStruct +} + +type FieldDefinition struct { + AnnotatedDefinition +} + +type StructDefinition struct { + AnnotatedDefinition + + Namespace string + + // Deprecated: Use the Name in AnnotatedDefinition, this is here for + // backward compatibility for previously generated code. + Name string + + IsException bool + IsUnion bool + + Fields []FieldDefinition +} + +func (sd StructDefinition) name() string { + if sd.AnnotatedDefinition.Name != "" { + return sd.AnnotatedDefinition.Name + } + + return sd.Name +} + +func (sd StructDefinition) CanonicalName() string { + return fmt.Sprintf("%s.%s", sd.Namespace, sd.name()) +} + +type FunctionDefinition struct { + AnnotatedDefinition + + IsOneway bool + + Args StructDefinition + Result *StructDefinition +} + +type ServiceDefinition struct { + AnnotatedDefinition + + Namespace string + + Functions []FunctionDefinition +} + +func (sd ServiceDefinition) CanonicalName() string { + return fmt.Sprintf("%s.%s", sd.Namespace, sd.Name) +} + +type RegistrableStruct interface { + StructDefinition() StructDefinition +} + +func RegisterService(def ServiceDefinition) { + defaultServiceRegistry.registerService(def) +} + +func GetServiceDefinition(n string) (ServiceDefinition, bool) { + def, ok := defaultServiceRegistry.defs[n] + + return def, ok +} + +func RegisterStruct(rs RegistrableStruct) { + defaultStructTypeRegistry.registerStructType(rs) +} + +func StructType(n string) (reflect.Type, bool) { + return defaultStructTypeRegistry.structType(n) +} diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go index 1430c7c2a11..a172da5b55c 100644 --- a/lib/go/thrift/json_protocol_test.go +++ b/lib/go/thrift/json_protocol_test.go @@ -608,7 +608,7 @@ func TestWriteJSONProtocolMap(t *testing.T) { for k, value := range DOUBLE_VALUES { ik, err := p.ReadI32() if err != nil { - t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, string(k), err.Error()) + t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, strconv.Itoa(k), err.Error()) } if int(ik) != k { t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v", thetype, k, ik, k) diff --git a/lib/go/thrift/numeric.go b/lib/go/thrift/numeric.go index aa8daa9b54f..cd844007bb1 100644 --- a/lib/go/thrift/numeric.go +++ b/lib/go/thrift/numeric.go @@ -69,7 +69,7 @@ func NewNumericFromDouble(dValue float64) Numeric { func NewNumericFromI64(iValue int64) Numeric { dValue := float64(iValue) - sValue := string(iValue) + sValue := strconv.Itoa(int(iValue)) isNil := false return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} } diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index f0397bd99af..2b3d4dbc16a 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -681,7 +681,7 @@ func TestWriteSimpleJSONProtocolMap(t *testing.T) { strv := l[k*2+4] ik, err := strconv.Atoi(strk) if err != nil { - t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, string(k), err.Error()) + t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, strconv.Itoa(k), err.Error()) } if ik != k { t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v", thetype, k, strk, k) diff --git a/lib/go/thrift/types/annotation/naming/naming.go b/lib/go/thrift/types/annotation/naming/naming.go new file mode 100644 index 00000000000..eeb1f4acc8b --- /dev/null +++ b/lib/go/thrift/types/annotation/naming/naming.go @@ -0,0 +1,30 @@ +package naming + +import "github.com/upfluence/thrift/lib/go/thrift/internal/reflection" + +func init() { + reflection.RegisterCanonicalNameExtractor( + reflection.CanonicalNameExtractorFunc(func(ns string, def reflection.AnnotatedDefinition) []string { + var res []string + + for _, sa := range def.StructuredAnnotations { + if pka, ok := sa.(*PreviouslyKnownAs); ok { + lns := pka.GetNamespace_() + ln := pka.GetName() + + if lns == "" { + lns = ns + } + + if ln == "" { + ln = def.Name + } + + res = append(res, lns+"."+ln) + } + } + + return res + }), + ) +} From ad51db7d2892b43bcb1ab56e61e41e425c485400 Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Tue, 8 Oct 2024 16:12:43 -0700 Subject: [PATCH 08/10] lib/rb: Handle the PreviouslyKnownAs annotation seamlessly --- compiler/cpp/src/generate/t_rb_generator.cc | 15 ++++++++++----- lib/rb/lib/thrift/definition.rb | 19 +++++++++++++++++++ .../thrift/types/annotation/naming_types.rb | 14 ++++++++++++++ lib/rb/lib/thrift/types/value_types.rb | 6 +++--- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/compiler/cpp/src/generate/t_rb_generator.cc b/compiler/cpp/src/generate/t_rb_generator.cc index 8269a5fa68b..f4cee178909 100644 --- a/compiler/cpp/src/generate/t_rb_generator.cc +++ b/compiler/cpp/src/generate/t_rb_generator.cc @@ -134,7 +134,8 @@ class t_rb_generator : public t_oop_generator { t_type* field_type, const std::string& field_name, t_const_value* field_value, - bool optional); + bool optional, + bool embed_annotations); /** * Service-level generation functions @@ -747,7 +748,8 @@ void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) (*f_iter)->get_type(), (*f_iter)->get_name(), (*f_iter)->get_value(), - (*f_iter)->get_req() == t_field::T_OPTIONAL); + (*f_iter)->get_req() == t_field::T_OPTIONAL, + true); } out.indent_down(); out << endl; @@ -760,7 +762,8 @@ void t_rb_generator::generate_field_data(t_rb_ofstream& out, t_type* field_type, const std::string& field_name = "", t_const_value* field_value = NULL, - bool optional = false) { + bool optional = false, + bool embed_annotations = false) { field_type = get_true_type(field_type); // Begin this field's defn @@ -804,8 +807,10 @@ void t_rb_generator::generate_field_data(t_rb_ofstream& out, out << ", enum_class: " << full_type_name(field_type); } - out << ", legacy_annotations: THRIFT_FIELD_" << upcase_string(field_name) << "_LEGACY_ANNOTATIONS"; - out << ", structured_annotations: THRIFT_FIELD_" << upcase_string(field_name) << "_STRUCTURED_ANNOTATIONS"; + if (embed_annotations) { + out << ", legacy_annotations: THRIFT_FIELD_" << upcase_string(field_name) << "_LEGACY_ANNOTATIONS"; + out << ", structured_annotations: THRIFT_FIELD_" << upcase_string(field_name) << "_STRUCTURED_ANNOTATIONS"; + } // End of this field's defn out << "}"; diff --git a/lib/rb/lib/thrift/definition.rb b/lib/rb/lib/thrift/definition.rb index 75147d9d742..82d1bd0e3f4 100644 --- a/lib/rb/lib/thrift/definition.rb +++ b/lib/rb/lib/thrift/definition.rb @@ -1,4 +1,12 @@ module Thrift + class DefaultCanonicalNameExtractor + class << self + def extract(definition) + [definition.struct_type] + end + end + end + class StructDefinition attr_reader :klass @@ -25,6 +33,12 @@ def name def struct_type "#{namespace}.#{name}" end + + def canonical_names + CANONICAL_NAME_EXTRACTORS.reduce([]) do |acc, cur| + acc + cur.extract(self) + end + end end class ServiceDefinition < StructDefinition @@ -51,6 +65,7 @@ def service_type STRUCT_DEFINITIONS = {} SERVICE_DEFINITIONS = {} + CANONICAL_NAME_EXTRACTORS = [DefaultCanonicalNameExtractor] class << self def register_struct_type(klass) @@ -62,5 +77,9 @@ def register_service_type(klass) definition = ServiceDefinition.new(klass) SERVICE_DEFINITIONS[definition.service_type] = definition end + + def register_canonical_name_extractor(klass) + CANONICAL_NAME_EXTRACTORS << klass + end end end diff --git a/lib/rb/lib/thrift/types/annotation/naming_types.rb b/lib/rb/lib/thrift/types/annotation/naming_types.rb index a0b26fde0a7..2b3e5d10d19 100644 --- a/lib/rb/lib/thrift/types/annotation/naming_types.rb +++ b/lib/rb/lib/thrift/types/annotation/naming_types.rb @@ -54,6 +54,20 @@ def validate end end + + class CanonicalNameExtractor + class << self + def extract(definition) + definition.structured_annotations.select do |sa| + sa.is_a? PreviouslyKnownAs + end.map do |pka| + "#{pka.namespace_ || definition.namespace}.#{pka.name || definition.name}" + end + end + end + + ::Thrift.register_canonical_name_extractor self + end end end end diff --git a/lib/rb/lib/thrift/types/value_types.rb b/lib/rb/lib/thrift/types/value_types.rb index e23b7671ea8..6fbb533991e 100644 --- a/lib/rb/lib/thrift/types/value_types.rb +++ b/lib/rb/lib/thrift/types/value_types.rb @@ -68,7 +68,7 @@ class ListValue ].freeze FIELDS = { - THRIFT_FIELD_INDEX_VALUES => {type: ::Thrift::Types::LIST, name: 'values', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, legacy_annotations: THRIFT_FIELD_VALUES_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_VALUES_STRUCTURED_ANNOTATIONS} + THRIFT_FIELD_INDEX_VALUES => {type: ::Thrift::Types::LIST, name: 'values', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value}, legacy_annotations: THRIFT_FIELD_VALUES_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_VALUES_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end @@ -145,7 +145,7 @@ class MapValue ].freeze FIELDS = { - THRIFT_FIELD_INDEX_ENTRIES => {type: ::Thrift::Types::LIST, name: 'entries', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::MapEntry, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, legacy_annotations: THRIFT_FIELD_ENTRIES_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_ENTRIES_STRUCTURED_ANNOTATIONS} + THRIFT_FIELD_INDEX_ENTRIES => {type: ::Thrift::Types::LIST, name: 'entries', element: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::MapEntry}, legacy_annotations: THRIFT_FIELD_ENTRIES_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_ENTRIES_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end @@ -179,7 +179,7 @@ class StructValue ].freeze FIELDS = { - THRIFT_FIELD_INDEX_FIELDS => {type: ::Thrift::Types::MAP, name: 'fields', key: {type: ::Thrift::Types::STRING, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, value: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value, legacy_annotations: THRIFT_FIELD__LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD__STRUCTURED_ANNOTATIONS}, legacy_annotations: THRIFT_FIELD_FIELDS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_FIELDS_STRUCTURED_ANNOTATIONS} + THRIFT_FIELD_INDEX_FIELDS => {type: ::Thrift::Types::MAP, name: 'fields', key: {type: ::Thrift::Types::STRING}, value: {type: ::Thrift::Types::STRUCT, class: ::Thrift::Types::Value::Value}, legacy_annotations: THRIFT_FIELD_FIELDS_LEGACY_ANNOTATIONS, structured_annotations: THRIFT_FIELD_FIELDS_STRUCTURED_ANNOTATIONS} } def struct_fields; FIELDS; end From 12d46f35d7a3b7ca5b18afbe430945c812eb9b63 Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Wed, 9 Oct 2024 14:46:22 -0700 Subject: [PATCH 09/10] compiler/cpp/src/generate/t_go_generator: Fix the render_const_value implementation --- Makefile.am | 3 ++ compiler/cpp/src/generate/t_go_generator.cc | 57 ++++++++++++++++----- lib/go/thrift/pointerize.go | 2 + 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2d73d5d10f9..b595c94bbb8 100755 --- a/Makefile.am +++ b/Makefile.am @@ -32,6 +32,9 @@ endif include_types_knowndir = ${TYPES_PREFIX}/types/known include_types_known_HEADERS = types/known/*.thrift +include_types_knowndir = ${TYPES_PREFIX}/types/annotation +include_types_known_HEADERS = types/annotation/*.thrift + include_typesdir = ${TYPES_PREFIX}/types include_types_HEADERS = types/*.thrift diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc index d08d849f4e7..d183176eac9 100644 --- a/compiler/cpp/src/generate/t_go_generator.cc +++ b/compiler/cpp/src/generate/t_go_generator.cc @@ -114,7 +114,7 @@ class t_go_generator : public t_generator { void generate_xception(t_struct* txception); void generate_service(t_service* tservice); - std::string render_const_value(t_type* type, t_const_value* value, const string& name); + std::string render_const_value(t_type* type, t_const_value* value, const string& name, bool is_optional = false); /** * Struct generation code @@ -942,39 +942,57 @@ void t_go_generator::generate_const(t_const* tconst) { * is NOT performed in this function as it is always run beforehand using the * validate_types method in main.cc */ -string t_go_generator::render_const_value(t_type* type, t_const_value* value, const string& name) { +string t_go_generator::render_const_value(t_type* type, t_const_value* value, const string& name, bool is_optional) { type = get_true_type(type); std::ostringstream out; if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); + std::ostringstream go_value; + std::string ptr_method; + + if (is_optional) { + out << "thrift."; + } + switch (tbase) { case t_base_type::TYPE_STRING: if (((t_base_type*)type)->is_binary()) { - out << "[]byte(\"" << get_escaped_string(value) << "\")"; + ptr_method = "ByteSlicePtr"; + go_value << "[]byte(\"" << get_escaped_string(value) << "\")"; } else { - out << '"' << get_escaped_string(value) << '"'; + ptr_method = "StringPtr"; + go_value << '"' << get_escaped_string(value) << '"'; } break; case t_base_type::TYPE_BOOL: - out << (value->get_integer() > 0 ? "true" : "false"); + ptr_method = "BoolPtr"; + go_value << (value->get_integer() > 0 ? "true" : "false"); break; case t_base_type::TYPE_BYTE: + ptr_method = "Int8Ptr"; case t_base_type::TYPE_I16: + ptr_method = "Int16Ptr"; case t_base_type::TYPE_I32: + ptr_method = "Int32Ptr"; case t_base_type::TYPE_I64: - out << value->get_integer(); + if (ptr_method == "") { + ptr_method = "Int64Ptr"; + } + + go_value << value->get_integer(); break; case t_base_type::TYPE_DOUBLE: + ptr_method = "Float64Ptr"; if (value->get_type() == t_const_value::CV_INTEGER) { - out << value->get_integer(); + go_value << value->get_integer(); } else { - out << value->get_double(); + go_value << value->get_double(); } break; @@ -982,6 +1000,16 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } + + if (is_optional) { + out << ptr_method << "("; + } + + out << go_value.str(); + + if (is_optional) { + out << ")"; + } } else if (type->is_enum()) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { @@ -993,21 +1021,24 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - t_type* field_type = NULL; + t_field* field = NULL; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_name() == v_iter->first->get_string()) { - field_type = (*f_iter)->get_type(); + field = *f_iter; + } } - if (field_type == NULL) { + if (field == NULL) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } + t_type* field_type = field->get_type(); + if (field_type->is_base_type() || field_type->is_enum()) { out << endl << indent() << publicize(v_iter->first->get_string()) << ": " - << render_const_value(field_type, v_iter->second, name) << ","; + << render_const_value(field_type, v_iter->second, name, field->get_req() == t_field::e_req::T_OPTIONAL) << ","; } else { string k(tmp("k")); string v(tmp("v")); @@ -1017,7 +1048,7 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co } } - out << "}"; + out << endl << "}"; indent_down(); } else if (type->is_map()) { diff --git a/lib/go/thrift/pointerize.go b/lib/go/thrift/pointerize.go index 8d6b2c2159d..fb564ea8193 100644 --- a/lib/go/thrift/pointerize.go +++ b/lib/go/thrift/pointerize.go @@ -41,6 +41,8 @@ package thrift func Float32Ptr(v float32) *float32 { return &v } func Float64Ptr(v float64) *float64 { return &v } func IntPtr(v int) *int { return &v } +func Int8Ptr(v int8) *int8 { return &v } +func Int16Ptr(v int16) *int16 { return &v } func Int32Ptr(v int32) *int32 { return &v } func Int64Ptr(v int64) *int64 { return &v } func StringPtr(v string) *string { return &v } From e82a32f6a9f2f8038000de1bc7dbddfc7032260a Mon Sep 17 00:00:00 2001 From: Alexis Montagne Date: Wed, 9 Oct 2024 15:02:59 -0700 Subject: [PATCH 10/10] lib/rb: Namespace properly the std libs --- lib/rb/Makefile.am | 4 ++-- lib/rb/lib/thrift.rb | 5 ++++ .../deprecation_constants.rb | 2 +- .../{ => deprecation}/deprecation_types.rb | 0 .../thrift/types/annotation/naming/naming.rb | 23 +++++++++++++++++++ .../{ => naming}/naming_constants.rb | 2 +- .../annotation/{ => naming}/naming_types.rb | 14 ----------- .../lib/thrift/types/known/{ => any}/any.rb | 2 +- .../types/known/{ => any}/any_constants.rb | 2 +- .../thrift/types/known/{ => any}/any_types.rb | 0 .../types/known/{ => duration}/duration.rb | 2 +- .../{ => duration}/duration_constants.rb | 2 +- .../known/{ => duration}/duration_types.rb | 0 .../types/known/{ => timestamp}/timestamp.rb | 2 +- .../{ => timestamp}/timestamp_constants.rb | 2 +- .../known/{ => timestamp}/timestamp_types.rb | 0 lib/rb/lib/thrift/types/{ => value}/value.rb | 2 +- .../types/{ => value}/value_constants.rb | 2 +- .../thrift/types/{ => value}/value_types.rb | 0 19 files changed, 40 insertions(+), 26 deletions(-) rename lib/rb/lib/thrift/types/annotation/{ => deprecation}/deprecation_constants.rb (79%) rename lib/rb/lib/thrift/types/annotation/{ => deprecation}/deprecation_types.rb (100%) create mode 100644 lib/rb/lib/thrift/types/annotation/naming/naming.rb rename lib/rb/lib/thrift/types/annotation/{ => naming}/naming_constants.rb (81%) rename lib/rb/lib/thrift/types/annotation/{ => naming}/naming_types.rb (79%) rename lib/rb/lib/thrift/types/known/{ => any}/any.rb (99%) rename lib/rb/lib/thrift/types/known/{ => any}/any_constants.rb (84%) rename lib/rb/lib/thrift/types/known/{ => any}/any_types.rb (100%) rename lib/rb/lib/thrift/types/known/{ => duration}/duration.rb (90%) rename lib/rb/lib/thrift/types/known/{ => duration}/duration_constants.rb (81%) rename lib/rb/lib/thrift/types/known/{ => duration}/duration_types.rb (100%) rename lib/rb/lib/thrift/types/known/{ => timestamp}/timestamp.rb (90%) rename lib/rb/lib/thrift/types/known/{ => timestamp}/timestamp_constants.rb (81%) rename lib/rb/lib/thrift/types/known/{ => timestamp}/timestamp_types.rb (100%) rename lib/rb/lib/thrift/types/{ => value}/value.rb (98%) rename lib/rb/lib/thrift/types/{ => value}/value_constants.rb (83%) rename lib/rb/lib/thrift/types/{ => value}/value_types.rb (100%) diff --git a/lib/rb/Makefile.am b/lib/rb/Makefile.am index 59e6ae7b667..96e1c51bf3b 100755 --- a/lib/rb/Makefile.am +++ b/lib/rb/Makefile.am @@ -42,8 +42,8 @@ TYPE_FILES = ../../types/*.thrift ../../types/*/*.thrift $(TYPE_FILES): mkdir -p lib/thrift/$(patsubst ../../%,%,$(dir $@)) - $(THRIFT) -gen rb:namespace_wrapper=thrift \ - --out lib/thrift/$(patsubst ../../%,%,$(dir $@)) $@ + $(THRIFT) -gen rb:namespaced,namespace_wrapper=thrift \ + --out lib/ $@ generate-types: $(TYPE_FILES) diff --git a/lib/rb/lib/thrift.rb b/lib/rb/lib/thrift.rb index 7253edfda6a..f7f343ee708 100644 --- a/lib/rb/lib/thrift.rb +++ b/lib/rb/lib/thrift.rb @@ -68,3 +68,8 @@ require 'thrift/server/thread_pool_server' require 'thrift/thrift_native' + +require 'thrift/types/known/any/any' +require 'thrift/types/known/timestamp/timestamp' +require 'thrift/types/known/duration/duration' +require 'thrift/types/annotation/naming/naming' diff --git a/lib/rb/lib/thrift/types/annotation/deprecation_constants.rb b/lib/rb/lib/thrift/types/annotation/deprecation/deprecation_constants.rb similarity index 79% rename from lib/rb/lib/thrift/types/annotation/deprecation_constants.rb rename to lib/rb/lib/thrift/types/annotation/deprecation/deprecation_constants.rb index 7915179b58c..2373bbf219f 100644 --- a/lib/rb/lib/thrift/types/annotation/deprecation_constants.rb +++ b/lib/rb/lib/thrift/types/annotation/deprecation/deprecation_constants.rb @@ -5,7 +5,7 @@ # require 'thrift' -require 'deprecation_types' +require 'thrift/types/annotation/deprecation/deprecation_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/annotation/deprecation_types.rb b/lib/rb/lib/thrift/types/annotation/deprecation/deprecation_types.rb similarity index 100% rename from lib/rb/lib/thrift/types/annotation/deprecation_types.rb rename to lib/rb/lib/thrift/types/annotation/deprecation/deprecation_types.rb diff --git a/lib/rb/lib/thrift/types/annotation/naming/naming.rb b/lib/rb/lib/thrift/types/annotation/naming/naming.rb new file mode 100644 index 00000000000..73afa35dcfe --- /dev/null +++ b/lib/rb/lib/thrift/types/annotation/naming/naming.rb @@ -0,0 +1,23 @@ +require 'thrift/types/annotation/naming/naming_types' + +module Thrift + module Types + module Annotation + module Naming + class CanonicalNameExtractor + class << self + def extract(definition) + definition.structured_annotations.select do |sa| + sa.is_a? PreviouslyKnownAs + end.map do |pka| + "#{pka.namespace_ || definition.namespace}.#{pka.name || definition.name}" + end + end + end + + ::Thrift.register_canonical_name_extractor self + end + end + end + end +end diff --git a/lib/rb/lib/thrift/types/annotation/naming_constants.rb b/lib/rb/lib/thrift/types/annotation/naming/naming_constants.rb similarity index 81% rename from lib/rb/lib/thrift/types/annotation/naming_constants.rb rename to lib/rb/lib/thrift/types/annotation/naming/naming_constants.rb index 6bcccde02ad..e61f7ea212b 100644 --- a/lib/rb/lib/thrift/types/annotation/naming_constants.rb +++ b/lib/rb/lib/thrift/types/annotation/naming/naming_constants.rb @@ -5,7 +5,7 @@ # require 'thrift' -require 'naming_types' +require 'thrift/types/annotation/naming/naming_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/annotation/naming_types.rb b/lib/rb/lib/thrift/types/annotation/naming/naming_types.rb similarity index 79% rename from lib/rb/lib/thrift/types/annotation/naming_types.rb rename to lib/rb/lib/thrift/types/annotation/naming/naming_types.rb index 2b3e5d10d19..a0b26fde0a7 100644 --- a/lib/rb/lib/thrift/types/annotation/naming_types.rb +++ b/lib/rb/lib/thrift/types/annotation/naming/naming_types.rb @@ -54,20 +54,6 @@ def validate end end - - class CanonicalNameExtractor - class << self - def extract(definition) - definition.structured_annotations.select do |sa| - sa.is_a? PreviouslyKnownAs - end.map do |pka| - "#{pka.namespace_ || definition.namespace}.#{pka.name || definition.name}" - end - end - end - - ::Thrift.register_canonical_name_extractor self - end end end end diff --git a/lib/rb/lib/thrift/types/known/any.rb b/lib/rb/lib/thrift/types/known/any/any.rb similarity index 99% rename from lib/rb/lib/thrift/types/known/any.rb rename to lib/rb/lib/thrift/types/known/any/any.rb index 897685cc047..e4ff8e1b803 100644 --- a/lib/rb/lib/thrift/types/known/any.rb +++ b/lib/rb/lib/thrift/types/known/any/any.rb @@ -1,4 +1,4 @@ -require 'thrift/types/known/any_types' +require 'thrift/types/known/any/any_types' require 'json' require 'yaml' diff --git a/lib/rb/lib/thrift/types/known/any_constants.rb b/lib/rb/lib/thrift/types/known/any/any_constants.rb similarity index 84% rename from lib/rb/lib/thrift/types/known/any_constants.rb rename to lib/rb/lib/thrift/types/known/any/any_constants.rb index c4ec82a5d20..d15b66898ff 100644 --- a/lib/rb/lib/thrift/types/known/any_constants.rb +++ b/lib/rb/lib/thrift/types/known/any/any_constants.rb @@ -5,7 +5,7 @@ # require 'thrift' -require 'any_types' +require 'thrift/types/known/any/any_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/known/any_types.rb b/lib/rb/lib/thrift/types/known/any/any_types.rb similarity index 100% rename from lib/rb/lib/thrift/types/known/any_types.rb rename to lib/rb/lib/thrift/types/known/any/any_types.rb diff --git a/lib/rb/lib/thrift/types/known/duration.rb b/lib/rb/lib/thrift/types/known/duration/duration.rb similarity index 90% rename from lib/rb/lib/thrift/types/known/duration.rb rename to lib/rb/lib/thrift/types/known/duration/duration.rb index a2d1c1d6015..672bd230000 100644 --- a/lib/rb/lib/thrift/types/known/duration.rb +++ b/lib/rb/lib/thrift/types/known/duration/duration.rb @@ -1,4 +1,4 @@ -require 'thrift/types/known/duration_types' +require 'thrift/types/known/duration/duration_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/known/duration_constants.rb b/lib/rb/lib/thrift/types/known/duration/duration_constants.rb similarity index 81% rename from lib/rb/lib/thrift/types/known/duration_constants.rb rename to lib/rb/lib/thrift/types/known/duration/duration_constants.rb index e4c10c17a44..0bafaae3be1 100644 --- a/lib/rb/lib/thrift/types/known/duration_constants.rb +++ b/lib/rb/lib/thrift/types/known/duration/duration_constants.rb @@ -5,7 +5,7 @@ # require 'thrift' -require 'duration_types' +require 'thrift/types/known/duration/duration_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/known/duration_types.rb b/lib/rb/lib/thrift/types/known/duration/duration_types.rb similarity index 100% rename from lib/rb/lib/thrift/types/known/duration_types.rb rename to lib/rb/lib/thrift/types/known/duration/duration_types.rb diff --git a/lib/rb/lib/thrift/types/known/timestamp.rb b/lib/rb/lib/thrift/types/known/timestamp/timestamp.rb similarity index 90% rename from lib/rb/lib/thrift/types/known/timestamp.rb rename to lib/rb/lib/thrift/types/known/timestamp/timestamp.rb index f44796073d5..bceaba4d821 100644 --- a/lib/rb/lib/thrift/types/known/timestamp.rb +++ b/lib/rb/lib/thrift/types/known/timestamp/timestamp.rb @@ -1,4 +1,4 @@ -require 'thrift/types/known/timestamp_types' +require 'thrift/types/known/timestamp/timestamp_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/known/timestamp_constants.rb b/lib/rb/lib/thrift/types/known/timestamp/timestamp_constants.rb similarity index 81% rename from lib/rb/lib/thrift/types/known/timestamp_constants.rb rename to lib/rb/lib/thrift/types/known/timestamp/timestamp_constants.rb index 17b079bd333..aba91989042 100644 --- a/lib/rb/lib/thrift/types/known/timestamp_constants.rb +++ b/lib/rb/lib/thrift/types/known/timestamp/timestamp_constants.rb @@ -5,7 +5,7 @@ # require 'thrift' -require 'timestamp_types' +require 'thrift/types/known/timestamp/timestamp_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/known/timestamp_types.rb b/lib/rb/lib/thrift/types/known/timestamp/timestamp_types.rb similarity index 100% rename from lib/rb/lib/thrift/types/known/timestamp_types.rb rename to lib/rb/lib/thrift/types/known/timestamp/timestamp_types.rb diff --git a/lib/rb/lib/thrift/types/value.rb b/lib/rb/lib/thrift/types/value/value.rb similarity index 98% rename from lib/rb/lib/thrift/types/value.rb rename to lib/rb/lib/thrift/types/value/value.rb index f532a14d224..03bf2aa07fd 100644 --- a/lib/rb/lib/thrift/types/value.rb +++ b/lib/rb/lib/thrift/types/value/value.rb @@ -1,4 +1,4 @@ -require 'thrift/types/value_types' +require 'thrift/types/value/value_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/value_constants.rb b/lib/rb/lib/thrift/types/value/value_constants.rb similarity index 83% rename from lib/rb/lib/thrift/types/value_constants.rb rename to lib/rb/lib/thrift/types/value/value_constants.rb index 4a9ec5b899f..c3fda45a4b1 100644 --- a/lib/rb/lib/thrift/types/value_constants.rb +++ b/lib/rb/lib/thrift/types/value/value_constants.rb @@ -5,7 +5,7 @@ # require 'thrift' -require 'value_types' +require 'thrift/types/value/value_types' module Thrift module Types diff --git a/lib/rb/lib/thrift/types/value_types.rb b/lib/rb/lib/thrift/types/value/value_types.rb similarity index 100% rename from lib/rb/lib/thrift/types/value_types.rb rename to lib/rb/lib/thrift/types/value/value_types.rb