LIBS: updated flatbuffers
parent
b1eaaffb7d
commit
42d0b14d96
|
@ -19,7 +19,6 @@
|
|||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
#include "bfbs_gen_lua.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
@ -65,7 +64,7 @@ const static FlatCOption options[] = {
|
|||
{ "I", "", "PATH", "Search for includes in the specified path." },
|
||||
{ "M", "", "", "Print make rules for generated files." },
|
||||
{ "", "version", "", "Print the version number of flatc and exit." },
|
||||
{ "", "help", "", "Prints this help text and exit." },
|
||||
{ "h", "help", "", "Prints this help text and exit." },
|
||||
{ "", "string-json", "",
|
||||
"Strict JSON: field names must be / will be quoted, no trailing commas in "
|
||||
"tables/vectors." },
|
||||
|
@ -184,6 +183,8 @@ const static FlatCOption options[] = {
|
|||
{ "", "reflect-types", "",
|
||||
"Add minimal type reflection to code generation." },
|
||||
{ "", "reflect-names", "", "Add minimal type/name reflection." },
|
||||
{ "", "rust-serialize", "",
|
||||
"Implement serde::Serialize on generated Rust types." },
|
||||
{ "", "root-type", "T", "Select or override the default root_type." },
|
||||
{ "", "require-explicit-ids", "",
|
||||
"When parsing schemas, require explicit ids (id: x)." },
|
||||
|
@ -199,6 +200,7 @@ const static FlatCOption options[] = {
|
|||
"Used with \"binary\" and \"json\" options, it generates data using "
|
||||
"schema-less FlexBuffers." },
|
||||
{ "", "no-warnings", "", "Inhibit all warnings messages." },
|
||||
{ "", "warning-as-errors", "", "Treat all warnings as errors." },
|
||||
{ "", "cs-global-alias", "",
|
||||
"Prepend \"global::\" to all user generated csharp classes and "
|
||||
"structs." },
|
||||
|
@ -268,6 +270,35 @@ static void AppendOption(std::stringstream &ss, const FlatCOption &option,
|
|||
ss << "\n";
|
||||
}
|
||||
|
||||
static void AppendShortOption(std::stringstream &ss,
|
||||
const FlatCOption &option) {
|
||||
if (!option.short_opt.empty()) {
|
||||
ss << "-" << option.short_opt;
|
||||
if (!option.long_opt.empty()) { ss << "|"; }
|
||||
}
|
||||
if (!option.long_opt.empty()) { ss << "--" << option.long_opt; }
|
||||
}
|
||||
|
||||
std::string FlatCompiler::GetShortUsageString(const char *program_name) const {
|
||||
std::stringstream ss;
|
||||
ss << "Usage: " << program_name << " [";
|
||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||
const Generator &g = params_.generators[i];
|
||||
AppendShortOption(ss, g.option);
|
||||
ss << ", ";
|
||||
}
|
||||
for (const FlatCOption &option : options) {
|
||||
AppendShortOption(ss, option);
|
||||
ss << ", ";
|
||||
}
|
||||
ss.seekp(-2, ss.cur);
|
||||
ss << "]... FILE... [-- FILE...]";
|
||||
std::string help = ss.str();
|
||||
std::stringstream ss_textwrap;
|
||||
AppendTextWrappedString(ss_textwrap, help, 80, 0);
|
||||
return ss_textwrap.str();
|
||||
}
|
||||
|
||||
std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
||||
std::stringstream ss;
|
||||
ss << "Usage: " << program_name << " [OPTION]... FILE... [-- FILE...]\n";
|
||||
|
@ -299,6 +330,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (argc <= 1) { Error("Need to provide at least one argument."); }
|
||||
|
||||
flatbuffers::IDLOptions opts;
|
||||
std::string output_path;
|
||||
|
||||
|
@ -453,7 +486,7 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||
} else if (arg == "--version") {
|
||||
printf("flatc version %s\n", FLATC_VERSION());
|
||||
exit(0);
|
||||
} else if (arg == "--help") {
|
||||
} else if (arg == "--help" || arg == "-h") {
|
||||
printf("%s\n", GetUsageString(program_name).c_str());
|
||||
exit(0);
|
||||
} else if (arg == "--grpc") {
|
||||
|
@ -468,6 +501,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||
opts.mini_reflect = IDLOptions::kTypes;
|
||||
} else if (arg == "--reflect-names") {
|
||||
opts.mini_reflect = IDLOptions::kTypesAndNames;
|
||||
} else if (arg == "--rust-serialize") {
|
||||
opts.rust_serialize = true;
|
||||
} else if (arg == "--require-explicit-ids") {
|
||||
opts.require_explicit_ids = true;
|
||||
} else if (arg == "--root-type") {
|
||||
|
@ -496,6 +531,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||
opts.gen_jvmstatic = true;
|
||||
} else if (arg == "--no-warnings") {
|
||||
opts.no_warnings = true;
|
||||
} else if (arg == "--warnings-as-errors") {
|
||||
opts.warnings_as_errors = true;
|
||||
} else if (arg == "--cpp-std") {
|
||||
if (++argi >= argc)
|
||||
Error("missing C++ standard specification" + arg, true);
|
||||
|
@ -729,9 +766,19 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||
// in any files coming up next.
|
||||
parser->MarkGenerated();
|
||||
}
|
||||
if (opts.lang_to_generate & IDLOptions::kRust && !parser->opts.one_file) {
|
||||
GenerateRustModuleRootFile(*parser, output_path);
|
||||
|
||||
// Once all the files have been parsed, run any generators Parsing Completed
|
||||
// function for final generation.
|
||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||
if (generator_enabled[i] &&
|
||||
params_.generators[i].parsing_completed != nullptr) {
|
||||
if (!params_.generators[i].parsing_completed(*parser, output_path)) {
|
||||
Error("failed running parsing completed for " +
|
||||
std::string(params_.generators[i].lang_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
|
||||
#include "bfbs_gen_lua.h"
|
||||
|
@ -27,16 +28,16 @@ static void Warn(const flatbuffers::FlatCompiler *flatc,
|
|||
const std::string &warn, bool show_exe_name) {
|
||||
(void)flatc;
|
||||
if (show_exe_name) { printf("%s: ", g_program_name); }
|
||||
fprintf(stderr, "warning:\n %s\n\n", warn.c_str());
|
||||
fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str());
|
||||
}
|
||||
|
||||
static void Error(const flatbuffers::FlatCompiler *flatc,
|
||||
const std::string &err, bool usage, bool show_exe_name) {
|
||||
if (show_exe_name) { printf("%s: ", g_program_name); }
|
||||
if (usage && flatc) {
|
||||
fprintf(stderr, "%s\n", flatc->GetUsageString(g_program_name).c_str());
|
||||
fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
|
||||
}
|
||||
fprintf(stderr, "error:\n %s\n\n", err.c_str());
|
||||
fprintf(stderr, "\nerror:\n %s\n\n", err.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -67,82 +68,83 @@ int main(int argc, const char *argv[]) {
|
|||
flatbuffers::FlatCOption{
|
||||
"b", "binary", "",
|
||||
"Generate wire format binaries for any data definitions" },
|
||||
flatbuffers::BinaryMakeRule, nullptr },
|
||||
flatbuffers::BinaryMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateTextFile, "text", false, nullptr,
|
||||
flatbuffers::IDLOptions::kJson,
|
||||
flatbuffers::FlatCOption{
|
||||
"t", "json", "", "Generate text output for any data definitions" },
|
||||
|
||||
flatbuffers::TextMakeRule, nullptr },
|
||||
flatbuffers::TextMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateCPP, "C++", true, flatbuffers::GenerateCppGRPC,
|
||||
flatbuffers::IDLOptions::kCpp,
|
||||
flatbuffers::FlatCOption{ "c", "cpp", "",
|
||||
"Generate C++ headers for tables/structs" },
|
||||
flatbuffers::CPPMakeRule, nullptr },
|
||||
flatbuffers::CPPMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateGo, "Go", true, flatbuffers::GenerateGoGRPC,
|
||||
flatbuffers::IDLOptions::kGo,
|
||||
flatbuffers::FlatCOption{ "g", "go", "",
|
||||
"Generate Go files for tables/structs" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateJava, "Java", true, flatbuffers::GenerateJavaGRPC,
|
||||
flatbuffers::IDLOptions::kJava,
|
||||
flatbuffers::FlatCOption{ "j", "java", "",
|
||||
"Generate Java classes for tables/structs" },
|
||||
flatbuffers::JavaMakeRule, nullptr },
|
||||
flatbuffers::JavaMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateDart, "Dart", true, nullptr,
|
||||
flatbuffers::IDLOptions::kDart,
|
||||
flatbuffers::FlatCOption{ "d", "dart", "",
|
||||
"Generate Dart classes for tables/structs" },
|
||||
flatbuffers::DartMakeRule, nullptr },
|
||||
flatbuffers::DartMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateTS, "TypeScript", true, flatbuffers::GenerateTSGRPC,
|
||||
flatbuffers::IDLOptions::kTs,
|
||||
flatbuffers::FlatCOption{ "T", "ts", "",
|
||||
"Generate TypeScript code for tables/structs" },
|
||||
flatbuffers::TSMakeRule, nullptr },
|
||||
flatbuffers::TSMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateCSharp, "C#", true, nullptr,
|
||||
flatbuffers::IDLOptions::kCSharp,
|
||||
flatbuffers::FlatCOption{ "n", "csharp", "",
|
||||
"Generate C# classes for tables/structs" },
|
||||
flatbuffers::CSharpMakeRule, nullptr },
|
||||
flatbuffers::CSharpMakeRule, nullptr, nullptr },
|
||||
{ flatbuffers::GeneratePython, "Python", true,
|
||||
flatbuffers::GeneratePythonGRPC, flatbuffers::IDLOptions::kPython,
|
||||
flatbuffers::FlatCOption{ "p", "python", "",
|
||||
"Generate Python files for tables/structs" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateLobster, "Lobster", true, nullptr,
|
||||
flatbuffers::IDLOptions::kLobster,
|
||||
flatbuffers::FlatCOption{ "", "lobster", "",
|
||||
"Generate Lobster files for tables/structs" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateLua, "Lua", true, nullptr,
|
||||
flatbuffers::IDLOptions::kLua,
|
||||
flatbuffers::FlatCOption{ "l", "lua", "",
|
||||
"Generate Lua files for tables/structs" },
|
||||
nullptr, bfbs_gen_lua.get() },
|
||||
nullptr, bfbs_gen_lua.get(), nullptr },
|
||||
{ flatbuffers::GenerateRust, "Rust", true, nullptr,
|
||||
flatbuffers::IDLOptions::kRust,
|
||||
flatbuffers::FlatCOption{ "r", "rust", "",
|
||||
"Generate Rust files for tables/structs" },
|
||||
flatbuffers::RustMakeRule, nullptr },
|
||||
flatbuffers::RustMakeRule, nullptr,
|
||||
flatbuffers::GenerateRustModuleRootFile },
|
||||
{ flatbuffers::GeneratePhp, "PHP", true, nullptr,
|
||||
flatbuffers::IDLOptions::kPhp,
|
||||
flatbuffers::FlatCOption{ "", "php", "",
|
||||
"Generate PHP files for tables/structs" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateKotlin, "Kotlin", true, nullptr,
|
||||
flatbuffers::IDLOptions::kKotlin,
|
||||
flatbuffers::FlatCOption{ "", "kotlin", "",
|
||||
"Generate Kotlin classes for tables/structs" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateJsonSchema, "JsonSchema", true, nullptr,
|
||||
flatbuffers::IDLOptions::kJsonSchema,
|
||||
flatbuffers::FlatCOption{ "", "jsonschema", "", "Generate Json schema" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
{ flatbuffers::GenerateSwift, "swift", true, flatbuffers::GenerateSwiftGRPC,
|
||||
flatbuffers::IDLOptions::kSwift,
|
||||
flatbuffers::FlatCOption{ "", "swift", "",
|
||||
"Generate Swift files for tables/structs" },
|
||||
nullptr, nullptr },
|
||||
nullptr, nullptr, nullptr },
|
||||
};
|
||||
|
||||
flatbuffers::FlatCompiler::InitParams params;
|
||||
|
|
|
@ -283,6 +283,9 @@ class CppGenerator : public BaseGenerator {
|
|||
code_ += "#pragma clang system_header\n\n";
|
||||
}
|
||||
|
||||
code_ += "#include \"flatbuffers/flatbuffers.h\"";
|
||||
code_ += "";
|
||||
|
||||
SetNameSpace(struct_def.defined_namespace);
|
||||
auto name = Name(struct_def);
|
||||
code_.SetValue("STRUCT_NAME", name);
|
||||
|
@ -532,6 +535,16 @@ class CppGenerator : public BaseGenerator {
|
|||
code_ += " buf, {{STRUCT_NAME}}Identifier());";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
// Check if a size-prefixed buffer has the identifier.
|
||||
code_ += "inline \\";
|
||||
code_ +=
|
||||
"bool SizePrefixed{{STRUCT_NAME}}BufferHasIdentifier(const void "
|
||||
"*buf) {";
|
||||
code_ += " return flatbuffers::BufferHasIdentifier(";
|
||||
code_ += " buf, {{STRUCT_NAME}}Identifier(), true);";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
// The root verifier.
|
||||
|
@ -658,8 +671,9 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
|
||||
bool VectorElementUserFacing(const Type &type) const {
|
||||
return opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
|
||||
IsEnum(type);
|
||||
return (opts_.scoped_enums && IsEnum(type)) ||
|
||||
(opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
|
||||
IsEnum(type));
|
||||
}
|
||||
|
||||
void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
|
||||
|
@ -799,7 +813,7 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
|
||||
std::string GenTypeNative(const Type &type, bool invector,
|
||||
const FieldDef &field) {
|
||||
const FieldDef &field, bool forcopy = false) {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING: {
|
||||
return NativeString(&field);
|
||||
|
@ -820,15 +834,14 @@ class CppGenerator : public BaseGenerator {
|
|||
if (IsStruct(type)) {
|
||||
auto native_type = type.struct_def->attributes.Lookup("native_type");
|
||||
if (native_type) { type_name = native_type->constant; }
|
||||
if (invector || field.native_inline) {
|
||||
if (invector || field.native_inline || forcopy) {
|
||||
return type_name;
|
||||
} else {
|
||||
return GenTypeNativePtr(type_name, &field, false);
|
||||
}
|
||||
} else {
|
||||
return GenTypeNativePtr(
|
||||
WrapNativeNameInNameSpace(*type.struct_def, opts_), &field,
|
||||
false);
|
||||
const auto nn = WrapNativeNameInNameSpace(*type.struct_def, opts_);
|
||||
return forcopy ? nn : GenTypeNativePtr(nn, &field, false);
|
||||
}
|
||||
}
|
||||
case BASE_TYPE_UNION: {
|
||||
|
@ -1472,7 +1485,7 @@ class CppGenerator : public BaseGenerator {
|
|||
if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (ev.union_type.struct_def->fixed) {
|
||||
code_.SetValue("ALIGN",
|
||||
NumToString(ev.union_type.struct_def->minalign));
|
||||
NumToString(ev.union_type.struct_def->minalign));
|
||||
code_ +=
|
||||
" return verifier.VerifyField<{{TYPE}}>("
|
||||
"static_cast<const uint8_t *>(obj), 0, {{ALIGN}});";
|
||||
|
@ -1590,7 +1603,8 @@ class CppGenerator : public BaseGenerator {
|
|||
code_.SetValue("TYPE", GetUnionElement(ev, true, opts_));
|
||||
code_ += " case {{LABEL}}: {";
|
||||
bool copyable = true;
|
||||
if (ev.union_type.base_type == BASE_TYPE_STRUCT &&
|
||||
if (opts_.g_cpp_std < cpp::CPP_STD_11 &&
|
||||
ev.union_type.base_type == BASE_TYPE_STRUCT &&
|
||||
!ev.union_type.struct_def->fixed) {
|
||||
// Don't generate code to copy if table is not copyable.
|
||||
// TODO(wvo): make tables copyable instead.
|
||||
|
@ -1793,13 +1807,50 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns true if `struct_def` needs a copy constructor and assignment
|
||||
// operator because it has one or more table members, struct members with a
|
||||
// custom cpp_type and non-naked pointer type, or vector members of those.
|
||||
bool NeedsCopyCtorAssignOp(const StructDef &struct_def) {
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
const auto &type = field.value.type;
|
||||
if (field.deprecated) continue;
|
||||
if (type.base_type == BASE_TYPE_STRUCT) {
|
||||
const auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
|
||||
const bool is_ptr = !(IsStruct(type) && field.native_inline) ||
|
||||
(cpp_type && cpp_ptr_type->constant != "naked");
|
||||
if (is_ptr) { return true; }
|
||||
} else if (IsVector(type)) {
|
||||
const auto vec_type = type.VectorType();
|
||||
if (vec_type.base_type == BASE_TYPE_UTYPE) continue;
|
||||
const auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
|
||||
const bool is_ptr =
|
||||
(vec_type.base_type == BASE_TYPE_STRUCT && !IsStruct(vec_type)) ||
|
||||
(cpp_type && cpp_ptr_type->constant != "naked");
|
||||
if (is_ptr) { return true; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate the default constructor for this struct. Properly initialize all
|
||||
// scalar members with default values.
|
||||
void GenDefaultConstructor(const StructDef &struct_def) {
|
||||
code_.SetValue("NATIVE_NAME",
|
||||
NativeName(Name(struct_def), &struct_def, opts_));
|
||||
// In >= C++11, default member initializers are generated.
|
||||
if (opts_.g_cpp_std >= cpp::CPP_STD_11) { return; }
|
||||
// In >= C++11, default member initializers are generated. To allow for
|
||||
// aggregate initialization, do not emit a default constructor at all, with
|
||||
// the exception of types that need a copy/move ctors and assignment
|
||||
// operators.
|
||||
if (opts_.g_cpp_std >= cpp::CPP_STD_11) {
|
||||
if (NeedsCopyCtorAssignOp(struct_def)) {
|
||||
code_ += " {{NATIVE_NAME}}() = default;";
|
||||
}
|
||||
return;
|
||||
}
|
||||
std::string initializer_list;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
|
@ -1843,6 +1894,125 @@ class CppGenerator : public BaseGenerator {
|
|||
code_ += " }";
|
||||
}
|
||||
|
||||
// Generate the >= C++11 copy/move constructor and assignment operator
|
||||
// declarations if required. Tables that are default-copyable do not get
|
||||
// user-provided copy/move constructors and assignment operators so they
|
||||
// remain aggregates.
|
||||
void GenCopyMoveCtorAndAssigOpDecls(const StructDef &struct_def) {
|
||||
if (opts_.g_cpp_std < cpp::CPP_STD_11) return;
|
||||
if (!NeedsCopyCtorAssignOp(struct_def)) return;
|
||||
code_.SetValue("NATIVE_NAME",
|
||||
NativeName(Name(struct_def), &struct_def, opts_));
|
||||
code_ += " {{NATIVE_NAME}}(const {{NATIVE_NAME}} &o);";
|
||||
code_ +=
|
||||
" {{NATIVE_NAME}}({{NATIVE_NAME}}&&) FLATBUFFERS_NOEXCEPT = "
|
||||
"default;";
|
||||
code_ +=
|
||||
" {{NATIVE_NAME}} &operator=({{NATIVE_NAME}} o) FLATBUFFERS_NOEXCEPT;";
|
||||
}
|
||||
|
||||
// Generate the >= C++11 copy constructor and assignment operator definitions.
|
||||
void GenCopyCtorAssignOpDefs(const StructDef &struct_def) {
|
||||
if (opts_.g_cpp_std < cpp::CPP_STD_11) return;
|
||||
if (!NeedsCopyCtorAssignOp(struct_def)) return;
|
||||
std::string initializer_list;
|
||||
std::string vector_copies;
|
||||
std::string swaps;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
const auto &type = field.value.type;
|
||||
if (field.deprecated || type.base_type == BASE_TYPE_UTYPE) continue;
|
||||
if (type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
||||
const auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
|
||||
auto type_name = (cpp_type) ? cpp_type->constant
|
||||
: GenTypeNative(type, /*invector*/ false,
|
||||
field, /*forcopy*/ true);
|
||||
const bool is_ptr = !(IsStruct(type) && field.native_inline) ||
|
||||
(cpp_type && cpp_ptr_type->constant != "naked");
|
||||
CodeWriter cw;
|
||||
cw.SetValue("FIELD", Name(field));
|
||||
cw.SetValue("TYPE", type_name);
|
||||
if (is_ptr) {
|
||||
cw +=
|
||||
"{{FIELD}}((o.{{FIELD}}) ? new {{TYPE}}(*o.{{FIELD}}) : "
|
||||
"nullptr)\\";
|
||||
initializer_list += cw.ToString();
|
||||
} else {
|
||||
cw += "{{FIELD}}(o.{{FIELD}})\\";
|
||||
initializer_list += cw.ToString();
|
||||
}
|
||||
} else if (IsVector(type)) {
|
||||
const auto vec_type = type.VectorType();
|
||||
if (vec_type.base_type == BASE_TYPE_UTYPE) continue;
|
||||
const auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
|
||||
const auto type_name = (cpp_type)
|
||||
? cpp_type->constant
|
||||
: GenTypeNative(vec_type, /*invector*/ true,
|
||||
field, /*forcopy*/ true);
|
||||
const bool is_ptr =
|
||||
(vec_type.base_type == BASE_TYPE_STRUCT && !IsStruct(vec_type)) ||
|
||||
(cpp_type && cpp_ptr_type->constant != "naked");
|
||||
CodeWriter cw(" ");
|
||||
cw.SetValue("FIELD", Name(field));
|
||||
cw.SetValue("TYPE", type_name);
|
||||
if (is_ptr) {
|
||||
// Use emplace_back to construct the potentially-smart pointer element
|
||||
// from a raw pointer to a new-allocated copy.
|
||||
cw.IncrementIdentLevel();
|
||||
cw += "{{FIELD}}.reserve(o.{{FIELD}}.size());";
|
||||
cw +=
|
||||
"for (const auto &v : o.{{FIELD}}) { "
|
||||
"{{FIELD}}.emplace_back((v) ? new {{TYPE}}(*v) : nullptr); }";
|
||||
vector_copies += cw.ToString();
|
||||
} else {
|
||||
// For non-pointer elements, use std::vector's copy constructor in the
|
||||
// initializer list. This will yield better performance than an insert
|
||||
// range loop for trivially-copyable element types.
|
||||
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
||||
cw += "{{FIELD}}(o.{{FIELD}})\\";
|
||||
initializer_list += cw.ToString();
|
||||
}
|
||||
} else {
|
||||
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
||||
CodeWriter cw;
|
||||
cw.SetValue("FIELD", Name(field));
|
||||
cw += "{{FIELD}}(o.{{FIELD}})\\";
|
||||
initializer_list += cw.ToString();
|
||||
}
|
||||
{
|
||||
if (!swaps.empty()) { swaps += "\n "; }
|
||||
CodeWriter cw;
|
||||
cw.SetValue("FIELD", Name(field));
|
||||
cw += "std::swap({{FIELD}}, o.{{FIELD}});\\";
|
||||
swaps += cw.ToString();
|
||||
}
|
||||
}
|
||||
if (!initializer_list.empty()) {
|
||||
initializer_list = "\n : " + initializer_list;
|
||||
}
|
||||
if (!swaps.empty()) { swaps = " " + swaps; }
|
||||
|
||||
code_.SetValue("NATIVE_NAME",
|
||||
NativeName(Name(struct_def), &struct_def, opts_));
|
||||
code_.SetValue("INIT_LIST", initializer_list);
|
||||
code_.SetValue("VEC_COPY", vector_copies);
|
||||
code_.SetValue("SWAPS", swaps);
|
||||
|
||||
code_ +=
|
||||
"inline {{NATIVE_NAME}}::{{NATIVE_NAME}}(const {{NATIVE_NAME}} &o)"
|
||||
"{{INIT_LIST}} {";
|
||||
code_ += "{{VEC_COPY}}}\n";
|
||||
code_ +=
|
||||
"inline {{NATIVE_NAME}} &{{NATIVE_NAME}}::operator="
|
||||
"({{NATIVE_NAME}} o) FLATBUFFERS_NOEXCEPT {";
|
||||
code_ += "{{SWAPS}}";
|
||||
code_ += " return *this;\n}\n";
|
||||
}
|
||||
|
||||
void GenCompareOperator(const StructDef &struct_def,
|
||||
std::string accessSuffix = "") {
|
||||
std::string compare_op;
|
||||
|
@ -1855,7 +2025,7 @@ class CppGenerator : public BaseGenerator {
|
|||
field.value.type.element != BASE_TYPE_UTYPE)) {
|
||||
if (!compare_op.empty()) { compare_op += " &&\n "; }
|
||||
auto accessor = Name(field) + accessSuffix;
|
||||
if (struct_def.fixed ||
|
||||
if (struct_def.fixed || field.native_inline ||
|
||||
field.value.type.base_type != BASE_TYPE_STRUCT) {
|
||||
compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
|
||||
} else {
|
||||
|
@ -1931,6 +2101,7 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
GenOperatorNewDelete(struct_def);
|
||||
GenDefaultConstructor(struct_def);
|
||||
GenCopyMoveCtorAndAssigOpDecls(struct_def);
|
||||
code_ += "};";
|
||||
code_ += "";
|
||||
}
|
||||
|
@ -1954,8 +2125,9 @@ class CppGenerator : public BaseGenerator {
|
|||
code_.SetValue("OFFSET", GenFieldOffsetName(field));
|
||||
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) {
|
||||
code_.SetValue("ALIGN", NumToString(InlineAlignment(field.value.type)));
|
||||
code_ += "{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, "
|
||||
"{{OFFSET}}, {{ALIGN}})\\";
|
||||
code_ +=
|
||||
"{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, "
|
||||
"{{OFFSET}}, {{ALIGN}})\\";
|
||||
} else {
|
||||
code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\";
|
||||
}
|
||||
|
@ -2007,11 +2179,13 @@ class CppGenerator : public BaseGenerator {
|
|||
if (!nfn.empty()) {
|
||||
code_.SetValue("CPP_NAME", nfn);
|
||||
// FIXME: file_identifier.
|
||||
code_ += "{{PRE}}verifier.VerifyNestedFlatBuffer<{{CPP_NAME}}>"
|
||||
"({{NAME}}(), nullptr)\\";
|
||||
code_ +=
|
||||
"{{PRE}}verifier.VerifyNestedFlatBuffer<{{CPP_NAME}}>"
|
||||
"({{NAME}}(), nullptr)\\";
|
||||
} else if (field.flexbuffer) {
|
||||
code_ += "{{PRE}}flexbuffers::VerifyNestedFlexBuffer"
|
||||
"({{NAME}}(), verifier)\\";
|
||||
code_ +=
|
||||
"{{PRE}}flexbuffers::VerifyNestedFlexBuffer"
|
||||
"({{NAME}}(), verifier)\\";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2048,7 +2222,8 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
// Returns {field<val: -1, field==val: 0, field>val: +1}.
|
||||
code_.SetValue("KEY_TYPE", type);
|
||||
code_ += " int KeyCompareWithValue({{KEY_TYPE}} _{{FIELD_NAME}}) const {";
|
||||
code_ +=
|
||||
" int KeyCompareWithValue({{KEY_TYPE}} _{{FIELD_NAME}}) const {";
|
||||
code_ +=
|
||||
" return static_cast<int>({{FIELD_NAME}}() > _{{FIELD_NAME}}) - "
|
||||
"static_cast<int>({{FIELD_NAME}}() < _{{FIELD_NAME}});";
|
||||
|
@ -3109,6 +3284,9 @@ class CppGenerator : public BaseGenerator {
|
|||
NativeName(Name(struct_def), &struct_def, opts_));
|
||||
|
||||
if (opts_.generate_object_based_api) {
|
||||
// Generate the >= C++11 copy ctor and assignment operator definitions.
|
||||
GenCopyCtorAssignOpDefs(struct_def);
|
||||
|
||||
// Generate the X::UnPack() method.
|
||||
code_ +=
|
||||
"inline " + TableUnPackSignature(struct_def, false, opts_) + " {";
|
||||
|
|
|
@ -738,11 +738,8 @@ class PythonGenerator : public BaseGenerator {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_UNION:
|
||||
GetUnionField(struct_def, field, code_ptr);
|
||||
break;
|
||||
default:
|
||||
FLATBUFFERS_ASSERT(0);
|
||||
case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break;
|
||||
default: FLATBUFFERS_ASSERT(0);
|
||||
}
|
||||
}
|
||||
if (IsVector(field.value.type) || IsArray(field.value.type)) {
|
||||
|
@ -913,14 +910,9 @@ class PythonGenerator : public BaseGenerator {
|
|||
import_list->insert("import " + package_reference);
|
||||
}
|
||||
break;
|
||||
case BASE_TYPE_STRING:
|
||||
field_type += "str";
|
||||
break;
|
||||
case BASE_TYPE_NONE:
|
||||
field_type += "None";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case BASE_TYPE_STRING: field_type += "str"; break;
|
||||
case BASE_TYPE_NONE: field_type += "None"; break;
|
||||
default: break;
|
||||
}
|
||||
field_types += field_type + separator_string;
|
||||
}
|
||||
|
@ -1253,8 +1245,7 @@ class PythonGenerator : public BaseGenerator {
|
|||
GenUnPackForScalarVector(struct_def, field, &code);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GenUnPackForScalar(struct_def, field, &code);
|
||||
default: GenUnPackForScalar(struct_def, field, &code);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,11 @@ bool IsOptionalToBuilder(const FieldDef &field) {
|
|||
|
||||
bool GenerateRustModuleRootFile(const Parser &parser,
|
||||
const std::string &output_dir) {
|
||||
if (parser.opts.one_file) {
|
||||
// Don't generate a root file when generating one file. This isn't an error
|
||||
// so return true.
|
||||
return true;
|
||||
}
|
||||
// We gather the symbols into a tree of namespaces (which are rust mods) and
|
||||
// generate a file that gathers them all.
|
||||
struct Module {
|
||||
|
@ -384,6 +389,11 @@ class RustGenerator : public BaseGenerator {
|
|||
code_ += "extern crate flatbuffers;";
|
||||
code_ += "use std::mem;";
|
||||
code_ += "use std::cmp::Ordering;";
|
||||
if (parser_.opts.rust_serialize) {
|
||||
code_ += "extern crate serde;";
|
||||
code_ +=
|
||||
"use self::serde::ser::{Serialize, Serializer, SerializeStruct};";
|
||||
}
|
||||
code_ += "use self::flatbuffers::{EndianScalar, Follow};";
|
||||
code_ += "use super::*;";
|
||||
cur_name_space_ = symbol.defined_namespace;
|
||||
|
@ -842,6 +852,27 @@ class RustGenerator : public BaseGenerator {
|
|||
code_.SetValue("INTO_BASE", "self.0");
|
||||
}
|
||||
|
||||
// Implement serde::Serialize
|
||||
if (parser_.opts.rust_serialize) {
|
||||
code_ += "impl Serialize for {{ENUM_NAME}} {";
|
||||
code_ +=
|
||||
" fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>";
|
||||
code_ += " where";
|
||||
code_ += " S: Serializer,";
|
||||
code_ += " {";
|
||||
if (IsBitFlagsEnum(enum_def)) {
|
||||
code_ += " serializer.serialize_u32(self.bits() as u32)";
|
||||
} else {
|
||||
code_ +=
|
||||
" serializer.serialize_unit_variant(\"{{ENUM_NAME}}\", self.0 "
|
||||
"as "
|
||||
"u32, self.variant_name().unwrap())";
|
||||
}
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
// Generate Follow and Push so we can serialize and stuff.
|
||||
code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
|
||||
code_ += " type Inner = Self;";
|
||||
|
@ -2005,6 +2036,74 @@ class RustGenerator : public BaseGenerator {
|
|||
code_ += " }";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
// Implement serde::Serialize
|
||||
if (parser_.opts.rust_serialize) {
|
||||
const auto numFields = struct_def.fields.vec.size();
|
||||
code_.SetValue("NUM_FIELDS", NumToString(numFields));
|
||||
code_ += "impl Serialize for {{STRUCT_NAME}}<'_> {";
|
||||
code_ +=
|
||||
" fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>";
|
||||
code_ += " where";
|
||||
code_ += " S: Serializer,";
|
||||
code_ += " {";
|
||||
if (numFields == 0) {
|
||||
code_ +=
|
||||
" let s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", 0)?;";
|
||||
} else {
|
||||
code_ +=
|
||||
" let mut s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", "
|
||||
"{{NUM_FIELDS}})?;";
|
||||
}
|
||||
ForAllTableFields(struct_def, [&](const FieldDef &field) {
|
||||
const Type &type = field.value.type;
|
||||
if (IsUnion(type)) {
|
||||
if (type.base_type == BASE_TYPE_UNION) {
|
||||
const auto &enum_def = *type.enum_def;
|
||||
code_.SetValue("ENUM_NAME", WrapInNameSpace(enum_def));
|
||||
code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name);
|
||||
|
||||
code_ += " match self.{{FIELD_TYPE_FIELD_NAME}}_type() {";
|
||||
code_ += " {{ENUM_NAME}}::NONE => (),";
|
||||
ForAllUnionObjectVariantsBesidesNone(enum_def, [&] {
|
||||
code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name);
|
||||
code_ += " {{ENUM_NAME}}::{{VARIANT_NAME}} => {";
|
||||
code_ +=
|
||||
" let f = "
|
||||
"self.{{FIELD_TYPE_FIELD_NAME}}_as_{{U_ELEMENT_NAME}}()";
|
||||
code_ +=
|
||||
" .expect(\"Invalid union table, expected "
|
||||
"`{{ENUM_NAME}}::{{VARIANT_NAME}}`.\");";
|
||||
code_ += " s.serialize_field(\"{{FIELD_NAME}}\", &f)?;";
|
||||
code_ += " }";
|
||||
});
|
||||
code_ += " _ => unimplemented!(),";
|
||||
code_ += " }";
|
||||
} else {
|
||||
code_ +=
|
||||
" s.serialize_field(\"{{FIELD_NAME}}\", "
|
||||
"&self.{{FIELD_NAME}}())?;";
|
||||
}
|
||||
} else {
|
||||
if (field.IsOptional()) {
|
||||
code_ += " if let Some(f) = self.{{FIELD_NAME}}() {";
|
||||
code_ += " s.serialize_field(\"{{FIELD_NAME}}\", &f)?;";
|
||||
code_ += " } else {";
|
||||
code_ += " s.skip_field(\"{{FIELD_NAME}}\")?;";
|
||||
code_ += " }";
|
||||
} else {
|
||||
code_ +=
|
||||
" s.serialize_field(\"{{FIELD_NAME}}\", "
|
||||
"&self.{{FIELD_NAME}}())?;";
|
||||
}
|
||||
}
|
||||
});
|
||||
code_ += " s.end()";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
// Generate a builder struct:
|
||||
code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {";
|
||||
|
@ -2636,6 +2735,37 @@ class RustGenerator : public BaseGenerator {
|
|||
code_ += " v.in_buffer::<Self>(pos)";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
// Implement serde::Serialize
|
||||
if (parser_.opts.rust_serialize) {
|
||||
const auto numFields = struct_def.fields.vec.size();
|
||||
code_.SetValue("NUM_FIELDS", NumToString(numFields));
|
||||
code_ += "impl Serialize for {{STRUCT_NAME}} {";
|
||||
code_ +=
|
||||
" fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>";
|
||||
code_ += " where";
|
||||
code_ += " S: Serializer,";
|
||||
code_ += " {";
|
||||
if (numFields == 0) {
|
||||
code_ +=
|
||||
" let s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", 0)?;";
|
||||
} else {
|
||||
code_ +=
|
||||
" let mut s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", "
|
||||
"{{NUM_FIELDS}})?;";
|
||||
}
|
||||
ForAllStructFields(struct_def, [&](const FieldDef &unused) {
|
||||
(void)unused;
|
||||
code_ +=
|
||||
" s.serialize_field(\"{{FIELD_NAME}}\", "
|
||||
"&self.{{FIELD_NAME}}())?;";
|
||||
});
|
||||
code_ += " s.end()";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
// Generate a constructor that takes all fields as arguments.
|
||||
code_ += "impl<'a> {{STRUCT_NAME}} {";
|
||||
|
@ -2834,6 +2964,13 @@ class RustGenerator : public BaseGenerator {
|
|||
code_ += indent + "use std::mem;";
|
||||
code_ += indent + "use std::cmp::Ordering;";
|
||||
code_ += "";
|
||||
if (parser_.opts.rust_serialize) {
|
||||
code_ += indent + "extern crate serde;";
|
||||
code_ +=
|
||||
indent +
|
||||
"use self::serde::ser::{Serialize, Serializer, SerializeStruct};";
|
||||
code_ += "";
|
||||
}
|
||||
code_ += indent + "extern crate flatbuffers;";
|
||||
code_ += indent + "use self::flatbuffers::{EndianScalar, Follow};";
|
||||
}
|
||||
|
|
|
@ -220,8 +220,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||
IsEnum(field.value.type) ? "{{BASEVALUE}}" : "{{VALUETYPE}}";
|
||||
code_ += "private var _{{VALUENAME}}: " + valueType;
|
||||
auto accessing_value = IsEnum(field.value.type) ? ".value" : "";
|
||||
auto base_value =
|
||||
IsStruct(field.value.type) ? (type + "()") : field.value.constant;
|
||||
auto is_bool = IsBool(field.value.type.base_type);
|
||||
auto base_value = IsStruct(field.value.type) ? (type + "()")
|
||||
: is_bool ? ("0" == field.value.constant ? "false" : "true")
|
||||
: field.value.constant;
|
||||
|
||||
main_constructor.push_back("_" + name + " = " + name + accessing_value);
|
||||
base_constructor.push_back("_" + name + " = " + base_value);
|
||||
|
@ -712,7 +714,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||
|
||||
if (IsBool(field.value.type.base_type)) {
|
||||
std::string default_value =
|
||||
"0" == field.value.constant ? "false" : "true";
|
||||
field.IsOptional() ? "nil"
|
||||
: ("0" == field.value.constant ? "false" : "true");
|
||||
code_.SetValue("CONSTANT", default_value);
|
||||
code_.SetValue("VALUETYPE", "Bool");
|
||||
code_ += GenReaderMainBody(optional) + "\\";
|
||||
|
|
|
@ -343,8 +343,7 @@ class TsGenerator : public BaseGenerator {
|
|||
switch (type.base_type) {
|
||||
case BASE_TYPE_BOOL: return allowNull ? "boolean|null" : "boolean";
|
||||
case BASE_TYPE_LONG:
|
||||
case BASE_TYPE_ULONG:
|
||||
return allowNull ? "bigint|null" : "bigint";
|
||||
case BASE_TYPE_ULONG: return allowNull ? "bigint|null" : "bigint";
|
||||
default:
|
||||
if (IsScalar(type.base_type)) {
|
||||
if (type.enum_def) {
|
||||
|
@ -907,8 +906,7 @@ class TsGenerator : public BaseGenerator {
|
|||
// a string that contains values for things that can be created inline or
|
||||
// the variable name from field_offset_decl
|
||||
std::string field_offset_val;
|
||||
const auto field_default_val =
|
||||
GenDefaultValue(field, imports);
|
||||
const auto field_default_val = GenDefaultValue(field, imports);
|
||||
|
||||
// Emit a scalar field
|
||||
const auto is_string = IsString(field.value.type);
|
||||
|
@ -1643,7 +1641,7 @@ class TsGenerator : public BaseGenerator {
|
|||
|
||||
std::string GetArgName(const FieldDef &field) {
|
||||
auto argname = MakeCamel(field.name, false);
|
||||
if (!IsScalar(field.value.type.base_type)) {
|
||||
if (!IsScalar(field.value.type.base_type)) {
|
||||
argname += "Offset";
|
||||
} else {
|
||||
argname = EscapeKeyword(argname);
|
||||
|
|
|
@ -144,7 +144,10 @@ void Parser::Message(const std::string &msg) {
|
|||
}
|
||||
|
||||
void Parser::Warning(const std::string &msg) {
|
||||
if (!opts.no_warnings) Message("warning: " + msg);
|
||||
if (!opts.no_warnings) {
|
||||
Message("warning: " + msg);
|
||||
has_warning_ = true; // for opts.warnings_as_errors
|
||||
}
|
||||
}
|
||||
|
||||
CheckedError Parser::Error(const std::string &msg) {
|
||||
|
@ -1674,8 +1677,9 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field,
|
|||
if (opts.json_nested_legacy_flatbuffers) {
|
||||
ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0));
|
||||
} else {
|
||||
return Error("cannot parse nested_flatbuffer as bytes unless"
|
||||
" --json-nested-bytes is set");
|
||||
return Error(
|
||||
"cannot parse nested_flatbuffer as bytes unless"
|
||||
" --json-nested-bytes is set");
|
||||
}
|
||||
} else {
|
||||
auto cursor_at_value_begin = cursor_;
|
||||
|
@ -2164,9 +2168,7 @@ void EnumDef::SortByValue() {
|
|||
});
|
||||
else
|
||||
std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
|
||||
if (e1->GetAsInt64() == e2->GetAsInt64()) {
|
||||
return e1->name < e2->name;
|
||||
}
|
||||
if (e1->GetAsInt64() == e2->GetAsInt64()) { return e1->name < e2->name; }
|
||||
return e1->GetAsInt64() < e2->GetAsInt64();
|
||||
});
|
||||
}
|
||||
|
@ -3444,6 +3446,9 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
|
|||
ECHECK(ParseDecl(source_filename));
|
||||
}
|
||||
}
|
||||
if (opts.warnings_as_errors && has_warning_) {
|
||||
return Error("treating warnings as errors, failed due to above warnings");
|
||||
}
|
||||
return NoError();
|
||||
}
|
||||
|
||||
|
|
|
@ -645,8 +645,7 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
|
|||
case reflection::Bool:
|
||||
case reflection::Byte:
|
||||
case reflection::UByte:
|
||||
if (!table->VerifyField<int8_t>(v, field_def->offset(),
|
||||
sizeof(int8_t)))
|
||||
if (!table->VerifyField<int8_t>(v, field_def->offset(), sizeof(int8_t)))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Short:
|
||||
|
@ -668,13 +667,11 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
|
|||
return false;
|
||||
break;
|
||||
case reflection::Float:
|
||||
if (!table->VerifyField<float>(v, field_def->offset(),
|
||||
sizeof(float)))
|
||||
if (!table->VerifyField<float>(v, field_def->offset(), sizeof(float)))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Double:
|
||||
if (!table->VerifyField<double>(v, field_def->offset(),
|
||||
sizeof(double)))
|
||||
if (!table->VerifyField<double>(v, field_def->offset(), sizeof(double)))
|
||||
return false;
|
||||
break;
|
||||
case reflection::String:
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRC_COMPILER_CONFIG_H
|
||||
#define SRC_COMPILER_CONFIG_H
|
||||
|
||||
// This file is here only because schema_interface.h, which is copied from gRPC,
|
||||
// includes it. There is nothing for Flatbuffers to configure.
|
||||
|
||||
#endif // SRC_COMPILER_CONFIG_H
|
|
@ -1,51 +1,17 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "src/compiler/cpp_generator.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "src/compiler/cpp_generator.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
namespace grpc_cpp_generator {
|
||||
namespace {
|
||||
|
||||
grpc::string message_header_ext() { return "_generated.h"; }
|
||||
grpc::string service_header_ext() { return ".grpc.fb.h"; }
|
||||
|
||||
template <class T>
|
||||
grpc::string as_string(T x) {
|
||||
template<class T> grpc::string as_string(T x) {
|
||||
std::ostringstream out;
|
||||
out << x;
|
||||
return out.str();
|
||||
|
@ -76,10 +42,7 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
template <class T, size_t N>
|
||||
T *array_end(T (&array)[N]) {
|
||||
return array + N;
|
||||
}
|
||||
template<class T, size_t N> T *array_end(T (&array)[N]) { return array + N; }
|
||||
|
||||
void PrintIncludes(grpc_generator::Printer *printer,
|
||||
const std::vector<grpc::string> &headers,
|
||||
|
@ -92,9 +55,7 @@ void PrintIncludes(grpc_generator::Printer *printer,
|
|||
auto &s = params.grpc_search_path;
|
||||
if (!s.empty()) {
|
||||
vars["l"] += s;
|
||||
if (s[s.size() - 1] != '/') {
|
||||
vars["l"] += '/';
|
||||
}
|
||||
if (s[s.size() - 1] != '/') { vars["l"] += '/'; }
|
||||
}
|
||||
|
||||
for (auto i = headers.begin(); i != headers.end(); i++) {
|
||||
|
@ -144,15 +105,16 @@ grpc::string GetHeaderIncludes(grpc_generator::File *file,
|
|||
std::map<grpc::string, grpc::string> vars;
|
||||
|
||||
static const char *headers_strs[] = {
|
||||
"grpcpp/impl/codegen/async_stream.h",
|
||||
"grpcpp/impl/codegen/async_unary_call.h",
|
||||
"grpcpp/impl/codegen/method_handler.h",
|
||||
"grpcpp/impl/codegen/proto_utils.h",
|
||||
"grpcpp/impl/codegen/rpc_method.h",
|
||||
"grpcpp/impl/codegen/service_type.h",
|
||||
"grpcpp/impl/codegen/status.h",
|
||||
"grpcpp/impl/codegen/stub_options.h",
|
||||
"grpcpp/impl/codegen/sync_stream.h"};
|
||||
"grpcpp/impl/codegen/async_stream.h",
|
||||
"grpcpp/impl/codegen/async_unary_call.h",
|
||||
"grpcpp/impl/codegen/method_handler.h",
|
||||
"grpcpp/impl/codegen/proto_utils.h",
|
||||
"grpcpp/impl/codegen/rpc_method.h",
|
||||
"grpcpp/impl/codegen/service_type.h",
|
||||
"grpcpp/impl/codegen/status.h",
|
||||
"grpcpp/impl/codegen/stub_options.h",
|
||||
"grpcpp/impl/codegen/sync_stream.h"
|
||||
};
|
||||
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
|
||||
PrintIncludes(printer.get(), headers, params);
|
||||
printer->Print(vars, "\n");
|
||||
|
@ -187,8 +149,8 @@ void PrintHeaderClientMethodInterfaces(
|
|||
grpc::string prefix;
|
||||
grpc::string method_params; // extra arguments to method
|
||||
grpc::string raw_args; // extra arguments to raw version of method
|
||||
} async_prefixes[] = {{"Async", ", void* tag", ", tag"},
|
||||
{"PrepareAsync", "", ""}};
|
||||
} async_prefixes[] = { { "Async", ", void* tag", ", tag" },
|
||||
{ "PrepareAsync", "", "" } };
|
||||
|
||||
if (is_public) {
|
||||
if (method->NoStreaming()) {
|
||||
|
@ -196,8 +158,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
*vars,
|
||||
"virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
|
||||
"const $Request$& request, $Response$* response) = 0;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -228,8 +191,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
"($Method$Raw(context, response));\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -262,8 +226,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
"($Method$Raw(context, request));\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -295,8 +260,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
"$Method$Raw(context));\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -318,8 +284,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
}
|
||||
} else {
|
||||
if (method->NoStreaming()) {
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -334,8 +301,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
"virtual ::grpc::ClientWriterInterface< $Request$>*"
|
||||
" $Method$Raw("
|
||||
"::grpc::ClientContext* context, $Response$* response) = 0;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
printer->Print(
|
||||
|
@ -351,8 +319,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
"virtual ::grpc::ClientReaderInterface< $Response$>* "
|
||||
"$Method$Raw("
|
||||
"::grpc::ClientContext* context, const $Request$& request) = 0;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
printer->Print(
|
||||
|
@ -367,8 +336,9 @@ void PrintHeaderClientMethodInterfaces(
|
|||
"virtual ::grpc::ClientReaderWriterInterface< $Request$, "
|
||||
"$Response$>* "
|
||||
"$Method$Raw(::grpc::ClientContext* context) = 0;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
printer->Print(
|
||||
|
@ -393,8 +363,8 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
grpc::string prefix;
|
||||
grpc::string method_params; // extra arguments to method
|
||||
grpc::string raw_args; // extra arguments to raw version of method
|
||||
} async_prefixes[] = {{"Async", ", void* tag", ", tag"},
|
||||
{"PrepareAsync", "", ""}};
|
||||
} async_prefixes[] = { { "Async", ", void* tag", ", tag" },
|
||||
{ "PrepareAsync", "", "" } };
|
||||
|
||||
if (is_public) {
|
||||
if (method->NoStreaming()) {
|
||||
|
@ -402,8 +372,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
*vars,
|
||||
"::grpc::Status $Method$(::grpc::ClientContext* context, "
|
||||
"const $Request$& request, $Response$* response) override;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -431,8 +402,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
"($Method$Raw(context, response));\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -463,8 +435,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
"($Method$Raw(context, request));\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -494,8 +467,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
"$Method$Raw(context));\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -516,8 +490,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
}
|
||||
} else {
|
||||
if (method->NoStreaming()) {
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -531,8 +506,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
"::grpc::ClientWriter< $Request$>* $Method$Raw("
|
||||
"::grpc::ClientContext* context, $Response$* response) "
|
||||
"override;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -547,8 +523,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
"::grpc::ClientReader< $Response$>* $Method$Raw("
|
||||
"::grpc::ClientContext* context, const $Request$& request)"
|
||||
" override;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -562,8 +539,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||
printer->Print(*vars,
|
||||
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
|
||||
"$Method$Raw(::grpc::ClientContext* context) override;\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||
|
@ -630,7 +608,8 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
|
|||
"class WithAsyncMethod_$Method$ : public BaseClass {\n");
|
||||
printer->Print(
|
||||
" private:\n"
|
||||
" void BaseClassMustBeDerivedFromService(const Service */*service*/) {}\n");
|
||||
" void BaseClassMustBeDerivedFromService(const Service */*service*/) "
|
||||
"{}\n");
|
||||
printer->Print(" public:\n");
|
||||
printer->Indent();
|
||||
printer->Print(*vars,
|
||||
|
@ -849,7 +828,8 @@ void PrintHeaderServerMethodGeneric(
|
|||
"class WithGenericMethod_$Method$ : public BaseClass {\n");
|
||||
printer->Print(
|
||||
" private:\n"
|
||||
" void BaseClassMustBeDerivedFromService(const Service */*service*/) {}\n");
|
||||
" void BaseClassMustBeDerivedFromService(const Service */*service*/) "
|
||||
"{}\n");
|
||||
printer->Print(" public:\n");
|
||||
printer->Indent();
|
||||
printer->Print(*vars,
|
||||
|
@ -1001,9 +981,7 @@ void PrintHeaderService(grpc_generator::Printer *printer,
|
|||
printer->Print(*vars, "WithAsyncMethod_$method_name$<");
|
||||
}
|
||||
printer->Print("Service");
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
printer->Print(" >");
|
||||
}
|
||||
for (int i = 0; i < service->method_count(); ++i) { printer->Print(" >"); }
|
||||
printer->Print(" AsyncService;\n");
|
||||
|
||||
// Server side - Generic
|
||||
|
@ -1028,9 +1006,7 @@ void PrintHeaderService(grpc_generator::Printer *printer,
|
|||
}
|
||||
printer->Print("Service");
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
if (service->method(i)->NoStreaming()) {
|
||||
printer->Print(" >");
|
||||
}
|
||||
if (service->method(i)->NoStreaming()) { printer->Print(" >"); }
|
||||
}
|
||||
printer->Print(" StreamedUnaryService;\n");
|
||||
|
||||
|
@ -1052,9 +1028,7 @@ void PrintHeaderService(grpc_generator::Printer *printer,
|
|||
printer->Print("Service");
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
auto method = service->method(i);
|
||||
if (ServerOnlyStreaming(method.get())) {
|
||||
printer->Print(" >");
|
||||
}
|
||||
if (ServerOnlyStreaming(method.get())) { printer->Print(" >"); }
|
||||
}
|
||||
printer->Print(" SplitStreamedService;\n");
|
||||
|
||||
|
@ -1095,9 +1069,7 @@ grpc::string GetHeaderServices(grpc_generator::File *file,
|
|||
// Package string is empty or ends with a dot. It is used to fully qualify
|
||||
// method names.
|
||||
vars["Package"] = file->package();
|
||||
if (!file->package().empty()) {
|
||||
vars["Package"].append(".");
|
||||
}
|
||||
if (!file->package().empty()) { vars["Package"].append("."); }
|
||||
|
||||
if (!params.services_namespace.empty()) {
|
||||
vars["services_namespace"] = params.services_namespace;
|
||||
|
@ -1179,14 +1151,15 @@ grpc::string GetSourceIncludes(grpc_generator::File *file,
|
|||
std::map<grpc::string, grpc::string> vars;
|
||||
|
||||
static const char *headers_strs[] = {
|
||||
"grpcpp/impl/codegen/async_stream.h",
|
||||
"grpcpp/impl/codegen/async_unary_call.h",
|
||||
"grpcpp/impl/codegen/channel_interface.h",
|
||||
"grpcpp/impl/codegen/client_unary_call.h",
|
||||
"grpcpp/impl/codegen/method_handler.h",
|
||||
"grpcpp/impl/codegen/rpc_service_method.h",
|
||||
"grpcpp/impl/codegen/service_type.h",
|
||||
"grpcpp/impl/codegen/sync_stream.h"};
|
||||
"grpcpp/impl/codegen/async_stream.h",
|
||||
"grpcpp/impl/codegen/async_unary_call.h",
|
||||
"grpcpp/impl/codegen/channel_interface.h",
|
||||
"grpcpp/impl/codegen/client_unary_call.h",
|
||||
"grpcpp/impl/codegen/method_handler.h",
|
||||
"grpcpp/impl/codegen/rpc_service_method.h",
|
||||
"grpcpp/impl/codegen/service_type.h",
|
||||
"grpcpp/impl/codegen/sync_stream.h"
|
||||
};
|
||||
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
|
||||
PrintIncludes(printer.get(), headers, params);
|
||||
|
||||
|
@ -1215,8 +1188,8 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
|||
grpc::string start; // bool literal expressed as string
|
||||
grpc::string method_params; // extra arguments to method
|
||||
grpc::string create_args; // extra arguments to creator
|
||||
} async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
|
||||
{"PrepareAsync", "false", "", ", nullptr"}};
|
||||
} async_prefixes[] = { { "Async", "true", ", void* tag", ", tag" },
|
||||
{ "PrepareAsync", "false", "", ", nullptr" } };
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(*vars,
|
||||
"::grpc::Status $ns$$Service$::Stub::$Method$("
|
||||
|
@ -1226,8 +1199,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
|||
" return ::grpc::internal::BlockingUnaryCall"
|
||||
"(channel_.get(), rpcmethod_$Method$_, "
|
||||
"context, request, response);\n}\n\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncStart"] = async_prefix.start;
|
||||
printer->Print(*vars,
|
||||
|
@ -1257,8 +1231,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
|||
"rpcmethod_$Method$_, "
|
||||
"context, response);\n"
|
||||
"}\n\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncStart"] = async_prefix.start;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
|
@ -1289,8 +1264,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
|||
"rpcmethod_$Method$_, "
|
||||
"context, request);\n"
|
||||
"}\n\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncStart"] = async_prefix.start;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
|
@ -1321,8 +1297,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
|||
"rpcmethod_$Method$_, "
|
||||
"context);\n"
|
||||
"}\n\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncStart"] = async_prefix.start;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
|
@ -1351,10 +1328,11 @@ void PrintSourceServerMethod(grpc_generator::Printer *printer,
|
|||
(*vars)["Request"] = method->input_type_name();
|
||||
(*vars)["Response"] = method->output_type_name();
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(*vars,
|
||||
"::grpc::Status $ns$$Service$::Service::$Method$("
|
||||
"::grpc::ServerContext* /*context*/, "
|
||||
"const $Request$* /*request*/, $Response$* /*response*/) {\n");
|
||||
printer->Print(
|
||||
*vars,
|
||||
"::grpc::Status $ns$$Service$::Service::$Method$("
|
||||
"::grpc::ServerContext* /*context*/, "
|
||||
"const $Request$* /*request*/, $Response$* /*response*/) {\n");
|
||||
printer->Print(
|
||||
" return ::grpc::Status("
|
||||
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
|
||||
|
@ -1519,9 +1497,7 @@ grpc::string GetSourceServices(grpc_generator::File *file,
|
|||
// Package string is empty or ends with a dot. It is used to fully qualify
|
||||
// method names.
|
||||
vars["Package"] = file->package();
|
||||
if (!file->package().empty()) {
|
||||
vars["Package"].append(".");
|
||||
}
|
||||
if (!file->package().empty()) { vars["Package"].append("."); }
|
||||
if (!params.services_namespace.empty()) {
|
||||
vars["ns"] = params.services_namespace + "::";
|
||||
vars["prefix"] = params.services_namespace;
|
||||
|
@ -1593,9 +1569,9 @@ grpc::string GetMockIncludes(grpc_generator::File *file,
|
|||
std::map<grpc::string, grpc::string> vars;
|
||||
|
||||
static const char *headers_strs[] = {
|
||||
"grpcpp/impl/codegen/async_stream.h",
|
||||
"grpcpp/impl/codegen/sync_stream.h",
|
||||
"gmock/gmock.h",
|
||||
"grpcpp/impl/codegen/async_stream.h",
|
||||
"grpcpp/impl/codegen/sync_stream.h",
|
||||
"gmock/gmock.h",
|
||||
};
|
||||
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
|
||||
PrintIncludes(printer.get(), headers, params);
|
||||
|
@ -1625,15 +1601,17 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
|
|||
grpc::string prefix;
|
||||
grpc::string method_params; // extra arguments to method
|
||||
int extra_method_param_count;
|
||||
} async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
|
||||
} async_prefixes[] = { { "Async", ", void* tag", 1 },
|
||||
{ "PrepareAsync", "", 0 } };
|
||||
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(
|
||||
*vars,
|
||||
"MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
|
||||
"const $Request$& request, $Response$* response));\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
printer->Print(
|
||||
*vars,
|
||||
|
@ -1648,12 +1626,13 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
|
|||
"MOCK_METHOD2($Method$Raw, "
|
||||
"::grpc::ClientWriterInterface< $Request$>*"
|
||||
"(::grpc::ClientContext* context, $Response$* response));\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["MockArgs"] =
|
||||
flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
|
||||
flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
|
||||
printer->Print(*vars,
|
||||
"MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
|
||||
"::grpc::ClientAsyncWriterInterface< $Request$>*"
|
||||
|
@ -1666,8 +1645,9 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
|
|||
"MOCK_METHOD2($Method$Raw, "
|
||||
"::grpc::ClientReaderInterface< $Response$>*"
|
||||
"(::grpc::ClientContext* context, const $Request$& request));\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["MockArgs"] =
|
||||
|
@ -1685,8 +1665,9 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
|
|||
"MOCK_METHOD1($Method$Raw, "
|
||||
"::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
|
||||
"(::grpc::ClientContext* context));\n");
|
||||
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||
auto& async_prefix = async_prefixes[i];
|
||||
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
|
||||
i++) {
|
||||
auto &async_prefix = async_prefixes[i];
|
||||
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||
(*vars)["MockArgs"] =
|
||||
|
@ -1727,9 +1708,7 @@ grpc::string GetMockServices(grpc_generator::File *file,
|
|||
// Package string is empty or ends with a dot. It is used to fully qualify
|
||||
// method names.
|
||||
vars["Package"] = file->package();
|
||||
if (!file->package().empty()) {
|
||||
vars["Package"].append(".");
|
||||
}
|
||||
if (!file->package().empty()) { vars["Package"].append("."); }
|
||||
|
||||
if (!params.services_namespace.empty()) {
|
||||
vars["services_namespace"] = params.services_namespace;
|
||||
|
|
|
@ -1,36 +1,3 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||
#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||
|
||||
|
@ -41,12 +8,11 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "src/compiler/config.h"
|
||||
#include "src/compiler/schema_interface.h"
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
#include <string>
|
||||
#define GRPC_CUSTOM_STRING std::string
|
||||
# include <string>
|
||||
# define GRPC_CUSTOM_STRING std::string
|
||||
#endif
|
||||
|
||||
namespace grpc {
|
||||
|
|
|
@ -1,47 +1,13 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation AN/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
#include "src/compiler/go_generator.h"
|
||||
|
||||
template <class T>
|
||||
grpc::string as_string(T x) {
|
||||
std::ostringstream out;
|
||||
out << x;
|
||||
return out.str();
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
template<class T> grpc::string as_string(T x) {
|
||||
std::ostringstream out;
|
||||
out << x;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
|
||||
|
@ -56,18 +22,16 @@ namespace grpc_go_generator {
|
|||
|
||||
// Returns string with first letter to lowerCase
|
||||
grpc::string unexportName(grpc::string s) {
|
||||
if (s.empty())
|
||||
return s;
|
||||
s[0] = static_cast<char>(std::tolower(s[0]));
|
||||
return s;
|
||||
if (s.empty()) return s;
|
||||
s[0] = static_cast<char>(std::tolower(s[0]));
|
||||
return s;
|
||||
}
|
||||
|
||||
// Returns string with first letter to uppercase
|
||||
grpc::string exportName(grpc::string s) {
|
||||
if (s.empty())
|
||||
return s;
|
||||
s[0] = static_cast<char>(std::toupper(s[0]));
|
||||
return s;
|
||||
if (s.empty()) return s;
|
||||
s[0] = static_cast<char>(std::toupper(s[0]));
|
||||
return s;
|
||||
}
|
||||
|
||||
void GenerateError(grpc_generator::Printer *printer,
|
||||
|
@ -82,50 +46,65 @@ void GenerateError(grpc_generator::Printer *printer,
|
|||
}
|
||||
|
||||
// Generates imports for the service
|
||||
void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
|
||||
void GenerateImports(grpc_generator::File *file,
|
||||
grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["filename"] = file->filename();
|
||||
printer->Print("//Generated by gRPC Go plugin\n");
|
||||
printer->Print("//If you make any local changes, they will be lost\n");
|
||||
printer->Print(vars, "//source: $filename$\n\n");
|
||||
printer->Print(vars, "package $Package$\n\n");
|
||||
printer->Print("import (\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$context$ \"context\"\n");
|
||||
vars["filename"] = file->filename();
|
||||
printer->Print("//Generated by gRPC Go plugin\n");
|
||||
printer->Print("//If you make any local changes, they will be lost\n");
|
||||
printer->Print(vars, "//source: $filename$\n\n");
|
||||
printer->Print(vars, "package $Package$\n\n");
|
||||
printer->Print("import (\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$context$ \"context\"\n");
|
||||
printer->Print("flatbuffers \"github.com/google/flatbuffers/go\"\n");
|
||||
printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
|
||||
printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
|
||||
printer->Print("\"google.golang.org/grpc/codes\"\n");
|
||||
printer->Print("\"google.golang.org/grpc/status\"\n");
|
||||
printer->Outdent();
|
||||
printer->Print(")\n\n");
|
||||
printer->Outdent();
|
||||
printer->Print(")\n\n");
|
||||
}
|
||||
|
||||
// Generates Server method signature source
|
||||
void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
void GenerateServerMethodSignature(const grpc_generator::Method *method,
|
||||
grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = method->get_input_type_name();
|
||||
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)$Ending$");
|
||||
} else if (ServerOnlyStreaming(method)) {
|
||||
printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error$Ending$");
|
||||
} else {
|
||||
printer->Print(vars, "$Method$($Service$_$Method$Server) error$Ending$");
|
||||
}
|
||||
vars["Request"] = method->get_input_type_name();
|
||||
vars["Response"] = (vars["CustomMethodIO"] == "")
|
||||
? method->get_output_type_name()
|
||||
: vars["CustomMethodIO"];
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(
|
||||
vars,
|
||||
"$Method$($context$.Context, *$Request$) (*$Response$, error)$Ending$");
|
||||
} else if (ServerOnlyStreaming(method)) {
|
||||
printer->Print(
|
||||
vars, "$Method$(*$Request$, $Service$_$Method$Server) error$Ending$");
|
||||
} else {
|
||||
printer->Print(vars, "$Method$($Service$_$Method$Server) error$Ending$");
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
void GenerateServerMethod(const grpc_generator::Method *method,
|
||||
grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = method->get_input_type_name();
|
||||
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
|
||||
vars["FullMethodName"] = "/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "in := new($Request$)\n");
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = method->get_input_type_name();
|
||||
vars["Response"] = (vars["CustomMethodIO"] == "")
|
||||
? method->get_output_type_name()
|
||||
: vars["CustomMethodIO"];
|
||||
vars["FullMethodName"] =
|
||||
"/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(
|
||||
vars,
|
||||
"func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec "
|
||||
"func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) "
|
||||
"(interface{}, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "in := new($Request$)\n");
|
||||
vars["Error_Check"] = "err := dec(in); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
printer->Print("if interceptor == nil {\n");
|
||||
|
@ -133,258 +112,281 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
|
|||
printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, in)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
|
||||
printer->Indent();
|
||||
printer->Print("Server: srv,\n");
|
||||
printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
|
||||
printer->Indent();
|
||||
printer->Print("Server: srv,\n");
|
||||
printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Outdent();
|
||||
printer->Print("\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(*$Request$))\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Print("return interceptor(ctx, in, info, handler)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
return;
|
||||
}
|
||||
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
|
||||
printer->Print(vars, "func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
|
||||
printer->Indent();
|
||||
if (ServerOnlyStreaming(method)) {
|
||||
printer->Print(vars, "m := new($Request$)\n");
|
||||
printer->Print(vars,
|
||||
"handler := func(ctx $context$.Context, req interface{}) "
|
||||
"(interface{}, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(
|
||||
vars, "return srv.($Service$Server).$Method$(ctx, req.(*$Request$))\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Print("return interceptor(ctx, in, info, handler)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
return;
|
||||
}
|
||||
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
|
||||
printer->Print(
|
||||
vars,
|
||||
"func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
|
||||
printer->Indent();
|
||||
if (ServerOnlyStreaming(method)) {
|
||||
printer->Print(vars, "m := new($Request$)\n");
|
||||
vars["Error_Check"] = "err := stream.RecvMsg(m); err != nil";
|
||||
GenerateError(printer, vars, false);
|
||||
printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
|
||||
} else {
|
||||
printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
printer->Print(
|
||||
vars,
|
||||
"return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
|
||||
} else {
|
||||
printer->Print(
|
||||
vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
|
||||
bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
|
||||
bool genSendAndClose = ClientOnlyStreaming(method);
|
||||
bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
|
||||
bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
|
||||
bool genSendAndClose = ClientOnlyStreaming(method);
|
||||
|
||||
printer->Print(vars, "type $Service$_$Method$Server interface {\n");
|
||||
printer->Indent();
|
||||
if (genSend) {
|
||||
printer->Print(vars, "Send(*$Response$) error\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "Recv() (*$Request$, error)\n");
|
||||
}
|
||||
if (genSendAndClose) {
|
||||
printer->Print(vars, "SendAndClose(*$Response$) error\n");
|
||||
}
|
||||
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
printer->Print(vars, "type $Service$_$Method$Server interface {\n");
|
||||
printer->Indent();
|
||||
if (genSend) { printer->Print(vars, "Send(*$Response$) error\n"); }
|
||||
if (genRecv) { printer->Print(vars, "Recv() (*$Request$, error)\n"); }
|
||||
if (genSendAndClose) {
|
||||
printer->Print(vars, "SendAndClose(*$Response$) error\n");
|
||||
}
|
||||
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
printer->Print(vars, "type $StreamType$ struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
printer->Print(vars, "type $StreamType$ struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
if (genSend) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Send(m *$Response$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "m := new($Request$)\n");
|
||||
if (genSend) {
|
||||
printer->Print(vars,
|
||||
"func (x *$StreamType$) Send(m *$Response$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars,
|
||||
"func (x *$StreamType$) Recv() (*$Request$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "m := new($Request$)\n");
|
||||
vars["Error_Check"] = "err := x.ServerStream.RecvMsg(m); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genSendAndClose) {
|
||||
printer->Print(vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genSendAndClose) {
|
||||
printer->Print(
|
||||
vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Generates Client method signature source
|
||||
void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
void GenerateClientMethodSignature(const grpc_generator::Method *method,
|
||||
grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = ", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"]);
|
||||
if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
|
||||
vars["Request"] = "";
|
||||
}
|
||||
vars["Response"] = "*" + method->get_output_type_name();
|
||||
if (ClientOnlyStreaming(method) || method->BidiStreaming() || ServerOnlyStreaming(method)) {
|
||||
vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
|
||||
}
|
||||
printer->Print(vars, "$Method$(ctx $context$.Context$Request$,\n\topts ...$grpc$.CallOption) ($Response$, error)$Ending$");
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] =
|
||||
", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name()
|
||||
: vars["CustomMethodIO"]);
|
||||
if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
|
||||
vars["Request"] = "";
|
||||
}
|
||||
vars["Response"] = "*" + method->get_output_type_name();
|
||||
if (ClientOnlyStreaming(method) || method->BidiStreaming() ||
|
||||
ServerOnlyStreaming(method)) {
|
||||
vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client";
|
||||
}
|
||||
printer->Print(vars,
|
||||
"$Method$(ctx $context$.Context$Request$,\n\topts "
|
||||
"...$grpc$.CallOption) ($Response$, error)$Ending$");
|
||||
}
|
||||
|
||||
// Generates Client method source
|
||||
void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
void GenerateClientMethod(const grpc_generator::Method *method,
|
||||
grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
|
||||
printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
|
||||
vars["Ending"] = " {\n";
|
||||
GenerateClientMethodSignature(method, printer, vars);
|
||||
printer->Indent();
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
|
||||
vars["Response"] = method->get_output_type_name();
|
||||
vars["FullMethodName"] = "/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "out := new($Response$)\n");
|
||||
printer->Print(vars, "err := c.cc.Invoke(ctx, \"$FullMethodName$\", in, out, opts...)\n");
|
||||
GenerateClientMethodSignature(method, printer, vars);
|
||||
printer->Indent();
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = (vars["CustomMethodIO"] == "")
|
||||
? method->get_input_type_name()
|
||||
: vars["CustomMethodIO"];
|
||||
vars["Response"] = method->get_output_type_name();
|
||||
vars["FullMethodName"] =
|
||||
"/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "out := new($Response$)\n");
|
||||
printer->Print(
|
||||
vars,
|
||||
"err := c.cc.Invoke(ctx, \"$FullMethodName$\", in, out, opts...)\n");
|
||||
vars["Error_Check"] = "err != nil";
|
||||
GenerateError(printer, vars);
|
||||
printer->Print("return out, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
return;
|
||||
}
|
||||
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
|
||||
printer->Print(vars, "stream, err := c.cc.NewStream(ctx, &$MethodDesc$, \"$FullMethodName$\", opts...)\n");
|
||||
printer->Print("return out, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
return;
|
||||
}
|
||||
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
|
||||
printer->Print(vars,
|
||||
"stream, err := c.cc.NewStream(ctx, &$MethodDesc$, "
|
||||
"\"$FullMethodName$\", opts...)\n");
|
||||
vars["Error_Check"] = "err != nil";
|
||||
GenerateError(printer, vars);
|
||||
|
||||
printer->Print(vars, "x := &$StreamType${stream}\n");
|
||||
if (ServerOnlyStreaming(method)) {
|
||||
printer->Print(vars, "x := &$StreamType${stream}\n");
|
||||
if (ServerOnlyStreaming(method)) {
|
||||
vars["Error_Check"] = "err := x.ClientStream.SendMsg(in); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
vars["Error_Check"] = "err := x.ClientStream.CloseSend(); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
}
|
||||
printer->Print("return x, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
printer->Print("return x, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
|
||||
bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
|
||||
bool genCloseAndRecv = ClientOnlyStreaming(method);
|
||||
bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
|
||||
bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
|
||||
bool genCloseAndRecv = ClientOnlyStreaming(method);
|
||||
|
||||
//Stream interface
|
||||
printer->Print(vars, "type $Service$_$Method$Client interface {\n");
|
||||
printer->Indent();
|
||||
if (genSend) {
|
||||
printer->Print(vars, "Send(*$Request$) error\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "Recv() (*$Response$, error)\n");
|
||||
}
|
||||
if (genCloseAndRecv) {
|
||||
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
|
||||
}
|
||||
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
// Stream interface
|
||||
printer->Print(vars, "type $Service$_$Method$Client interface {\n");
|
||||
printer->Indent();
|
||||
if (genSend) { printer->Print(vars, "Send(*$Request$) error\n"); }
|
||||
if (genRecv) { printer->Print(vars, "Recv() (*$Response$, error)\n"); }
|
||||
if (genCloseAndRecv) {
|
||||
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
|
||||
}
|
||||
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
//Stream Client
|
||||
printer->Print(vars, "type $StreamType$ struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
// Stream Client
|
||||
printer->Print(vars, "type $StreamType$ struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
if (genSend) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ClientStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genSend) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ClientStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "m := new($Response$)\n");
|
||||
if (genRecv) {
|
||||
printer->Print(vars,
|
||||
"func (x *$StreamType$) Recv() (*$Response$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "m := new($Response$)\n");
|
||||
vars["Error_Check"] = "err := x.ClientStream.RecvMsg(m); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
if (genCloseAndRecv) {
|
||||
printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
|
||||
printer->Indent();
|
||||
if (genCloseAndRecv) {
|
||||
printer->Print(
|
||||
vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
|
||||
printer->Indent();
|
||||
vars["Error_Check"] = "err := x.ClientStream.CloseSend(); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
printer->Print(vars, "m := new($Response$)\n");
|
||||
printer->Print(vars, "m := new($Response$)\n");
|
||||
vars["Error_Check"] = "err := x.ClientStream.RecvMsg(m); err != nil";
|
||||
GenerateError(printer, vars);
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Generates client API for the service
|
||||
void GenerateService(const grpc_generator::Service *service, grpc_generator::Printer* printer,
|
||||
void GenerateService(const grpc_generator::Service *service,
|
||||
grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Service"] = exportName(service->name());
|
||||
// Client Interface
|
||||
printer->Print(vars, "// Client API for $Service$ service\n");
|
||||
printer->Print(vars, "type $Service$Client interface {\n");
|
||||
printer->Indent();
|
||||
vars["Service"] = exportName(service->name());
|
||||
// Client Interface
|
||||
printer->Print(vars, "// Client API for $Service$ service\n");
|
||||
printer->Print(vars, "type $Service$Client interface {\n");
|
||||
printer->Indent();
|
||||
vars["Ending"] = "\n";
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateClientMethodSignature(service->method(i).get(), printer, vars);
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateClientMethodSignature(service->method(i).get(), printer, vars);
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
// Client structure
|
||||
vars["ServiceUnexported"] = unexportName(vars["Service"]);
|
||||
printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "cc $grpc$.ClientConnInterface\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
// Client structure
|
||||
vars["ServiceUnexported"] = unexportName(vars["Service"]);
|
||||
printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "cc $grpc$.ClientConnInterface\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
// NewClient
|
||||
printer->Print(vars, "func New$Service$Client(cc $grpc$.ClientConnInterface) $Service$Client {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
|
||||
printer->Outdent();
|
||||
printer->Print("\n}\n\n");
|
||||
// NewClient
|
||||
printer->Print(vars,
|
||||
"func New$Service$Client(cc $grpc$.ClientConnInterface) "
|
||||
"$Service$Client {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
|
||||
printer->Outdent();
|
||||
printer->Print("\n}\n\n");
|
||||
|
||||
int unary_methods = 0, streaming_methods = 0;
|
||||
vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
if (method->NoStreaming()) {
|
||||
vars["MethodDesc"] = vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
|
||||
unary_methods++;
|
||||
} else {
|
||||
vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" + as_string(streaming_methods) + "]";
|
||||
streaming_methods++;
|
||||
}
|
||||
GenerateClientMethod(method.get(), printer, vars);
|
||||
}
|
||||
int unary_methods = 0, streaming_methods = 0;
|
||||
vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
if (method->NoStreaming()) {
|
||||
vars["MethodDesc"] =
|
||||
vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
|
||||
unary_methods++;
|
||||
} else {
|
||||
vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" +
|
||||
as_string(streaming_methods) + "]";
|
||||
streaming_methods++;
|
||||
}
|
||||
GenerateClientMethod(method.get(), printer, vars);
|
||||
}
|
||||
|
||||
//Server Interface
|
||||
printer->Print(vars, "// Server API for $Service$ service\n");
|
||||
printer->Print(vars, "type $Service$Server interface {\n");
|
||||
printer->Indent();
|
||||
// Server Interface
|
||||
printer->Print(vars, "// Server API for $Service$ service\n");
|
||||
printer->Print(vars, "type $Service$Server interface {\n");
|
||||
printer->Indent();
|
||||
vars["Ending"] = "\n";
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateServerMethodSignature(service->method(i).get(), printer, vars);
|
||||
}
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateServerMethodSignature(service->method(i).get(), printer, vars);
|
||||
}
|
||||
printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
printer->Print(vars, "type Unimplemented$Service$Server struct {\n");
|
||||
printer->Print("}\n\n");
|
||||
|
@ -397,13 +399,17 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
|
|||
printer->Print(vars, "func (Unimplemented$Service$Server) ");
|
||||
GenerateServerMethodSignature(method.get(), printer, vars);
|
||||
printer->Indent();
|
||||
printer->Print(vars, "return $Nil$status.Errorf(codes.Unimplemented, \"method $Method$ not implemented\")\n");
|
||||
printer->Print(vars,
|
||||
"return $Nil$status.Errorf(codes.Unimplemented, \"method "
|
||||
"$Method$ not implemented\")\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
printer->Print(vars, "func (Unimplemented$Service$Server) mustEmbedUnimplemented$Service$Server() {}");
|
||||
printer->Print(vars,
|
||||
"func (Unimplemented$Service$Server) "
|
||||
"mustEmbedUnimplemented$Service$Server() {}");
|
||||
printer->Print("\n\n");
|
||||
|
||||
printer->Print(vars, "type Unsafe$Service$Server interface {\n");
|
||||
|
@ -411,91 +417,89 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
|
|||
printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
// Server registration.
|
||||
printer->Print(vars, "func Register$Service$Server(s $grpc$.ServiceRegistrar, srv $Service$Server) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
// Server registration.
|
||||
printer->Print(vars,
|
||||
"func Register$Service$Server(s $grpc$.ServiceRegistrar, srv "
|
||||
"$Service$Server) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateServerMethod(service->method(i).get(), printer, vars);
|
||||
}
|
||||
|
||||
|
||||
//Service Descriptor
|
||||
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "ServiceName: \"$ServicePrefix$$Service$\",\n");
|
||||
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
|
||||
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "MethodName: \"$Method$\",\n");
|
||||
printer->Print(vars, "Handler: $Handler$,\n");
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (!method->NoStreaming()) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "StreamName: \"$Method$\",\n");
|
||||
printer->Print(vars, "Handler: $Handler$,\n");
|
||||
if (ClientOnlyStreaming(method.get())) {
|
||||
printer->Print("ClientStreams: true,\n");
|
||||
} else if (ServerOnlyStreaming(method.get())) {
|
||||
printer->Print("ServerStreams: true,\n");
|
||||
} else {
|
||||
printer->Print("ServerStreams: true,\n");
|
||||
printer->Print("ClientStreams: true,\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateServerMethod(service->method(i).get(), printer, vars);
|
||||
}
|
||||
|
||||
// Service Descriptor
|
||||
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "ServiceName: \"$ServicePrefix$$Service$\",\n");
|
||||
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
|
||||
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "MethodName: \"$Method$\",\n");
|
||||
printer->Print(vars, "Handler: $Handler$,\n");
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (!method->NoStreaming()) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "StreamName: \"$Method$\",\n");
|
||||
printer->Print(vars, "Handler: $Handler$,\n");
|
||||
if (ClientOnlyStreaming(method.get())) {
|
||||
printer->Print("ClientStreams: true,\n");
|
||||
} else if (ServerOnlyStreaming(method.get())) {
|
||||
printer->Print("ServerStreams: true,\n");
|
||||
} else {
|
||||
printer->Print("ServerStreams: true,\n");
|
||||
printer->Print("ClientStreams: true,\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
}
|
||||
|
||||
|
||||
// Returns source for the service
|
||||
grpc::string GenerateServiceSource(grpc_generator::File *file,
|
||||
const grpc_generator::Service *service,
|
||||
grpc_go_generator::Parameters *parameters) {
|
||||
grpc::string out;
|
||||
auto p = file->CreatePrinter(&out, '\t');
|
||||
grpc::string out;
|
||||
auto p = file->CreatePrinter(&out, '\t');
|
||||
p->SetIndentationSize(1);
|
||||
auto printer = p.get();
|
||||
std::map<grpc::string, grpc::string> vars;
|
||||
vars["Package"] = parameters->package_name;
|
||||
vars["ServicePrefix"] = parameters->service_prefix;
|
||||
if (!parameters->service_prefix.empty())
|
||||
vars["ServicePrefix"].append(".");
|
||||
vars["grpc"] = "grpc";
|
||||
vars["context"] = "context";
|
||||
GenerateImports(file, printer, vars);
|
||||
if (parameters->custom_method_io_type != "") {
|
||||
vars["CustomMethodIO"] = parameters->custom_method_io_type;
|
||||
}
|
||||
GenerateService(service, printer, vars);
|
||||
return out;
|
||||
auto printer = p.get();
|
||||
std::map<grpc::string, grpc::string> vars;
|
||||
vars["Package"] = parameters->package_name;
|
||||
vars["ServicePrefix"] = parameters->service_prefix;
|
||||
if (!parameters->service_prefix.empty()) vars["ServicePrefix"].append(".");
|
||||
vars["grpc"] = "grpc";
|
||||
vars["context"] = "context";
|
||||
GenerateImports(file, printer, vars);
|
||||
if (parameters->custom_method_io_type != "") {
|
||||
vars["CustomMethodIO"] = parameters->custom_method_io_type;
|
||||
}
|
||||
GenerateService(service, printer, vars);
|
||||
return out;
|
||||
}
|
||||
}// Namespace grpc_go_generator
|
||||
} // Namespace grpc_go_generator
|
||||
|
|
|
@ -1,40 +1,8 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||
#define GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||
|
||||
//go generator is used to generate GRPC code for serialization system, such as flatbuffers
|
||||
// go generator is used to generate GRPC code for serialization system, such as
|
||||
// flatbuffers
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
@ -43,14 +11,15 @@
|
|||
namespace grpc_go_generator {
|
||||
|
||||
struct Parameters {
|
||||
//Defines the custom parameter types for methods
|
||||
//eg: flatbuffers uses flatbuffers.Builder as input for the client and output for the server
|
||||
// Defines the custom parameter types for methods
|
||||
// eg: flatbuffers uses flatbuffers.Builder as input for the client and output
|
||||
// for the server
|
||||
grpc::string custom_method_io_type;
|
||||
|
||||
//Package name for the service
|
||||
// Package name for the service
|
||||
grpc::string package_name;
|
||||
|
||||
//Prefix for RPC Calls
|
||||
// Prefix for RPC Calls
|
||||
grpc::string service_prefix;
|
||||
};
|
||||
|
||||
|
@ -59,6 +28,6 @@ grpc::string GenerateServiceSource(grpc_generator::File *file,
|
|||
const grpc_generator::Service *service,
|
||||
grpc_go_generator::Parameters *parameters);
|
||||
|
||||
}
|
||||
} // namespace grpc_go_generator
|
||||
|
||||
#endif // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||
|
|
|
@ -23,21 +23,18 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// just to get flatbuffer_version_string()
|
||||
#include <flatbuffers/flatbuffers.h>
|
||||
#include <flatbuffers/util.h>
|
||||
#include "flatbuffers/util.h"
|
||||
#define to_string flatbuffers::NumToString
|
||||
|
||||
// Stringify helpers used solely to cast GRPC_VERSION
|
||||
#ifndef STR
|
||||
#define STR(s) #s
|
||||
# define STR(s) # s
|
||||
#endif
|
||||
|
||||
#ifndef XSTR
|
||||
#define XSTR(s) STR(s)
|
||||
# define XSTR(s) STR(s)
|
||||
#endif
|
||||
|
||||
|
||||
typedef grpc_generator::Printer Printer;
|
||||
typedef std::map<grpc::string, grpc::string> VARS;
|
||||
typedef grpc_generator::Service ServiceDescriptor;
|
||||
|
@ -48,12 +45,11 @@ typedef grpc_generator::Method MethodDescriptor;
|
|||
namespace grpc_java_generator {
|
||||
typedef std::string string;
|
||||
// Generates imports for the service
|
||||
void GenerateImports(grpc_generator::File* file,
|
||||
grpc_generator::Printer* printer, VARS& vars) {
|
||||
void GenerateImports(grpc_generator::File *file,
|
||||
grpc_generator::Printer *printer, VARS &vars) {
|
||||
vars["filename"] = file->filename();
|
||||
printer->Print(
|
||||
vars,
|
||||
"//Generated by flatc compiler (version $flatc_version$)\n");
|
||||
printer->Print(vars,
|
||||
"//Generated by flatc compiler (version $flatc_version$)\n");
|
||||
printer->Print("//If you make any local changes, they will be lost\n");
|
||||
printer->Print(vars, "//source: $filename$.fbs\n\n");
|
||||
printer->Print(vars, "package $Package$;\n\n");
|
||||
|
@ -67,7 +63,7 @@ void GenerateImports(grpc_generator::File* file,
|
|||
// Adjust a method name prefix identifier to follow the JavaBean spec:
|
||||
// - decapitalize the first letter
|
||||
// - remove embedded underscores & capitalize the following letter
|
||||
static string MixedLower(const string& word) {
|
||||
static string MixedLower(const string &word) {
|
||||
string w;
|
||||
w += static_cast<string::value_type>(tolower(word[0]));
|
||||
bool after_underscore = false;
|
||||
|
@ -87,7 +83,7 @@ static string MixedLower(const string& word) {
|
|||
// - An underscore is inserted where a lower case letter is followed by an
|
||||
// upper case letter.
|
||||
// - All letters are converted to upper case
|
||||
static string ToAllUpperCase(const string& word) {
|
||||
static string ToAllUpperCase(const string &word) {
|
||||
string w;
|
||||
for (size_t i = 0; i < word.length(); ++i) {
|
||||
w += static_cast<string::value_type>(toupper(word[i]));
|
||||
|
@ -98,47 +94,47 @@ static string ToAllUpperCase(const string& word) {
|
|||
return w;
|
||||
}
|
||||
|
||||
static inline string LowerMethodName(const MethodDescriptor* method) {
|
||||
static inline string LowerMethodName(const MethodDescriptor *method) {
|
||||
return MixedLower(method->name());
|
||||
}
|
||||
|
||||
static inline string MethodPropertiesFieldName(const MethodDescriptor* method) {
|
||||
static inline string MethodPropertiesFieldName(const MethodDescriptor *method) {
|
||||
return "METHOD_" + ToAllUpperCase(method->name());
|
||||
}
|
||||
|
||||
static inline string MethodPropertiesGetterName(
|
||||
const MethodDescriptor* method) {
|
||||
const MethodDescriptor *method) {
|
||||
return MixedLower("get_" + method->name() + "_method");
|
||||
}
|
||||
|
||||
static inline string MethodIdFieldName(const MethodDescriptor* method) {
|
||||
static inline string MethodIdFieldName(const MethodDescriptor *method) {
|
||||
return "METHODID_" + ToAllUpperCase(method->name());
|
||||
}
|
||||
|
||||
static inline string JavaClassName(VARS& vars, const string& name) {
|
||||
static inline string JavaClassName(VARS &vars, const string &name) {
|
||||
// string name = google::protobuf::compiler::java::ClassName(desc);
|
||||
return vars["Package"] + name;
|
||||
}
|
||||
|
||||
static inline string ServiceClassName(const string& service_name) {
|
||||
static inline string ServiceClassName(const string &service_name) {
|
||||
return service_name + "Grpc";
|
||||
}
|
||||
|
||||
// TODO(nmittler): Remove once protobuf includes javadoc methods in
|
||||
// distribution.
|
||||
template <typename ITR>
|
||||
static void GrpcSplitStringToIteratorUsing(const string& full,
|
||||
const char* delim, ITR& result) {
|
||||
template<typename ITR>
|
||||
static void GrpcSplitStringToIteratorUsing(const string &full,
|
||||
const char *delim, ITR &result) {
|
||||
// Optimize the common case where delim is a single character.
|
||||
if (delim[0] != '\0' && delim[1] == '\0') {
|
||||
char c = delim[0];
|
||||
const char* p = full.data();
|
||||
const char* end = p + full.size();
|
||||
const char *p = full.data();
|
||||
const char *end = p + full.size();
|
||||
while (p != end) {
|
||||
if (*p == c) {
|
||||
++p;
|
||||
} else {
|
||||
const char* start = p;
|
||||
const char *start = p;
|
||||
while (++p != end && *p != c)
|
||||
;
|
||||
*result++ = string(start, p - start);
|
||||
|
@ -160,13 +156,13 @@ static void GrpcSplitStringToIteratorUsing(const string& full,
|
|||
}
|
||||
}
|
||||
|
||||
static void GrpcSplitStringUsing(const string& full, const char* delim,
|
||||
std::vector<string>* result) {
|
||||
static void GrpcSplitStringUsing(const string &full, const char *delim,
|
||||
std::vector<string> *result) {
|
||||
std::back_insert_iterator<std::vector<string>> it(*result);
|
||||
GrpcSplitStringToIteratorUsing(full, delim, it);
|
||||
}
|
||||
|
||||
static std::vector<string> GrpcSplit(const string& full, const char* delim) {
|
||||
static std::vector<string> GrpcSplit(const string &full, const char *delim) {
|
||||
std::vector<string> result;
|
||||
GrpcSplitStringUsing(full, delim, &result);
|
||||
return result;
|
||||
|
@ -174,7 +170,7 @@ static std::vector<string> GrpcSplit(const string& full, const char* delim) {
|
|||
|
||||
// TODO(nmittler): Remove once protobuf includes javadoc methods in
|
||||
// distribution.
|
||||
static string GrpcEscapeJavadoc(const string& input) {
|
||||
static string GrpcEscapeJavadoc(const string &input) {
|
||||
string result;
|
||||
result.reserve(input.size() * 2);
|
||||
|
||||
|
@ -221,9 +217,7 @@ static string GrpcEscapeJavadoc(const string& input) {
|
|||
// Java interprets Unicode escape sequences anywhere!
|
||||
result.append("\");
|
||||
break;
|
||||
default:
|
||||
result.push_back(c);
|
||||
break;
|
||||
default: result.push_back(c); break;
|
||||
}
|
||||
|
||||
prev = c;
|
||||
|
@ -232,7 +226,7 @@ static string GrpcEscapeJavadoc(const string& input) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static std::vector<string> GrpcGetDocLines(const string& comments) {
|
||||
static std::vector<string> GrpcGetDocLines(const string &comments) {
|
||||
if (!comments.empty()) {
|
||||
// TODO(kenton): Ideally we should parse the comment text as Markdown and
|
||||
// write it back as HTML, but this requires a Markdown parser. For now
|
||||
|
@ -243,27 +237,23 @@ static std::vector<string> GrpcGetDocLines(const string& comments) {
|
|||
string escapedComments = GrpcEscapeJavadoc(comments);
|
||||
|
||||
std::vector<string> lines = GrpcSplit(escapedComments, "\n");
|
||||
while (!lines.empty() && lines.back().empty()) {
|
||||
lines.pop_back();
|
||||
}
|
||||
while (!lines.empty() && lines.back().empty()) { lines.pop_back(); }
|
||||
return lines;
|
||||
}
|
||||
return std::vector<string>();
|
||||
}
|
||||
|
||||
static std::vector<string> GrpcGetDocLinesForDescriptor(
|
||||
const DescriptorType* descriptor) {
|
||||
const DescriptorType *descriptor) {
|
||||
return descriptor->GetAllComments();
|
||||
// return GrpcGetDocLines(descriptor->GetLeadingComments("///"));
|
||||
}
|
||||
|
||||
static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
|
||||
const std::vector<string>& lines,
|
||||
static void GrpcWriteDocCommentBody(Printer *printer, VARS &vars,
|
||||
const std::vector<string> &lines,
|
||||
bool surroundWithPreTag) {
|
||||
if (!lines.empty()) {
|
||||
if (surroundWithPreTag) {
|
||||
printer->Print(" * <pre>\n");
|
||||
}
|
||||
if (surroundWithPreTag) { printer->Print(" * <pre>\n"); }
|
||||
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
// Most lines should start with a space. Watch out for lines that start
|
||||
|
@ -277,73 +267,72 @@ static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
|
|||
}
|
||||
}
|
||||
|
||||
if (surroundWithPreTag) {
|
||||
printer->Print(" * </pre>\n");
|
||||
}
|
||||
if (surroundWithPreTag) { printer->Print(" * </pre>\n"); }
|
||||
}
|
||||
}
|
||||
|
||||
static void GrpcWriteDocComment(Printer* printer, VARS& vars,
|
||||
const string& comments) {
|
||||
static void GrpcWriteDocComment(Printer *printer, VARS &vars,
|
||||
const string &comments) {
|
||||
printer->Print("/**\n");
|
||||
std::vector<string> lines = GrpcGetDocLines(comments);
|
||||
GrpcWriteDocCommentBody(printer, vars, lines, false);
|
||||
printer->Print(" */\n");
|
||||
}
|
||||
|
||||
static void GrpcWriteServiceDocComment(Printer* printer, VARS& vars,
|
||||
const ServiceDescriptor* service) {
|
||||
static void GrpcWriteServiceDocComment(Printer *printer, VARS &vars,
|
||||
const ServiceDescriptor *service) {
|
||||
printer->Print("/**\n");
|
||||
std::vector<string> lines = GrpcGetDocLinesForDescriptor(service);
|
||||
GrpcWriteDocCommentBody(printer, vars, lines, true);
|
||||
printer->Print(" */\n");
|
||||
}
|
||||
|
||||
void GrpcWriteMethodDocComment(Printer* printer, VARS& vars,
|
||||
const MethodDescriptor* method) {
|
||||
void GrpcWriteMethodDocComment(Printer *printer, VARS &vars,
|
||||
const MethodDescriptor *method) {
|
||||
printer->Print("/**\n");
|
||||
std::vector<string> lines = GrpcGetDocLinesForDescriptor(method);
|
||||
GrpcWriteDocCommentBody(printer, vars, lines, true);
|
||||
printer->Print(" */\n");
|
||||
}
|
||||
|
||||
//outputs static singleton extractor for type stored in "extr_type" and "extr_type_name" vars
|
||||
static void PrintTypeExtractor(Printer* p, VARS& vars) {
|
||||
p->Print(
|
||||
vars,
|
||||
"private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
|
||||
"extractorOf$extr_type_name$;\n"
|
||||
"private static FlatbuffersUtils.FBExtactor<$extr_type$> "
|
||||
"getExtractorOf$extr_type_name$() {\n"
|
||||
" if (extractorOf$extr_type_name$ != null) return "
|
||||
"extractorOf$extr_type_name$;\n"
|
||||
" synchronized ($service_class_name$.class) {\n"
|
||||
" if (extractorOf$extr_type_name$ != null) return "
|
||||
"extractorOf$extr_type_name$;\n"
|
||||
" extractorOf$extr_type_name$ = new "
|
||||
"FlatbuffersUtils.FBExtactor<$extr_type$>() {\n"
|
||||
" public $extr_type$ extract (ByteBuffer buffer) {\n"
|
||||
" return "
|
||||
"$extr_type$.getRootAs$extr_type_name$(buffer);\n"
|
||||
" }\n"
|
||||
" };\n"
|
||||
" return extractorOf$extr_type_name$;\n"
|
||||
" }\n"
|
||||
"}\n\n");
|
||||
// outputs static singleton extractor for type stored in "extr_type" and
|
||||
// "extr_type_name" vars
|
||||
static void PrintTypeExtractor(Printer *p, VARS &vars) {
|
||||
p->Print(vars,
|
||||
"private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
|
||||
"extractorOf$extr_type_name$;\n"
|
||||
"private static FlatbuffersUtils.FBExtactor<$extr_type$> "
|
||||
"getExtractorOf$extr_type_name$() {\n"
|
||||
" if (extractorOf$extr_type_name$ != null) return "
|
||||
"extractorOf$extr_type_name$;\n"
|
||||
" synchronized ($service_class_name$.class) {\n"
|
||||
" if (extractorOf$extr_type_name$ != null) return "
|
||||
"extractorOf$extr_type_name$;\n"
|
||||
" extractorOf$extr_type_name$ = new "
|
||||
"FlatbuffersUtils.FBExtactor<$extr_type$>() {\n"
|
||||
" public $extr_type$ extract (ByteBuffer buffer) {\n"
|
||||
" return "
|
||||
"$extr_type$.getRootAs$extr_type_name$(buffer);\n"
|
||||
" }\n"
|
||||
" };\n"
|
||||
" return extractorOf$extr_type_name$;\n"
|
||||
" }\n"
|
||||
"}\n\n");
|
||||
}
|
||||
static void PrintMethodFields(Printer* p, VARS& vars,
|
||||
const ServiceDescriptor* service) {
|
||||
static void PrintMethodFields(Printer *p, VARS &vars,
|
||||
const ServiceDescriptor *service) {
|
||||
p->Print("// Static method descriptors that strictly reflect the proto.\n");
|
||||
vars["service_name"] = service->name();
|
||||
|
||||
//set of names of rpc input- and output- types that were already encountered.
|
||||
//this is needed to avoid duplicating type extractor since it's possible that
|
||||
//the same type is used as an input or output type of more than a single RPC method
|
||||
// set of names of rpc input- and output- types that were already encountered.
|
||||
// this is needed to avoid duplicating type extractor since it's possible that
|
||||
// the same type is used as an input or output type of more than a single RPC
|
||||
// method
|
||||
std::set<std::string> encounteredTypes;
|
||||
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
auto method = service->method(i);
|
||||
vars["arg_in_id"] = to_string(2L * i); //trying to make msvc 10 happy
|
||||
vars["arg_in_id"] = to_string(2L * i); // trying to make msvc 10 happy
|
||||
vars["arg_out_id"] = to_string(2L * i + 1);
|
||||
vars["method_name"] = method->name();
|
||||
vars["input_type_name"] = method->get_input_type_name();
|
||||
|
@ -353,8 +342,10 @@ static void PrintMethodFields(Printer* p, VARS& vars,
|
|||
vars["method_field_name"] = MethodPropertiesFieldName(method.get());
|
||||
vars["method_new_field_name"] = MethodPropertiesGetterName(method.get());
|
||||
vars["method_method_name"] = MethodPropertiesGetterName(method.get());
|
||||
bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
|
||||
bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
|
||||
bool client_streaming =
|
||||
method->ClientStreaming() || method->BidiStreaming();
|
||||
bool server_streaming =
|
||||
method->ServerStreaming() || method->BidiStreaming();
|
||||
if (client_streaming) {
|
||||
if (server_streaming) {
|
||||
vars["method_type"] = "BIDI_STREAMING";
|
||||
|
@ -394,32 +385,32 @@ static void PrintMethodFields(Printer* p, VARS& vars,
|
|||
}
|
||||
|
||||
p->Print(
|
||||
vars,
|
||||
"@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
|
||||
"1901\")\n"
|
||||
"public static $MethodDescriptor$<$input_type$,\n"
|
||||
" $output_type$> $method_method_name$() {\n"
|
||||
" $MethodDescriptor$<$input_type$, $output_type$> "
|
||||
"$method_new_field_name$;\n"
|
||||
" if (($method_new_field_name$ = "
|
||||
"$service_class_name$.$method_new_field_name$) == null) {\n"
|
||||
" synchronized ($service_class_name$.class) {\n"
|
||||
" if (($method_new_field_name$ = "
|
||||
"$service_class_name$.$method_new_field_name$) == null) {\n"
|
||||
" $service_class_name$.$method_new_field_name$ = "
|
||||
"$method_new_field_name$ = \n"
|
||||
" $MethodDescriptor$.<$input_type$, "
|
||||
"$output_type$>newBuilder()\n"
|
||||
" .setType($MethodType$.$method_type$)\n"
|
||||
" .setFullMethodName(generateFullMethodName(\n"
|
||||
" \"$Package$$service_name$\", \"$method_name$\"))\n"
|
||||
" .setSampledToLocalTracing(true)\n"
|
||||
" .setRequestMarshaller(FlatbuffersUtils.marshaller(\n"
|
||||
" $input_type$.class, "
|
||||
"getExtractorOf$input_type_name$()))\n"
|
||||
" .setResponseMarshaller(FlatbuffersUtils.marshaller(\n"
|
||||
" $output_type$.class, "
|
||||
"getExtractorOf$output_type_name$()))\n");
|
||||
vars,
|
||||
"@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
|
||||
"1901\")\n"
|
||||
"public static $MethodDescriptor$<$input_type$,\n"
|
||||
" $output_type$> $method_method_name$() {\n"
|
||||
" $MethodDescriptor$<$input_type$, $output_type$> "
|
||||
"$method_new_field_name$;\n"
|
||||
" if (($method_new_field_name$ = "
|
||||
"$service_class_name$.$method_new_field_name$) == null) {\n"
|
||||
" synchronized ($service_class_name$.class) {\n"
|
||||
" if (($method_new_field_name$ = "
|
||||
"$service_class_name$.$method_new_field_name$) == null) {\n"
|
||||
" $service_class_name$.$method_new_field_name$ = "
|
||||
"$method_new_field_name$ = \n"
|
||||
" $MethodDescriptor$.<$input_type$, "
|
||||
"$output_type$>newBuilder()\n"
|
||||
" .setType($MethodType$.$method_type$)\n"
|
||||
" .setFullMethodName(generateFullMethodName(\n"
|
||||
" \"$Package$$service_name$\", \"$method_name$\"))\n"
|
||||
" .setSampledToLocalTracing(true)\n"
|
||||
" .setRequestMarshaller(FlatbuffersUtils.marshaller(\n"
|
||||
" $input_type$.class, "
|
||||
"getExtractorOf$input_type_name$()))\n"
|
||||
" .setResponseMarshaller(FlatbuffersUtils.marshaller(\n"
|
||||
" $output_type$.class, "
|
||||
"getExtractorOf$output_type_name$()))\n");
|
||||
|
||||
// vars["proto_method_descriptor_supplier"] = service->name() +
|
||||
// "MethodDescriptorSupplier";
|
||||
|
@ -451,11 +442,11 @@ enum StubType {
|
|||
|
||||
enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 };
|
||||
|
||||
static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
|
||||
const ServiceDescriptor* service);
|
||||
static void PrintBindServiceMethodBody(Printer *p, VARS &vars,
|
||||
const ServiceDescriptor *service);
|
||||
|
||||
// Prints a client interface or implementation class, or a server interface.
|
||||
static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
||||
static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service,
|
||||
StubType type) {
|
||||
const string service_name = service->name();
|
||||
vars["service_name"] = service_name;
|
||||
|
@ -476,7 +467,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
break;
|
||||
case BLOCKING_CLIENT_INTERFACE:
|
||||
interface = true;
|
||||
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||
case BLOCKING_CLIENT_IMPL:
|
||||
call_type = BLOCKING_CALL;
|
||||
stub_name += "BlockingStub";
|
||||
|
@ -484,7 +475,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
break;
|
||||
case FUTURE_CLIENT_INTERFACE:
|
||||
interface = true;
|
||||
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||
case FUTURE_CLIENT_IMPL:
|
||||
call_type = FUTURE_CALL;
|
||||
stub_name += "FutureStub";
|
||||
|
@ -501,9 +492,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
vars["client_name"] = client_name;
|
||||
|
||||
// Class head
|
||||
if (!interface) {
|
||||
GrpcWriteServiceDocComment(p, vars, service);
|
||||
}
|
||||
if (!interface) { GrpcWriteServiceDocComment(p, vars, service); }
|
||||
if (impl_base) {
|
||||
p->Print(vars,
|
||||
"public static abstract class $abstract_name$ implements "
|
||||
|
@ -546,8 +535,10 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
|
||||
vars["lower_method_name"] = LowerMethodName(&*method);
|
||||
vars["method_method_name"] = MethodPropertiesGetterName(&*method);
|
||||
bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
|
||||
bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
|
||||
bool client_streaming =
|
||||
method->ClientStreaming() || method->BidiStreaming();
|
||||
bool server_streaming =
|
||||
method->ServerStreaming() || method->BidiStreaming();
|
||||
|
||||
if (call_type == BLOCKING_CALL && client_streaming) {
|
||||
// Blocking client interface with client streaming is not available
|
||||
|
@ -563,9 +554,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
p->Print("\n");
|
||||
// TODO(nmittler): Replace with WriteMethodDocComment once included by the
|
||||
// protobuf distro.
|
||||
if (!interface) {
|
||||
GrpcWriteMethodDocComment(p, vars, &*method);
|
||||
}
|
||||
if (!interface) { GrpcWriteMethodDocComment(p, vars, &*method); }
|
||||
p->Print("public ");
|
||||
switch (call_type) {
|
||||
case BLOCKING_CALL:
|
||||
|
@ -630,8 +619,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
"responseObserver);\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else if (!interface) {
|
||||
switch (call_type) {
|
||||
|
@ -706,15 +694,15 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
|
|||
}
|
||||
|
||||
static bool CompareMethodClientStreaming(
|
||||
const std::unique_ptr<const grpc_generator::Method>& method1,
|
||||
const std::unique_ptr<const grpc_generator::Method>& method2) {
|
||||
const std::unique_ptr<const grpc_generator::Method> &method1,
|
||||
const std::unique_ptr<const grpc_generator::Method> &method2) {
|
||||
return method1->ClientStreaming() < method2->ClientStreaming();
|
||||
}
|
||||
|
||||
// Place all method invocations into a single class to reduce memory footprint
|
||||
// on Android.
|
||||
static void PrintMethodHandlerClass(Printer* p, VARS& vars,
|
||||
const ServiceDescriptor* service) {
|
||||
static void PrintMethodHandlerClass(Printer *p, VARS &vars,
|
||||
const ServiceDescriptor *service) {
|
||||
// Sort method ids based on ClientStreaming() so switch tables are compact.
|
||||
std::vector<std::unique_ptr<const grpc_generator::Method>> sorted_methods(
|
||||
service->method_count());
|
||||
|
@ -724,7 +712,7 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
|
|||
stable_sort(sorted_methods.begin(), sorted_methods.end(),
|
||||
CompareMethodClientStreaming);
|
||||
for (size_t i = 0; i < sorted_methods.size(); i++) {
|
||||
auto& method = sorted_methods[i];
|
||||
auto &method = sorted_methods[i];
|
||||
vars["method_id"] = to_string(i);
|
||||
vars["method_id_name"] = MethodIdFieldName(&*method);
|
||||
p->Print(vars,
|
||||
|
@ -757,9 +745,7 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
|
|||
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
auto method = service->method(i);
|
||||
if (method->ClientStreaming() || method->BidiStreaming()) {
|
||||
continue;
|
||||
}
|
||||
if (method->ClientStreaming() || method->BidiStreaming()) { continue; }
|
||||
vars["method_id_name"] = MethodIdFieldName(&*method);
|
||||
vars["lower_method_name"] = LowerMethodName(&*method);
|
||||
vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
|
||||
|
@ -791,9 +777,7 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
|
|||
|
||||
for (int i = 0; i < service->method_count(); ++i) {
|
||||
auto method = service->method(i);
|
||||
if (!(method->ClientStreaming() || method->BidiStreaming())) {
|
||||
continue;
|
||||
}
|
||||
if (!(method->ClientStreaming() || method->BidiStreaming())) { continue; }
|
||||
vars["method_id_name"] = MethodIdFieldName(&*method);
|
||||
vars["lower_method_name"] = LowerMethodName(&*method);
|
||||
vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
|
||||
|
@ -818,8 +802,8 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
|
|||
p->Print("}\n\n");
|
||||
}
|
||||
|
||||
static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
|
||||
const ServiceDescriptor* service) {
|
||||
static void PrintGetServiceDescriptorMethod(Printer *p, VARS &vars,
|
||||
const ServiceDescriptor *service) {
|
||||
vars["service_name"] = service->name();
|
||||
// vars["proto_base_descriptor_supplier"] = service->name() +
|
||||
// "BaseDescriptorSupplier"; vars["proto_file_descriptor_supplier"] =
|
||||
|
@ -911,8 +895,8 @@ static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
|
|||
p->Print("}\n");
|
||||
}
|
||||
|
||||
static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
|
||||
const ServiceDescriptor* service) {
|
||||
static void PrintBindServiceMethodBody(Printer *p, VARS &vars,
|
||||
const ServiceDescriptor *service) {
|
||||
vars["service_name"] = service->name();
|
||||
p->Indent();
|
||||
p->Print(vars,
|
||||
|
@ -927,8 +911,10 @@ static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
|
|||
vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
|
||||
vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
|
||||
vars["method_id_name"] = MethodIdFieldName(&*method);
|
||||
bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
|
||||
bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
|
||||
bool client_streaming =
|
||||
method->ClientStreaming() || method->BidiStreaming();
|
||||
bool server_streaming =
|
||||
method->ServerStreaming() || method->BidiStreaming();
|
||||
if (client_streaming) {
|
||||
if (server_streaming) {
|
||||
vars["calls_method"] = "asyncBidiStreamingCall";
|
||||
|
@ -962,8 +948,8 @@ static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
|
|||
p->Outdent();
|
||||
}
|
||||
|
||||
static void PrintService(Printer* p, VARS& vars,
|
||||
const ServiceDescriptor* service,
|
||||
static void PrintService(Printer *p, VARS &vars,
|
||||
const ServiceDescriptor *service,
|
||||
bool disable_version) {
|
||||
vars["service_name"] = service->name();
|
||||
vars["service_class_name"] = ServiceClassName(service->name());
|
||||
|
@ -1043,7 +1029,7 @@ static void PrintService(Printer* p, VARS& vars,
|
|||
p->Print("}\n");
|
||||
}
|
||||
|
||||
void PrintStaticImports(Printer* p) {
|
||||
void PrintStaticImports(Printer *p) {
|
||||
p->Print(
|
||||
"import java.nio.ByteBuffer;\n"
|
||||
"import static "
|
||||
|
@ -1076,8 +1062,8 @@ void PrintStaticImports(Printer* p) {
|
|||
"io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n");
|
||||
}
|
||||
|
||||
void GenerateService(const grpc_generator::Service* service,
|
||||
grpc_generator::Printer* printer, VARS& vars,
|
||||
void GenerateService(const grpc_generator::Service *service,
|
||||
grpc_generator::Printer *printer, VARS &vars,
|
||||
bool disable_version) {
|
||||
// All non-generated classes must be referred by fully qualified names to
|
||||
// avoid collision with generated classes.
|
||||
|
@ -1113,8 +1099,8 @@ void GenerateService(const grpc_generator::Service* service,
|
|||
}
|
||||
|
||||
grpc::string GenerateServiceSource(
|
||||
grpc_generator::File* file, const grpc_generator::Service* service,
|
||||
grpc_java_generator::Parameters* parameters) {
|
||||
grpc_generator::File *file, const grpc_generator::Service *service,
|
||||
grpc_java_generator::Parameters *parameters) {
|
||||
grpc::string out;
|
||||
auto printer = file->CreatePrinter(&out);
|
||||
VARS vars;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
#include "src/compiler/config.h"
|
||||
#include "src/compiler/schema_interface.h"
|
||||
|
||||
namespace grpc_python_generator {
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "src/compiler/config.h"
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
# include <string>
|
||||
# define GRPC_CUSTOM_STRING std::string
|
||||
|
|
|
@ -1,40 +1,22 @@
|
|||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Copyright 2020, Google Inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "src/compiler/config.h"
|
||||
#include "src/compiler/schema_interface.h"
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
|
|
|
@ -1,41 +1,7 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2020, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "src/compiler/config.h"
|
||||
#include "src/compiler/schema_interface.h"
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
|
@ -58,4 +24,3 @@ grpc::string GenerateInterface(grpc_generator::File *file,
|
|||
const grpc_generator::Service *service,
|
||||
const grpc::string &filename);
|
||||
} // namespace grpc_ts_generator
|
||||
|
||||
|
|
|
@ -285,9 +285,7 @@ class FlatBufferBuilder {
|
|||
FieldLoc fl = { off, field };
|
||||
buf_.scratch_push_small(fl);
|
||||
num_field_loc++;
|
||||
if (field > max_voffset_) {
|
||||
max_voffset_ = field;
|
||||
}
|
||||
if (field > max_voffset_) { max_voffset_ = field; }
|
||||
}
|
||||
|
||||
// Like PushElement, but additionally tracks the field this represents.
|
||||
|
@ -1074,7 +1072,7 @@ class FlatBufferBuilder {
|
|||
void SwapBufAllocator(FlatBufferBuilder &other) {
|
||||
buf_.swap_allocator(other.buf_);
|
||||
}
|
||||
|
||||
|
||||
/// @brief The length of a FlatBuffer file header.
|
||||
static const size_t kFileIdentifierLength =
|
||||
::flatbuffers::kFileIdentifierLength;
|
||||
|
|
|
@ -226,27 +226,13 @@ struct TypeTable {
|
|||
};
|
||||
|
||||
// String which identifies the current version of FlatBuffers.
|
||||
// flatbuffer_version_string is used by Google developers to identify which
|
||||
// applications uploaded to Google Play are using this library. This allows
|
||||
// the development team at Google to determine the popularity of the library.
|
||||
// How it works: Applications that are uploaded to the Google Play Store are
|
||||
// scanned for this version string. We track which applications are using it
|
||||
// to measure popularity. You are free to remove it (of course) but we would
|
||||
// appreciate if you left it in.
|
||||
inline const char *flatbuffers_version_string() {
|
||||
return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
|
||||
}
|
||||
|
||||
// Weak linkage is culled by VS & doesn't work on cygwin.
|
||||
// clang-format off
|
||||
#if !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|
||||
extern volatile __attribute__((weak)) const char *flatbuffer_version_string;
|
||||
volatile __attribute__((weak)) const char *flatbuffer_version_string =
|
||||
"FlatBuffers "
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
|
||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
|
||||
|
||||
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|
||||
#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
|
||||
inline E operator | (E lhs, E rhs){\
|
||||
return E(T(lhs) | T(rhs));\
|
||||
|
|
|
@ -49,6 +49,8 @@ class FlatCompiler {
|
|||
typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
typedef bool (*ParsingCompletedFn)(const flatbuffers::Parser &parser,
|
||||
const std::string &output_path);
|
||||
|
||||
GenerateFn generate;
|
||||
const char *lang_name;
|
||||
|
@ -58,6 +60,7 @@ class FlatCompiler {
|
|||
FlatCOption option;
|
||||
MakeRuleFn make_rule;
|
||||
BfbsGenerator *bfbs_generator;
|
||||
ParsingCompletedFn parsing_completed;
|
||||
};
|
||||
|
||||
typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
|
||||
|
@ -84,6 +87,7 @@ class FlatCompiler {
|
|||
|
||||
int Compile(int argc, const char **argv);
|
||||
|
||||
std::string GetShortUsageString(const char *program_name) const;
|
||||
std::string GetUsageString(const char *program_name) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -371,10 +371,7 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted) {
|
|||
class Reference {
|
||||
public:
|
||||
Reference()
|
||||
: data_(nullptr),
|
||||
parent_width_(0),
|
||||
byte_width_(0),
|
||||
type_(FBT_NULL) {}
|
||||
: data_(nullptr), parent_width_(0), byte_width_(0), type_(FBT_NULL) {}
|
||||
|
||||
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
|
||||
Type type)
|
||||
|
@ -1645,8 +1642,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
// comes at the cost of using additional memory the same size of
|
||||
// the buffer being verified, so it is by default off.
|
||||
std::vector<uint8_t> *reuse_tracker = nullptr,
|
||||
bool _check_alignment = true,
|
||||
size_t max_depth = 64)
|
||||
bool _check_alignment = true, size_t max_depth = 64)
|
||||
: buf_(buf),
|
||||
size_(buf_len),
|
||||
depth_(0),
|
||||
|
@ -1689,18 +1685,16 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
auto o = static_cast<size_t>(p - buf_);
|
||||
return VerifyBefore(o, len);
|
||||
}
|
||||
|
||||
|
||||
bool VerifyByteWidth(size_t width) {
|
||||
return Check(width == 1 || width == 2 || width == 4 || width == 8);
|
||||
}
|
||||
|
||||
bool VerifyType(int type) {
|
||||
return Check(type >= 0 && type < FBT_MAX_TYPE);
|
||||
}
|
||||
bool VerifyType(int type) { return Check(type >= 0 && type < FBT_MAX_TYPE); }
|
||||
|
||||
bool VerifyOffset(uint64_t off, const uint8_t *p) {
|
||||
return Check(off <= static_cast<uint64_t>(size_)) &&
|
||||
off <= static_cast<uint64_t>(p - buf_);
|
||||
off <= static_cast<uint64_t>(p - buf_);
|
||||
}
|
||||
|
||||
bool VerifyAlignment(const uint8_t *p, size_t size) const {
|
||||
|
@ -1708,16 +1702,16 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
return Check((o & (size - 1)) == 0 || !check_alignment_);
|
||||
}
|
||||
|
||||
// Macro, since we want to escape from parent function & use lazy args.
|
||||
#define FLEX_CHECK_VERIFIED(P, PACKED_TYPE) \
|
||||
if (reuse_tracker_) { \
|
||||
auto packed_type = PACKED_TYPE; \
|
||||
auto existing = (*reuse_tracker_)[P - buf_]; \
|
||||
if (existing == packed_type) return true; \
|
||||
/* Fail verification if already set with different type! */ \
|
||||
if (!Check(existing == 0)) return false; \
|
||||
(*reuse_tracker_)[P - buf_] = packed_type; \
|
||||
}
|
||||
// Macro, since we want to escape from parent function & use lazy args.
|
||||
#define FLEX_CHECK_VERIFIED(P, PACKED_TYPE) \
|
||||
if (reuse_tracker_) { \
|
||||
auto packed_type = PACKED_TYPE; \
|
||||
auto existing = (*reuse_tracker_)[P - buf_]; \
|
||||
if (existing == packed_type) return true; \
|
||||
/* Fail verification if already set with different type! */ \
|
||||
if (!Check(existing == 0)) return false; \
|
||||
(*reuse_tracker_)[P - buf_] = packed_type; \
|
||||
}
|
||||
|
||||
bool VerifyVector(Reference r, const uint8_t *p, Type elem_type) {
|
||||
// Any kind of nesting goes thru this function, so guard against that
|
||||
|
@ -1727,19 +1721,19 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
if (!Check(depth_ <= max_depth_ && num_vectors_ <= max_vectors_))
|
||||
return false;
|
||||
auto size_byte_width = r.byte_width_;
|
||||
FLEX_CHECK_VERIFIED(p, PackedType(Builder::WidthB(size_byte_width), r.type_));
|
||||
if (!VerifyBeforePointer(p, size_byte_width))
|
||||
return false;
|
||||
FLEX_CHECK_VERIFIED(p,
|
||||
PackedType(Builder::WidthB(size_byte_width), r.type_));
|
||||
if (!VerifyBeforePointer(p, size_byte_width)) return false;
|
||||
auto sized = Sized(p, size_byte_width);
|
||||
auto num_elems = sized.size();
|
||||
auto elem_byte_width =
|
||||
r.type_ == FBT_STRING || r.type_ == FBT_BLOB ? uint8_t(1) : r.byte_width_;
|
||||
auto elem_byte_width = r.type_ == FBT_STRING || r.type_ == FBT_BLOB
|
||||
? uint8_t(1)
|
||||
: r.byte_width_;
|
||||
auto max_elems = SIZE_MAX / elem_byte_width;
|
||||
if (!Check(num_elems < max_elems))
|
||||
return false; // Protect against byte_size overflowing.
|
||||
auto byte_size = num_elems * elem_byte_width;
|
||||
if (!VerifyFromPointer(p, byte_size))
|
||||
return false;
|
||||
if (!VerifyFromPointer(p, byte_size)) return false;
|
||||
if (elem_type == FBT_NULL) {
|
||||
// Verify type bytes after the vector.
|
||||
if (!VerifyFromPointer(p + byte_size, num_elems)) return false;
|
||||
|
@ -1760,28 +1754,25 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
bool VerifyKeys(const uint8_t *p, uint8_t byte_width) {
|
||||
// The vector part of the map has already been verified.
|
||||
const size_t num_prefixed_fields = 3;
|
||||
if (!VerifyBeforePointer(p, byte_width * num_prefixed_fields))
|
||||
return false;
|
||||
if (!VerifyBeforePointer(p, byte_width * num_prefixed_fields)) return false;
|
||||
p -= byte_width * num_prefixed_fields;
|
||||
auto off = ReadUInt64(p, byte_width);
|
||||
if (!VerifyOffset(off, p))
|
||||
return false;
|
||||
if (!VerifyOffset(off, p)) return false;
|
||||
auto key_byte_with =
|
||||
static_cast<uint8_t>(ReadUInt64(p + byte_width, byte_width));
|
||||
if (!VerifyByteWidth(key_byte_with))
|
||||
return false;
|
||||
static_cast<uint8_t>(ReadUInt64(p + byte_width, byte_width));
|
||||
if (!VerifyByteWidth(key_byte_with)) return false;
|
||||
return VerifyVector(Reference(p, byte_width, key_byte_with, FBT_VECTOR_KEY),
|
||||
p - off, FBT_KEY);
|
||||
}
|
||||
|
||||
bool VerifyKey(const uint8_t* p) {
|
||||
bool VerifyKey(const uint8_t *p) {
|
||||
FLEX_CHECK_VERIFIED(p, PackedType(BIT_WIDTH_8, FBT_KEY));
|
||||
while (p < buf_ + size_)
|
||||
if (*p++) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef FLEX_CHECK_VERIFIED
|
||||
#undef FLEX_CHECK_VERIFIED
|
||||
|
||||
bool VerifyTerminator(const String &s) {
|
||||
return VerifyFromPointer(reinterpret_cast<const uint8_t *>(s.c_str()),
|
||||
|
@ -1799,37 +1790,26 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
}
|
||||
// All remaining types are an offset.
|
||||
auto off = ReadUInt64(r.data_, r.parent_width_);
|
||||
if (!VerifyOffset(off, r.data_))
|
||||
return false;
|
||||
if (!VerifyOffset(off, r.data_)) return false;
|
||||
auto p = r.Indirect();
|
||||
if (!VerifyAlignment(p, r.byte_width_))
|
||||
return false;
|
||||
if (!VerifyAlignment(p, r.byte_width_)) return false;
|
||||
switch (r.type_) {
|
||||
case FBT_INDIRECT_INT:
|
||||
case FBT_INDIRECT_UINT:
|
||||
case FBT_INDIRECT_FLOAT:
|
||||
return VerifyFromPointer(p, r.byte_width_);
|
||||
case FBT_KEY:
|
||||
return VerifyKey(p);
|
||||
case FBT_INDIRECT_FLOAT: return VerifyFromPointer(p, r.byte_width_);
|
||||
case FBT_KEY: return VerifyKey(p);
|
||||
case FBT_MAP:
|
||||
return VerifyVector(r, p, FBT_NULL) &&
|
||||
VerifyKeys(p, r.byte_width_);
|
||||
case FBT_VECTOR:
|
||||
return VerifyVector(r, p, FBT_NULL);
|
||||
case FBT_VECTOR_INT:
|
||||
return VerifyVector(r, p, FBT_INT);
|
||||
return VerifyVector(r, p, FBT_NULL) && VerifyKeys(p, r.byte_width_);
|
||||
case FBT_VECTOR: return VerifyVector(r, p, FBT_NULL);
|
||||
case FBT_VECTOR_INT: return VerifyVector(r, p, FBT_INT);
|
||||
case FBT_VECTOR_BOOL:
|
||||
case FBT_VECTOR_UINT:
|
||||
return VerifyVector(r, p, FBT_UINT);
|
||||
case FBT_VECTOR_FLOAT:
|
||||
return VerifyVector(r, p, FBT_FLOAT);
|
||||
case FBT_VECTOR_KEY:
|
||||
return VerifyVector(r, p, FBT_KEY);
|
||||
case FBT_VECTOR_UINT: return VerifyVector(r, p, FBT_UINT);
|
||||
case FBT_VECTOR_FLOAT: return VerifyVector(r, p, FBT_FLOAT);
|
||||
case FBT_VECTOR_KEY: return VerifyVector(r, p, FBT_KEY);
|
||||
case FBT_VECTOR_STRING_DEPRECATED:
|
||||
// Use of FBT_KEY here intentional, see elsewhere.
|
||||
return VerifyVector(r, p, FBT_KEY);
|
||||
case FBT_BLOB:
|
||||
return VerifyVector(r, p, FBT_UINT);
|
||||
case FBT_BLOB: return VerifyVector(r, p, FBT_UINT);
|
||||
case FBT_STRING:
|
||||
return VerifyVector(r, p, FBT_UINT) &&
|
||||
VerifyTerminator(String(p, r.byte_width_));
|
||||
|
@ -1844,12 +1824,10 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
case FBT_VECTOR_FLOAT4: {
|
||||
uint8_t len = 0;
|
||||
auto vtype = ToFixedTypedVectorElementType(r.type_, &len);
|
||||
if (!VerifyType(vtype))
|
||||
return false;
|
||||
if (!VerifyType(vtype)) return false;
|
||||
return VerifyFromPointer(p, r.byte_width_ * len);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1859,8 +1837,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
auto end = buf_ + size_;
|
||||
auto byte_width = *--end;
|
||||
auto packed_type = *--end;
|
||||
return VerifyByteWidth(byte_width) &&
|
||||
Check(end - buf_ >= byte_width) &&
|
||||
return VerifyByteWidth(byte_width) && Check(end - buf_ >= byte_width) &&
|
||||
VerifyRef(Reference(end - byte_width, byte_width, packed_type));
|
||||
}
|
||||
|
||||
|
@ -1875,14 +1852,14 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
std::vector<uint8_t> *reuse_tracker_;
|
||||
};
|
||||
|
||||
// Utility function that contructs the Verifier for you, see above for parameters.
|
||||
// Utility function that contructs the Verifier for you, see above for
|
||||
// parameters.
|
||||
inline bool VerifyBuffer(const uint8_t *buf, size_t buf_len,
|
||||
std::vector<uint8_t> *reuse_tracker = nullptr) {
|
||||
Verifier verifier(buf, buf_len, reuse_tracker);
|
||||
return verifier.VerifyBuffer();
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLATBUFFERS_H_
|
||||
// This is a verifier utility function that works together with the
|
||||
// FlatBuffers verifier, which should only be present if flatbuffer.h
|
||||
|
@ -1890,9 +1867,8 @@ inline bool VerifyBuffer(const uint8_t *buf, size_t buf_len,
|
|||
inline bool VerifyNestedFlexBuffer(const flatbuffers::Vector<uint8_t> *nv,
|
||||
flatbuffers::Verifier &verifier) {
|
||||
if (!nv) return true;
|
||||
return verifier.Check(
|
||||
flexbuffers::VerifyBuffer(nv->data(), nv->size(),
|
||||
verifier.GetFlexReuseTracker()));
|
||||
return verifier.Check(flexbuffers::VerifyBuffer(
|
||||
nv->data(), nv->size(), verifier.GetFlexReuseTracker()));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -72,8 +72,8 @@ namespace flatbuffers {
|
|||
// - Go type.
|
||||
// - C# / .Net type.
|
||||
// - Python type.
|
||||
// - Rust type.
|
||||
// - Kotlin type.
|
||||
// - Rust type.
|
||||
|
||||
// using these macros, we can now write code dealing with types just once, e.g.
|
||||
|
||||
|
@ -468,6 +468,10 @@ inline bool IsUnion(const Type &type) {
|
|||
return type.enum_def != nullptr && type.enum_def->is_union;
|
||||
}
|
||||
|
||||
inline bool IsUnionType(const Type &type) {
|
||||
return IsUnion(type) && IsInteger(type.base_type);
|
||||
}
|
||||
|
||||
inline bool IsVector(const Type &type) {
|
||||
return type.base_type == BASE_TYPE_VECTOR;
|
||||
}
|
||||
|
@ -591,6 +595,7 @@ struct IDLOptions {
|
|||
std::string filename_suffix;
|
||||
std::string filename_extension;
|
||||
bool no_warnings;
|
||||
bool warnings_as_errors;
|
||||
std::string project_root;
|
||||
bool cs_global_alias;
|
||||
bool json_nested_flatbuffers;
|
||||
|
@ -625,6 +630,9 @@ struct IDLOptions {
|
|||
// If set, require all fields in a table to be explicitly numbered.
|
||||
bool require_explicit_ids;
|
||||
|
||||
// If set, implement serde::Serialize for generated Rust types
|
||||
bool rust_serialize;
|
||||
|
||||
// The corresponding language bit will be set if a language is included
|
||||
// for code generation.
|
||||
unsigned long lang_to_generate;
|
||||
|
@ -681,6 +689,7 @@ struct IDLOptions {
|
|||
filename_suffix("_generated"),
|
||||
filename_extension(),
|
||||
no_warnings(false),
|
||||
warnings_as_errors(false),
|
||||
project_root(""),
|
||||
cs_global_alias(false),
|
||||
json_nested_flatbuffers(true),
|
||||
|
@ -688,6 +697,7 @@ struct IDLOptions {
|
|||
json_nested_legacy_flatbuffers(false),
|
||||
mini_reflect(IDLOptions::kNone),
|
||||
require_explicit_ids(false),
|
||||
rust_serialize(false),
|
||||
lang_to_generate(0),
|
||||
set_empty_strings_to_null(true),
|
||||
set_empty_vectors_to_null(true) {}
|
||||
|
@ -787,6 +797,7 @@ class Parser : public ParserState {
|
|||
root_struct_def_(nullptr),
|
||||
opts(options),
|
||||
uses_flexbuffers_(false),
|
||||
has_warning_(false),
|
||||
advanced_features_(0),
|
||||
source_(nullptr),
|
||||
anonymous_counter_(0),
|
||||
|
@ -1021,6 +1032,7 @@ class Parser : public ParserState {
|
|||
|
||||
IDLOptions opts;
|
||||
bool uses_flexbuffers_;
|
||||
bool has_warning_;
|
||||
|
||||
uint64_t advanced_features_;
|
||||
|
||||
|
|
|
@ -1413,6 +1413,11 @@ inline bool SchemaBufferHasIdentifier(const void *buf) {
|
|||
buf, SchemaIdentifier());
|
||||
}
|
||||
|
||||
inline bool SizePrefixedSchemaBufferHasIdentifier(const void *buf) {
|
||||
return flatbuffers::BufferHasIdentifier(
|
||||
buf, SchemaIdentifier(), true);
|
||||
}
|
||||
|
||||
inline bool VerifySchemaBuffer(
|
||||
flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());
|
||||
|
|
|
@ -112,18 +112,19 @@ class Table {
|
|||
|
||||
// Verify a particular field.
|
||||
template<typename T>
|
||||
bool VerifyField(const Verifier &verifier, voffset_t field, size_t align) const {
|
||||
bool VerifyField(const Verifier &verifier, voffset_t field,
|
||||
size_t align) const {
|
||||
// Calling GetOptionalFieldOffset should be safe now thanks to
|
||||
// VerifyTable().
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
// Check the actual field.
|
||||
return !field_offset ||
|
||||
verifier.VerifyField<T>(data_, field_offset, align);
|
||||
return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
|
||||
}
|
||||
|
||||
// VerifyField for required fields.
|
||||
template<typename T>
|
||||
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field, size_t align) const {
|
||||
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
|
||||
size_t align) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return verifier.Check(field_offset != 0) &&
|
||||
verifier.VerifyField<T>(data_, field_offset, align);
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
#ifndef FLATBUFFERS_UTIL_H_
|
||||
#define FLATBUFFERS_UTIL_H_
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/stl_emulation.h"
|
||||
|
||||
#ifndef FLATBUFFERS_PREFER_PRINTF
|
||||
# include <sstream>
|
||||
# include <iomanip>
|
||||
# include <sstream>
|
||||
#else // FLATBUFFERS_PREFER_PRINTF
|
||||
# include <float.h>
|
||||
# include <stdio.h>
|
||||
|
|
|
@ -81,14 +81,15 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
}
|
||||
|
||||
// Verify relative to a known-good base pointer.
|
||||
bool VerifyFieldStruct(const uint8_t *base, voffset_t elem_off, size_t elem_len,
|
||||
size_t align) const {
|
||||
bool VerifyFieldStruct(const uint8_t *base, voffset_t elem_off,
|
||||
size_t elem_len, size_t align) const {
|
||||
auto f = static_cast<size_t>(base - buf_) + elem_off;
|
||||
return VerifyAlignment(f, align) && Verify(f, elem_len);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool VerifyField(const uint8_t *base, voffset_t elem_off, size_t align) const {
|
||||
bool VerifyField(const uint8_t *base, voffset_t elem_off,
|
||||
size_t align) const {
|
||||
auto f = static_cast<size_t>(base - buf_) + elem_off;
|
||||
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
|
||||
}
|
||||
|
@ -259,9 +260,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
std::vector<uint8_t> *GetFlexReuseTracker() {
|
||||
return flex_reuse_tracker_;
|
||||
}
|
||||
std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; }
|
||||
|
||||
void SetFlexReuseTracker(std::vector<uint8_t> *rt) {
|
||||
flex_reuse_tracker_ = rt;
|
||||
|
|
Loading…
Reference in New Issue