summaryrefslogtreecommitdiff
path: root/compiler/cpp/src/thrift/generate/t_go_generator.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cpp/src/thrift/generate/t_go_generator.h')
-rw-r--r--compiler/cpp/src/thrift/generate/t_go_generator.h329
1 files changed, 329 insertions, 0 deletions
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.h b/compiler/cpp/src/thrift/generate/t_go_generator.h
new file mode 100644
index 000000000..5080e1a0d
--- /dev/null
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.h
@@ -0,0 +1,329 @@
+/*
+ * 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_GO_GENERATOR_H
+#define T_GO_GENERATOR_H
+
+#include <fstream>
+#include <iostream>
+#include <limits>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "thrift/generate/t_generator.h"
+#include "thrift/platform.h"
+#include "thrift/version.h"
+#include <algorithm>
+#include <clocale>
+#include <sstream>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+using std::map;
+using std::ostream;
+using std::ostringstream;
+using std::string;
+using std::stringstream;
+using std::vector;
+
+static const string endl = "\n"; // avoid ostream << std::endl flushes
+
+const string DEFAULT_THRIFT_IMPORT = "github.com/apache/thrift/lib/go/thrift";
+static std::string package_flag;
+
+/**
+ * Go code generator.
+ */
+class t_go_generator : public t_generator {
+public:
+ t_go_generator(t_program* program,
+ const std::map<std::string, std::string>& parsed_options,
+ const std::string& option_string)
+ : t_generator(program) {
+ (void)option_string;
+ std::map<std::string, std::string>::const_iterator iter;
+
+ gen_thrift_import_ = DEFAULT_THRIFT_IMPORT;
+ gen_package_prefix_ = "";
+ package_flag = "";
+ read_write_private_ = false;
+ ignore_initialisms_ = false;
+ skip_remote_ = false;
+ for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
+ if (iter->first.compare("package_prefix") == 0) {
+ gen_package_prefix_ = (iter->second);
+ } else if (iter->first.compare("thrift_import") == 0) {
+ gen_thrift_import_ = (iter->second);
+ } else if (iter->first.compare("package") == 0) {
+ package_flag = (iter->second);
+ } else if (iter->first.compare("read_write_private") == 0) {
+ read_write_private_ = true;
+ } else if (iter->first.compare("ignore_initialisms") == 0) {
+ ignore_initialisms_ = true;
+ } else if( iter->first.compare("skip_remote") == 0) {
+ skip_remote_ = true;
+ } else {
+ throw "unknown option go:" + iter->first;
+ }
+ }
+
+ out_dir_base_ = "gen-go";
+ }
+
+ /**
+ * Init and close methods
+ */
+
+ void init_generator() override;
+ void close_generator() override;
+
+ /**
+ * Program-level generation functions
+ */
+
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
+
+ std::string render_const_value(t_type* type,
+ t_const_value* value,
+ const string& name,
+ bool opt = false);
+
+ /**
+ * Struct generation code
+ */
+
+ void generate_go_struct(t_struct* tstruct, bool is_exception);
+ void generate_go_struct_definition(std::ostream& out,
+ t_struct* tstruct,
+ bool is_xception = false,
+ bool is_result = false,
+ bool is_args = false);
+ void generate_go_struct_initializer(std::ostream& out,
+ t_struct* tstruct,
+ bool is_args_or_result = false);
+ void generate_isset_helpers(std::ostream& out,
+ t_struct* tstruct,
+ const string& tstruct_name,
+ bool is_result = false);
+ void generate_countsetfields_helper(std::ostream& out,
+ t_struct* tstruct,
+ const string& tstruct_name,
+ bool is_result = false);
+ void generate_go_struct_reader(std::ostream& out,
+ t_struct* tstruct,
+ const string& tstruct_name,
+ bool is_result = false);
+ void generate_go_struct_writer(std::ostream& out,
+ t_struct* tstruct,
+ const string& tstruct_name,
+ bool is_result = false,
+ bool uses_countsetfields = false);
+ void generate_go_struct_equals(std::ostream& out, t_struct* tstruct, const string& tstruct_name);
+ void generate_go_function_helpers(t_function* tfunction);
+ void get_publicized_name_and_def_value(t_field* tfield,
+ string* OUT_pub_name,
+ t_const_value** OUT_def_value) const;
+
+ /**
+ * Service-level generation functions
+ */
+
+ void generate_service_helpers(t_service* tservice);
+ void generate_service_interface(t_service* tservice);
+ void generate_service_client(t_service* tservice);
+ void generate_service_remote(t_service* tservice);
+ void generate_service_server(t_service* tservice);
+ void generate_process_function(t_service* tservice, t_function* tfunction);
+
+ /**
+ * Serialization constructs
+ */
+
+ void generate_deserialize_field(std::ostream& out,
+ t_field* tfield,
+ bool declare,
+ std::string prefix = "",
+ bool inclass = false,
+ bool coerceData = false,
+ bool inkey = false,
+ bool in_container = false);
+
+ void generate_deserialize_struct(std::ostream& out,
+ t_struct* tstruct,
+ bool is_pointer_field,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_container(std::ostream& out,
+ t_type* ttype,
+ bool pointer_field,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_set_element(std::ostream& out,
+ t_set* tset,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_map_element(std::ostream& out,
+ t_map* tmap,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_list_element(std::ostream& out,
+ t_list* tlist,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_serialize_field(std::ostream& out,
+ t_field* tfield,
+ std::string prefix = "",
+ bool inkey = false);
+
+ void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+
+ void generate_serialize_container(std::ostream& out,
+ t_type* ttype,
+ bool pointer_field,
+ std::string prefix = "");
+
+ void generate_serialize_map_element(std::ostream& out,
+ t_map* tmap,
+ std::string kiter,
+ std::string viter);
+
+ void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
+
+ void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
+
+ void generate_go_equals(std::ostream& out, t_type* ttype, string tgt, string src);
+
+ void generate_go_equals_struct(std::ostream& out, t_type* ttype, string tgt, string src);
+
+ void generate_go_equals_container(std::ostream& out, t_type* ttype, string tgt, string src);
+
+ void generate_go_docstring(std::ostream& out, t_struct* tstruct);
+
+ void generate_go_docstring(std::ostream& out, t_function* tfunction);
+
+ void generate_go_docstring(std::ostream& out,
+ t_doc* tdoc,
+ t_struct* tstruct,
+ const char* subheader);
+
+ void generate_go_docstring(std::ostream& out, t_doc* tdoc);
+
+ void parse_go_tags(map<string, string>* tags, const string in);
+
+ /**
+ * Helper rendering functions
+ */
+
+ std::string go_autogen_comment();
+ std::string go_package();
+ std::string go_imports_begin(bool consts);
+ std::string go_imports_end();
+ std::string render_includes(bool consts);
+ std::string render_included_programs(string& unused_protection);
+ std::string render_program_import(const t_program* program, string& unused_protection);
+ std::string render_system_packages(std::vector<string>& system_packages);
+ std::string render_import_protection();
+ std::string render_fastbinary_includes();
+ std::string declare_argument(t_field* tfield);
+ std::string render_field_initial_value(t_field* tfield, const string& name, bool optional_field);
+ std::string type_name(t_type* ttype);
+ std::string module_name(t_type* ttype);
+ std::string function_signature(t_function* tfunction, std::string prefix = "");
+ std::string function_signature_if(t_function* tfunction,
+ std::string prefix = "",
+ bool addError = false);
+ std::string argument_list(t_struct* tstruct);
+ std::string type_to_enum(t_type* ttype);
+ std::string type_to_go_type(t_type* ttype);
+ std::string type_to_go_type_with_opt(t_type* ttype, bool optional_field);
+ std::string type_to_go_key_type(t_type* ttype);
+ std::string type_to_spec_args(t_type* ttype);
+
+ void indent_up() { t_generator::indent_up(); }
+ void indent_down() { t_generator::indent_down(); }
+ std::string indent() { return t_generator::indent(); }
+ std::ostream& indent(std::ostream& os) { return t_generator::indent(os); }
+
+ static std::string get_real_go_module(const t_program* program) {
+
+ if (!package_flag.empty()) {
+ return package_flag;
+ }
+ std::string real_module = program->get_namespace("go");
+ if (!real_module.empty()) {
+ return real_module;
+ }
+
+ return lowercase(program->get_name());
+ }
+
+ static bool is_pointer_field(t_field* tfield, bool in_container = false);
+
+private:
+ std::string gen_package_prefix_;
+ std::string gen_thrift_import_;
+ bool read_write_private_;
+ bool ignore_initialisms_;
+ bool skip_remote_;
+
+ /**
+ * File streams
+ */
+
+ ofstream_with_content_based_conditional_update f_types_;
+ std::string f_types_name_;
+ ofstream_with_content_based_conditional_update f_consts_;
+ std::string f_consts_name_;
+ std::stringstream f_const_values_;
+
+ std::string package_name_;
+ std::string package_dir_;
+ std::unordered_map<std::string, std::string> package_identifiers_;
+ std::set<std::string> package_identifiers_set_;
+ std::string read_method_name_;
+ std::string write_method_name_;
+ std::string equals_method_name_;
+
+ std::set<std::string> commonInitialisms;
+
+ std::string camelcase(const std::string& value) const;
+ void fix_common_initialism(std::string& value, int i) const;
+ std::string publicize(const std::string& value, bool is_args_or_result = false) const;
+ std::string publicize(const std::string& value,
+ bool is_args_or_result,
+ const std::string& service_name) const;
+ std::string privatize(const std::string& value) const;
+ std::string new_prefix(const std::string& value) const;
+ static std::string variable_name_to_go_name(const std::string& value);
+ static bool omit_initialization(t_field* tfield);
+};
+
+#endif